Skip to content

Enrich builtin component schemas with property descriptions and enum constraints #70

@geoffjay

Description

@geoffjay

Summary

Add per-property descriptions and enum (OneOf) constraints to all builtin component schemas in nemo-registry so the LSP can provide rich hover documentation and accurate enum value completions.

Context

The nemo-lsp server (#62) provides:

  • Hover documentation: sourced from PropertySchema.description
  • Enum value completions: sourced from ValidationRule::OneOf on string-typed properties

Currently, the builtin component schemas in crates/nemo-registry/src/builtins.rs have:

  • ✅ Component-level display names and descriptions (via ComponentMetadata)
  • ✅ Property names and types (via ConfigSchema::property(name, type))
  • ❌ No .description() calls on individual properties → no per-property hover docs
  • ❌ No .one_of() constraints on enum-like string properties → no enum completions
  • ❌ Sparse .require() calls → incomplete required-field validation

Example: The button component has variant: PropertySchema::string().with_default("primary") — the LSP has no way to know valid variants are ["primary", "secondary", "danger", "ghost"].

Acceptance Criteria

Property descriptions

  • Every property in every builtin component has a .description() call with a concise one-line description
  • Descriptions include the expected type in human-readable form (e.g., "text to display (string)")
  • Properties with defaults mention the default value (e.g., "layout direction, \"vertical\" or \"horizontal\"")

Enum constraints

  • All string properties with a known fixed set of values use .one_of():
    • button.variant["primary", "secondary", "danger", "ghost"]
    • button.size["xs", "sm", "md", "lg", "xl"]
    • stack.direction["vertical", "horizontal"]
    • radio.direction["vertical", "horizontal"]
    • dock.position["top", "bottom", "left", "right", "center"]
    • alert.variant["info", "success", "warning", "error"]
    • progress.variant["determinate", "indeterminate"]
    • spinner.variant (if applicable)
    • code_editor.language["plain", "rust", "javascript", "typescript", "python", "json", "xml", "toml", "yaml", "css", "html", "sql"]
    • avatar.shape["circle", "square"]
    • badge.variant["default", "primary", "success", "warning", "danger"]
    • theme.mode["light", "dark", "system"]
  • Enum values are consistent with what the GPUI rendering code actually supports
  • Chart component properties with constrained values use .one_of()

Required field validation

  • All components that have truly required properties mark them with .require():
    • label requires text
    • image requires src
    • icon requires name
    • select requires options
    • checkbox requires label
    • radio requires options
    • slider requires value
    • table requires columns
    • Data source http requires url
  • Required field list is verified against actual component implementations

Verification

  • cargo test -p nemo-registry — existing tests still pass
  • Manual check: run nemo storybook and verify no schema changes broke rendering
  • Manual check: a quick script that iterates all builtin schemas and lists properties missing descriptions

Guidance for each component category

Layout (dock, stack, panel, tabs)

  • Direction properties need enum + description
  • Sizing properties (width, height, min_width, etc.) need descriptions about CSS-like values

Input (button, input, textarea, select, checkbox, radio, slider, switch, toggle, code_editor, text_editor)

  • variant on button needs description + enum
  • type attributes (if present) need enum for "text", "password", "email", "number"
  • Slider min/max/step need descriptions about allowed ranges

Display (label, icon, image, spinner, progress, tag, avatar, alert)

  • text on label should be marked required
  • src on image should be marked required
  • Progress variant needs enum

Data (table, tree, list, accordion)

  • columns on table should be marked required
  • items on list/tree needs description

Charts (line-chart, bar-chart, etc.)

  • data-source, x-field, y-field properties should be consistently named and described

Feedback (modal, tooltip, badge, notification, collapsible)

  • Badge and alert variants need enum
  • Modal open state needs description

Relevant Files

  • crates/nemo-registry/src/builtins.rs — All builtin component schema definitions
  • crates/nemo-config/src/schema.rsPropertySchema, .description(), .one_of(), .require()
  • crates/nemo-registry/src/descriptor.rsComponentMetadata (already has component-level descriptions)

Stack Base

  • Stack on: main
  • Blocked by: none (independent schema data improvement)

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions