Skip to content

Implement visual designer for Object UI schemas - #1

Merged
huangyiirene merged 10 commits into
mainfrom
copilot/add-designer-feature
Jan 13, 2026
Merged

Implement visual designer for Object UI schemas#1
huangyiirene merged 10 commits into
mainfrom
copilot/add-designer-feature

Conversation

CopilotAI commented Jan 13, 2026

Copy link
Copy Markdown
Contributor

Adds @object-ui/designer package - a visual editor for creating and modifying Object UI schemas through a GUI.

Components

  • DesignerContext: State management for schema, selection, and CRUD operations
  • Canvas: Live preview with click-to-select and visual highlighting
  • ComponentPalette: Categorized browser for 50+ components (Form, Layout, Overlay, etc.)
  • PropertyPanel: Dynamic forms generated from component metadata with type-specific inputs
  • Toolbar: JSON import/export with modal editor
  • Designer: Main component integrating three-column layout

Usage

import{Designer}from'@object-ui/designer';functionApp(){const[schema,setSchema]=useState({type: 'div',body: []});return<DesignerinitialSchema={schema}onSchemaChange={setSchema}/>;}

Implementation Details

  • Real-time preview updates on property changes
  • Automatic ID generation for all nodes
  • Recursive tree operations for nested schemas
  • Support for both single-node and array body types
  • Click-to-add workflow (drag-and-drop deferred)

Documentation

  • English README with API reference
  • Chinese implementation guide
  • Visual layout documentation
  • Working demo application

Node operations handle schema mutation immutably. Selection state syncs across all panels via Context. Component metadata drives property form generation dynamically.

Original prompt

帮我开发设计器


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

CopilotAIand others added 4 commits January 13, 2026 11:31
Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com>
Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com>
Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com>
Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com>
CopilotAI changed the title [WIP] Add designer feature to applicationImplement visual designer for Object UI schemasJan 13, 2026
@huangyiirene
huangyiirene requested review from Copilot and removed request for huangyiireneJanuary 13, 2026 11:58

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements a comprehensive visual designer package for creating and modifying Object UI schemas through a graphical interface. The designer provides real-time preview, component palette, property editing, and JSON import/export capabilities.

Changes:

  • Added @object-ui/designer package with 6 core React components
  • Implemented context-based state management for schema operations
  • Created demo application with Vite + React 19
  • Added comprehensive documentation (English README, Chinese implementation guide, visual guide)

Reviewed changes

Copilot reviewed 21 out of 22 changed files in this pull request and generated 5 comments.

Show a summary per file
FileDescription
packages/designer/tsconfig.jsonConfigured TypeScript with ES2020 target, module paths, and build settings
packages/designer/src/index.tsMain entry point exporting Designer components, context, hooks, and types
packages/designer/src/context/DesignerContext.tsxState management context with schema CRUD operations and helper functions
packages/designer/src/components/Toolbar.tsxTop toolbar with JSON import/export and modal editor
packages/designer/src/components/PropertyPanel.tsxDynamic property editor with type-specific inputs
packages/designer/src/components/Designer.tsxMain component integrating three-column layout
packages/designer/src/components/ComponentPalette.tsxCategorized component browser with click-to-add functionality
packages/designer/src/components/Canvas.tsxLive preview canvas with selection and hover highlighting
packages/designer/package.jsonPackage configuration with dependencies and scripts
packages/designer/VISUAL_GUIDE.mdVisual documentation of interface layout and features
packages/designer/README.mdComprehensive usage guide with API reference
packages/designer/IMPLEMENTATION.zh-CN.mdChinese implementation guide
examples/designer-demo/*Complete demo application setup
DESIGNER_SUMMARY.mdBilingual implementation summary
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadpackages/designer/tsconfig.json Outdated
},
"include": ["src"]
"include": ["src"],
"exclude": ["node_modules", "dist", "../renderer", "../ui"]

CopilotAIJan 13, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The exclude pattern '../renderer' and '../ui' use relative paths that may not work as intended from the tsconfig location. Consider using absolute patterns or verifying these paths exclude the intended directories.

Suggested change
"exclude": ["node_modules", "dist", "../renderer", "../ui"]
"exclude": ["node_modules", "dist"]

Copilot uses AI. Check for mistakes.

// Helper function to ensure all nodes have unique IDs
const ensureNodeIds = (node: SchemaNode, idPrefix = ''): SchemaNode => {
const nodeId = node.id || `${idPrefix}${node.type}-${Math.random().toString(36).substr(2, 9)}`;

CopilotAIJan 13, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using Math.random() for ID generation can result in collisions. Consider using a more robust ID generation method like crypto.randomUUID() or a library like uuid for guaranteed uniqueness.

Copilot uses AI. Check for mistakes.

const handleCopyJson = () => {
navigator.clipboard.writeText(JSON.stringify(schema, null, 2));
alert('Schema copied to clipboard!');

CopilotAIJan 13, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using alert() is not user-friendly and blocks the UI. Consider using a toast notification or non-blocking feedback mechanism instead.

Copilot uses AI. Check for mistakes.
};

const handleDelete = () => {
if (confirm('Are you sure you want to delete this component?')) {

CopilotAIJan 13, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using confirm() is not consistent with modern UI patterns. Consider using a custom dialog component or alert-dialog from @object-ui/ui for better user experience.

Copilot uses AI. Check for mistakes.
Comment on lines +2 to +8
content: [
"./index.html",
"./src/**/*.{js,ts,jsx,tsx}",
"../../packages/ui/src/**/*.{js,ts,jsx,tsx}",
"../../packages/renderer/src/**/*.{js,ts,jsx,tsx}",
"../../packages/designer/src/**/*.{js,ts,jsx,tsx}",
],

CopilotAIJan 13, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 'content' field is for Tailwind CSS configuration, not PostCSS. This configuration should be in tailwind.config.js. PostCSS config should only contain plugins like 'tailwindcss' and 'autoprefixer'.

Suggested change
content: [
"./index.html",
"./src/**/*.{js,ts,jsx,tsx}",
"../../packages/ui/src/**/*.{js,ts,jsx,tsx}",
"../../packages/renderer/src/**/*.{js,ts,jsx,tsx}",
"../../packages/designer/src/**/*.{js,ts,jsx,tsx}",
],
plugins: {
tailwindcss: {},
autoprefixer: {},
},

Copilot uses AI. Check for mistakes.
@huangyiirene
huangyiirene marked this pull request as ready for review January 13, 2026 12:53
@huangyiirene
huangyiirene merged commit 9c5497b into mainJan 13, 2026
2 of 5 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

✅ All checks passed!

  • ✅ Type check passed
  • ✅ Tests passed
  • ✅ Lint check completed

CopilotAI added a commit that referenced this pull request Jan 24, 2026
- Fix handleExportCSV to guard on gridRef.current?.api (issue #1)
- Add dedicated onContextMenuAction callback instead of overloading onCellClicked (issue #2)
- Remove icon property from customItems to prevent HTML injection (issue #3)
- Remove validation claim from README - only basic AG Grid editing (issue #4)
- Add test assertions for all new inputs (editable, exportConfig, etc.) (issue #5)
- Fix onExport type to only support 'csv' format (issue #6)
- Remove unused ColumnConfig properties (autoSize, groupable) (issue #9)
- Type schema props with proper interfaces instead of 'any' (issue #10)
- Update export description to only mention CSV (issue #11)
- Add AG Grid Community vs Enterprise section to docs (issue #8)
- Update README and docs with new callback and clarifications
All tests pass (8/8), lint clean (0 errors)
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
CopilotAI added a commit that referenced this pull request Feb 20, 2026
…warning, i18n fallback
- Issue #1: Normalize `in`/`not in` operators to backend-compatible `or`/`and` of `=`/`!=`
- Issue #2: Filter merging now validates and filters empty conditions
- Issue #3: CSV export safely serializes arrays (semicolon-separated) and objects (JSON)
- Issue #5: Request counter prevents stale data from overwriting latest results
- Issue #6: PullToRefresh resets pull distance immediately to prevent UI lock
- Issue #7: $top configurable via schema.pagination, data limit warning shown
- Issue #8: Extended i18n fallback translations for all ListView labels
- Issue #9: Defensive null checks in effectiveFields for mismatched objectDef
- Issue #10: Added FilterNormalization, Export, and DataFetch test suites
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
@github-actionsgithub-actionsBot mentioned this pull request Jul 19, 2026
os-zhuang added a commit that referenced this pull request Jul 29, 2026
`@objectstack/spec` 17 (objectstack#3855) retired `Field.conditionalRequired`,
the deprecated alias of `requiredWhen`. It is tombstoned with `retiredKey()`
(`z.never()`), so authoring it is a `tsc` error AND a hard parse rejection
carrying the rename prescription — verified against 17.0.0-rc.0 at both
`FieldSchema` and `ObjectSchema`. Spec-parsed metadata therefore cannot carry
the key: an object declaring it fails to load rather than loading with the rule
silently dropped.
Keeping a renderer-side `requiredWhen ?? conditionalRequired` would have
re-created the second de-facto contract the tombstone exists to prevent — the
key would keep working in the UI while being rejected everywhere else, hiding
the producer's bug (AGENTS.md #0.1). Backend-agnosticism (#1) does not argue for
keeping it: `conditionalRequired` is an ObjectStack-spec-ism, so the only
producers that emit it are ObjectStack producers on <=16, and the spec ships
them `os migrate meta --from 16`.
Removed from the `FormField` member (types), the `??` fallback and rules-param
member in `resolveFieldRuleState` (core), three form-renderer pass-throughs
(components), `ObjectForm` / `ModalForm` / `sectionFields` / `deriveMasterDetail`
(plugin-form), and the field inspector's legacy read/auto-migrate plus the key's
CEL-lint entry (app-shell).
Studio authors lose nothing: draft validation parses against the spec's own
`ObjectSchema`, so a draft carrying the key now surfaces the tombstone's rename
prescription under the same `fields.<name>.conditionalRequired` path the CEL
lint used to report — a better message than the silent auto-migration, and one
the server agrees with. Pinned by a test.
Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@huangyiirene@qq9340100