Uh oh!
There was an error while loading. Please reload this page.
feat: add live playground for interactive schema demonstration - #8
Conversation
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR introduces a Live Playground application for Object UI - a standalone interactive demo environment that showcases the schema-driven rendering engine's capabilities through real-time JSON editing and live preview.
Changes:
- Created a new Vite-based playground application in
apps/playgroundwith split-view interface (example gallery, JSON editor, and live preview) - Added 7 curated example schemas organized into three categories: Primitives, Layouts, and Forms
- Implemented responsive viewport toggles and one-click schema copy functionality
- Updated workspace configuration to include the new
apps/*directory
Reviewed changes
Copilot reviewed 15 out of 17 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
pnpm-workspace.yaml | Added apps/* to workspace packages |
package.json | Added playground development, build, and preview scripts |
apps/playground/vite.config.ts | Configured Vite with path aliases to monorepo packages |
apps/playground/tsconfig.json | TypeScript configuration for the playground app |
apps/playground/tailwind.config.js | Tailwind CSS configuration matching Shadcn design system |
apps/playground/src/main.tsx | React application entry point |
apps/playground/src/index.css | Tailwind base styles and CSS variables for theming |
apps/playground/src/data/examples.ts | Seven example schemas demonstrating various UI capabilities |
apps/playground/src/App.tsx | Main playground component with split-view layout |
apps/playground/postcss.config.js | PostCSS configuration for Tailwind processing |
apps/playground/package.json | Playground dependencies and scripts |
apps/playground/index.html | HTML entry point for the playground |
apps/playground/README.md | Documentation for the playground application |
apps/playground/.gitignore | Standard Node.js project ignore patterns |
README.md | Removed trailing empty lines |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
Uh oh!
There was an error while loading. Please reload this page.
| export default function Playground() { | ||
| const [selectedExample, setSelectedExample] = useState<ExampleKey>('dashboard'); | ||
| const [code, setCode] = useState(examples['dashboard']); | ||
| const [schema, setSchema] = useState<any>(null); |
There was a problem hiding this comment.
The schema state uses any type which bypasses TypeScript's type checking. Consider using a more specific type from @object-ui/types or define an interface for the schema structure to maintain type safety.
| /** | ||
| * Predefined JSON schema examples for the Object UI Playground | ||
| * Organized by category to showcase different capabilities | ||
| */ |
There was a problem hiding this comment.
This file defines example schemas as template strings but lacks JSDoc annotations for the individual examples and exported types. According to CodingGuidelineID 1000000, properties in the Schema should have JSDoc documentation to enable auto-generated documentation for the open-source community. Add JSDoc comments for the examples object, ExampleKey type, and exampleCategories to document their purpose and structure.
| } | ||
| `} | ||
| > | ||
| {key.split('-').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ')} |
There was a problem hiding this comment.
The inline string transformation logic for converting kebab-case to Title Case is complex and duplicates formatting logic. Extract this into a utility function (e.g., formatExampleName) to improve readability and maintainability.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
✅ All checks passed!
|
✅ All checks passed!
|
Uh oh!
There was an error while loading. Please reload this page.
- 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>
…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>
- #39 showRecordCount: conditionally show/hide record count bar - #24 rowHeight: add short and extra_tall mapping in ListView + bridge - #7 sort: parse legacy string format "field desc" - #22 description: render view description below toolbar - #40 allowPrinting: add print button with window.print() - #31 virtualScroll: forward flag to grid view schema - #35 userActions: wire sort/search/filter/rowHeight to toolbar visibility - #38 addRecord: render "+ Add Record" button from spec config - #37 tabs: render tab bar UI for view tabs - #9 filterableFields: restrict FilterBuilder to whitelist fields - #8 searchableFields: scope search queries to specified fields - #36 appearance: wire showDescription and allowedVisualizations - #16 pageSizeOptions: add page size selector UI in status bar - #17-21: use spec kanban/calendar/gantt/gallery/timeline configs - #20 gallery: add typed GalleryConfig to ListViewSchema - #21 timeline: add typed TimelineConfig to ListViewSchema - Bridge: add short/extra_tall density mapping, filterableFields pass-through Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
… — refresh data, don't rebuild UI (#2269) (#2274) P1 of #2269, plus the P2/P3 guardrails: - @object-ui/react: notifyDataChanged / useDataInvalidation / subscribeDataChanges + useMutationInvalidationBridge(dataSource), which fans every dataSource write (MutationEvent — the bus list views already use) onto one seam. The bus also dispatches the legacy objectui:related-changed window event so pre-bus listeners keep working; notifyRelatedChanged is now a thin alias for writes that bypass the dataSource (row actions). - DELETED both refetch-by-remount keys: key={refreshKey} on RecordDetailView (AppContent) and key={actionRefreshKey} on DetailView. The schema-path pageRecord fetch and DetailView's self-fetch subscribe to the bus and refetch IN PLACE; all nine action-success bumps became precisely-scoped notifyDataChanged calls; undo/redo use the UndoableOperation's own objectName/recordId. - RelatedCountStore wired to the bus + snapshot fixed: getSnapshot returned the same Map reference, so emit() never re-rendered subscribers (pre-existing latent bug — badges only updated by luck) and invalidation left them stale. Snapshot is now a monotonic version; useRelatedCountVersion() drives the probe effect's re-fetch. - P3: app-shell/src/urlParams.ts — single registry of reserved console URL params (recordId/form/formObject/formLink/tab/palette/shortcuts); all literals migrated. - P2: AGENTS.md Commandment #8 — UI-state classification (addressable → URL; preference → storage; ephemeral → component) + 'refresh data, don't rebuild UI'. Browser-verified (showcase, StrictMode): account edit-save on the Related tab → name updates in place, tab kept; child create → subtable refetches via the bridge alone (manual notify removed) and the Related badge re-probes 11 → 12. Unit: +10 bus tests; suites 1679 green; type-check 32/32. Claude-Session: https://claude.ai/code/session_019zKcAtbtxuF9SXYgSzjk9v Co-authored-by: Claude <noreply@anthropic.com>
#8) (#2498) * feat(app-shell,plugin-chatbot,i18n): proactive AI usage indicator in the ChatDock (ADR-0057 #8) Surfaces remaining AI headroom BEFORE a send hits the 429 wall, instead of only learning the limit reactively. Consumes the cloud `GET /api/v1/ai/usage` endpoint. - AiUsageIndicator (app-shell): two meters (build + dataChat) as small progress rings in the ChatDock header (desktop rail + mobile sheet). Near-full → amber "running low" + a popover with "resets tonight/next cycle" and the upgrade / top-up CTA, reusing the 429 deep-link (cloudPricingDeepLink). D5-safe: renders fractions/qualitative words only, never a token number. Hides itself when the endpoint is absent (older backend / OSS / no seat) — fail-soft, never broken. - useAiUsage (app-shell): fetches the D5-safe per-meter fractions; refetches on the chat engine's post-turn / 429 nudge and on tab re-focus; inert without an apiBase; fails soft to null on any error. - useObjectChat (plugin-chatbot): emits AI_USAGE_REFRESH_EVENT on a rejected send (429) and on the loading→ready turn-finish edge, so the ring moves right after the user's action. Decoupled window event — no callback threaded through ChatPane. - i18n: console.ai.usage.* in en + zh-CN. Depends on cloud PR #824 (the read endpoint) being deployed; until then the indicator stays hidden. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: add changeset for AI usage indicator --------- Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Implements a split-view playground to demonstrate Object UI's schema-driven rendering without requiring backend infrastructure.
Implementation
New Application:
apps/playground/Workspace Integration
apps/*to monorepo configurationplayground:dev,playground:build,playground:previewTechnical Decisions
Examples Structure
Screenshots
Dashboard Example

Button Variants with Custom Tailwind Styling

Responsive Preview Modes

Usage
pnpm playground:dev # http://localhost:5174 pnpm playground:buildOriginal prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.