Improve editor UI

Improve editor UI

You can use the render methods to customize how content is displayed in Val Studio and make the UI easier to navigate.

Multiline strings

Sometimes you want something that is not richtext but still multiple lines. Simple descriptions or even code blocks for example. Use render({ as: "textarea" }) to change the input to a multi-line textarea, making it easier to edit longer text content.

const articleSchema = s.object({
  title: s.string(),
  // Multi-line textarea for longer descriptions
  description: s.string().render({ as: "textarea" }),
  body: s.richtext(),
});

export default c.define("/content/article.val.ts", articleSchema, {
  title: "My Article",
  description: "This is a longer description that benefits from a textarea input.\nIt can span multiple lines.",
  body: s.richtext([
    { tag: "p", children: ["Article content..."] },
  ]),
});

Code editor for strings

For strings that contain code, configuration, or structured data, you can use render({ as: "code", language: "..." }) to display a code editor with syntax highlighting. This provides a much better editing experience for technical content.

const configSchema = s.object({
  title: s.string(),
  // JSON configuration with syntax highlighting
  apiConfig: s.string().render({ as: "code", language: "json" }),
  // TypeScript code snippet
  customHook: s.string().render({ as: "code", language: "typescript" }),
  // CSS styles
  customStyles: s.string().render({ as: "code", language: "css" }),
});

export default c.define("/content/config.val.ts", configSchema, {
  title: "API Configuration",
  apiConfig: JSON.stringify({
    endpoint: "https://api.example.com",
    timeout: 5000,
    retries: 3
  }, null, 2),
  customHook: `export function useCustomHook() {
  const [state, setState] = useState();
  return state;
}`,
  customStyles: `.custom-class {
  color: blue;
  font-size: 16px;
}`,
});

Supported languages

The code editor supports syntax highlighting for many popular languages including:

  • JavaScript and TypeScript

  • JSON, YAML, TOML

  • HTML, CSS, SCSS

  • Python, Java, Go, Rust

  • SQL, GraphQL

  • Markdown, Shell/Bash

List view

When working with records of objects, you can use render({ as: "list" }) to display items as a nice looking list with thumbnails. This makes it much easier for editors to navigate and edit collections of content.

Basic list view

The select() function determines what information is displayed in the list view. You can show a title, subtitle, and image for each item.

const teamSchema = s.record(
  s.object({
    name: s.string(),
    position: s.string(),
    bio: s.string().render({ as: "textarea" }),
    image: s.image(),
  })
).render({
  as: "list",
  select({ val }) {
    return {
      title: val.name,
      subtitle: val.position,
      image: val.image,
    };
  },
});

export default c.define("/content/team.val.ts", teamSchema, {
  "john-doe": {
    name: "John Doe",
    position: "Software Engineer",
    bio: "John has been building web applications for over 10 years.",
    image: c.image("/public/team/john.jpg"),
  },
  "jane-smith": {
    name: "Jane Smith",
    position: "Product Designer",
    bio: "Jane specializes in user experience and interface design.",
    image: c.image("/public/team/jane.jpg"),
  },
});

List view benefits

Using list view makes it significantly easier for editors to browse and manage collections. Instead of navigating through a tree of items, editors see a visual list with thumbnails and key information at a glance.

Customizing list display

The select() function receives the current value in the val parameter. You can return any combination of title, subtitle, and image. Both subtitle and image are optional.