@cratis/scene.react 3.2.0 → 3.3.1

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 (59) 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.map +1 -1
  23. package/dist/cjs/theme/SceneThemeProvider.js.map +1 -1
  24. package/dist/cjs/theme/themeTokens.js.map +1 -1
  25. package/dist/esm/NavBar/NavBar.js.map +1 -1
  26. package/dist/esm/NavBar/extractNavigationItem.js.map +1 -1
  27. package/dist/esm/SceneElementView.js.map +1 -1
  28. package/dist/esm/core/CoreButton.js.map +1 -1
  29. package/dist/esm/core/CoreCard.js.map +1 -1
  30. package/dist/esm/core/CoreText.js.map +1 -1
  31. package/dist/esm/core/ScreenplayCoreComponents.d.ts +13 -0
  32. package/dist/esm/core/ScreenplayCoreComponents.d.ts.map +1 -0
  33. package/dist/esm/core/ScreenplayCoreComponents.js +116 -0
  34. package/dist/esm/core/ScreenplayCoreComponents.js.map +1 -0
  35. package/dist/esm/core/coreComponents.d.ts.map +1 -1
  36. package/dist/esm/core/coreComponents.js +13 -1
  37. package/dist/esm/core/coreComponents.js.map +1 -1
  38. package/dist/esm/core/corePackage.d.ts.map +1 -1
  39. package/dist/esm/core/corePackage.js +12 -1
  40. package/dist/esm/core/corePackage.js.map +1 -1
  41. package/dist/esm/core/index.d.ts +1 -0
  42. package/dist/esm/core/index.d.ts.map +1 -1
  43. package/dist/esm/core/index.js +1 -0
  44. package/dist/esm/core/index.js.map +1 -1
  45. package/dist/esm/for_ScreenplayCoreComponents/when_rendering_a_translated_screen.d.ts +2 -0
  46. package/dist/esm/for_ScreenplayCoreComponents/when_rendering_a_translated_screen.d.ts.map +1 -0
  47. package/dist/esm/for_ScreenplayCoreComponents/when_rendering_a_translated_screen.js +46 -0
  48. package/dist/esm/for_ScreenplayCoreComponents/when_rendering_a_translated_screen.js.map +1 -0
  49. package/dist/esm/index.js +1 -0
  50. package/dist/esm/index.js.map +1 -1
  51. package/dist/esm/packages/ScenePackageBundle.js.map +1 -1
  52. package/dist/esm/renderer/UnresolvedComponent.js.map +1 -1
  53. package/dist/esm/renderer/createReactRenderer.js.map +1 -1
  54. package/dist/esm/renderer/panelLayout.js.map +1 -1
  55. package/dist/esm/theme/SceneThemeProvider.js.map +1 -1
  56. package/dist/esm/theme/themeTokens.js.map +1 -1
  57. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  58. package/for_ScreenplayCoreComponents/when_rendering_a_translated_screen.tsx +60 -0
  59. package/package.json +11 -11
@@ -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.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
+ {"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;;"}