Refactor VitePress homepage with professional SDUI positioning#98
Refactor VitePress homepage with professional SDUI positioning#98
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
|
✅ All checks passed!
|
There was a problem hiding this comment.
Pull request overview
This pull request refactors the VitePress homepage to better position ObjectUI as a professional Server-Driven UI (SDUI) engine for modern frontend developers. The new content emphasizes the product's unique positioning as the "JSON-to-Shadcn Bridge" that combines low-code speed with high-quality design using React + Tailwind + Shadcn.
Changes:
- Rewrote hero section with stronger value proposition: "Stop Hand-Coding Enterprise UIs"
- Restructured feature cards into 3 pillars: The Stack You Love, Server-Driven Agility, and Enterprise Ready-Made
- Added comprehensive "Magic Trick" section demonstrating JSON → UI transformation with concrete data-table example
- Expanded architecture explanation with clear 3-layer model (Protocol, Engine, Renderer)
- Added extensibility section addressing lock-in concerns with custom component registration examples
- Enhanced ObjectStack ecosystem positioning while maintaining backend-agnostic stance
| import { registerRenderer } from '@object-ui/core'; | ||
| import { MyCustomWidget } from './components/MyCustomWidget'; | ||
|
|
||
| // Register your custom component | ||
| registerRenderer('custom-widget', MyCustomWidget); |
There was a problem hiding this comment.
The function registerRenderer does not exist in the @object-ui/core package. Based on the actual codebase, the correct API is either:
ComponentRegistry.register()(imported from@object-ui/core)getComponentRegistry().register()(imported from@object-ui/react)
This inconsistency could confuse developers trying to use the documented API. Update to use the actual API that exists in the codebase.
| import { registerRenderer } from '@object-ui/core'; | |
| import { MyCustomWidget } from './components/MyCustomWidget'; | |
| // Register your custom component | |
| registerRenderer('custom-widget', MyCustomWidget); | |
| import { ComponentRegistry } from '@object-ui/core'; | |
| import { MyCustomWidget } from './components/MyCustomWidget'; | |
| // Register your custom component | |
| ComponentRegistry.register('custom-widget', MyCustomWidget); |
| import { registerRenderer } from '@object-ui/core'; | ||
| import { MyCustomButton } from './components/MyCustomButton'; | ||
|
|
||
| // Override the built-in button | ||
| registerRenderer('button', MyCustomButton); |
There was a problem hiding this comment.
The function registerRenderer does not exist in the @object-ui/core package. Based on the actual codebase, the correct API is either:
ComponentRegistry.register()(imported from@object-ui/core)getComponentRegistry().register()(imported from@object-ui/react)
This inconsistency could confuse developers trying to use the documented API. Update to use the actual API that exists in the codebase.
| import { registerRenderer } from '@object-ui/core'; | |
| import { MyCustomButton } from './components/MyCustomButton'; | |
| // Override the built-in button | |
| registerRenderer('button', MyCustomButton); | |
| import { ComponentRegistry } from '@object-ui/core'; | |
| import { MyCustomButton } from './components/MyCustomButton'; | |
| // Override the built-in button | |
| ComponentRegistry.register('button', MyCustomButton); |
| "actions": [ | ||
| { | ||
| "label": "Edit", | ||
| "type": "button", | ||
| "variant": "outline", | ||
| "onClick": { | ||
| "action": "navigate", | ||
| "target": "/users/${row.id}/edit" | ||
| } | ||
| } | ||
| ] |
There was a problem hiding this comment.
The JSON schema example shows an actions array with an onClick handler structure that doesn't match the actual DataTableSchema type definition. According to the types in packages/types/src/data-display.ts, the DataTableSchema interface doesn't have an actions property. Instead, it uses onRowEdit and onRowDelete callback handlers.
The example also shows onClick with an object containing action and target properties, but the actual EventHandler interface (from api-types.ts) uses type and navigate properties for navigation actions.
Update the example to match the actual schema implementation, or if this represents future functionality, add a note indicating this is a planned feature.
| "actions": [ | |
| { | |
| "label": "Edit", | |
| "type": "button", | |
| "variant": "outline", | |
| "onClick": { | |
| "action": "navigate", | |
| "target": "/users/${row.id}/edit" | |
| } | |
| } | |
| ] | |
| "onRowEdit": { | |
| "type": "navigate", | |
| "navigate": "/users/${row.id}/edit" | |
| } |
| - **Manages** component state and data flow | ||
| - **Registers** custom components | ||
|
|
||
| **Zero React dependencies.** The core is pure TypeScript logic—fully testable, fully portable. | ||
|
|
There was a problem hiding this comment.
The documentation states that @object-ui/core has "Zero React dependencies" and is "pure TypeScript logic." However, it also claims that custom components can be registered using registerRenderer from @object-ui/core.
Based on the codebase examination, the actual API is ComponentRegistry.register() from @object-ui/core, and the component registry accepts React components. This creates a conceptual inconsistency - if core is truly React-free, it shouldn't be importing or registering React components directly.
Consider clarifying that while the core logic (validation, expressions) is React-free, the component registry is part of the bridge layer that connects to React components.
| - **Manages** component state and data flow | |
| - **Registers** custom components | |
| **Zero React dependencies.** The core is pure TypeScript logic—fully testable, fully portable. | |
| - **Manages** component state, expressions, and data flow | |
| The engine is implemented as **pure TypeScript logic** and can run fully outside of React (Node.js, edge runtimes, tests) for validation, expression evaluation, and action handling. | |
| > Note: React-specific concerns—like wiring `"type"` strings to concrete React components and registering custom renderers—live in the runtime/bridge layer, not in the core logic. This keeps `@object-ui/core` React-free while still allowing you to plug in your own React components where you render the schema. |
Homepage content didn't effectively position ObjectUI for modern frontend developers or differentiate from low-code tools. Needed to communicate Server-Driven UI value while emphasizing professional-grade flexibility with React + Tailwind + Shadcn.
Changes
Hero Section
/protocol/overviewand/components/Feature Cards (3 Pillars)
Magic Trick Section
Shows JSON schema → rendered UI transformation with concrete data-table example:
{ "type": "data-table", "dataSource": { "api": "/api/users" }, "columns": [ { "key": "name", "sortable": true }, { "key": "status", "render": "badge" } ], "actions": [ { "label": "Edit", "onClick": { "action": "navigate" } } ] }Output description lists: server-side fetching, sorting, actions, responsive, a11y, themes.
Architecture (3-Layer Flow)
Extensibility
registerRenderer('custom-widget', MyWidget)registerRenderer('button', MyCustomButton)ObjectStack Ecosystem
Screenshot
Files:
docs/index.md(+284, -35)Original prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.