@petrarca/sonnet-playground 0.4.2 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{PlayCoreComponents-GXFMB24T.js → PlayCoreComponents-YTEAS3GL.js} +2 -2
- package/dist/{PlayFormWidgets-IWJJQ5XL.js → PlayFormWidgets-6JYFRTAL.js} +2 -2
- package/dist/PlayForms-2G7PROCH.js +7 -0
- package/dist/PlayGraph-M7UE5MZC.js +7 -0
- package/dist/PlaySchemaDesigner-ZM4F7KBU.js +7 -0
- package/dist/PlaySchemaDesigner-ZM4F7KBU.js.map +1 -0
- package/dist/chunk-6VQJFBTM.js +315 -0
- package/dist/chunk-6VQJFBTM.js.map +1 -0
- package/dist/{chunk-YOOWJORD.js → chunk-6WI3N7JI.js} +361 -2
- package/dist/chunk-6WI3N7JI.js.map +1 -0
- package/dist/chunk-C2P3UQMZ.js +1058 -0
- package/dist/chunk-C2P3UQMZ.js.map +1 -0
- package/dist/{chunk-DZB6WFHA.js → chunk-UB7462QG.js} +106 -1
- package/dist/chunk-UB7462QG.js.map +1 -0
- package/dist/{chunk-6DZ3TSV4.js → chunk-ZSUCFEB6.js} +101 -4
- package/dist/chunk-ZSUCFEB6.js.map +1 -0
- package/dist/index.d.ts +41 -9
- package/dist/index.js +216 -51
- package/dist/index.js.map +1 -1
- package/dist/pages/index.d.ts +10 -2
- package/dist/pages/index.js +8 -4
- package/package.json +7 -6
- package/dist/PlayForms-FOF3XE6G.js +0 -7
- package/dist/PlayGraph-ADRTDRA7.js +0 -7
- package/dist/chunk-4ORSUS65.js +0 -359
- package/dist/chunk-4ORSUS65.js.map +0 -1
- package/dist/chunk-6DZ3TSV4.js.map +0 -1
- package/dist/chunk-DZB6WFHA.js.map +0 -1
- package/dist/chunk-YOOWJORD.js.map +0 -1
- /package/dist/{PlayCoreComponents-GXFMB24T.js.map → PlayCoreComponents-YTEAS3GL.js.map} +0 -0
- /package/dist/{PlayFormWidgets-IWJJQ5XL.js.map → PlayFormWidgets-6JYFRTAL.js.map} +0 -0
- /package/dist/{PlayForms-FOF3XE6G.js.map → PlayForms-2G7PROCH.js.map} +0 -0
- /package/dist/{PlayGraph-ADRTDRA7.js.map → PlayGraph-M7UE5MZC.js.map} +0 -0
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/PlaygroundRegistry.ts","../src/builtinEntries.ts","../src/createPlaygroundModule.tsx","../src/PlaygroundOverview.tsx","../src/index.ts"],"sourcesContent":["/**\n * PlaygroundRegistry -- mutable collection of playground entries.\n *\n * The library ships a default instance pre-populated with the built-in\n * sonnet component demos. Consumers register additional entries for\n * domain-specific playgrounds before passing the registry to\n * createPlaygroundModule().\n */\nimport type { PlaygroundEntry } from \"./types\";\n\nexport class PlaygroundRegistry {\n private entries: Map<string, PlaygroundEntry> = new Map();\n\n /** Register a playground entry. Overwrites any existing entry with the same id. */\n register(entry: PlaygroundEntry): void {\n this.entries.set(entry.id, entry);\n }\n\n /** Register multiple entries at once. */\n registerAll(entries: PlaygroundEntry[]): void {\n for (const entry of entries) {\n this.entries.set(entry.id, entry);\n }\n }\n\n /** Remove an entry by id. Returns true if it existed. */\n unregister(id: string): boolean {\n return this.entries.delete(id);\n }\n\n /** Get a single entry by id. */\n get(id: string): PlaygroundEntry | undefined {\n return this.entries.get(id);\n }\n\n /** Fallback group label for entries with no group defined. */\n static readonly DEFAULT_GROUP = \"General\";\n\n /**\n * All registered entries, sorted by group registration order then\n * by `order` within each group.\n */\n getAll(): PlaygroundEntry[] {\n const groupOrder = this.getGroupOrder();\n return [...this.entries.values()].sort((a, b) => {\n const groupA = a.group ?? PlaygroundRegistry.DEFAULT_GROUP;\n const groupB = b.group ?? PlaygroundRegistry.DEFAULT_GROUP;\n if (groupA !== groupB) {\n return (\n (groupOrder.get(groupA) ?? 999) - (groupOrder.get(groupB) ?? 999)\n );\n }\n return (a.order ?? 0) - (b.order ?? 0);\n });\n }\n\n /**\n * Entries grouped by their group label.\n * Returns an array of [groupLabel, entries[]] tuples, preserving\n * first-seen registration order for groups and `order` within each group.\n */\n getGrouped(): Array<[string, PlaygroundEntry[]]> {\n const grouped = new Map<string, PlaygroundEntry[]>();\n for (const entry of this.getAll()) {\n const group = entry.group ?? PlaygroundRegistry.DEFAULT_GROUP;\n const list = grouped.get(group) ?? [];\n list.push(entry);\n grouped.set(group, list);\n }\n return [...grouped.entries()];\n }\n\n /** Map of group name → first-seen index (registration order). */\n private getGroupOrder(): Map<string, number> {\n const order = new Map<string, number>();\n let idx = 0;\n for (const entry of this.entries.values()) {\n const group = entry.group ?? PlaygroundRegistry.DEFAULT_GROUP;\n if (!order.has(group)) {\n order.set(group, idx++);\n }\n }\n return order;\n }\n\n /** Number of registered entries. */\n get size(): number {\n return this.entries.size;\n }\n}\n","/**\n * Built-in playground entries for the sonnet component library.\n *\n * These entries demonstrate @petrarca/sonnet-* components with static\n * mock data -- no application backend required. Each page is lazy-loaded.\n */\nimport { lazy } from \"react\";\nimport {\n Type,\n Palette,\n Grid,\n Layers,\n Braces,\n Check,\n Edit,\n Package,\n Table2,\n Network,\n SquareTerminal,\n} from \"lucide-react\";\nimport type { PlaygroundEntry } from \"./types\";\n\nexport const builtinEntries: PlaygroundEntry[] = [\n {\n id: \"sonnet.typography\",\n title: \"Typography\",\n description:\n \"Living style-guide for the typography system. Font families, type scale, weights, heading hierarchy, color tiers, and component patterns.\",\n icon: Type,\n color: \"teal\",\n path: \"typography\",\n component: lazy(() => import(\"./pages/PlayTypography\")),\n group: \"Design System\",\n order: 0,\n },\n {\n id: \"sonnet.color-palette\",\n title: \"Color Palette\",\n description:\n \"Living reference for the color system. Semantic tokens, extended palette, badge colors, icon accents, and usage guidance.\",\n icon: Palette,\n color: \"violet\",\n path: \"color-palette\",\n component: lazy(() => import(\"./pages/PlayColorPalette\")),\n group: \"Design System\",\n order: 1,\n },\n {\n id: \"sonnet.core-components\",\n title: \"Core UI Components\",\n description:\n \"Test all core UI components (notifications, buttons, dialogs, forms, etc.) in isolation before production use.\",\n icon: Grid,\n color: \"indigo\",\n path: \"core-components\",\n component: lazy(() => import(\"./pages/PlayCoreComponents\")),\n group: \"Components\",\n order: 0,\n },\n {\n id: \"sonnet.advanced-components\",\n title: \"Advanced Components\",\n description:\n \"Multi-step workflows (Stepper) and hierarchical data structures (TreeView) with keyboard navigation and selection.\",\n icon: Layers,\n color: \"emerald\",\n path: \"advanced-components\",\n component: lazy(() => import(\"./pages/PlayAdvancedComponents\")),\n group: \"Components\",\n order: 1,\n },\n {\n id: \"sonnet.json-editor\",\n title: \"JSON Editor\",\n description:\n \"Constrained JSON editor with selectively editable regions using JSON Pointer (RFC 6901). Readonly sections are visible but locked.\",\n icon: Braces,\n color: \"amber\",\n path: \"json-editor\",\n component: lazy(() => import(\"./pages/PlayJsonEditor\")),\n group: \"Components\",\n order: 2,\n },\n {\n id: \"sonnet.form-components\",\n title: \"Form Components\",\n description:\n \"Test custom Form wrapper components with labels, descriptions, and error states. Includes Input, Textarea, Number, Checkbox, Select, MultiSelect, and Tags.\",\n icon: Check,\n color: \"blue\",\n path: \"form-components\",\n component: lazy(() => import(\"./pages/PlayFormComponents\")),\n group: \"Forms\",\n order: 0,\n },\n {\n id: \"sonnet.forms\",\n title: \"Forms Renderer\",\n description:\n \"Test and experiment with the JsonSchemaFormRenderer component. Try different schemas and see real-time validation.\",\n icon: Edit,\n color: \"purple\",\n path: \"forms\",\n component: lazy(() => import(\"./pages/PlayForms\")),\n group: \"Forms\",\n order: 1,\n },\n {\n id: \"sonnet.form-widgets\",\n title: \"Form Widgets\",\n description:\n \"Pluggable field components consumed by the Forms Renderer. Each widget maps to a JSON Schema type or format and can be swapped independently.\",\n icon: Package,\n color: \"indigo\",\n path: \"form-widgets\",\n component: lazy(() => import(\"./pages/PlayFormWidgets\")),\n group: \"Forms\",\n order: 2,\n },\n {\n id: \"sonnet.data-components\",\n title: \"Data Components\",\n description:\n \"Interactive sandbox for SearchInput (simple and faceted mode) and EntityTable. Includes a live table wired to the faceted search.\",\n icon: Table2,\n color: \"teal\",\n path: \"data-components\",\n component: lazy(() => import(\"./pages/PlayDataComponents\")),\n group: \"Data\",\n order: 0,\n },\n {\n id: \"sonnet.graph\",\n title: \"Graph Visualization\",\n description:\n \"Interactive property graph visualization with dual renderer support (Cytoscape, Reagraph). Org hierarchy demo with filtering, selection, and exploration.\",\n icon: Network,\n color: \"cyan\",\n path: \"graph\",\n component: lazy(() => import(\"./pages/PlayGraph\")),\n group: \"Graph\",\n order: 0,\n },\n {\n id: \"sonnet.shell-api\",\n title: \"Shell API\",\n description:\n \"Interactive demo of the shell API: notifications, dialogs, programmatic navigation, slide-over panels, the resizable sidePane, and the Cmd+K command menu.\",\n icon: SquareTerminal,\n color: \"orange\",\n path: \"shell-api\",\n component: lazy(() => import(\"./pages/PlayShellApi\")),\n group: \"Shell\",\n order: 0,\n },\n];\n","/**\n * Factory that turns a PlaygroundRegistry into a ShellModule.\n *\n * Generates routes (lazy + Suspense), sidebar navigation, and the\n * overview index page -- all derived from the registry entries.\n * The consumer just passes a registry and optional overrides.\n */\nimport React, { Suspense } from \"react\";\nimport { FlaskConical } from \"lucide-react\";\nimport type { ShellModule, NavGroup } from \"@petrarca/sonnet-shell\";\nimport type { PlaygroundRegistry } from \"./PlaygroundRegistry\";\nimport type { PlaygroundModuleOptions } from \"./types\";\nimport { PlaygroundOverview } from \"./PlaygroundOverview\";\n\n/**\n * Build sidebar navigation groups from registry entries.\n *\n * Groups entries by their `group` field. Each group becomes a NavGroup\n * with a heading. Ungrouped entries go into a \"General\" group.\n */\nfunction buildNavigation(\n registry: PlaygroundRegistry,\n basePath: string,\n): NavGroup[] {\n const groups = registry.getGrouped();\n const navGroups: NavGroup[] = [];\n\n // Overview link is always first\n const overviewGroup: NavGroup = {\n id: \"playground-overview\",\n links: [{ label: \"Overview\", path: basePath }],\n };\n navGroups.push(overviewGroup);\n\n for (const [groupLabel, entries] of groups) {\n navGroups.push({\n id: `playground-${groupLabel.toLowerCase().replace(/\\s+/g, \"-\")}`,\n heading: groupLabel,\n links: entries.map((e) => ({\n label: e.title,\n path: `${basePath}/${e.path}`,\n })),\n });\n }\n\n return navGroups;\n}\n\n/** Wrap a component in Suspense for lazy loading. */\nfunction suspended(Component: React.ComponentType): React.ReactElement {\n return (\n <Suspense>\n <Component />\n </Suspense>\n );\n}\n\n/**\n * Create a ShellModule for the playground.\n *\n * Returns a complete module definition ready to pass to\n * createModuleRegistry(). Routes, navigation, and the overview page\n * are all generated from the registry.\n */\nexport function createPlaygroundModule(\n registry: PlaygroundRegistry,\n options: PlaygroundModuleOptions = {},\n): ShellModule {\n const {\n icon = FlaskConical,\n label = \"Playground\",\n basePath = \"/playground\",\n overviewTitle = \"Developer Playground\",\n overviewSubtitle = \"Experiment with components, test features, and explore capabilities.\",\n grouped = true,\n } = options;\n\n // Strip leading slash for route paths (React Router relative convention)\n const routeBase = basePath.replace(/^\\//, \"\");\n\n const routes = [\n {\n path: routeBase,\n element: suspended(() => (\n <PlaygroundOverview\n registry={registry}\n basePath={basePath}\n title={overviewTitle}\n subtitle={overviewSubtitle}\n grouped={grouped}\n />\n )),\n },\n ...registry.getAll().map((entry) => ({\n path: `${routeBase}/${entry.path}`,\n element: suspended(entry.component),\n })),\n ];\n\n return {\n id: \"playground\",\n label,\n icon,\n basePath,\n pinBottom: true,\n navigation: buildNavigation(registry, basePath),\n routes,\n };\n}\n","/**\n * PlaygroundOverview -- tile grid rendered from a PlaygroundRegistry.\n *\n * Displays cards with colored icons. Clicking a card navigates to the\n * playground page. A toggle in the header lets the user switch between\n * grouped (by category) and flat (all tiles) views.\n */\nimport React, { useState } from \"react\";\nimport { useNavigate } from \"react-router-dom\";\nimport { LayoutGrid, List } from \"lucide-react\";\nimport { Card, Button, SimpleTooltip } from \"@petrarca/sonnet-ui\";\nimport type { PlaygroundRegistry } from \"./PlaygroundRegistry\";\nimport type { PlaygroundColor, PlaygroundEntry } from \"./types\";\n\n// Maps colour name to icon container classes (bg-*-100 text-*-600 pairing).\nconst COLOR_CLASSES: Record<PlaygroundColor, string> = {\n blue: \"bg-blue-100 text-blue-600\",\n violet: \"bg-violet-100 text-violet-600\",\n indigo: \"bg-indigo-100 text-indigo-600\",\n purple: \"bg-purple-100 text-purple-600\",\n teal: \"bg-teal-100 text-teal-600\",\n amber: \"bg-amber-100 text-amber-600\",\n emerald: \"bg-emerald-100 text-emerald-600\",\n rose: \"bg-rose-100 text-rose-600\",\n orange: \"bg-orange-100 text-orange-600\",\n cyan: \"bg-cyan-100 text-cyan-600\",\n};\n\nconst TILE_GRID = \"grid grid-cols-1 sm:grid-cols-2 2xl:grid-cols-3 gap-6\";\n\ninterface PlaygroundOverviewProps {\n registry: PlaygroundRegistry;\n basePath: string;\n title: string;\n subtitle: string;\n /** Initial grouping state. Defaults to true. User can toggle at runtime. */\n grouped?: boolean;\n}\n\ninterface TileProps {\n item: PlaygroundEntry;\n onNavigate: (path: string) => void;\n}\n\n/** A single playground tile card. */\nfunction PlaygroundTile({ item, onNavigate }: TileProps): React.ReactElement {\n return (\n <Card\n className=\"cursor-pointer shadow-sm border rounded-md p-6 transition-transform duration-200 motion-safe:hover:-translate-y-1\"\n onClick={() => onNavigate(item.path)}\n >\n <div className=\"flex items-center mb-4\">\n <div\n className={`flex items-center justify-center w-9 h-9 rounded-md ${COLOR_CLASSES[item.color] ?? COLOR_CLASSES.blue}`}\n >\n <item.icon size={18} />\n </div>\n </div>\n <h3 className=\"heading-section mb-1\">{item.title}</h3>\n <p className=\"text-sm text-muted-foreground\">{item.description}</p>\n </Card>\n );\n}\n\n/** Developer playground overview -- card grid linking to all registered pages. */\nexport function PlaygroundOverview({\n registry,\n basePath,\n title,\n subtitle,\n grouped: initialGrouped = true,\n}: PlaygroundOverviewProps): React.ReactElement {\n const navigate = useNavigate();\n const [grouped, setGrouped] = useState(initialGrouped);\n\n const handleNavigate = (path: string) => navigate(`${basePath}/${path}`);\n\n return (\n <div className=\"w-full\">\n <div className=\"flex items-start justify-between mb-6\">\n <div>\n <h1 className=\"mb-1\">{title}</h1>\n <p className=\"text-sm text-muted-foreground\">{subtitle}</p>\n </div>\n <SimpleTooltip label={grouped ? \"Show flat list\" : \"Group by category\"}>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => setGrouped((v) => !v)}\n >\n {grouped ? (\n <LayoutGrid className=\"h-4 w-4\" />\n ) : (\n <List className=\"h-4 w-4\" />\n )}\n </Button>\n </SimpleTooltip>\n </div>\n\n {grouped ? (\n registry.getGrouped().map(([groupLabel, entries]) => (\n <div key={groupLabel} className=\"mb-8\">\n <h2 className=\"text-sm font-medium text-muted-foreground uppercase tracking-wider mb-4\">\n {groupLabel}\n </h2>\n <div className={TILE_GRID}>\n {entries.map((item) => (\n <PlaygroundTile\n key={item.id}\n item={item}\n onNavigate={handleNavigate}\n />\n ))}\n </div>\n </div>\n ))\n ) : (\n <div className={TILE_GRID}>\n {registry.getAll().map((item) => (\n <PlaygroundTile\n key={item.id}\n item={item}\n onNavigate={handleNavigate}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n","/**\n * @petrarca/sonnet-playground\n *\n * Playground framework and built-in component demos for the Petrarca\n * Sonnet component library.\n *\n * Usage:\n *\n * import {\n * createPlaygroundRegistry,\n * createPlaygroundModule,\n * } from \"@petrarca/sonnet-playground\";\n *\n * const playground = createPlaygroundRegistry();\n * // Optionally register additional entries:\n * playground.register({ id: \"app.custom\", ... });\n *\n * const playgroundModule = createPlaygroundModule(playground);\n */\n\nimport { PlaygroundRegistry } from \"./PlaygroundRegistry\";\nimport { builtinEntries } from \"./builtinEntries\";\n\n// Framework\nexport { PlaygroundRegistry } from \"./PlaygroundRegistry\";\nexport { createPlaygroundModule } from \"./createPlaygroundModule\";\nexport { PlaygroundOverview } from \"./PlaygroundOverview\";\nexport { PlaygroundSection } from \"./PlaygroundSection\";\n\n// Types\nexport type {\n PlaygroundEntry,\n PlaygroundColor,\n PlaygroundModuleOptions,\n} from \"./types\";\n\n// Built-in entries (for selective use or extending)\nexport { builtinEntries } from \"./builtinEntries\";\n\n/**\n * Convenience factory: creates a new PlaygroundRegistry pre-populated\n * with all built-in sonnet component demos.\n */\nexport function createPlaygroundRegistry(): PlaygroundRegistry {\n const registry = new PlaygroundRegistry();\n registry.registerAll(builtinEntries);\n return registry;\n}\n"],"mappings":";;;;;AAUO,IAAM,qBAAN,MAAM,oBAAmB;AAAA,EACtB,UAAwC,oBAAI,IAAI;AAAA;AAAA,EAGxD,SAAS,OAA8B;AACrC,SAAK,QAAQ,IAAI,MAAM,IAAI,KAAK;AAAA,EAClC;AAAA;AAAA,EAGA,YAAY,SAAkC;AAC5C,eAAW,SAAS,SAAS;AAC3B,WAAK,QAAQ,IAAI,MAAM,IAAI,KAAK;AAAA,IAClC;AAAA,EACF;AAAA;AAAA,EAGA,WAAW,IAAqB;AAC9B,WAAO,KAAK,QAAQ,OAAO,EAAE;AAAA,EAC/B;AAAA;AAAA,EAGA,IAAI,IAAyC;AAC3C,WAAO,KAAK,QAAQ,IAAI,EAAE;AAAA,EAC5B;AAAA;AAAA,EAGA,OAAgB,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMhC,SAA4B;AAC1B,UAAM,aAAa,KAAK,cAAc;AACtC,WAAO,CAAC,GAAG,KAAK,QAAQ,OAAO,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM;AAC/C,YAAM,SAAS,EAAE,SAAS,oBAAmB;AAC7C,YAAM,SAAS,EAAE,SAAS,oBAAmB;AAC7C,UAAI,WAAW,QAAQ;AACrB,gBACG,WAAW,IAAI,MAAM,KAAK,QAAQ,WAAW,IAAI,MAAM,KAAK;AAAA,MAEjE;AACA,cAAQ,EAAE,SAAS,MAAM,EAAE,SAAS;AAAA,IACtC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAiD;AAC/C,UAAM,UAAU,oBAAI,IAA+B;AACnD,eAAW,SAAS,KAAK,OAAO,GAAG;AACjC,YAAM,QAAQ,MAAM,SAAS,oBAAmB;AAChD,YAAM,OAAO,QAAQ,IAAI,KAAK,KAAK,CAAC;AACpC,WAAK,KAAK,KAAK;AACf,cAAQ,IAAI,OAAO,IAAI;AAAA,IACzB;AACA,WAAO,CAAC,GAAG,QAAQ,QAAQ,CAAC;AAAA,EAC9B;AAAA;AAAA,EAGQ,gBAAqC;AAC3C,UAAM,QAAQ,oBAAI,IAAoB;AACtC,QAAI,MAAM;AACV,eAAW,SAAS,KAAK,QAAQ,OAAO,GAAG;AACzC,YAAM,QAAQ,MAAM,SAAS,oBAAmB;AAChD,UAAI,CAAC,MAAM,IAAI,KAAK,GAAG;AACrB,cAAM,IAAI,OAAO,KAAK;AAAA,MACxB;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,IAAI,OAAe;AACjB,WAAO,KAAK,QAAQ;AAAA,EACtB;AACF;;;ACnFA,SAAS,YAAY;AACrB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGA,IAAM,iBAAoC;AAAA,EAC/C;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aACE;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,IACN,WAAW,KAAK,MAAM,OAAO,8BAAwB,CAAC;AAAA,IACtD,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aACE;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,IACN,WAAW,KAAK,MAAM,OAAO,gCAA0B,CAAC;AAAA,IACxD,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aACE;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,IACN,WAAW,KAAK,MAAM,OAAO,kCAA4B,CAAC;AAAA,IAC1D,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aACE;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,IACN,WAAW,KAAK,MAAM,OAAO,sCAAgC,CAAC;AAAA,IAC9D,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aACE;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,IACN,WAAW,KAAK,MAAM,OAAO,8BAAwB,CAAC;AAAA,IACtD,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aACE;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,IACN,WAAW,KAAK,MAAM,OAAO,kCAA4B,CAAC;AAAA,IAC1D,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aACE;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,IACN,WAAW,KAAK,MAAM,OAAO,yBAAmB,CAAC;AAAA,IACjD,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aACE;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,IACN,WAAW,KAAK,MAAM,OAAO,+BAAyB,CAAC;AAAA,IACvD,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aACE;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,IACN,WAAW,KAAK,MAAM,OAAO,kCAA4B,CAAC;AAAA,IAC1D,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aACE;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,IACN,WAAW,KAAK,MAAM,OAAO,yBAAmB,CAAC;AAAA,IACjD,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aACE;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,IACN,WAAW,KAAK,MAAM,OAAO,4BAAsB,CAAC;AAAA,IACpD,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AACF;;;ACpJA,SAAgB,gBAAgB;AAChC,SAAS,oBAAoB;;;ACD7B,SAAgB,gBAAgB;AAChC,SAAS,mBAAmB;AAC5B,SAAS,YAAY,YAAY;AACjC,SAAS,MAAM,QAAQ,qBAAqB;AAqCxC,SAQM,KARN;AAhCJ,IAAM,gBAAiD;AAAA,EACrD,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,OAAO;AAAA,EACP,SAAS;AAAA,EACT,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,MAAM;AACR;AAEA,IAAM,YAAY;AAiBlB,SAAS,eAAe,EAAE,MAAM,WAAW,GAAkC;AAC3E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,SAAS,MAAM,WAAW,KAAK,IAAI;AAAA,MAEnC;AAAA,4BAAC,SAAI,WAAU,0BACb;AAAA,UAAC;AAAA;AAAA,YACC,WAAW,uDAAuD,cAAc,KAAK,KAAK,KAAK,cAAc,IAAI;AAAA,YAEjH,8BAAC,KAAK,MAAL,EAAU,MAAM,IAAI;AAAA;AAAA,QACvB,GACF;AAAA,QACA,oBAAC,QAAG,WAAU,wBAAwB,eAAK,OAAM;AAAA,QACjD,oBAAC,OAAE,WAAU,iCAAiC,eAAK,aAAY;AAAA;AAAA;AAAA,EACjE;AAEJ;AAGO,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS,iBAAiB;AAC5B,GAAgD;AAC9C,QAAM,WAAW,YAAY;AAC7B,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,cAAc;AAErD,QAAM,iBAAiB,CAAC,SAAiB,SAAS,GAAG,QAAQ,IAAI,IAAI,EAAE;AAEvE,SACE,qBAAC,SAAI,WAAU,UACb;AAAA,yBAAC,SAAI,WAAU,yCACb;AAAA,2BAAC,SACC;AAAA,4BAAC,QAAG,WAAU,QAAQ,iBAAM;AAAA,QAC5B,oBAAC,OAAE,WAAU,iCAAiC,oBAAS;AAAA,SACzD;AAAA,MACA,oBAAC,iBAAc,OAAO,UAAU,mBAAmB,qBACjD;AAAA,QAAC;AAAA;AAAA,UACC,SAAQ;AAAA,UACR,MAAK;AAAA,UACL,SAAS,MAAM,WAAW,CAAC,MAAM,CAAC,CAAC;AAAA,UAElC,oBACC,oBAAC,cAAW,WAAU,WAAU,IAEhC,oBAAC,QAAK,WAAU,WAAU;AAAA;AAAA,MAE9B,GACF;AAAA,OACF;AAAA,IAEC,UACC,SAAS,WAAW,EAAE,IAAI,CAAC,CAAC,YAAY,OAAO,MAC7C,qBAAC,SAAqB,WAAU,QAC9B;AAAA,0BAAC,QAAG,WAAU,2EACX,sBACH;AAAA,MACA,oBAAC,SAAI,WAAW,WACb,kBAAQ,IAAI,CAAC,SACZ;AAAA,QAAC;AAAA;AAAA,UAEC;AAAA,UACA,YAAY;AAAA;AAAA,QAFP,KAAK;AAAA,MAGZ,CACD,GACH;AAAA,SAZQ,UAaV,CACD,IAED,oBAAC,SAAI,WAAW,WACb,mBAAS,OAAO,EAAE,IAAI,CAAC,SACtB;AAAA,MAAC;AAAA;AAAA,QAEC;AAAA,QACA,YAAY;AAAA;AAAA,MAFP,KAAK;AAAA,IAGZ,CACD,GACH;AAAA,KAEJ;AAEJ;;;AD7EM,gBAAAA,YAAA;AAhCN,SAAS,gBACP,UACA,UACY;AACZ,QAAM,SAAS,SAAS,WAAW;AACnC,QAAM,YAAwB,CAAC;AAG/B,QAAM,gBAA0B;AAAA,IAC9B,IAAI;AAAA,IACJ,OAAO,CAAC,EAAE,OAAO,YAAY,MAAM,SAAS,CAAC;AAAA,EAC/C;AACA,YAAU,KAAK,aAAa;AAE5B,aAAW,CAAC,YAAY,OAAO,KAAK,QAAQ;AAC1C,cAAU,KAAK;AAAA,MACb,IAAI,cAAc,WAAW,YAAY,EAAE,QAAQ,QAAQ,GAAG,CAAC;AAAA,MAC/D,SAAS;AAAA,MACT,OAAO,QAAQ,IAAI,CAAC,OAAO;AAAA,QACzB,OAAO,EAAE;AAAA,QACT,MAAM,GAAG,QAAQ,IAAI,EAAE,IAAI;AAAA,MAC7B,EAAE;AAAA,IACJ,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAGA,SAAS,UAAU,WAAoD;AACrE,SACE,gBAAAA,KAAC,YACC,0BAAAA,KAAC,aAAU,GACb;AAEJ;AASO,SAAS,uBACd,UACA,UAAmC,CAAC,GACvB;AACb,QAAM;AAAA,IACJ,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,gBAAgB;AAAA,IAChB,mBAAmB;AAAA,IACnB,UAAU;AAAA,EACZ,IAAI;AAGJ,QAAM,YAAY,SAAS,QAAQ,OAAO,EAAE;AAE5C,QAAM,SAAS;AAAA,IACb;AAAA,MACE,MAAM;AAAA,MACN,SAAS,UAAU,MACjB,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA,OAAO;AAAA,UACP,UAAU;AAAA,UACV;AAAA;AAAA,MACF,CACD;AAAA,IACH;AAAA,IACA,GAAG,SAAS,OAAO,EAAE,IAAI,CAAC,WAAW;AAAA,MACnC,MAAM,GAAG,SAAS,IAAI,MAAM,IAAI;AAAA,MAChC,SAAS,UAAU,MAAM,SAAS;AAAA,IACpC,EAAE;AAAA,EACJ;AAEA,SAAO;AAAA,IACL,IAAI;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX,YAAY,gBAAgB,UAAU,QAAQ;AAAA,IAC9C;AAAA,EACF;AACF;;;AEjEO,SAAS,2BAA+C;AAC7D,QAAM,WAAW,IAAI,mBAAmB;AACxC,WAAS,YAAY,cAAc;AACnC,SAAO;AACT;","names":["jsx"]}
|
|
1
|
+
{"version":3,"sources":["../src/PlaygroundRegistry.ts","../src/builtinEntries.ts","../src/createPlaygroundModule.tsx","../src/PlaygroundOverview.tsx","../src/PlaygroundSettingsPanel.tsx","../src/PlaygroundSettings.tsx","../src/index.ts"],"sourcesContent":["/**\n * PlaygroundRegistry -- mutable collection of playground entries.\n *\n * The library ships a default instance pre-populated with the built-in\n * sonnet component demos. Consumers register additional entries for\n * domain-specific playgrounds before passing the registry to\n * createPlaygroundModule().\n */\nimport type { PlaygroundEntry } from \"./types\";\n\nexport class PlaygroundRegistry {\n private entries: Map<string, PlaygroundEntry> = new Map();\n\n /** Register a playground entry. Overwrites any existing entry with the same id. */\n register(entry: PlaygroundEntry): void {\n this.entries.set(entry.id, entry);\n }\n\n /** Register multiple entries at once. */\n registerAll(entries: PlaygroundEntry[]): void {\n for (const entry of entries) {\n this.entries.set(entry.id, entry);\n }\n }\n\n /** Remove an entry by id. Returns true if it existed. */\n unregister(id: string): boolean {\n return this.entries.delete(id);\n }\n\n /** Get a single entry by id. */\n get(id: string): PlaygroundEntry | undefined {\n return this.entries.get(id);\n }\n\n /** Fallback group label for entries with no group defined. */\n static readonly DEFAULT_GROUP = \"General\";\n\n /**\n * All registered entries, sorted by group registration order then\n * by `order` within each group.\n */\n getAll(): PlaygroundEntry[] {\n const groupOrder = this.getGroupOrder();\n return [...this.entries.values()].sort((a, b) => {\n const groupA = a.group ?? PlaygroundRegistry.DEFAULT_GROUP;\n const groupB = b.group ?? PlaygroundRegistry.DEFAULT_GROUP;\n if (groupA !== groupB) {\n return (\n (groupOrder.get(groupA) ?? 999) - (groupOrder.get(groupB) ?? 999)\n );\n }\n return (a.order ?? 0) - (b.order ?? 0);\n });\n }\n\n /**\n * Entries grouped by their group label.\n * Returns an array of [groupLabel, entries[]] tuples, preserving\n * first-seen registration order for groups and `order` within each group.\n */\n getGrouped(): Array<[string, PlaygroundEntry[]]> {\n const grouped = new Map<string, PlaygroundEntry[]>();\n for (const entry of this.getAll()) {\n const group = entry.group ?? PlaygroundRegistry.DEFAULT_GROUP;\n const list = grouped.get(group) ?? [];\n list.push(entry);\n grouped.set(group, list);\n }\n return [...grouped.entries()];\n }\n\n /** Map of group name → first-seen index (registration order). */\n private getGroupOrder(): Map<string, number> {\n const order = new Map<string, number>();\n let idx = 0;\n for (const entry of this.entries.values()) {\n const group = entry.group ?? PlaygroundRegistry.DEFAULT_GROUP;\n if (!order.has(group)) {\n order.set(group, idx++);\n }\n }\n return order;\n }\n\n /** Number of registered entries. */\n get size(): number {\n return this.entries.size;\n }\n}\n","/**\n * Built-in playground entries for the sonnet component library.\n *\n * These entries demonstrate @petrarca/sonnet-* components with static\n * mock data -- no application backend required. Each page is lazy-loaded.\n */\nimport { lazy } from \"react\";\nimport {\n Type,\n Palette,\n Grid,\n Layers,\n Braces,\n Check,\n Edit,\n Package,\n Table2,\n Network,\n SquareTerminal,\n PencilRuler,\n} from \"lucide-react\";\nimport type { PlaygroundEntry } from \"./types\";\n\nexport const builtinEntries: PlaygroundEntry[] = [\n {\n id: \"sonnet.typography\",\n title: \"Typography\",\n description:\n \"Living style-guide for the typography system. Font families, type scale, weights, heading hierarchy, color tiers, and component patterns.\",\n icon: Type,\n color: \"teal\",\n path: \"typography\",\n component: lazy(() => import(\"./pages/PlayTypography\")),\n group: \"Design System\",\n order: 0,\n },\n {\n id: \"sonnet.color-palette\",\n title: \"Color Palette\",\n description:\n \"Living reference for the color system. Semantic tokens, extended palette, badge colors, icon accents, and usage guidance.\",\n icon: Palette,\n color: \"violet\",\n path: \"color-palette\",\n component: lazy(() => import(\"./pages/PlayColorPalette\")),\n group: \"Design System\",\n order: 1,\n },\n {\n id: \"sonnet.core-components\",\n title: \"Core UI Components\",\n description:\n \"Test all core UI components (notifications, buttons, dialogs, forms, etc.) in isolation before production use.\",\n icon: Grid,\n color: \"indigo\",\n path: \"core-components\",\n component: lazy(() => import(\"./pages/PlayCoreComponents\")),\n group: \"Components\",\n order: 0,\n },\n {\n id: \"sonnet.advanced-components\",\n title: \"Advanced Components\",\n description:\n \"Multi-step workflows (Stepper) and hierarchical data structures (TreeView) with keyboard navigation and selection.\",\n icon: Layers,\n color: \"emerald\",\n path: \"advanced-components\",\n component: lazy(() => import(\"./pages/PlayAdvancedComponents\")),\n group: \"Components\",\n order: 1,\n },\n {\n id: \"sonnet.json-editor\",\n title: \"JSON Editor\",\n description:\n \"Constrained JSON editor with selectively editable regions using JSON Pointer (RFC 6901). Readonly sections are visible but locked.\",\n icon: Braces,\n color: \"amber\",\n path: \"json-editor\",\n component: lazy(() => import(\"./pages/PlayJsonEditor\")),\n group: \"Components\",\n order: 2,\n },\n {\n id: \"sonnet.form-components\",\n title: \"Form Components\",\n description:\n \"Test custom Form wrapper components with labels, descriptions, and error states. Includes Input, Textarea, Number, Checkbox, Select, MultiSelect, and Tags.\",\n icon: Check,\n color: \"blue\",\n path: \"form-components\",\n component: lazy(() => import(\"./pages/PlayFormComponents\")),\n group: \"Forms\",\n order: 0,\n },\n {\n id: \"sonnet.forms\",\n title: \"Forms Renderer\",\n description:\n \"Test and experiment with the JsonSchemaFormRenderer component. Try different schemas and see real-time validation.\",\n icon: Edit,\n color: \"purple\",\n path: \"forms\",\n component: lazy(() => import(\"./pages/PlayForms\")),\n group: \"Forms\",\n order: 1,\n },\n {\n id: \"sonnet.form-widgets\",\n title: \"Form Widgets\",\n description:\n \"Pluggable field components consumed by the Forms Renderer. Each widget maps to a JSON Schema type or format and can be swapped independently.\",\n icon: Package,\n color: \"indigo\",\n path: \"form-widgets\",\n component: lazy(() => import(\"./pages/PlayFormWidgets\")),\n group: \"Forms\",\n order: 2,\n },\n {\n id: \"sonnet.schema-designer\",\n title: \"Schema Designer\",\n description:\n \"Visually author a JSON Schema and its UI presentation hints. Field tree, inspector, and live preview; edits emit a valid schema + uiSchema.\",\n icon: PencilRuler,\n color: \"teal\",\n path: \"schema-designer\",\n component: lazy(() => import(\"./pages/PlaySchemaDesigner\")),\n group: \"Schemas\",\n order: 0,\n },\n {\n id: \"sonnet.data-components\",\n title: \"Data Components\",\n description:\n \"Interactive sandbox for SearchInput (simple and faceted mode) and EntityTable. Includes a live table wired to the faceted search.\",\n icon: Table2,\n color: \"teal\",\n path: \"data-components\",\n component: lazy(() => import(\"./pages/PlayDataComponents\")),\n group: \"Data\",\n order: 0,\n },\n {\n id: \"sonnet.graph\",\n title: \"Graph Visualization\",\n description:\n \"Interactive property graph visualization with dual renderer support (Cytoscape, Reagraph). Org hierarchy demo with filtering, selection, and exploration.\",\n icon: Network,\n color: \"cyan\",\n path: \"graph\",\n component: lazy(() => import(\"./pages/PlayGraph\")),\n group: \"Graph\",\n order: 0,\n },\n {\n id: \"sonnet.shell-api\",\n title: \"Shell API\",\n description:\n \"Interactive demo of the shell API: notifications, dialogs, programmatic navigation, slide-over panels, the resizable sidePane, and the Cmd+K command menu.\",\n icon: SquareTerminal,\n color: \"orange\",\n path: \"shell-api\",\n component: lazy(() => import(\"./pages/PlayShellApi\")),\n group: \"Shell\",\n order: 0,\n },\n];\n","/**\n * Factory that turns a PlaygroundRegistry into a ShellModule.\n *\n * Generates routes (lazy + Suspense), sidebar navigation, and the\n * overview index page -- all derived from the registry entries.\n * The consumer just passes a registry and optional overrides.\n */\nimport React, { Suspense } from \"react\";\nimport { Outlet } from \"react-router-dom\";\nimport { FlaskConical } from \"lucide-react\";\nimport type { ShellModule, NavGroup } from \"@petrarca/sonnet-shell\";\nimport type { PlaygroundRegistry } from \"./PlaygroundRegistry\";\nimport type { PlaygroundModuleOptions } from \"./types\";\nimport { PlaygroundOverview } from \"./PlaygroundOverview\";\nimport { PlaygroundSettingsProvider } from \"./PlaygroundSettings\";\n\nfunction buildNavigation(\n registry: PlaygroundRegistry,\n basePath: string,\n): NavGroup[] {\n const groups = registry.getGrouped();\n const navGroups: NavGroup[] = [];\n\n navGroups.push({\n id: \"playground-overview\",\n links: [{ label: \"Overview\", path: basePath }],\n });\n\n for (const [groupLabel, entries] of groups) {\n navGroups.push({\n id: `playground-${groupLabel.toLowerCase().replace(/\\s+/g, \"-\")}`,\n heading: groupLabel,\n links: entries.map((e) => ({\n label: e.title,\n path: `${basePath}/${e.path}`,\n })),\n });\n }\n\n return navGroups;\n}\n\n// Wrap a component in Suspense for lazy loading.\nfunction suspended(Component: React.ComponentType): React.ReactElement {\n return (\n <Suspense>\n <Component />\n </Suspense>\n );\n}\n\n// Layout route element: a single PlaygroundSettingsProvider wrapping all\n// playground routes via <Outlet>. Mounted once, never torn down on navigation,\n// so settings state is stable across route changes within the playground.\nfunction PlaygroundLayout(): React.ReactElement {\n return (\n <PlaygroundSettingsProvider>\n <Outlet />\n </PlaygroundSettingsProvider>\n );\n}\n\nexport function createPlaygroundModule(\n registry: PlaygroundRegistry,\n options: PlaygroundModuleOptions = {},\n): ShellModule {\n const {\n icon = FlaskConical,\n label = \"Playground\",\n basePath = \"/playground\",\n overviewTitle = \"Developer Playground\",\n overviewSubtitle = \"Experiment with components, test features, and explore capabilities.\",\n grouped = true,\n } = options;\n\n const routeBase = basePath.replace(/^\\//, \"\");\n\n // A single layout route wraps all playground routes. The settings provider\n // lives here -- mounted once, alive for the full playground session.\n const routes = [\n {\n path: routeBase,\n element: <PlaygroundLayout />,\n children: [\n {\n index: true,\n element: suspended(() => (\n <PlaygroundOverview\n registry={registry}\n basePath={basePath}\n title={overviewTitle}\n subtitle={overviewSubtitle}\n grouped={grouped}\n />\n )),\n },\n ...registry.getAll().map((entry) => ({\n path: entry.path,\n element: suspended(entry.component),\n })),\n ],\n },\n ];\n\n return {\n id: \"playground\",\n label,\n icon,\n basePath,\n pinBottom: true,\n navigation: buildNavigation(registry, basePath),\n routes,\n };\n}\n","/**\n * PlaygroundOverview -- tile grid rendered from a PlaygroundRegistry.\n *\n * Displays cards with colored icons. Clicking a card navigates to the\n * playground page. A toggle in the header lets the user switch between\n * grouped (by category) and flat (all tiles) views.\n */\nimport React, { useState } from \"react\";\nimport { useNavigate } from \"react-router-dom\";\nimport { LayoutGrid, List } from \"lucide-react\";\nimport { Card, Button, SimpleTooltip } from \"@petrarca/sonnet-ui\";\nimport type { PlaygroundRegistry } from \"./PlaygroundRegistry\";\nimport type { PlaygroundColor, PlaygroundEntry } from \"./types\";\nimport { PlaygroundSettingsPanel } from \"./PlaygroundSettingsPanel\";\n\n// Maps colour name to icon container classes (bg-*-100 text-*-600 pairing).\nconst COLOR_CLASSES: Record<PlaygroundColor, string> = {\n blue: \"bg-blue-100 text-blue-600\",\n violet: \"bg-violet-100 text-violet-600\",\n indigo: \"bg-indigo-100 text-indigo-600\",\n purple: \"bg-purple-100 text-purple-600\",\n teal: \"bg-teal-100 text-teal-600\",\n amber: \"bg-amber-100 text-amber-600\",\n emerald: \"bg-emerald-100 text-emerald-600\",\n rose: \"bg-rose-100 text-rose-600\",\n orange: \"bg-orange-100 text-orange-600\",\n cyan: \"bg-cyan-100 text-cyan-600\",\n};\n\nconst TILE_GRID = \"grid grid-cols-1 sm:grid-cols-2 2xl:grid-cols-3 gap-6\";\n\ninterface PlaygroundOverviewProps {\n registry: PlaygroundRegistry;\n basePath: string;\n title: string;\n subtitle: string;\n /** Initial grouping state. Defaults to true. User can toggle at runtime. */\n grouped?: boolean;\n}\n\ninterface TileProps {\n item: PlaygroundEntry;\n onNavigate: (path: string) => void;\n}\n\n/** A single playground tile card. */\nfunction PlaygroundTile({ item, onNavigate }: TileProps): React.ReactElement {\n return (\n <Card\n className=\"cursor-pointer shadow-sm border rounded-md p-6 transition-transform duration-200 motion-safe:hover:-translate-y-1\"\n onClick={() => onNavigate(item.path)}\n >\n <div className=\"flex items-center mb-4\">\n <div\n className={`flex items-center justify-center w-9 h-9 rounded-md ${COLOR_CLASSES[item.color] ?? COLOR_CLASSES.blue}`}\n >\n <item.icon size={18} />\n </div>\n </div>\n <h3 className=\"heading-section mb-1\">{item.title}</h3>\n <p className=\"text-sm text-muted-foreground\">{item.description}</p>\n </Card>\n );\n}\n\n/** Developer playground overview -- card grid linking to all registered pages. */\nexport function PlaygroundOverview({\n registry,\n basePath,\n title,\n subtitle,\n grouped: initialGrouped = true,\n}: PlaygroundOverviewProps): React.ReactElement {\n const navigate = useNavigate();\n const [grouped, setGrouped] = useState(initialGrouped);\n\n const handleNavigate = (path: string) => navigate(`${basePath}/${path}`);\n\n return (\n <div className=\"w-full\">\n <div className=\"flex items-start justify-between mb-6\">\n <div>\n <h1 className=\"mb-1\">{title}</h1>\n <p className=\"text-sm text-muted-foreground\">{subtitle}</p>\n </div>\n <div className=\"flex items-center gap-1\">\n <SimpleTooltip\n label={grouped ? \"Show flat list\" : \"Group by category\"}\n >\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => setGrouped((v) => !v)}\n >\n {grouped ? (\n <LayoutGrid className=\"h-4 w-4\" />\n ) : (\n <List className=\"h-4 w-4\" />\n )}\n </Button>\n </SimpleTooltip>\n <PlaygroundSettingsPanel />\n </div>\n </div>\n\n {grouped ? (\n registry.getGrouped().map(([groupLabel, entries]) => (\n <div key={groupLabel} className=\"mb-8\">\n <h2 className=\"text-sm font-medium text-muted-foreground uppercase tracking-wider mb-4\">\n {groupLabel}\n </h2>\n <div className={TILE_GRID}>\n {entries.map((item) => (\n <PlaygroundTile\n key={item.id}\n item={item}\n onNavigate={handleNavigate}\n />\n ))}\n </div>\n </div>\n ))\n ) : (\n <div className={TILE_GRID}>\n {registry.getAll().map((item) => (\n <PlaygroundTile\n key={item.id}\n item={item}\n onNavigate={handleNavigate}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n","/**\n * PlaygroundSettingsPanel -- gear button that opens a right-side settings sheet.\n *\n * Hosts playground-wide settings (currently locale). Edits flow through\n * usePlaygroundSettings, which drives the SonnetConfigProvider wrapping all\n * playground routes.\n */\n\nimport React, { useState } from \"react\";\nimport { Settings } from \"lucide-react\";\nimport {\n IconButton,\n Label,\n Sheet,\n SheetContent,\n SheetHeader,\n SheetTitle,\n SheetDescription,\n SheetBody,\n Select,\n SelectTrigger,\n SelectValue,\n SelectContent,\n SelectItem,\n} from \"@petrarca/sonnet-ui\";\nimport { usePlaygroundSettings } from \"./PlaygroundSettings\";\n\n// Locale choices for the playground. \"__inherit__\" uses the app/browser locale.\nconst INHERIT = \"__inherit__\";\nconst LOCALE_OPTIONS = [\n { code: INHERIT, label: \"Inherit (app / browser)\" },\n { code: \"en-US\", label: \"English (US) - MM/DD, Sun\" },\n { code: \"en-GB\", label: \"English (UK) - DD/MM, Mon\" },\n { code: \"de-DE\", label: \"German - DD.MM, Mon\" },\n { code: \"fr-FR\", label: \"French - DD/MM, Mon\" },\n { code: \"sv-SE\", label: \"Swedish - YYYY-MM-DD, Mon\" },\n { code: \"ja-JP\", label: \"Japanese - YYYY/MM/DD, Sun\" },\n];\n\nexport function PlaygroundSettingsPanel(): React.ReactElement {\n const [open, setOpen] = useState(false);\n const { settings, setSettings } = usePlaygroundSettings();\n\n return (\n <Sheet open={open} onOpenChange={setOpen}>\n <IconButton label=\"Playground settings\" onClick={() => setOpen(true)}>\n <Settings />\n </IconButton>\n <SheetContent side=\"right\">\n <SheetHeader>\n <SheetTitle>Playground settings</SheetTitle>\n <SheetDescription>\n Scoped to the playground. Values exchanged with components stay\n locale-independent (ISO); only display and input parsing change.\n </SheetDescription>\n </SheetHeader>\n <SheetBody>\n <div className=\"space-y-2\">\n <Label htmlFor=\"playground-locale\">Locale</Label>\n <Select\n value={settings.locale || INHERIT}\n onValueChange={(value) =>\n setSettings({ locale: value === INHERIT ? \"\" : value })\n }\n >\n <SelectTrigger id=\"playground-locale\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {LOCALE_OPTIONS.map((opt) => (\n <SelectItem key={opt.code} value={opt.code}>\n {opt.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <p className=\"text-xs text-tertiary-foreground\">\n Drives locale-sensitive components (e.g. Date Input) across every\n playground page.\n </p>\n </div>\n </SheetBody>\n </SheetContent>\n </Sheet>\n );\n}\n","/**\n * Playground-scoped settings (locale, ...).\n *\n * A self-contained provider that wraps all playground routes. It owns a small\n * settings object, persists it to a namespaced localStorage key, and renders a\n * SonnetConfigProvider so the settings flow to every playground page.\n *\n * Scope and containment: the provider is nested under any host-app provider and\n * merges onto it, so a playground override shadows the app/browser value only\n * within the playground subtree -- it never mutates the host app's global\n * config. The default is \"inherit\" (empty locale), so out of the box the\n * playground changes nothing.\n */\n\nimport React, {\n createContext,\n useCallback,\n useContext,\n useMemo,\n useState,\n} from \"react\";\nimport { SonnetConfigProvider } from \"@petrarca/sonnet-core/config\";\n\nconst STORAGE_KEY = \"sonnet.playground.settings\";\n\nexport interface PlaygroundSettings {\n /** BCP-47 locale override, or \"\" to inherit the app/browser locale. */\n locale: string;\n}\n\ninterface PlaygroundSettingsContextValue {\n settings: PlaygroundSettings;\n setSettings: (next: Partial<PlaygroundSettings>) => void;\n}\n\nconst DEFAULT_SETTINGS: PlaygroundSettings = { locale: \"\" };\n\nconst PlaygroundSettingsContext =\n createContext<PlaygroundSettingsContextValue | null>(null);\n\n// Safe localStorage access (guards against SSR and storage failures).\nconst storage = {\n get(key: string): string | null {\n try {\n return typeof localStorage !== \"undefined\"\n ? localStorage.getItem(key)\n : null;\n } catch {\n return null;\n }\n },\n set(key: string, value: string): void {\n try {\n if (typeof localStorage !== \"undefined\") localStorage.setItem(key, value);\n } catch {\n // Ignore quota / private-mode failures.\n }\n },\n};\n\nfunction loadSettings(): PlaygroundSettings {\n const raw = storage.get(STORAGE_KEY);\n if (!raw) return DEFAULT_SETTINGS;\n try {\n return { ...DEFAULT_SETTINGS, ...(JSON.parse(raw) as PlaygroundSettings) };\n } catch {\n return DEFAULT_SETTINGS;\n }\n}\n\nfunction persistSettings(settings: PlaygroundSettings): void {\n storage.set(STORAGE_KEY, JSON.stringify(settings));\n}\n\nexport interface PlaygroundSettingsProviderProps {\n children: React.ReactNode;\n}\n\nexport function PlaygroundSettingsProvider({\n children,\n}: PlaygroundSettingsProviderProps): React.ReactElement {\n const [settings, setSettingsState] =\n useState<PlaygroundSettings>(loadSettings);\n\n const setSettings = useCallback(\n (next: Partial<PlaygroundSettings>) =>\n setSettingsState((prev) => {\n const merged = { ...prev, ...next };\n persistSettings(merged);\n return merged;\n }),\n [],\n );\n\n const contextValue = useMemo(\n () => ({ settings, setSettings }),\n [settings, setSettings],\n );\n\n // Only override the global locale when explicitly set; \"\" inherits.\n const config = useMemo(\n () => ({ globals: { locale: settings.locale || undefined } }),\n [settings.locale],\n );\n\n return (\n <PlaygroundSettingsContext.Provider value={contextValue}>\n <SonnetConfigProvider value={config}>{children}</SonnetConfigProvider>\n </PlaygroundSettingsContext.Provider>\n );\n}\n\n/** Access playground settings. Returns defaults when no provider is present. */\nexport function usePlaygroundSettings(): PlaygroundSettingsContextValue {\n return (\n useContext(PlaygroundSettingsContext) ?? {\n settings: DEFAULT_SETTINGS,\n setSettings: () => {},\n }\n );\n}\n","/**\n * @petrarca/sonnet-playground\n *\n * Playground framework and built-in component demos for the Petrarca\n * Sonnet component library.\n *\n * Usage:\n *\n * import {\n * createPlaygroundRegistry,\n * createPlaygroundModule,\n * } from \"@petrarca/sonnet-playground\";\n *\n * const playground = createPlaygroundRegistry();\n * // Optionally register additional entries:\n * playground.register({ id: \"app.custom\", ... });\n *\n * const playgroundModule = createPlaygroundModule(playground);\n */\n\nimport { PlaygroundRegistry } from \"./PlaygroundRegistry\";\nimport { builtinEntries } from \"./builtinEntries\";\n\n// Framework\nexport { PlaygroundRegistry } from \"./PlaygroundRegistry\";\nexport { createPlaygroundModule } from \"./createPlaygroundModule\";\nexport { PlaygroundOverview } from \"./PlaygroundOverview\";\nexport { PlaygroundSection } from \"./PlaygroundSection\";\nexport {\n PlaygroundSettingsProvider,\n usePlaygroundSettings,\n type PlaygroundSettings,\n} from \"./PlaygroundSettings\";\nexport { PlaygroundSettingsPanel } from \"./PlaygroundSettingsPanel\";\n\n// Types\nexport type {\n PlaygroundEntry,\n PlaygroundColor,\n PlaygroundModuleOptions,\n} from \"./types\";\n\n// Built-in entries (for selective use or extending)\nexport { builtinEntries } from \"./builtinEntries\";\n\n/**\n * Convenience factory: creates a new PlaygroundRegistry pre-populated\n * with all built-in sonnet component demos.\n */\nexport function createPlaygroundRegistry(): PlaygroundRegistry {\n const registry = new PlaygroundRegistry();\n registry.registerAll(builtinEntries);\n return registry;\n}\n"],"mappings":"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","names":["useState","useState","jsx","useState","jsx","jsxs","useState","jsx"]}
|
package/dist/pages/index.d.ts
CHANGED
|
@@ -46,6 +46,14 @@ declare function PlayForms(): react_jsx_runtime.JSX.Element;
|
|
|
46
46
|
*/
|
|
47
47
|
declare function PlayFormWidgets(): react_jsx_runtime.JSX.Element;
|
|
48
48
|
|
|
49
|
+
/**
|
|
50
|
+
* PlaySchemaDesigner -- exercises SchemaDesigner: visually author a JsonSchema
|
|
51
|
+
* (and its uiSchema presentation hints), with a live preview. The profile
|
|
52
|
+
* switcher presets the capability profile (data/full triage, scoped editing,
|
|
53
|
+
* read-only); the in-designer Capabilities tab tweaks it live.
|
|
54
|
+
*/
|
|
55
|
+
declare function PlaySchemaDesigner(): react_jsx_runtime.JSX.Element;
|
|
56
|
+
|
|
49
57
|
/**
|
|
50
58
|
* Playground page for SearchInput, EntitySelect, EntityTable, and EntityTree.
|
|
51
59
|
* Accessible at /playground/data-components
|
|
@@ -68,7 +76,7 @@ declare function PlayDataComponents(): React.ReactElement;
|
|
|
68
76
|
*
|
|
69
77
|
* Demonstrates graph visualization with static mock data -- no backend required.
|
|
70
78
|
* Uses the GraphStoresContext provider pattern that consumers like explorer
|
|
71
|
-
* and
|
|
79
|
+
* and any consumer app would use to wire their own stores.
|
|
72
80
|
*/
|
|
73
81
|
|
|
74
82
|
declare function PlayGraph(): React.ReactElement;
|
|
@@ -81,4 +89,4 @@ declare function PlayGraph(): React.ReactElement;
|
|
|
81
89
|
*/
|
|
82
90
|
declare function PlayShellApi(): react_jsx_runtime.JSX.Element;
|
|
83
91
|
|
|
84
|
-
export { PlayAdvancedComponents, PlayColorPalette, PlayCoreComponents, PlayDataComponents, PlayFormComponents, PlayFormWidgets, PlayForms, PlayGraph, PlayJsonEditor, PlayShellApi, PlayTypography };
|
|
92
|
+
export { PlayAdvancedComponents, PlayColorPalette, PlayCoreComponents, PlayDataComponents, PlayFormComponents, PlayFormWidgets, PlayForms, PlayGraph, PlayJsonEditor, PlaySchemaDesigner, PlayShellApi, PlayTypography };
|
package/dist/pages/index.js
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
2
|
PlayForms
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-ZSUCFEB6.js";
|
|
4
4
|
import {
|
|
5
5
|
PlayFormWidgets
|
|
6
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-UB7462QG.js";
|
|
7
|
+
import {
|
|
8
|
+
PlaySchemaDesigner
|
|
9
|
+
} from "../chunk-6VQJFBTM.js";
|
|
7
10
|
import {
|
|
8
11
|
PlayDataComponents
|
|
9
12
|
} from "../chunk-O2QMWJZI.js";
|
|
10
13
|
import {
|
|
11
14
|
PlayGraph
|
|
12
|
-
} from "../chunk-
|
|
15
|
+
} from "../chunk-C2P3UQMZ.js";
|
|
13
16
|
import {
|
|
14
17
|
PlayShellApi
|
|
15
18
|
} from "../chunk-CQ6PGFRV.js";
|
|
@@ -21,7 +24,7 @@ import {
|
|
|
21
24
|
} from "../chunk-DA3BIB5N.js";
|
|
22
25
|
import {
|
|
23
26
|
PlayCoreComponents
|
|
24
|
-
} from "../chunk-
|
|
27
|
+
} from "../chunk-6WI3N7JI.js";
|
|
25
28
|
import {
|
|
26
29
|
PlayAdvancedComponents
|
|
27
30
|
} from "../chunk-4Y4JFKAK.js";
|
|
@@ -42,6 +45,7 @@ export {
|
|
|
42
45
|
PlayForms,
|
|
43
46
|
PlayGraph,
|
|
44
47
|
PlayJsonEditor,
|
|
48
|
+
PlaySchemaDesigner,
|
|
45
49
|
PlayShellApi,
|
|
46
50
|
PlayTypography
|
|
47
51
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@petrarca/sonnet-playground",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Playground framework and built-in component demos for the Petrarca Sonnet component library",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"publishConfig": {
|
|
@@ -26,11 +26,12 @@
|
|
|
26
26
|
"lucide-react": "^0.553.0",
|
|
27
27
|
"sonner": "^2.0.7",
|
|
28
28
|
"zod": "^4.3.6",
|
|
29
|
-
"@petrarca/sonnet-
|
|
30
|
-
"@petrarca/sonnet-
|
|
31
|
-
"@petrarca/sonnet-
|
|
32
|
-
"@petrarca/sonnet-
|
|
33
|
-
"@petrarca/sonnet-
|
|
29
|
+
"@petrarca/sonnet-ui": "0.6.0",
|
|
30
|
+
"@petrarca/sonnet-shell": "0.6.0",
|
|
31
|
+
"@petrarca/sonnet-forms": "0.6.0",
|
|
32
|
+
"@petrarca/sonnet-core": "0.6.0",
|
|
33
|
+
"@petrarca/sonnet-graph": "0.6.0",
|
|
34
|
+
"@petrarca/sonnet-schema-designer": "0.6.0"
|
|
34
35
|
},
|
|
35
36
|
"peerDependencies": {
|
|
36
37
|
"react": ">=19",
|
package/dist/chunk-4ORSUS65.js
DELETED
|
@@ -1,359 +0,0 @@
|
|
|
1
|
-
// src/pages/PlayGraph.tsx
|
|
2
|
-
import { useCallback, useRef, useState } from "react";
|
|
3
|
-
import {
|
|
4
|
-
GraphVisualizer,
|
|
5
|
-
ActionPanel,
|
|
6
|
-
GraphA11yList,
|
|
7
|
-
GraphRendererProvider,
|
|
8
|
-
GraphStoresContext,
|
|
9
|
-
createGraphDataStore,
|
|
10
|
-
createGraphFilterStore,
|
|
11
|
-
createGraphExplorationStore,
|
|
12
|
-
createSelectionStore,
|
|
13
|
-
createGraphFocusStore,
|
|
14
|
-
enrichNodes,
|
|
15
|
-
enrichEdges,
|
|
16
|
-
buildColorPalette
|
|
17
|
-
} from "@petrarca/sonnet-graph";
|
|
18
|
-
import {
|
|
19
|
-
Button,
|
|
20
|
-
Alert,
|
|
21
|
-
AlertDescription,
|
|
22
|
-
Tabs,
|
|
23
|
-
TabsContent,
|
|
24
|
-
TabsList,
|
|
25
|
-
TabsTrigger,
|
|
26
|
-
ResizeHandle
|
|
27
|
-
} from "@petrarca/sonnet-ui";
|
|
28
|
-
import { Play, RotateCcw } from "lucide-react";
|
|
29
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
30
|
-
var MOCK_NODES = [
|
|
31
|
-
{
|
|
32
|
-
id_: 1,
|
|
33
|
-
label_: "Company",
|
|
34
|
-
properties_: { name: "Acme Corp", founded: 1985, industry: "Technology" }
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
id_: 2,
|
|
38
|
-
label_: "Department",
|
|
39
|
-
properties_: { name: "Engineering", headcount: 42 }
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
id_: 3,
|
|
43
|
-
label_: "Department",
|
|
44
|
-
properties_: { name: "Marketing", headcount: 18 }
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
id_: 4,
|
|
48
|
-
label_: "Department",
|
|
49
|
-
properties_: { name: "Sales", headcount: 25 }
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
id_: 5,
|
|
53
|
-
label_: "Person",
|
|
54
|
-
properties_: { name: "Alice Chen", role: "CTO" }
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
id_: 6,
|
|
58
|
-
label_: "Person",
|
|
59
|
-
properties_: { name: "Bob Smith", role: "VP Engineering" }
|
|
60
|
-
},
|
|
61
|
-
{
|
|
62
|
-
id_: 7,
|
|
63
|
-
label_: "Person",
|
|
64
|
-
properties_: { name: "Carol Davis", role: "CMO" }
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
id_: 8,
|
|
68
|
-
label_: "Person",
|
|
69
|
-
properties_: { name: "Dave Wilson", role: "VP Sales" }
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
id_: 9,
|
|
73
|
-
label_: "Person",
|
|
74
|
-
properties_: { name: "Eve Johnson", role: "Senior Engineer" }
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
id_: 10,
|
|
78
|
-
label_: "Person",
|
|
79
|
-
properties_: { name: "Frank Brown", role: "Product Manager" }
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
id_: 11,
|
|
83
|
-
label_: "Product",
|
|
84
|
-
properties_: { name: "CloudSuite", version: "3.2", status: "GA" }
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
id_: 12,
|
|
88
|
-
label_: "Product",
|
|
89
|
-
properties_: { name: "DataPipeline", version: "1.0", status: "Beta" }
|
|
90
|
-
}
|
|
91
|
-
];
|
|
92
|
-
var MOCK_EDGES = [
|
|
93
|
-
{
|
|
94
|
-
id_: 101,
|
|
95
|
-
label_: "HAS_DEPARTMENT",
|
|
96
|
-
start_id_: 1,
|
|
97
|
-
end_id_: 2,
|
|
98
|
-
properties_: {}
|
|
99
|
-
},
|
|
100
|
-
{
|
|
101
|
-
id_: 102,
|
|
102
|
-
label_: "HAS_DEPARTMENT",
|
|
103
|
-
start_id_: 1,
|
|
104
|
-
end_id_: 3,
|
|
105
|
-
properties_: {}
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
id_: 103,
|
|
109
|
-
label_: "HAS_DEPARTMENT",
|
|
110
|
-
start_id_: 1,
|
|
111
|
-
end_id_: 4,
|
|
112
|
-
properties_: {}
|
|
113
|
-
},
|
|
114
|
-
{
|
|
115
|
-
id_: 104,
|
|
116
|
-
label_: "LEADS",
|
|
117
|
-
start_id_: 5,
|
|
118
|
-
end_id_: 2,
|
|
119
|
-
properties_: { since: 2019 }
|
|
120
|
-
},
|
|
121
|
-
{
|
|
122
|
-
id_: 105,
|
|
123
|
-
label_: "WORKS_IN",
|
|
124
|
-
start_id_: 6,
|
|
125
|
-
end_id_: 2,
|
|
126
|
-
properties_: { since: 2020 }
|
|
127
|
-
},
|
|
128
|
-
{
|
|
129
|
-
id_: 106,
|
|
130
|
-
label_: "LEADS",
|
|
131
|
-
start_id_: 7,
|
|
132
|
-
end_id_: 3,
|
|
133
|
-
properties_: { since: 2021 }
|
|
134
|
-
},
|
|
135
|
-
{
|
|
136
|
-
id_: 107,
|
|
137
|
-
label_: "LEADS",
|
|
138
|
-
start_id_: 8,
|
|
139
|
-
end_id_: 4,
|
|
140
|
-
properties_: { since: 2018 }
|
|
141
|
-
},
|
|
142
|
-
{
|
|
143
|
-
id_: 108,
|
|
144
|
-
label_: "WORKS_IN",
|
|
145
|
-
start_id_: 9,
|
|
146
|
-
end_id_: 2,
|
|
147
|
-
properties_: { since: 2022 }
|
|
148
|
-
},
|
|
149
|
-
{
|
|
150
|
-
id_: 109,
|
|
151
|
-
label_: "WORKS_IN",
|
|
152
|
-
start_id_: 10,
|
|
153
|
-
end_id_: 2,
|
|
154
|
-
properties_: { since: 2021 }
|
|
155
|
-
},
|
|
156
|
-
{ id_: 110, label_: "REPORTS_TO", start_id_: 6, end_id_: 5, properties_: {} },
|
|
157
|
-
{ id_: 111, label_: "REPORTS_TO", start_id_: 9, end_id_: 6, properties_: {} },
|
|
158
|
-
{
|
|
159
|
-
id_: 112,
|
|
160
|
-
label_: "REPORTS_TO",
|
|
161
|
-
start_id_: 10,
|
|
162
|
-
end_id_: 6,
|
|
163
|
-
properties_: {}
|
|
164
|
-
},
|
|
165
|
-
{ id_: 113, label_: "OWNS", start_id_: 2, end_id_: 11, properties_: {} },
|
|
166
|
-
{ id_: 114, label_: "OWNS", start_id_: 2, end_id_: 12, properties_: {} }
|
|
167
|
-
];
|
|
168
|
-
function createPlaygroundStores() {
|
|
169
|
-
const graphFilter = createGraphFilterStore();
|
|
170
|
-
const graphData = createGraphDataStore();
|
|
171
|
-
const selection = createSelectionStore();
|
|
172
|
-
const graphFocus = createGraphFocusStore();
|
|
173
|
-
const graphExploration = createGraphExplorationStore({
|
|
174
|
-
graphData,
|
|
175
|
-
selection,
|
|
176
|
-
graphFocus,
|
|
177
|
-
graphFilter,
|
|
178
|
-
// Static data -- no server expansion available in the playground
|
|
179
|
-
expandNode: async () => ({ nodes: [], edges: [], has_more: false }),
|
|
180
|
-
getNodes: async () => []
|
|
181
|
-
});
|
|
182
|
-
return { graphFilter, graphData, graphExploration, selection };
|
|
183
|
-
}
|
|
184
|
-
var PLAYGROUND_STORES = createPlaygroundStores();
|
|
185
|
-
var INITIAL_DATA = { nodes: MOCK_NODES, edges: MOCK_EDGES };
|
|
186
|
-
function serializeGraphData(data) {
|
|
187
|
-
return JSON.stringify(data, null, 2);
|
|
188
|
-
}
|
|
189
|
-
function validateNode(n, i) {
|
|
190
|
-
if (!n || typeof n !== "object") return `nodes[${i}] must be an object`;
|
|
191
|
-
const node = n;
|
|
192
|
-
if (node.id_ === void 0) return `nodes[${i}] is missing id_`;
|
|
193
|
-
if (typeof node.label_ !== "string") return `nodes[${i}] is missing label_`;
|
|
194
|
-
return null;
|
|
195
|
-
}
|
|
196
|
-
function validateEdge(e, i) {
|
|
197
|
-
if (!e || typeof e !== "object") return `edges[${i}] must be an object`;
|
|
198
|
-
const edge = e;
|
|
199
|
-
if (edge.id_ === void 0) return `edges[${i}] is missing id_`;
|
|
200
|
-
if (typeof edge.label_ !== "string") return `edges[${i}] is missing label_`;
|
|
201
|
-
if (edge.start_id_ === void 0) return `edges[${i}] is missing start_id_`;
|
|
202
|
-
if (edge.end_id_ === void 0) return `edges[${i}] is missing end_id_`;
|
|
203
|
-
return null;
|
|
204
|
-
}
|
|
205
|
-
function validateGraphInput(value) {
|
|
206
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
207
|
-
return "JSON must be an object with nodes and edges arrays";
|
|
208
|
-
}
|
|
209
|
-
const obj = value;
|
|
210
|
-
if (!Array.isArray(obj.nodes)) return '"nodes" must be an array';
|
|
211
|
-
if (!Array.isArray(obj.edges)) return '"edges" must be an array';
|
|
212
|
-
for (const [i, n] of obj.nodes.entries()) {
|
|
213
|
-
const err = validateNode(n, i);
|
|
214
|
-
if (err) return err;
|
|
215
|
-
}
|
|
216
|
-
for (const [i, e] of obj.edges.entries()) {
|
|
217
|
-
const err = validateEdge(e, i);
|
|
218
|
-
if (err) return err;
|
|
219
|
-
}
|
|
220
|
-
return null;
|
|
221
|
-
}
|
|
222
|
-
function loadIntoStore(stores, data) {
|
|
223
|
-
const labelCounts = {};
|
|
224
|
-
for (const n of data.nodes) {
|
|
225
|
-
labelCounts[n.label_] = (labelCounts[n.label_] ?? 0) + 1;
|
|
226
|
-
}
|
|
227
|
-
const palette = buildColorPalette(labelCounts);
|
|
228
|
-
const nodes = enrichNodes(data.nodes, palette);
|
|
229
|
-
const edges = enrichEdges(data.edges, palette);
|
|
230
|
-
stores.graphFilter.getState().resetFilters();
|
|
231
|
-
stores.graphData.getState().setQueryData(nodes, edges, {
|
|
232
|
-
nodes: nodes.length,
|
|
233
|
-
edges: edges.length
|
|
234
|
-
});
|
|
235
|
-
stores.graphFilter.getState().notifyDataChange();
|
|
236
|
-
}
|
|
237
|
-
loadIntoStore(PLAYGROUND_STORES, INITIAL_DATA);
|
|
238
|
-
function PlayGraph() {
|
|
239
|
-
const [jsonText, setJsonText] = useState(
|
|
240
|
-
() => serializeGraphData(INITIAL_DATA)
|
|
241
|
-
);
|
|
242
|
-
const [parseError, setParseError] = useState(null);
|
|
243
|
-
const [panelWidth, setPanelWidth] = useState(300);
|
|
244
|
-
const rowRef = useRef(null);
|
|
245
|
-
const startResize = useCallback((e) => {
|
|
246
|
-
e.preventDefault();
|
|
247
|
-
const target = e.currentTarget;
|
|
248
|
-
target.setPointerCapture(e.pointerId);
|
|
249
|
-
const move = (ev) => {
|
|
250
|
-
const right = rowRef.current?.getBoundingClientRect().right ?? 0;
|
|
251
|
-
setPanelWidth(Math.min(560, Math.max(200, right - ev.clientX)));
|
|
252
|
-
};
|
|
253
|
-
const up = () => {
|
|
254
|
-
window.removeEventListener("pointermove", move);
|
|
255
|
-
window.removeEventListener("pointerup", up);
|
|
256
|
-
};
|
|
257
|
-
window.addEventListener("pointermove", move);
|
|
258
|
-
window.addEventListener("pointerup", up);
|
|
259
|
-
}, []);
|
|
260
|
-
const handleApply = useCallback(() => {
|
|
261
|
-
let parsed;
|
|
262
|
-
try {
|
|
263
|
-
parsed = JSON.parse(jsonText);
|
|
264
|
-
} catch (e) {
|
|
265
|
-
setParseError(e instanceof Error ? e.message : "Invalid JSON");
|
|
266
|
-
return;
|
|
267
|
-
}
|
|
268
|
-
const validationError = validateGraphInput(parsed);
|
|
269
|
-
if (validationError) {
|
|
270
|
-
setParseError(validationError);
|
|
271
|
-
return;
|
|
272
|
-
}
|
|
273
|
-
setParseError(null);
|
|
274
|
-
loadIntoStore(PLAYGROUND_STORES, parsed);
|
|
275
|
-
}, [jsonText]);
|
|
276
|
-
const handleReset = useCallback(() => {
|
|
277
|
-
setJsonText(serializeGraphData(INITIAL_DATA));
|
|
278
|
-
setParseError(null);
|
|
279
|
-
loadIntoStore(PLAYGROUND_STORES, INITIAL_DATA);
|
|
280
|
-
}, []);
|
|
281
|
-
const handleKeyDown = useCallback(
|
|
282
|
-
(e) => {
|
|
283
|
-
if ((e.metaKey || e.ctrlKey) && e.key === "Enter") {
|
|
284
|
-
e.preventDefault();
|
|
285
|
-
handleApply();
|
|
286
|
-
}
|
|
287
|
-
},
|
|
288
|
-
[handleApply]
|
|
289
|
-
);
|
|
290
|
-
return /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
|
|
291
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
292
|
-
/* @__PURE__ */ jsx("h1", { children: "Graph Visualization" }),
|
|
293
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mt-1", children: "Interactive property graph with dual renderer support. Edit the JSON data and apply to re-render." })
|
|
294
|
-
] }),
|
|
295
|
-
/* @__PURE__ */ jsx(GraphStoresContext.Provider, { value: PLAYGROUND_STORES, children: /* @__PURE__ */ jsxs(Tabs, { defaultValue: "graph", className: "space-y-3", children: [
|
|
296
|
-
/* @__PURE__ */ jsxs(TabsList, { children: [
|
|
297
|
-
/* @__PURE__ */ jsx(TabsTrigger, { value: "graph", children: "Graph" }),
|
|
298
|
-
/* @__PURE__ */ jsx(TabsTrigger, { value: "data", children: "Data" })
|
|
299
|
-
] }),
|
|
300
|
-
/* @__PURE__ */ jsx(TabsContent, { value: "graph", className: "mt-0", children: /* @__PURE__ */ jsx(GraphRendererProvider, { defaultRenderer: "cytoscape", children: /* @__PURE__ */ jsxs("div", { ref: rowRef, className: "flex overflow-hidden h-[600px]", children: [
|
|
301
|
-
/* @__PURE__ */ jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsx(GraphVisualizer, {}) }),
|
|
302
|
-
/* @__PURE__ */ jsx(
|
|
303
|
-
ResizeHandle,
|
|
304
|
-
{
|
|
305
|
-
orientation: "vertical",
|
|
306
|
-
"aria-valuenow": panelWidth,
|
|
307
|
-
"aria-valuemin": 200,
|
|
308
|
-
"aria-valuemax": 560,
|
|
309
|
-
onPointerDown: startResize,
|
|
310
|
-
onDoubleClick: () => setPanelWidth(300)
|
|
311
|
-
}
|
|
312
|
-
),
|
|
313
|
-
/* @__PURE__ */ jsxs(
|
|
314
|
-
"div",
|
|
315
|
-
{
|
|
316
|
-
style: { width: panelWidth },
|
|
317
|
-
className: "flex-shrink-0 flex flex-col min-h-0",
|
|
318
|
-
children: [
|
|
319
|
-
/* @__PURE__ */ jsx("div", { className: "flex-1 min-h-0 overflow-hidden", children: /* @__PURE__ */ jsx(ActionPanel, {}) }),
|
|
320
|
-
/* @__PURE__ */ jsxs("div", { className: "shrink-0 px-4 pb-4 pt-2", children: [
|
|
321
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wide mb-2", children: "Accessible list (demo)" }),
|
|
322
|
-
/* @__PURE__ */ jsx(GraphA11yList, { visible: true, maxHeight: 160 })
|
|
323
|
-
] })
|
|
324
|
-
]
|
|
325
|
-
}
|
|
326
|
-
)
|
|
327
|
-
] }) }) }),
|
|
328
|
-
/* @__PURE__ */ jsx(TabsContent, { value: "data", className: "mt-0", children: /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
329
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
330
|
-
/* @__PURE__ */ jsxs(Button, { size: "sm", onClick: handleApply, children: [
|
|
331
|
-
/* @__PURE__ */ jsx(Play, { className: "h-4 w-4 mr-1" }),
|
|
332
|
-
"Apply"
|
|
333
|
-
] }),
|
|
334
|
-
/* @__PURE__ */ jsxs(Button, { size: "sm", variant: "outline", onClick: handleReset, children: [
|
|
335
|
-
/* @__PURE__ */ jsx(RotateCcw, { className: "h-4 w-4 mr-1" }),
|
|
336
|
-
"Reset"
|
|
337
|
-
] }),
|
|
338
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground ml-2", children: "Cmd+Enter to apply" })
|
|
339
|
-
] }),
|
|
340
|
-
parseError && /* @__PURE__ */ jsx(Alert, { variant: "destructive", children: /* @__PURE__ */ jsx(AlertDescription, { children: parseError }) }),
|
|
341
|
-
/* @__PURE__ */ jsx(
|
|
342
|
-
"textarea",
|
|
343
|
-
{
|
|
344
|
-
value: jsonText,
|
|
345
|
-
onChange: (e) => setJsonText(e.target.value),
|
|
346
|
-
onKeyDown: handleKeyDown,
|
|
347
|
-
spellCheck: false,
|
|
348
|
-
className: "w-full h-[600px] font-mono text-xs p-3 border rounded-lg bg-muted/30 resize-y focus:outline-none focus:ring-2 focus:ring-ring"
|
|
349
|
-
}
|
|
350
|
-
)
|
|
351
|
-
] }) })
|
|
352
|
-
] }) })
|
|
353
|
-
] });
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
export {
|
|
357
|
-
PlayGraph
|
|
358
|
-
};
|
|
359
|
-
//# sourceMappingURL=chunk-4ORSUS65.js.map
|