@cratis/scene.react 3.1.0 → 3.3.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.
Files changed (66) hide show
  1. package/core/ScreenplayCoreComponents.tsx +72 -0
  2. package/core/coreComponents.ts +24 -0
  3. package/core/corePackage.ts +16 -1
  4. package/core/index.ts +1 -0
  5. package/dist/cjs/NavBar/NavBar.js.map +1 -1
  6. package/dist/cjs/NavBar/extractNavigationItem.js.map +1 -1
  7. package/dist/cjs/SceneElementView.js.map +1 -1
  8. package/dist/cjs/core/CoreButton.js.map +1 -1
  9. package/dist/cjs/core/CoreCard.js.map +1 -1
  10. package/dist/cjs/core/CoreText.js.map +1 -1
  11. package/dist/cjs/core/ScreenplayCoreComponents.js +128 -0
  12. package/dist/cjs/core/ScreenplayCoreComponents.js.map +1 -0
  13. package/dist/cjs/core/coreComponents.js +13 -1
  14. package/dist/cjs/core/coreComponents.js.map +1 -1
  15. package/dist/cjs/core/corePackage.js +12 -1
  16. package/dist/cjs/core/corePackage.js.map +1 -1
  17. package/dist/cjs/index.js +12 -0
  18. package/dist/cjs/index.js.map +1 -1
  19. package/dist/cjs/packages/ScenePackageBundle.js.map +1 -1
  20. package/dist/cjs/renderer/UnresolvedComponent.js.map +1 -1
  21. package/dist/cjs/renderer/createReactRenderer.js.map +1 -1
  22. package/dist/cjs/renderer/panelLayout.js +25 -0
  23. package/dist/cjs/renderer/panelLayout.js.map +1 -1
  24. package/dist/cjs/theme/SceneThemeProvider.js.map +1 -1
  25. package/dist/cjs/theme/themeTokens.js.map +1 -1
  26. package/dist/esm/NavBar/NavBar.js.map +1 -1
  27. package/dist/esm/NavBar/extractNavigationItem.js.map +1 -1
  28. package/dist/esm/SceneElementView.js.map +1 -1
  29. package/dist/esm/core/CoreButton.js.map +1 -1
  30. package/dist/esm/core/CoreCard.js.map +1 -1
  31. package/dist/esm/core/CoreText.js.map +1 -1
  32. package/dist/esm/core/ScreenplayCoreComponents.d.ts +13 -0
  33. package/dist/esm/core/ScreenplayCoreComponents.d.ts.map +1 -0
  34. package/dist/esm/core/ScreenplayCoreComponents.js +116 -0
  35. package/dist/esm/core/ScreenplayCoreComponents.js.map +1 -0
  36. package/dist/esm/core/coreComponents.d.ts.map +1 -1
  37. package/dist/esm/core/coreComponents.js +13 -1
  38. package/dist/esm/core/coreComponents.js.map +1 -1
  39. package/dist/esm/core/corePackage.d.ts.map +1 -1
  40. package/dist/esm/core/corePackage.js +12 -1
  41. package/dist/esm/core/corePackage.js.map +1 -1
  42. package/dist/esm/core/index.d.ts +1 -0
  43. package/dist/esm/core/index.d.ts.map +1 -1
  44. package/dist/esm/core/index.js +1 -0
  45. package/dist/esm/core/index.js.map +1 -1
  46. package/dist/esm/for_ScreenplayCoreComponents/when_rendering_a_translated_screen.d.ts +2 -0
  47. package/dist/esm/for_ScreenplayCoreComponents/when_rendering_a_translated_screen.d.ts.map +1 -0
  48. package/dist/esm/for_ScreenplayCoreComponents/when_rendering_a_translated_screen.js +46 -0
  49. package/dist/esm/for_ScreenplayCoreComponents/when_rendering_a_translated_screen.js.map +1 -0
  50. package/dist/esm/for_panelLayout/when_arranging_a_panel.js +19 -0
  51. package/dist/esm/for_panelLayout/when_arranging_a_panel.js.map +1 -1
  52. package/dist/esm/index.js +1 -0
  53. package/dist/esm/index.js.map +1 -1
  54. package/dist/esm/packages/ScenePackageBundle.js.map +1 -1
  55. package/dist/esm/renderer/UnresolvedComponent.js.map +1 -1
  56. package/dist/esm/renderer/createReactRenderer.js.map +1 -1
  57. package/dist/esm/renderer/panelLayout.d.ts.map +1 -1
  58. package/dist/esm/renderer/panelLayout.js +26 -1
  59. package/dist/esm/renderer/panelLayout.js.map +1 -1
  60. package/dist/esm/theme/SceneThemeProvider.js.map +1 -1
  61. package/dist/esm/theme/themeTokens.js.map +1 -1
  62. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  63. package/for_ScreenplayCoreComponents/when_rendering_a_translated_screen.tsx +60 -0
  64. package/for_panelLayout/when_arranging_a_panel.ts +24 -1
  65. package/package.json +11 -11
  66. package/renderer/panelLayout.ts +22 -1
package/dist/esm/index.js CHANGED
@@ -4,6 +4,7 @@ export { createReactRenderer } from './renderer/createReactRenderer.js';
4
4
  export { CoreText } from './core/CoreText.js';
5
5
  export { CoreButton } from './core/CoreButton.js';
6
6
  export { CoreCard } from './core/CoreCard.js';
7
+ export { CoreAction, CoreCode, CoreColumn, CoreData, CoreField, CoreFile, CoreNavigate, CoreSection, CoreSummary, CoreTable, CoreTitle } from './core/ScreenplayCoreComponents.js';
7
8
  export { coreComponents } from './core/coreComponents.js';
8
9
  export { corePackage, corePackageManifest } from './core/corePackage.js';
9
10
  export { NavBar } from './NavBar/NavBar.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"ScenePackageBundle.js","sources":["../../../packages/ScenePackageBundle.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { DialogTemplate, Layout, ScenePackage, Screen, ScreenTemplate, Theme } from '@cratis/scene.model';\nimport { ComponentRegistry } from '../renderer';\n\n/**\n * What a package actually ships to a React renderer, as opposed to what it *declares*.\n *\n * `ScenePackage` is the declaration — a name, a kind, dependencies, and the names of what it\n * contributes. It is deliberately platform-agnostic and lives in `Scene.Model`, because Stage's build and\n * Studio's design-time queries both read it without ever loading a component. A bundle is the other half:\n * the real React components, layouts, screens and themes behind those names, which only a renderer needs.\n *\n * A package publishes exactly one bundle, as a named export following its own name —\n * `primeReactPackage`, `cratisComponentsPackage`, `corePackage`. A host loads it from the module the\n * declaration's `ScenePackage.module` names.\n */\nexport interface ScenePackageBundle {\n /**\n * The package's own declaration. Its `components`, `layouts` and `themes` name lists must agree with\n * what this bundle actually provides — {@link validatePackageBundle} is what proves they do.\n */\n manifest: ScenePackage;\n\n /**\n * The components this package provides, keyed by {@link componentRegistryKey}.\n */\n components: ComponentRegistry;\n\n /**\n * The application shells this package provides, if any. Only a blueprint has these.\n */\n layouts?: Layout[];\n\n /**\n * The screen templates this package provides — the shapes that go inside a layout, each declaring\n * which of its parent's slots it fills.\n */\n screenTemplates?: ScreenTemplate[];\n\n /**\n * The dialog templates this package provides.\n */\n dialogTemplates?: DialogTemplate[];\n\n /**\n * Sample screens this package ships — a layout package's gallery, so a preview has real content to\n * put through the real engine rather than a mockup.\n */\n screens?: Screen[];\n\n /**\n * The themes this package ships, if any.\n */\n themes?: Theme[];\n}\n\n/**\n * The key a component is registered and looked up under: the package that provides it, then the bare name\n * a screen refers to it by.\n *\n * A screen writes a bare name (`button`) or a package-qualified one (`PrimeReact.button`);\n * `resolveComponentName` turns either into a `{ name, package }` pair, and this turns that pair into the\n * registry key. Nothing should build this string by hand — the separator is an implementation detail of\n * the registry, deliberately not the `.` used for qualification in a screen, so a package name containing\n * dots stays unambiguous.\n */\nexport function componentRegistryKey(packageName: string, componentName: string): string {\n return `${packageName}:${componentName}`;\n}\n\n/**\n * Checks that a bundle provides everything its manifest declares, and declares everything it provides.\n *\n * A manifest that promises a component the bundle does not register renders as `UnresolvedComponent` at\n * runtime — a blank box, far from where the mistake was made. A component registered but not declared is\n * invisible to `resolveComponentName`, so a screen can never name it. Both are silent failures, which is\n * why every package's specs run this.\n */\nexport function validatePackageBundle(bundle: ScenePackageBundle): string[] {\n const problems: string[] = [];\n const { manifest } = bundle;\n\n for (const name of manifest.components) {\n if (!(componentRegistryKey(manifest.name, name) in bundle.components)) {\n problems.push(`declares the component '${name}' but registers no implementation for it`);\n }\n }\n\n const declared = new Set(manifest.components.map((name) => componentRegistryKey(manifest.name, name)));\n for (const key of Object.keys(bundle.components)) {\n if (!declared.has(key)) {\n problems.push(`registers '${key}', which the manifest does not declare`);\n }\n }\n\n const providedLayouts = new Set((bundle.layouts ?? []).map((layout) => layout.name));\n for (const name of manifest.layouts) {\n if (!providedLayouts.has(name)) {\n problems.push(`declares the layout '${name}' but provides no definition for it`);\n }\n }\n\n const providedScreenTemplates = new Set((bundle.screenTemplates ?? []).map((template) => template.name));\n for (const name of manifest.screenTemplates) {\n if (!providedScreenTemplates.has(name)) {\n problems.push(`declares the screen template '${name}' but provides no definition for it`);\n }\n }\n\n const providedDialogTemplates = new Set((bundle.dialogTemplates ?? []).map((template) => template.name));\n for (const name of manifest.dialogTemplates) {\n if (!providedDialogTemplates.has(name)) {\n problems.push(`declares the dialog template '${name}' but provides no definition for it`);\n }\n }\n\n const providedThemes = new Set((bundle.themes ?? []).map((theme) => theme.name));\n for (const name of manifest.themes) {\n if (!providedThemes.has(name)) {\n problems.push(`declares the theme '${name}' but provides no definition for it`);\n }\n }\n\n return problems;\n}\n\n/**\n * Merges the component registries of several bundles into the single registry a renderer consumes.\n *\n * Keys carry their package name, so nothing collides and merge order does not matter — which package wins\n * a *bare* name is decided earlier, by `resolveComponentName` walking the profile's priority order.\n */\nexport function mergePackageRegistries(bundles: ScenePackageBundle[]): ComponentRegistry {\n return Object.assign({}, ...bundles.map((bundle) => bundle.components)) as ComponentRegistry;\n}\n"],"names":["componentRegistryKey","packageName","componentName","validatePackageBundle","bundle","problems","manifest","name","components","push","declared","Set","map","key","Object","keys","has","providedLayouts","layouts","layout","providedScreenTemplates","screenTemplates","template","providedDialogTemplates","dialogTemplates","providedThemes","themes","theme","mergePackageRegistries","bundles","assign"],"mappings":"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"}
1
+ {"version":3,"file":"ScenePackageBundle.js","sources":["../../../packages/ScenePackageBundle.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { DialogTemplate, Layout, ScenePackage, Screen, ScreenTemplate, Theme } from '@cratis/scene.model';\nimport { ComponentRegistry } from '../renderer';\n\n/**\n * What a package actually ships to a React renderer, as opposed to what it *declares*.\n *\n * `ScenePackage` is the declaration — a name, a kind, dependencies, and the names of what it\n * contributes. It is deliberately platform-agnostic and lives in `Scene.Model`, because Stage's build and\n * Studio's design-time queries both read it without ever loading a component. A bundle is the other half:\n * the real React components, layouts, screens and themes behind those names, which only a renderer needs.\n *\n * A package publishes exactly one bundle, as a named export following its own name —\n * `primeReactPackage`, `cratisComponentsPackage`, `corePackage`. A host loads it from the module the\n * declaration's `ScenePackage.module` names.\n */\nexport interface ScenePackageBundle {\n /**\n * The package's own declaration. Its `components`, `layouts` and `themes` name lists must agree with\n * what this bundle actually provides — {@link validatePackageBundle} is what proves they do.\n */\n manifest: ScenePackage;\n\n /**\n * The components this package provides, keyed by {@link componentRegistryKey}.\n */\n components: ComponentRegistry;\n\n /**\n * The application shells this package provides, if any. Only a blueprint has these.\n */\n layouts?: Layout[];\n\n /**\n * The screen templates this package provides — the shapes that go inside a layout, each declaring\n * which of its parent's slots it fills.\n */\n screenTemplates?: ScreenTemplate[];\n\n /**\n * The dialog templates this package provides.\n */\n dialogTemplates?: DialogTemplate[];\n\n /**\n * Sample screens this package ships — a layout package's gallery, so a preview has real content to\n * put through the real engine rather than a mockup.\n */\n screens?: Screen[];\n\n /**\n * The themes this package ships, if any.\n */\n themes?: Theme[];\n}\n\n/**\n * The key a component is registered and looked up under: the package that provides it, then the bare name\n * a screen refers to it by.\n *\n * A screen writes a bare name (`button`) or a package-qualified one (`PrimeReact.button`);\n * `resolveComponentName` turns either into a `{ name, package }` pair, and this turns that pair into the\n * registry key. Nothing should build this string by hand — the separator is an implementation detail of\n * the registry, deliberately not the `.` used for qualification in a screen, so a package name containing\n * dots stays unambiguous.\n */\nexport function componentRegistryKey(packageName: string, componentName: string): string {\n return `${packageName}:${componentName}`;\n}\n\n/**\n * Checks that a bundle provides everything its manifest declares, and declares everything it provides.\n *\n * A manifest that promises a component the bundle does not register renders as `UnresolvedComponent` at\n * runtime — a blank box, far from where the mistake was made. A component registered but not declared is\n * invisible to `resolveComponentName`, so a screen can never name it. Both are silent failures, which is\n * why every package's specs run this.\n */\nexport function validatePackageBundle(bundle: ScenePackageBundle): string[] {\n const problems: string[] = [];\n const { manifest } = bundle;\n\n for (const name of manifest.components) {\n if (!(componentRegistryKey(manifest.name, name) in bundle.components)) {\n problems.push(`declares the component '${name}' but registers no implementation for it`);\n }\n }\n\n const declared = new Set(manifest.components.map((name) => componentRegistryKey(manifest.name, name)));\n for (const key of Object.keys(bundle.components)) {\n if (!declared.has(key)) {\n problems.push(`registers '${key}', which the manifest does not declare`);\n }\n }\n\n const providedLayouts = new Set((bundle.layouts ?? []).map((layout) => layout.name));\n for (const name of manifest.layouts) {\n if (!providedLayouts.has(name)) {\n problems.push(`declares the layout '${name}' but provides no definition for it`);\n }\n }\n\n const providedScreenTemplates = new Set((bundle.screenTemplates ?? []).map((template) => template.name));\n for (const name of manifest.screenTemplates) {\n if (!providedScreenTemplates.has(name)) {\n problems.push(`declares the screen template '${name}' but provides no definition for it`);\n }\n }\n\n const providedDialogTemplates = new Set((bundle.dialogTemplates ?? []).map((template) => template.name));\n for (const name of manifest.dialogTemplates) {\n if (!providedDialogTemplates.has(name)) {\n problems.push(`declares the dialog template '${name}' but provides no definition for it`);\n }\n }\n\n const providedThemes = new Set((bundle.themes ?? []).map((theme) => theme.name));\n for (const name of manifest.themes) {\n if (!providedThemes.has(name)) {\n problems.push(`declares the theme '${name}' but provides no definition for it`);\n }\n }\n\n return problems;\n}\n\n/**\n * Merges the component registries of several bundles into the single registry a renderer consumes.\n *\n * Keys carry their package name, so nothing collides and merge order does not matter — which package wins\n * a *bare* name is decided earlier, by `resolveComponentName` walking the profile's priority order.\n */\nexport function mergePackageRegistries(bundles: ScenePackageBundle[]): ComponentRegistry {\n return Object.assign({}, ...bundles.map((bundle) => bundle.components)) as ComponentRegistry;\n}\n"],"names":["componentRegistryKey","packageName","componentName","validatePackageBundle","bundle","problems","manifest","name","components","push","declared","Set","map","key","Object","keys","has","providedLayouts","layouts","layout","providedScreenTemplates","screenTemplates","template","providedDialogTemplates","dialogTemplates","providedThemes","themes","theme","mergePackageRegistries","bundles","assign"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"UnresolvedComponent.js","sources":["../../../renderer/UnresolvedComponent.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { RegisteredComponentProps } from './ComponentRegistry';\n\n/**\n * The fallback rendered for an {@link ExternalComponent} whose `componentName` is not in the active\n * {@link ComponentRegistry} - a visibly broken placeholder, never a silent blank, since a missing\n * component is a real configuration gap the renderer should surface, not hide.\n */\nexport function UnresolvedComponent({ element }: RegisteredComponentProps) {\n return (\n <div\n data-scene-unresolved-component={element.componentName}\n style={{ border: '1px dashed red', color: 'red', padding: '0.25rem 0.5rem', fontFamily: 'monospace' }}\n >\n Unresolved component: {element.componentName}\n </div>\n );\n}\n"],"names":["UnresolvedComponent","element","_jsxs","div","data-scene-unresolved-component","componentName","style","border","color","padding","fontFamily"],"mappings":";;AAAA;AACA;AAIA;;;;AAIC,IACM,SAASA,mBAAAA,CAAoB,EAAEC,OAAO,EAA4B,EAAA;AACrE,IAAA,qBACIC,IAAA,CAACC,KAAAA,EAAAA;AACGC,QAAAA,iCAAAA,EAAiCH,QAAQI,aAAa;QACtDC,KAAAA,EAAO;YAAEC,MAAAA,EAAQ,gBAAA;YAAkBC,KAAAA,EAAO,KAAA;YAAOC,OAAAA,EAAS,gBAAA;YAAkBC,UAAAA,EAAY;AAAY,SAAA;;AACvG,YAAA,wBAAA;AAC0BT,YAAAA,OAAAA,CAAQI;;;AAG3C;;;;"}
1
+ {"version":3,"file":"UnresolvedComponent.js","sources":["../../../renderer/UnresolvedComponent.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { RegisteredComponentProps } from './ComponentRegistry';\n\n/**\n * The fallback rendered for an {@link ExternalComponent} whose `componentName` is not in the active\n * {@link ComponentRegistry} - a visibly broken placeholder, never a silent blank, since a missing\n * component is a real configuration gap the renderer should surface, not hide.\n */\nexport function UnresolvedComponent({ element }: RegisteredComponentProps) {\n return (\n <div\n data-scene-unresolved-component={element.componentName}\n style={{ border: '1px dashed red', color: 'red', padding: '0.25rem 0.5rem', fontFamily: 'monospace' }}\n >\n Unresolved component: {element.componentName}\n </div>\n );\n}\n"],"names":["UnresolvedComponent","element","_jsxs","div","data-scene-unresolved-component","componentName","style","border","color","padding","fontFamily"],"mappings":";;AAAA;AACA;AAIA;;;;AAIC,IACM,SAASA,mBAAAA,CAAoB,EAAEC,OAAO,EAA4B,EAAA;AACrE,IAAA,qBACIC,IAAA,CAACC,KAAAA,EAAAA;AACGC,QAAAA,iCAAAA,EAAiCH,QAAQI,aAAa;QACtDC,KAAAA,EAAO;YAAEC,MAAAA,EAAQ,gBAAA;YAAkBC,KAAAA,EAAO,KAAA;YAAOC,OAAAA,EAAS,gBAAA;YAAkBC,UAAAA,EAAY;AAAY,SAAA;;AACvG,YAAA,wBAAA;AAC0BT,YAAAA,OAAAA,CAAQI;;;AAG3C;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"createReactRenderer.js","sources":["../../../renderer/createReactRenderer.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { ReactNode, createElement } from 'react';\nimport { Renderer } from '@cratis/scene.engine';\nimport { ContentControl, ExternalComponent, ItemsControl, Panel } from '@cratis/scene.model';\nimport { ComponentRegistry } from './ComponentRegistry';\nimport { childStyle, panelStyle } from './panelLayout';\nimport { UnresolvedComponent } from './UnresolvedComponent';\n\n/**\n * Creates a {@link Renderer} that turns a Scene element tree into React elements.\n *\n * `ItemsControl` and `ContentControl` render as plain wrapping `div`s. A `Panel` renders as the\n * arrangement it declares - a grid, a stack, a wrap or a dock - because that is what those panels are\n * for; see `panelLayout` for the mapping. Arranging a *layout's slots* by `flow`/`freeform` is a\n * different thing and stays Scene#4's, layered on top of this renderer rather than folded into it.\n */\nexport function createReactRenderer(registry: ComponentRegistry): Renderer<ReactNode> {\n return {\n renderContentControl(element: ContentControl, content: ReactNode): ReactNode {\n return createElement('div', { key: element.id, 'data-scene-id': element.id, 'data-scene-kind': 'ContentControl' }, content);\n },\n\n renderItemsControl(element: ItemsControl, items: ReactNode[]): ReactNode {\n return createElement('div', { key: element.id, 'data-scene-id': element.id, 'data-scene-kind': 'ItemsControl' }, items);\n },\n\n renderExternalComponent(element: ExternalComponent, slots: Record<string, ReactNode[]>): ReactNode {\n const Component = registry[element.componentName] ?? UnresolvedComponent;\n return createElement(Component, { key: element.id, element, slots });\n },\n\n renderPanel(element: Panel, children: ReactNode[]): ReactNode {\n // The rendered children arrive in the same order as `element.children`, so a panel that places\n // its children individually - a grid cell, a docked edge - can wrap each one in the box that\n // places it without needing to re-render anything.\n const placed = children.map((child, index) => {\n const style = childStyle(element, element.children[index], index);\n return style\n ? createElement('div', { key: `${element.id}-${index}`, 'data-scene-placement': index, style }, child)\n : child;\n });\n\n return createElement(\n 'div',\n { key: element.id, 'data-scene-id': element.id, 'data-scene-kind': 'Panel', style: panelStyle(element) },\n placed);\n },\n };\n}\n"],"names":["createReactRenderer","registry","renderContentControl","element","content","createElement","key","id","renderItemsControl","items","renderExternalComponent","slots","Component","componentName","UnresolvedComponent","renderPanel","children","placed","map","child","index","style","childStyle","panelStyle"],"mappings":";;;;AAAA;AACA;AASA;;;;;;;IAQO,SAASA,mBAAAA,CAAoBC,QAA2B,EAAA;IAC3D,OAAO;QACHC,oBAAAA,CAAAA,CAAqBC,OAAuB,EAAEC,OAAkB,EAAA;AAC5D,YAAA,qBAAOC,cAAc,KAAA,EAAO;AAAEC,gBAAAA,GAAAA,EAAKH,QAAQI,EAAE;AAAE,gBAAA,eAAA,EAAiBJ,QAAQI,EAAE;gBAAE,iBAAA,EAAmB;aAAiB,EAAGH,OAAAA,CAAAA;AACvH,QAAA,CAAA;QAEAI,kBAAAA,CAAAA,CAAmBL,OAAqB,EAAEM,KAAkB,EAAA;AACxD,YAAA,qBAAOJ,cAAc,KAAA,EAAO;AAAEC,gBAAAA,GAAAA,EAAKH,QAAQI,EAAE;AAAE,gBAAA,eAAA,EAAiBJ,QAAQI,EAAE;gBAAE,iBAAA,EAAmB;aAAe,EAAGE,KAAAA,CAAAA;AACrH,QAAA,CAAA;QAEAC,uBAAAA,CAAAA,CAAwBP,OAA0B,EAAEQ,KAAkC,EAAA;AAClF,YAAA,MAAMC,YAAYX,QAAQ,CAACE,OAAAA,CAAQU,aAAa,CAAC,IAAIC,mBAAAA;AACrD,YAAA,qBAAOT,cAAcO,SAAAA,EAAW;AAAEN,gBAAAA,GAAAA,EAAKH,QAAQI,EAAE;AAAEJ,gBAAAA,OAAAA;AAASQ,gBAAAA;AAAM,aAAA,CAAA;AACtE,QAAA,CAAA;QAEAI,WAAAA,CAAAA,CAAYZ,OAAc,EAAEa,QAAqB,EAAA;;;;AAI7C,YAAA,MAAMC,MAAAA,GAASD,QAAAA,CAASE,GAAG,CAAC,CAACC,KAAAA,EAAOC,KAAAA,GAAAA;AAChC,gBAAA,MAAMC,QAAQC,UAAAA,CAAWnB,OAAAA,EAASA,QAAQa,QAAQ,CAACI,MAAM,EAAEA,KAAAA,CAAAA;gBAC3D,OAAOC,KAAAA,iBACDhB,cAAc,KAAA,EAAO;AAAEC,oBAAAA,GAAAA,EAAK,GAAGH,OAAAA,CAAQI,EAAE,CAAC,CAAC,EAAEa,KAAAA,CAAAA,CAAO;oBAAE,sBAAA,EAAwBA,KAAAA;AAAOC,oBAAAA;AAAM,iBAAA,EAAGF,KAAAA,CAAAA,GAC9FA,KAAAA;AACV,YAAA,CAAA,CAAA;AAEA,YAAA,qBAAOd,cACH,KAAA,EACA;AAAEC,gBAAAA,GAAAA,EAAKH,QAAQI,EAAE;AAAE,gBAAA,eAAA,EAAiBJ,QAAQI,EAAE;gBAAE,iBAAA,EAAmB,OAAA;AAASc,gBAAAA,KAAAA,EAAOE,UAAAA,CAAWpB,OAAAA;aAAS,EACvGc,MAAAA,CAAAA;AACR,QAAA;AACJ,KAAA;AACJ;;;;"}
1
+ {"version":3,"file":"createReactRenderer.js","sources":["../../../renderer/createReactRenderer.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { ReactNode, createElement } from 'react';\nimport { Renderer } from '@cratis/scene.engine';\nimport { ContentControl, ExternalComponent, ItemsControl, Panel } from '@cratis/scene.model';\nimport { ComponentRegistry } from './ComponentRegistry';\nimport { childStyle, panelStyle } from './panelLayout';\nimport { UnresolvedComponent } from './UnresolvedComponent';\n\n/**\n * Creates a {@link Renderer} that turns a Scene element tree into React elements.\n *\n * `ItemsControl` and `ContentControl` render as plain wrapping `div`s. A `Panel` renders as the\n * arrangement it declares - a grid, a stack, a wrap or a dock - because that is what those panels are\n * for; see `panelLayout` for the mapping. Arranging a *layout's slots* by `flow`/`freeform` is a\n * different thing and stays Scene#4's, layered on top of this renderer rather than folded into it.\n */\nexport function createReactRenderer(registry: ComponentRegistry): Renderer<ReactNode> {\n return {\n renderContentControl(element: ContentControl, content: ReactNode): ReactNode {\n return createElement('div', { key: element.id, 'data-scene-id': element.id, 'data-scene-kind': 'ContentControl' }, content);\n },\n\n renderItemsControl(element: ItemsControl, items: ReactNode[]): ReactNode {\n return createElement('div', { key: element.id, 'data-scene-id': element.id, 'data-scene-kind': 'ItemsControl' }, items);\n },\n\n renderExternalComponent(element: ExternalComponent, slots: Record<string, ReactNode[]>): ReactNode {\n const Component = registry[element.componentName] ?? UnresolvedComponent;\n return createElement(Component, { key: element.id, element, slots });\n },\n\n renderPanel(element: Panel, children: ReactNode[]): ReactNode {\n // The rendered children arrive in the same order as `element.children`, so a panel that places\n // its children individually - a grid cell, a docked edge - can wrap each one in the box that\n // places it without needing to re-render anything.\n const placed = children.map((child, index) => {\n const style = childStyle(element, element.children[index], index);\n return style\n ? createElement('div', { key: `${element.id}-${index}`, 'data-scene-placement': index, style }, child)\n : child;\n });\n\n return createElement(\n 'div',\n { key: element.id, 'data-scene-id': element.id, 'data-scene-kind': 'Panel', style: panelStyle(element) },\n placed);\n },\n };\n}\n"],"names":["createReactRenderer","registry","renderContentControl","element","content","createElement","key","id","renderItemsControl","items","renderExternalComponent","slots","Component","componentName","UnresolvedComponent","renderPanel","children","placed","map","child","index","style","childStyle","panelStyle"],"mappings":";;;;AAAA;AACA;AASA;;;;;;;IAQO,SAASA,mBAAAA,CAAoBC,QAA2B,EAAA;IAC3D,OAAO;QACHC,oBAAAA,CAAAA,CAAqBC,OAAuB,EAAEC,OAAkB,EAAA;AAC5D,YAAA,qBAAOC,cAAc,KAAA,EAAO;AAAEC,gBAAAA,GAAAA,EAAKH,QAAQI,EAAE;AAAE,gBAAA,eAAA,EAAiBJ,QAAQI,EAAE;gBAAE,iBAAA,EAAmB;aAAiB,EAAGH,OAAAA,CAAAA;AACvH,QAAA,CAAA;QAEAI,kBAAAA,CAAAA,CAAmBL,OAAqB,EAAEM,KAAkB,EAAA;AACxD,YAAA,qBAAOJ,cAAc,KAAA,EAAO;AAAEC,gBAAAA,GAAAA,EAAKH,QAAQI,EAAE;AAAE,gBAAA,eAAA,EAAiBJ,QAAQI,EAAE;gBAAE,iBAAA,EAAmB;aAAe,EAAGE,KAAAA,CAAAA;AACrH,QAAA,CAAA;QAEAC,uBAAAA,CAAAA,CAAwBP,OAA0B,EAAEQ,KAAkC,EAAA;AAClF,YAAA,MAAMC,YAAYX,QAAQ,CAACE,OAAAA,CAAQU,aAAa,CAAC,IAAIC,mBAAAA;AACrD,YAAA,qBAAOT,cAAcO,SAAAA,EAAW;AAAEN,gBAAAA,GAAAA,EAAKH,QAAQI,EAAE;AAAEJ,gBAAAA,OAAAA;AAASQ,gBAAAA;AAAM,aAAA,CAAA;AACtE,QAAA,CAAA;QAEAI,WAAAA,CAAAA,CAAYZ,OAAc,EAAEa,QAAqB,EAAA;;;;AAI7C,YAAA,MAAMC,MAAAA,GAASD,QAAAA,CAASE,GAAG,CAAC,CAACC,KAAAA,EAAOC,KAAAA,GAAAA;AAChC,gBAAA,MAAMC,QAAQC,UAAAA,CAAWnB,OAAAA,EAASA,QAAQa,QAAQ,CAACI,MAAM,EAAEA,KAAAA,CAAAA;gBAC3D,OAAOC,KAAAA,iBACDhB,cAAc,KAAA,EAAO;AAAEC,oBAAAA,GAAAA,EAAK,GAAGH,OAAAA,CAAQI,EAAE,CAAC,CAAC,EAAEa,KAAAA,CAAAA,CAAO;oBAAE,sBAAA,EAAwBA,KAAAA;AAAOC,oBAAAA;AAAM,iBAAA,EAAGF,KAAAA,CAAAA,GAC9FA,KAAAA;AACV,YAAA,CAAA,CAAA;AAEA,YAAA,qBAAOd,cACH,KAAA,EACA;AAAEC,gBAAAA,GAAAA,EAAKH,QAAQI,EAAE;AAAE,gBAAA,eAAA,EAAiBJ,QAAQI,EAAE;gBAAE,iBAAA,EAAmB,OAAA;AAASc,gBAAAA,KAAAA,EAAOE,UAAAA,CAAWpB,OAAAA;aAAS,EACvGc,MAAAA,CAAAA;AACR,QAAA;AACJ,KAAA;AACJ;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"panelLayout.d.ts","sourceRoot":"","sources":["../../../renderer/panelLayout.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAG3C,OAAO,KAAK,EAAgC,KAAK,EAAiB,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAkC5G,wBAAgB,UAAU,CAAC,KAAK,EAAE,KAAK,GAAG,aAAa,GAAG,SAAS,CAiClE;AAGD,wBAAgB,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAgCtG"}
1
+ {"version":3,"file":"panelLayout.d.ts","sourceRoot":"","sources":["../../../renderer/panelLayout.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAG3C,OAAO,KAAK,EAAgC,KAAK,EAAiB,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAkC5G,wBAAgB,UAAU,CAAC,KAAK,EAAE,KAAK,GAAG,aAAa,GAAG,SAAS,CA2ClE;AAGD,wBAAgB,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CA2CtG"}
@@ -1,4 +1,4 @@
1
- import { isGrid, isDockPanel, isWrapPanel, isStackPanel } from '@cratis/scene.engine';
1
+ import { isCanvas, isGrid, isDockPanel, isWrapPanel, isStackPanel } from '@cratis/scene.engine';
2
2
  import { Dock, Orientation, GridUnitType } from '@cratis/scene.model';
3
3
 
4
4
  // Copyright (c) Cratis. All rights reserved.
@@ -29,6 +29,15 @@ const rowTrack = (row)=>bound(row.minimumHeight, row.maximumHeight, track(row.he
29
29
  const columnTrack = (column)=>bound(column.minimumWidth, column.maximumWidth, track(column.width));
30
30
  const number = (value)=>typeof value === 'number' ? value : undefined;
31
31
  /** The CSS that arranges a panel's own children. */ function panelStyle(panel) {
32
+ if (isCanvas(panel)) {
33
+ // Absolutely placed children need a positioned ancestor to be placed against, and the canvas is
34
+ // that ancestor rather than whatever happens to be above it.
35
+ return {
36
+ position: 'relative',
37
+ width: panel.extent?.width ?? undefined,
38
+ height: panel.extent?.height ?? undefined
39
+ };
40
+ }
32
41
  if (isGrid(panel)) {
33
42
  return {
34
43
  display: 'grid',
@@ -63,6 +72,22 @@ const number = (value)=>typeof value === 'number' ? value : undefined;
63
72
  }
64
73
  /** The CSS that places one child within its panel, or `undefined` when the panel places children implicitly. */ function childStyle(panel, child, index) {
65
74
  const properties = child.properties ?? {};
75
+ if (isCanvas(panel)) {
76
+ const left = number(properties['Canvas.Left']);
77
+ const top = number(properties['Canvas.Top']);
78
+ const right = number(properties['Canvas.Right']);
79
+ const bottom = number(properties['Canvas.Bottom']);
80
+ // A child that names no edge is not placed by the canvas at all, so it keeps whatever flow the
81
+ // renderer would otherwise have given it rather than being pinned to the origin.
82
+ if (left === undefined && top === undefined && right === undefined && bottom === undefined) return undefined;
83
+ return {
84
+ position: 'absolute',
85
+ left,
86
+ top,
87
+ right,
88
+ bottom
89
+ };
90
+ }
66
91
  if (isGrid(panel)) {
67
92
  const row = number(properties['Grid.Row']);
68
93
  const column = number(properties['Grid.Column']);
@@ -1 +1 @@
1
- {"version":3,"file":"panelLayout.js","sources":["../../../renderer/panelLayout.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport type { CSSProperties } from 'react';\nimport { isDockPanel, isGrid, isStackPanel, isWrapPanel } from '@cratis/scene.engine';\nimport { Dock, GridUnitType, Orientation } from '@cratis/scene.model';\nimport type { ColumnDefinition, GridLength, Panel, RowDefinition, SceneElement } from '@cratis/scene.model';\n\n/**\n * Turns a panel into the CSS that arranges it, and a child into the CSS that places it inside one.\n *\n * The panels say what an arrangement *is*; this says what it looks like on the web. A second renderer -\n * native, desktop - answers the same question with its own platform's layout primitives, which is why\n * this lives in `Scene.React` rather than in the model or the engine.\n *\n * Where a panel needs to say something about an individual child - which grid cell, which edge - it does\n * so through that child's own `properties` bag, because the model has no attached properties of its own.\n * The keys are the ones the model's documentation names: `Grid.Row`, `Grid.Column`, `Grid.RowSpan`,\n * `Grid.ColumnSpan` and `Dock`.\n */\n\nconst track = (length: GridLength): string => {\n switch (length.unitType) {\n case GridUnitType.Auto: return 'auto';\n case GridUnitType.Absolute: return `${length.value}px`;\n case GridUnitType.Star: return `${length.value}fr`;\n }\n};\n\nconst bound = (minimum: number, maximum: number, size: string): string =>\n minimum === 0 && !Number.isFinite(maximum)\n ? size\n : `minmax(${minimum}px, ${Number.isFinite(maximum) ? `${maximum}px` : size})`;\n\nconst rowTrack = (row: RowDefinition): string => bound(row.minimumHeight, row.maximumHeight, track(row.height));\nconst columnTrack = (column: ColumnDefinition): string => bound(column.minimumWidth, column.maximumWidth, track(column.width));\n\nconst number = (value: unknown): number | undefined => (typeof value === 'number' ? value : undefined);\n\n/** The CSS that arranges a panel's own children. */\nexport function panelStyle(panel: Panel): CSSProperties | undefined {\n if (isGrid(panel)) {\n return {\n display: 'grid',\n gridTemplateRows: panel.rows.map(rowTrack).join(' ') || undefined,\n gridTemplateColumns: panel.columns.map(columnTrack).join(' ') || undefined,\n };\n }\n\n if (isDockPanel(panel)) {\n // Docking has no single CSS primitive. A column of rows with a middle that grows is the shape a\n // dock panel actually produces, and `lastChildFill` decides whether the final child is that\n // middle or just another docked edge.\n return { display: 'flex', flexDirection: 'column' };\n }\n\n if (isStackPanel(panel)) {\n return {\n display: 'flex',\n flexDirection: panel.orientation === Orientation.Horizontal ? 'row' : 'column',\n gap: panel.spacing ? `${panel.spacing}px` : undefined,\n };\n }\n\n if (isWrapPanel(panel)) {\n return {\n display: 'flex',\n flexWrap: 'wrap',\n flexDirection: panel.orientation === Orientation.Horizontal ? 'row' : 'column',\n };\n }\n\n return undefined;\n}\n\n/** The CSS that places one child within its panel, or `undefined` when the panel places children implicitly. */\nexport function childStyle(panel: Panel, child: SceneElement, index: number): CSSProperties | undefined {\n const properties = child.properties ?? {};\n\n if (isGrid(panel)) {\n const row = number(properties['Grid.Row']);\n const column = number(properties['Grid.Column']);\n const rowSpan = number(properties['Grid.RowSpan']) ?? 1;\n const columnSpan = number(properties['Grid.ColumnSpan']) ?? 1;\n if (row === undefined && column === undefined) return undefined;\n return {\n gridRow: row === undefined ? undefined : `${row + 1} / span ${rowSpan}`,\n gridColumn: column === undefined ? undefined : `${column + 1} / span ${columnSpan}`,\n };\n }\n\n if (isDockPanel(panel)) {\n const dock = properties['Dock'] as Dock | undefined;\n const isFill = panel.lastChildFill && index === (panel.children?.length ?? 0) - 1;\n if (isFill) return { flex: '1 1 auto', minHeight: 0 };\n // Left and right dock along the cross axis of the column the panel lays out, so they become a row\n // of their own rather than a sibling in the column.\n return dock === Dock.Left || dock === Dock.Right\n ? { alignSelf: dock === Dock.Left ? 'flex-start' : 'flex-end', flex: '0 0 auto' }\n : { flex: '0 0 auto' };\n }\n\n if (isWrapPanel(panel)) {\n if (panel.itemWidth === undefined && panel.itemHeight === undefined) return undefined;\n return { width: panel.itemWidth, height: panel.itemHeight, flex: '0 0 auto' };\n }\n\n return undefined;\n}\n"],"names":["track","length","unitType","GridUnitType","Auto","Absolute","value","Star","bound","minimum","maximum","size","Number","isFinite","rowTrack","row","minimumHeight","maximumHeight","height","columnTrack","column","minimumWidth","maximumWidth","width","number","undefined","panelStyle","panel","isGrid","display","gridTemplateRows","rows","map","join","gridTemplateColumns","columns","isDockPanel","flexDirection","isStackPanel","orientation","Orientation","Horizontal","gap","spacing","isWrapPanel","flexWrap","childStyle","child","index","properties","rowSpan","columnSpan","gridRow","gridColumn","dock","isFill","lastChildFill","children","flex","minHeight","Dock","Left","Right","alignSelf","itemWidth","itemHeight"],"mappings":";;;AAAA;AACA;AAOA;;;;;;;;;;;IAaA,MAAMA,QAAQ,CAACC,MAAAA,GAAAA;AACX,IAAA,OAAQA,OAAOC,QAAQ;AACnB,QAAA,KAAKC,aAAaC,IAAI;YAAE,OAAO,MAAA;AAC/B,QAAA,KAAKD,aAAaE,QAAQ;AAAE,YAAA,OAAO,CAAA,EAAGJ,MAAAA,CAAOK,KAAK,CAAC,EAAE,CAAC;AACtD,QAAA,KAAKH,aAAaI,IAAI;AAAE,YAAA,OAAO,CAAA,EAAGN,MAAAA,CAAOK,KAAK,CAAC,EAAE,CAAC;AACtD;AACJ,CAAA;AAEA,MAAME,KAAAA,GAAQ,CAACC,OAAAA,EAAiBC,OAAAA,EAAiBC,IAAAA,GAC7CF,OAAAA,KAAY,CAAA,IAAK,CAACG,MAAAA,CAAOC,QAAQ,CAACH,OAAAA,CAAAA,GAC5BC,OACA,CAAC,OAAO,EAAEF,OAAAA,CAAQ,IAAI,EAAEG,MAAAA,CAAOC,QAAQ,CAACH,OAAAA,CAAAA,GAAW,CAAA,EAAGA,OAAAA,CAAQ,EAAE,CAAC,GAAGC,IAAAA,CAAK,CAAC,CAAC;AAErF,MAAMG,QAAAA,GAAW,CAACC,GAAAA,GAA+BP,KAAAA,CAAMO,GAAAA,CAAIC,aAAa,EAAED,GAAAA,CAAIE,aAAa,EAAEjB,KAAAA,CAAMe,GAAAA,CAAIG,MAAM,CAAA,CAAA;AAC7G,MAAMC,WAAAA,GAAc,CAACC,MAAAA,GAAqCZ,KAAAA,CAAMY,MAAAA,CAAOC,YAAY,EAAED,MAAAA,CAAOE,YAAY,EAAEtB,KAAAA,CAAMoB,MAAAA,CAAOG,KAAK,CAAA,CAAA;AAE5H,MAAMC,SAAS,CAAClB,KAAAA,GAAwC,OAAOA,KAAAA,KAAU,WAAWA,KAAAA,GAAQmB,SAAAA;AAE5F,qDACO,SAASC,UAAAA,CAAWC,KAAY,EAAA;AACnC,IAAA,IAAIC,OAAOD,KAAAA,CAAAA,EAAQ;QACf,OAAO;YACHE,OAAAA,EAAS,MAAA;YACTC,gBAAAA,EAAkBH,KAAAA,CAAMI,IAAI,CAACC,GAAG,CAAClB,QAAAA,CAAAA,CAAUmB,IAAI,CAAC,GAAA,CAAA,IAAQR,SAAAA;YACxDS,mBAAAA,EAAqBP,KAAAA,CAAMQ,OAAO,CAACH,GAAG,CAACb,WAAAA,CAAAA,CAAac,IAAI,CAAC,GAAA,CAAA,IAAQR;AACrE,SAAA;AACJ,IAAA;AAEA,IAAA,IAAIW,YAAYT,KAAAA,CAAAA,EAAQ;;;;QAIpB,OAAO;YAAEE,OAAAA,EAAS,MAAA;YAAQQ,aAAAA,EAAe;AAAS,SAAA;AACtD,IAAA;AAEA,IAAA,IAAIC,aAAaX,KAAAA,CAAAA,EAAQ;QACrB,OAAO;YACHE,OAAAA,EAAS,MAAA;AACTQ,YAAAA,aAAAA,EAAeV,MAAMY,WAAW,KAAKC,WAAAA,CAAYC,UAAU,GAAG,KAAA,GAAQ,QAAA;YACtEC,GAAAA,EAAKf,KAAAA,CAAMgB,OAAO,GAAG,CAAA,EAAGhB,MAAMgB,OAAO,CAAC,EAAE,CAAC,GAAGlB;AAChD,SAAA;AACJ,IAAA;AAEA,IAAA,IAAImB,YAAYjB,KAAAA,CAAAA,EAAQ;QACpB,OAAO;YACHE,OAAAA,EAAS,MAAA;YACTgB,QAAAA,EAAU,MAAA;AACVR,YAAAA,aAAAA,EAAeV,MAAMY,WAAW,KAAKC,WAAAA,CAAYC,UAAU,GAAG,KAAA,GAAQ;AAC1E,SAAA;AACJ,IAAA;IAEA,OAAOhB,SAAAA;AACX;AAEA,iHACO,SAASqB,UAAAA,CAAWnB,KAAY,EAAEoB,KAAmB,EAAEC,KAAa,EAAA;AACvE,IAAA,MAAMC,UAAAA,GAAaF,KAAAA,CAAME,UAAU,IAAI,EAAC;AAExC,IAAA,IAAIrB,OAAOD,KAAAA,CAAAA,EAAQ;AACf,QAAA,MAAMZ,GAAAA,GAAMS,MAAAA,CAAOyB,UAAU,CAAC,UAAA,CAAW,CAAA;AACzC,QAAA,MAAM7B,MAAAA,GAASI,MAAAA,CAAOyB,UAAU,CAAC,aAAA,CAAc,CAAA;AAC/C,QAAA,MAAMC,OAAAA,GAAU1B,MAAAA,CAAOyB,UAAU,CAAC,eAAe,CAAA,IAAK,CAAA;AACtD,QAAA,MAAME,UAAAA,GAAa3B,MAAAA,CAAOyB,UAAU,CAAC,kBAAkB,CAAA,IAAK,CAAA;AAC5D,QAAA,IAAIlC,GAAAA,KAAQU,SAAAA,IAAaL,MAAAA,KAAWK,SAAAA,EAAW,OAAOA,SAAAA;QACtD,OAAO;YACH2B,OAAAA,EAASrC,GAAAA,KAAQU,YAAYA,SAAAA,GAAY,CAAA,EAAGV,MAAM,CAAA,CAAE,QAAQ,EAAEmC,OAAAA,CAAAA,CAAS;YACvEG,UAAAA,EAAYjC,MAAAA,KAAWK,YAAYA,SAAAA,GAAY,CAAA,EAAGL,SAAS,CAAA,CAAE,QAAQ,EAAE+B,UAAAA,CAAAA;AAC3E,SAAA;AACJ,IAAA;AAEA,IAAA,IAAIf,YAAYT,KAAAA,CAAAA,EAAQ;QACpB,MAAM2B,IAAAA,GAAOL,UAAU,CAAC,MAAA,CAAO;AAC/B,QAAA,MAAMM,MAAAA,GAAS5B,KAAAA,CAAM6B,aAAa,IAAIR,KAAAA,KAAWrB,CAAAA,KAAAA,CAAM8B,QAAQ,EAAExD,MAAAA,IAAU,CAAA,IAAK,CAAA;AAChF,QAAA,IAAIsD,QAAQ,OAAO;YAAEG,IAAAA,EAAM,UAAA;YAAYC,SAAAA,EAAW;AAAE,SAAA;;;AAGpD,QAAA,OAAOL,SAASM,IAAAA,CAAKC,IAAI,IAAIP,IAAAA,KAASM,IAAAA,CAAKE,KAAK,GAC1C;AAAEC,YAAAA,SAAAA,EAAWT,IAAAA,KAASM,IAAAA,CAAKC,IAAI,GAAG,YAAA,GAAe,UAAA;YAAYH,IAAAA,EAAM;SAAW,GAC9E;YAAEA,IAAAA,EAAM;AAAW,SAAA;AAC7B,IAAA;AAEA,IAAA,IAAId,YAAYjB,KAAAA,CAAAA,EAAQ;QACpB,IAAIA,KAAAA,CAAMqC,SAAS,KAAKvC,SAAAA,IAAaE,MAAMsC,UAAU,KAAKxC,WAAW,OAAOA,SAAAA;QAC5E,OAAO;AAAEF,YAAAA,KAAAA,EAAOI,MAAMqC,SAAS;AAAE9C,YAAAA,MAAAA,EAAQS,MAAMsC,UAAU;YAAEP,IAAAA,EAAM;AAAW,SAAA;AAChF,IAAA;IAEA,OAAOjC,SAAAA;AACX;;;;"}
1
+ {"version":3,"file":"panelLayout.js","sources":["../../../renderer/panelLayout.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport type { CSSProperties } from 'react';\nimport { isCanvas, isDockPanel, isGrid, isStackPanel, isWrapPanel } from '@cratis/scene.engine';\nimport { Dock, GridUnitType, Orientation } from '@cratis/scene.model';\nimport type { ColumnDefinition, GridLength, Panel, RowDefinition, SceneElement } from '@cratis/scene.model';\n\n/**\n * Turns a panel into the CSS that arranges it, and a child into the CSS that places it inside one.\n *\n * The panels say what an arrangement *is*; this says what it looks like on the web. A second renderer -\n * native, desktop - answers the same question with its own platform's layout primitives, which is why\n * this lives in `Scene.React` rather than in the model or the engine.\n *\n * Where a panel needs to say something about an individual child - which grid cell, which edge - it does\n * so through that child's own `properties` bag, because the model has no attached properties of its own.\n * The keys are the ones the model's documentation names: `Grid.Row`, `Grid.Column`, `Grid.RowSpan`,\n * `Grid.ColumnSpan` and `Dock`.\n */\n\nconst track = (length: GridLength): string => {\n switch (length.unitType) {\n case GridUnitType.Auto: return 'auto';\n case GridUnitType.Absolute: return `${length.value}px`;\n case GridUnitType.Star: return `${length.value}fr`;\n }\n};\n\nconst bound = (minimum: number, maximum: number, size: string): string =>\n minimum === 0 && !Number.isFinite(maximum)\n ? size\n : `minmax(${minimum}px, ${Number.isFinite(maximum) ? `${maximum}px` : size})`;\n\nconst rowTrack = (row: RowDefinition): string => bound(row.minimumHeight, row.maximumHeight, track(row.height));\nconst columnTrack = (column: ColumnDefinition): string => bound(column.minimumWidth, column.maximumWidth, track(column.width));\n\nconst number = (value: unknown): number | undefined => (typeof value === 'number' ? value : undefined);\n\n/** The CSS that arranges a panel's own children. */\nexport function panelStyle(panel: Panel): CSSProperties | undefined {\n if (isCanvas(panel)) {\n // Absolutely placed children need a positioned ancestor to be placed against, and the canvas is\n // that ancestor rather than whatever happens to be above it.\n return {\n position: 'relative',\n width: panel.extent?.width ?? undefined,\n height: panel.extent?.height ?? undefined,\n };\n }\n\n if (isGrid(panel)) {\n return {\n display: 'grid',\n gridTemplateRows: panel.rows.map(rowTrack).join(' ') || undefined,\n gridTemplateColumns: panel.columns.map(columnTrack).join(' ') || undefined,\n };\n }\n\n if (isDockPanel(panel)) {\n // Docking has no single CSS primitive. A column of rows with a middle that grows is the shape a\n // dock panel actually produces, and `lastChildFill` decides whether the final child is that\n // middle or just another docked edge.\n return { display: 'flex', flexDirection: 'column' };\n }\n\n if (isStackPanel(panel)) {\n return {\n display: 'flex',\n flexDirection: panel.orientation === Orientation.Horizontal ? 'row' : 'column',\n gap: panel.spacing ? `${panel.spacing}px` : undefined,\n };\n }\n\n if (isWrapPanel(panel)) {\n return {\n display: 'flex',\n flexWrap: 'wrap',\n flexDirection: panel.orientation === Orientation.Horizontal ? 'row' : 'column',\n };\n }\n\n return undefined;\n}\n\n/** The CSS that places one child within its panel, or `undefined` when the panel places children implicitly. */\nexport function childStyle(panel: Panel, child: SceneElement, index: number): CSSProperties | undefined {\n const properties = child.properties ?? {};\n\n if (isCanvas(panel)) {\n const left = number(properties['Canvas.Left']);\n const top = number(properties['Canvas.Top']);\n const right = number(properties['Canvas.Right']);\n const bottom = number(properties['Canvas.Bottom']);\n // A child that names no edge is not placed by the canvas at all, so it keeps whatever flow the\n // renderer would otherwise have given it rather than being pinned to the origin.\n if (left === undefined && top === undefined && right === undefined && bottom === undefined) return undefined;\n return { position: 'absolute', left, top, right, bottom };\n }\n\n if (isGrid(panel)) {\n const row = number(properties['Grid.Row']);\n const column = number(properties['Grid.Column']);\n const rowSpan = number(properties['Grid.RowSpan']) ?? 1;\n const columnSpan = number(properties['Grid.ColumnSpan']) ?? 1;\n if (row === undefined && column === undefined) return undefined;\n return {\n gridRow: row === undefined ? undefined : `${row + 1} / span ${rowSpan}`,\n gridColumn: column === undefined ? undefined : `${column + 1} / span ${columnSpan}`,\n };\n }\n\n if (isDockPanel(panel)) {\n const dock = properties['Dock'] as Dock | undefined;\n const isFill = panel.lastChildFill && index === (panel.children?.length ?? 0) - 1;\n if (isFill) return { flex: '1 1 auto', minHeight: 0 };\n // Left and right dock along the cross axis of the column the panel lays out, so they become a row\n // of their own rather than a sibling in the column.\n return dock === Dock.Left || dock === Dock.Right\n ? { alignSelf: dock === Dock.Left ? 'flex-start' : 'flex-end', flex: '0 0 auto' }\n : { flex: '0 0 auto' };\n }\n\n if (isWrapPanel(panel)) {\n if (panel.itemWidth === undefined && panel.itemHeight === undefined) return undefined;\n return { width: panel.itemWidth, height: panel.itemHeight, flex: '0 0 auto' };\n }\n\n return undefined;\n}\n"],"names":["track","length","unitType","GridUnitType","Auto","Absolute","value","Star","bound","minimum","maximum","size","Number","isFinite","rowTrack","row","minimumHeight","maximumHeight","height","columnTrack","column","minimumWidth","maximumWidth","width","number","undefined","panelStyle","panel","isCanvas","position","extent","isGrid","display","gridTemplateRows","rows","map","join","gridTemplateColumns","columns","isDockPanel","flexDirection","isStackPanel","orientation","Orientation","Horizontal","gap","spacing","isWrapPanel","flexWrap","childStyle","child","index","properties","left","top","right","bottom","rowSpan","columnSpan","gridRow","gridColumn","dock","isFill","lastChildFill","children","flex","minHeight","Dock","Left","Right","alignSelf","itemWidth","itemHeight"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"SceneThemeProvider.js","sources":["../../../theme/SceneThemeProvider.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { ReactNode, createContext, useContext, useLayoutEffect, useRef } from 'react';\nimport { Theme } from '@cratis/scene.model';\nimport { applyThemeTokens } from './themeTokens';\n\nconst SceneThemeContext = createContext<Theme | undefined>(undefined);\n\n/**\n * The theme currently applied by the nearest {@link SceneThemeProvider}, for a package component that has\n * to make a decision a token cannot express - picking a light or dark logo asset, say.\n */\nexport function useSceneTheme(): Theme | undefined {\n return useContext(SceneThemeContext);\n}\n\nexport interface SceneThemePropsBase {\n /**\n * The theme to apply. Changing it re-resolves in place - no reload, no remount of the subtree.\n */\n theme?: Theme;\n\n /**\n * The content the theme applies to.\n */\n children?: ReactNode;\n\n /**\n * A class name for the element the tokens land on.\n */\n className?: string;\n}\n\n/**\n * Applies a {@link Theme}'s tokens to a wrapping element and makes the theme available to everything\n * inside it.\n *\n * Theme switching is live re-resolution: the tokens are written onto the same element rather than\n * swapping a stylesheet, so a preview changes theme without a flash and without losing any state below\n * it. That is what lets Studio's gallery switch themes as fast as you can click.\n */\nexport function SceneThemeProvider({ theme, children, className }: SceneThemePropsBase) {\n const elementRef = useRef<HTMLDivElement>(null);\n const previousRef = useRef<Theme | undefined>(undefined);\n\n useLayoutEffect(() => {\n if (!elementRef.current) return;\n applyThemeTokens(elementRef.current, theme, previousRef.current);\n previousRef.current = theme;\n }, [theme]);\n\n return (\n <div ref={elementRef} className={className} data-scene-theme-root=''>\n <SceneThemeContext.Provider value={theme}>{children}</SceneThemeContext.Provider>\n </div>\n );\n}\n"],"names":["SceneThemeContext","createContext","undefined","useSceneTheme","useContext","SceneThemeProvider","theme","children","className","elementRef","useRef","previousRef","useLayoutEffect","current","applyThemeTokens","_jsx","div","ref","data-scene-theme-root","Provider","value"],"mappings":";;;;AAOA,MAAMA,kCAAoBC,aAAAA,CAAiCC,SAAAA,CAAAA;AAE3D;;;AAGC,IACM,SAASC,aAAAA,GAAAA;AACZ,IAAA,OAAOC,UAAAA,CAAWJ,iBAAAA,CAAAA;AACtB;AAmBA;;;;;;;IAQO,SAASK,kBAAAA,CAAmB,EAAEC,KAAK,EAAEC,QAAQ,EAAEC,SAAS,EAAuB,EAAA;AAClF,IAAA,MAAMC,aAAaC,MAAAA,CAAuB,IAAA,CAAA;AAC1C,IAAA,MAAMC,cAAcD,MAAAA,CAA0BR,SAAAA,CAAAA;IAE9CU,eAAAA,CAAgB,IAAA;QACZ,IAAI,CAACH,UAAAA,CAAWI,OAAO,EAAE;AACzBC,QAAAA,gBAAAA,CAAiBL,UAAAA,CAAWI,OAAO,EAAEP,KAAAA,EAAOK,YAAYE,OAAO,CAAA;AAC/DF,QAAAA,WAAAA,CAAYE,OAAO,GAAGP,KAAAA;IAC1B,CAAA,EAAG;AAACA,QAAAA;AAAM,KAAA,CAAA;AAEV,IAAA,qBACIS,GAAA,CAACC,KAAAA,EAAAA;QAAIC,GAAAA,EAAKR,UAAAA;QAAYD,SAAAA,EAAWA,SAAAA;QAAWU,uBAAAA,EAAsB,EAAA;gCAC9DH,GAAA,CAACf,kBAAkBmB,QAAQ,EAAA;YAACC,KAAAA,EAAOd,KAAAA;AAAQC,YAAAA,QAAAA,EAAAA;;;AAGvD;;;;"}
1
+ {"version":3,"file":"SceneThemeProvider.js","sources":["../../../theme/SceneThemeProvider.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { ReactNode, createContext, useContext, useLayoutEffect, useRef } from 'react';\nimport { Theme } from '@cratis/scene.model';\nimport { applyThemeTokens } from './themeTokens';\n\nconst SceneThemeContext = createContext<Theme | undefined>(undefined);\n\n/**\n * The theme currently applied by the nearest {@link SceneThemeProvider}, for a package component that has\n * to make a decision a token cannot express - picking a light or dark logo asset, say.\n */\nexport function useSceneTheme(): Theme | undefined {\n return useContext(SceneThemeContext);\n}\n\nexport interface SceneThemePropsBase {\n /**\n * The theme to apply. Changing it re-resolves in place - no reload, no remount of the subtree.\n */\n theme?: Theme;\n\n /**\n * The content the theme applies to.\n */\n children?: ReactNode;\n\n /**\n * A class name for the element the tokens land on.\n */\n className?: string;\n}\n\n/**\n * Applies a {@link Theme}'s tokens to a wrapping element and makes the theme available to everything\n * inside it.\n *\n * Theme switching is live re-resolution: the tokens are written onto the same element rather than\n * swapping a stylesheet, so a preview changes theme without a flash and without losing any state below\n * it. That is what lets Studio's gallery switch themes as fast as you can click.\n */\nexport function SceneThemeProvider({ theme, children, className }: SceneThemePropsBase) {\n const elementRef = useRef<HTMLDivElement>(null);\n const previousRef = useRef<Theme | undefined>(undefined);\n\n useLayoutEffect(() => {\n if (!elementRef.current) return;\n applyThemeTokens(elementRef.current, theme, previousRef.current);\n previousRef.current = theme;\n }, [theme]);\n\n return (\n <div ref={elementRef} className={className} data-scene-theme-root=''>\n <SceneThemeContext.Provider value={theme}>{children}</SceneThemeContext.Provider>\n </div>\n );\n}\n"],"names":["SceneThemeContext","createContext","undefined","useSceneTheme","useContext","SceneThemeProvider","theme","children","className","elementRef","useRef","previousRef","useLayoutEffect","current","applyThemeTokens","_jsx","div","ref","data-scene-theme-root","Provider","value"],"mappings":";;;;AAOA,MAAMA,kCAAoBC,aAAAA,CAAiCC,SAAAA,CAAAA;AAE3D;;;AAGC,IACM,SAASC,aAAAA,GAAAA;AACZ,IAAA,OAAOC,UAAAA,CAAWJ,iBAAAA,CAAAA;AACtB;AAmBA;;;;;;;IAQO,SAASK,kBAAAA,CAAmB,EAAEC,KAAK,EAAEC,QAAQ,EAAEC,SAAS,EAAuB,EAAA;AAClF,IAAA,MAAMC,aAAaC,MAAAA,CAAuB,IAAA,CAAA;AAC1C,IAAA,MAAMC,cAAcD,MAAAA,CAA0BR,SAAAA,CAAAA;IAE9CU,eAAAA,CAAgB,IAAA;QACZ,IAAI,CAACH,UAAAA,CAAWI,OAAO,EAAE;AACzBC,QAAAA,gBAAAA,CAAiBL,UAAAA,CAAWI,OAAO,EAAEP,KAAAA,EAAOK,YAAYE,OAAO,CAAA;AAC/DF,QAAAA,WAAAA,CAAYE,OAAO,GAAGP,KAAAA;IAC1B,CAAA,EAAG;AAACA,QAAAA;AAAM,KAAA,CAAA;AAEV,IAAA,qBACIS,GAAA,CAACC,KAAAA,EAAAA;QAAIC,GAAAA,EAAKR,UAAAA;QAAYD,SAAAA,EAAWA,SAAAA;QAAWU,uBAAAA,EAAsB,EAAA;gCAC9DH,GAAA,CAACf,kBAAkBmB,QAAQ,EAAA;YAACC,KAAAA,EAAOd,KAAAA;AAAQC,YAAAA,QAAAA,EAAAA;;;AAGvD;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"themeTokens.js","sources":["../../../theme/themeTokens.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { Theme } from '@cratis/scene.model';\n\n/**\n * The prefix every Scene design token gets as a CSS custom property. A package adapts these to whatever\n * its own component library expects — the PrimeReact package maps them onto PrimeReact's variables, the\n * same indirection `@cratis/components` uses for its `--cratis-*` layer — so layout and component CSS\n * never hardcodes one library's variable names.\n */\nexport const themeTokenPrefix = '--scene';\n\n/**\n * Turns a semantic token name into its CSS custom property name: `primary.color` becomes\n * `--scene-primary-color`, `surface.borderColor` becomes `--scene-surface-border-color`.\n *\n * Token names are semantic and platform-neutral in `Scene.Model` on purpose; this is the one place that\n * decides what they look like in CSS, so a non-DOM renderer can make an entirely different choice.\n */\nexport function themeTokenProperty(token: string): string {\n const kebab = token\n .split('.')\n .map((part) => part.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase())\n .join('-');\n return `${themeTokenPrefix}-${kebab}`;\n}\n\n/**\n * Applies a theme to an element, in place.\n *\n * Every token becomes a custom property on the element, and the element is marked with the theme's name\n * and colour scheme so CSS can key off either. Tokens the previous theme set and this one does not are\n * removed, so switching themes cannot leave a stale value behind.\n *\n * This is deliberately a mutation of an existing element rather than a re-render: switching theme has to\n * be live re-resolution against the running profile, with no reload and no remount, or a gallery preview\n * flickers every time someone tries a different theme.\n */\nexport function applyThemeTokens(element: HTMLElement, theme: Theme | undefined, previous?: Theme): void {\n for (const token of Object.keys(previous?.tokens ?? {})) {\n if (!theme?.tokens || !(token in theme.tokens)) {\n element.style.removeProperty(themeTokenProperty(token));\n }\n }\n\n if (!theme) {\n element.removeAttribute('data-scene-theme');\n element.removeAttribute('data-scene-color-scheme');\n return;\n }\n\n for (const [token, value] of Object.entries(theme.tokens ?? {})) {\n element.style.setProperty(themeTokenProperty(token), value);\n }\n\n element.setAttribute('data-scene-theme', theme.name);\n element.setAttribute('data-scene-color-scheme', theme.isDark ? 'dark' : 'light');\n}\n"],"names":["themeTokenPrefix","themeTokenProperty","token","kebab","split","map","part","replace","toLowerCase","join","applyThemeTokens","element","theme","previous","Object","keys","tokens","style","removeProperty","removeAttribute","value","entries","setProperty","setAttribute","name","isDark"],"mappings":"AAAA;AACA;AAIA;;;;;IAMO,MAAMA,gBAAAA,GAAmB;AAEhC;;;;;;IAOO,SAASC,kBAAAA,CAAmBC,KAAa,EAAA;AAC5C,IAAA,MAAMC,QAAQD,KAAAA,CACTE,KAAK,CAAC,GAAA,CAAA,CACNC,GAAG,CAAC,CAACC,IAAAA,GAASA,IAAAA,CAAKC,OAAO,CAAC,oBAAA,EAAsB,SAASC,WAAW,EAAA,CAAA,CACrEC,IAAI,CAAC,GAAA,CAAA;AACV,IAAA,OAAO,CAAA,EAAGT,gBAAAA,CAAiB,CAAC,EAAEG,KAAAA,CAAAA,CAAO;AACzC;AAEA;;;;;;;;;;AAUC,IACM,SAASO,gBAAAA,CAAiBC,OAAoB,EAAEC,KAAwB,EAAEC,QAAgB,EAAA;IAC7F,KAAK,MAAMX,SAASY,MAAAA,CAAOC,IAAI,CAACF,QAAAA,EAAUG,MAAAA,IAAU,EAAC,CAAA,CAAI;QACrD,IAAI,CAACJ,OAAOI,MAAAA,IAAU,EAAEd,KAAAA,IAASU,KAAAA,CAAMI,MAAK,CAAA,EAAI;AAC5CL,YAAAA,OAAAA,CAAQM,KAAK,CAACC,cAAc,CAACjB,kBAAAA,CAAmBC,KAAAA,CAAAA,CAAAA;AACpD,QAAA;AACJ,IAAA;AAEA,IAAA,IAAI,CAACU,KAAAA,EAAO;AACRD,QAAAA,OAAAA,CAAQQ,eAAe,CAAC,kBAAA,CAAA;AACxBR,QAAAA,OAAAA,CAAQQ,eAAe,CAAC,yBAAA,CAAA;AACxB,QAAA;AACJ,IAAA;AAEA,IAAA,KAAK,MAAM,CAACjB,KAAAA,EAAOkB,KAAAA,CAAM,IAAIN,MAAAA,CAAOO,OAAO,CAACT,KAAAA,CAAMI,MAAM,IAAI,EAAC,CAAA,CAAI;AAC7DL,QAAAA,OAAAA,CAAQM,KAAK,CAACK,WAAW,CAACrB,mBAAmBC,KAAAA,CAAAA,EAAQkB,KAAAA,CAAAA;AACzD,IAAA;AAEAT,IAAAA,OAAAA,CAAQY,YAAY,CAAC,kBAAA,EAAoBX,KAAAA,CAAMY,IAAI,CAAA;AACnDb,IAAAA,OAAAA,CAAQY,YAAY,CAAC,yBAAA,EAA2BX,KAAAA,CAAMa,MAAM,GAAG,MAAA,GAAS,OAAA,CAAA;AAC5E;;;;"}
1
+ {"version":3,"file":"themeTokens.js","sources":["../../../theme/themeTokens.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { Theme } from '@cratis/scene.model';\n\n/**\n * The prefix every Scene design token gets as a CSS custom property. A package adapts these to whatever\n * its own component library expects — the PrimeReact package maps them onto PrimeReact's variables, the\n * same indirection `@cratis/components` uses for its `--cratis-*` layer — so layout and component CSS\n * never hardcodes one library's variable names.\n */\nexport const themeTokenPrefix = '--scene';\n\n/**\n * Turns a semantic token name into its CSS custom property name: `primary.color` becomes\n * `--scene-primary-color`, `surface.borderColor` becomes `--scene-surface-border-color`.\n *\n * Token names are semantic and platform-neutral in `Scene.Model` on purpose; this is the one place that\n * decides what they look like in CSS, so a non-DOM renderer can make an entirely different choice.\n */\nexport function themeTokenProperty(token: string): string {\n const kebab = token\n .split('.')\n .map((part) => part.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase())\n .join('-');\n return `${themeTokenPrefix}-${kebab}`;\n}\n\n/**\n * Applies a theme to an element, in place.\n *\n * Every token becomes a custom property on the element, and the element is marked with the theme's name\n * and colour scheme so CSS can key off either. Tokens the previous theme set and this one does not are\n * removed, so switching themes cannot leave a stale value behind.\n *\n * This is deliberately a mutation of an existing element rather than a re-render: switching theme has to\n * be live re-resolution against the running profile, with no reload and no remount, or a gallery preview\n * flickers every time someone tries a different theme.\n */\nexport function applyThemeTokens(element: HTMLElement, theme: Theme | undefined, previous?: Theme): void {\n for (const token of Object.keys(previous?.tokens ?? {})) {\n if (!theme?.tokens || !(token in theme.tokens)) {\n element.style.removeProperty(themeTokenProperty(token));\n }\n }\n\n if (!theme) {\n element.removeAttribute('data-scene-theme');\n element.removeAttribute('data-scene-color-scheme');\n return;\n }\n\n for (const [token, value] of Object.entries(theme.tokens ?? {})) {\n element.style.setProperty(themeTokenProperty(token), value);\n }\n\n element.setAttribute('data-scene-theme', theme.name);\n element.setAttribute('data-scene-color-scheme', theme.isDark ? 'dark' : 'light');\n}\n"],"names":["themeTokenPrefix","themeTokenProperty","token","kebab","split","map","part","replace","toLowerCase","join","applyThemeTokens","element","theme","previous","Object","keys","tokens","style","removeProperty","removeAttribute","value","entries","setProperty","setAttribute","name","isDark"],"mappings":"AAAA;AACA;AAIA;;;;;IAMO,MAAMA,gBAAAA,GAAmB;AAEhC;;;;;;IAOO,SAASC,kBAAAA,CAAmBC,KAAa,EAAA;AAC5C,IAAA,MAAMC,QAAQD,KAAAA,CACTE,KAAK,CAAC,GAAA,CAAA,CACNC,GAAG,CAAC,CAACC,IAAAA,GAASA,IAAAA,CAAKC,OAAO,CAAC,oBAAA,EAAsB,SAASC,WAAW,EAAA,CAAA,CACrEC,IAAI,CAAC,GAAA,CAAA;AACV,IAAA,OAAO,CAAA,EAAGT,gBAAAA,CAAiB,CAAC,EAAEG,KAAAA,CAAAA,CAAO;AACzC;AAEA;;;;;;;;;;AAUC,IACM,SAASO,gBAAAA,CAAiBC,OAAoB,EAAEC,KAAwB,EAAEC,QAAgB,EAAA;IAC7F,KAAK,MAAMX,SAASY,MAAAA,CAAOC,IAAI,CAACF,QAAAA,EAAUG,MAAAA,IAAU,EAAC,CAAA,CAAI;QACrD,IAAI,CAACJ,OAAOI,MAAAA,IAAU,EAAEd,KAAAA,IAASU,KAAAA,CAAMI,MAAK,CAAA,EAAI;AAC5CL,YAAAA,OAAAA,CAAQM,KAAK,CAACC,cAAc,CAACjB,kBAAAA,CAAmBC,KAAAA,CAAAA,CAAAA;AACpD,QAAA;AACJ,IAAA;AAEA,IAAA,IAAI,CAACU,KAAAA,EAAO;AACRD,QAAAA,OAAAA,CAAQQ,eAAe,CAAC,kBAAA,CAAA;AACxBR,QAAAA,OAAAA,CAAQQ,eAAe,CAAC,yBAAA,CAAA;AACxB,QAAA;AACJ,IAAA;AAEA,IAAA,KAAK,MAAM,CAACjB,KAAAA,EAAOkB,KAAAA,CAAM,IAAIN,MAAAA,CAAOO,OAAO,CAACT,KAAAA,CAAMI,MAAM,IAAI,EAAC,CAAA,CAAI;AAC7DL,QAAAA,OAAAA,CAAQM,KAAK,CAACK,WAAW,CAACrB,mBAAmBC,KAAAA,CAAAA,EAAQkB,KAAAA,CAAAA;AACzD,IAAA;AAEAT,IAAAA,OAAAA,CAAQY,YAAY,CAAC,kBAAA,EAAoBX,KAAAA,CAAMY,IAAI,CAAA;AACnDb,IAAAA,OAAAA,CAAQY,YAAY,CAAC,yBAAA,EAA2BX,KAAAA,CAAMa,MAAM,GAAG,MAAA,GAAS,OAAA,CAAA;AAC5E;;"}