@cratis/scene.blueprint.default 1.0.0 → 2.0.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 (49) hide show
  1. package/.storybook/preview.tsx +44 -0
  2. package/README.md +25 -12
  3. package/dist/cjs/shell/Breadcrumb.js +47 -10
  4. package/dist/cjs/shell/Breadcrumb.js.map +1 -1
  5. package/dist/cjs/shell/ConfigPanel.js +111 -82
  6. package/dist/cjs/shell/ConfigPanel.js.map +1 -1
  7. package/dist/cjs/shell/Sidebar.js +7 -3
  8. package/dist/cjs/shell/Sidebar.js.map +1 -1
  9. package/dist/cjs/shell/Topbar.js +7 -3
  10. package/dist/cjs/shell/Topbar.js.map +1 -1
  11. package/dist/cjs/shell/UserMenu.js +48 -21
  12. package/dist/cjs/shell/UserMenu.js.map +1 -1
  13. package/dist/esm/for_AppShell/when_rendering_a_gallery_screen.js +2 -1
  14. package/dist/esm/for_AppShell/when_rendering_a_gallery_screen.js.map +1 -1
  15. package/dist/esm/shell/Breadcrumb.d.ts.map +1 -1
  16. package/dist/esm/shell/Breadcrumb.js +49 -12
  17. package/dist/esm/shell/Breadcrumb.js.map +1 -1
  18. package/dist/esm/shell/ConfigPanel.d.ts.map +1 -1
  19. package/dist/esm/shell/ConfigPanel.js +112 -83
  20. package/dist/esm/shell/ConfigPanel.js.map +1 -1
  21. package/dist/esm/shell/MenuEntry.d.ts +6 -0
  22. package/dist/esm/shell/MenuEntry.d.ts.map +1 -0
  23. package/dist/esm/shell/MenuEntry.js +2 -0
  24. package/dist/esm/shell/MenuEntry.js.map +1 -0
  25. package/dist/esm/shell/Sidebar.d.ts.map +1 -1
  26. package/dist/esm/shell/Sidebar.js +7 -3
  27. package/dist/esm/shell/Sidebar.js.map +1 -1
  28. package/dist/esm/shell/Topbar.d.ts.map +1 -1
  29. package/dist/esm/shell/Topbar.js +7 -3
  30. package/dist/esm/shell/Topbar.js.map +1 -1
  31. package/dist/esm/shell/UserMenu.d.ts.map +1 -1
  32. package/dist/esm/shell/UserMenu.js +48 -21
  33. package/dist/esm/shell/UserMenu.js.map +1 -1
  34. package/dist/esm/shell/index.d.ts +1 -0
  35. package/dist/esm/shell/index.d.ts.map +1 -1
  36. package/dist/esm/shell/index.js +1 -0
  37. package/dist/esm/shell/index.js.map +1 -1
  38. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  39. package/for_AppShell/when_rendering_a_gallery_screen.tsx +10 -1
  40. package/package.json +18 -12
  41. package/shell/Breadcrumb.tsx +44 -8
  42. package/shell/ConfigPanel.tsx +72 -61
  43. package/shell/MenuEntry.ts +27 -0
  44. package/shell/Sidebar.tsx +5 -4
  45. package/shell/Topbar.tsx +5 -4
  46. package/shell/UserMenu.tsx +32 -17
  47. package/shell/index.ts +1 -0
  48. package/shell/layout.css +5 -5
  49. package/.storybook/preview.ts +0 -20
@@ -1 +1 @@
1
- {"version":3,"file":"Sidebar.js","sources":["../../../shell/Sidebar.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 { Button } from 'primereact/button';\nimport { RegisteredComponentProps } from '@cratis/scene.react';\nimport { isPointerRevealMode, useLayoutConfig } from '../configuration';\nimport { readString } from './elementProperties';\n\n/**\n * The sidebar's own chrome, inside the panel {@link AppShell} positions.\n *\n * The panel and its contents are deliberately different components. Everything about *where* the sidebar\n * is - translated off-canvas, collapsed to a rail, growing on hover - belongs to the mode and therefore to\n * the shell; everything about *what is in it* belongs to the screen. A template can replace this header\n * wholesale without any of the mode CSS noticing.\n *\n * The pin button only appears in `reveal` and `drawer`, the two modes where the sidebar answers to the\n * pointer and therefore needs a way to be made to stay.\n */\nexport function Sidebar({ element, slots }: RegisteredComponentProps) {\n const { effectiveMode, config, toggleSidebarAnchor } = useLayoutConfig();\n const title = readString(element, 'title');\n const isPinnable = isPointerRevealMode(effectiveMode);\n\n return (\n <>\n <div className='layout-sidebar-header' data-scene-id={element.id}>\n {slots.logo}\n {title && <span className='layout-sidebar-title'>{title}</span>}\n {isPinnable && (\n <Button\n type='button'\n text\n rounded\n icon={config.isSidebarAnchored ? 'pi pi-lock' : 'pi pi-lock-open'}\n aria-label={config.isSidebarAnchored ? 'Unpin the menu' : 'Pin the menu open'}\n aria-pressed={config.isSidebarAnchored}\n onClick={toggleSidebarAnchor}\n />\n )}\n </div>\n {slots.content}\n </>\n );\n}\n"],"names":["Sidebar","element","slots","effectiveMode","config","toggleSidebarAnchor","useLayoutConfig","title","readString","isPinnable","isPointerRevealMode","_jsxs","_Fragment","div","className","data-scene-id","id","logo","_jsx","span","Button","type","text","rounded","icon","isSidebarAnchored","aria-label","aria-pressed","onClick","content"],"mappings":";;;;;;AAQA;;;;;;;;;;AAUC,IACM,SAASA,OAAAA,CAAQ,EAAEC,OAAO,EAAEC,KAAK,EAA4B,EAAA;AAChE,IAAA,MAAM,EAAEC,aAAa,EAAEC,MAAM,EAAEC,mBAAmB,EAAE,GAAGC,eAAAA,EAAAA;IACvD,MAAMC,KAAAA,GAAQC,WAAWP,OAAAA,EAAS,OAAA,CAAA;AAClC,IAAA,MAAMQ,aAAaC,mBAAAA,CAAoBP,aAAAA,CAAAA;IAEvC,qBACIQ,IAAA,CAAAC,QAAA,EAAA;;0BACID,IAAA,CAACE,KAAAA,EAAAA;gBAAIC,SAAAA,EAAU,uBAAA;AAAwBC,gBAAAA,eAAAA,EAAed,QAAQe,EAAE;;AAC3Dd,oBAAAA,KAAAA,CAAMe,IAAI;AACVV,oBAAAA,KAAAA,kBAASW,GAAA,CAACC,MAAAA,EAAAA;wBAAKL,SAAAA,EAAU,sBAAA;AAAwBP,wBAAAA,QAAAA,EAAAA;;AACjDE,oBAAAA,UAAAA,kBACGS,GAAA,CAACE,MAAAA,EAAAA;wBACGC,IAAAA,EAAK,QAAA;wBACLC,IAAI,EAAA,IAAA;wBACJC,OAAO,EAAA,IAAA;wBACPC,IAAAA,EAAMpB,MAAAA,CAAOqB,iBAAiB,GAAG,YAAA,GAAe,iBAAA;wBAChDC,YAAAA,EAAYtB,MAAAA,CAAOqB,iBAAiB,GAAG,gBAAA,GAAmB,mBAAA;AAC1DE,wBAAAA,cAAAA,EAAcvB,OAAOqB,iBAAiB;wBACtCG,OAAAA,EAASvB;;;;AAIpBH,YAAAA,KAAAA,CAAM2B;;;AAGnB;;;;"}
1
+ {"version":3,"file":"Sidebar.js","sources":["../../../shell/Sidebar.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 { Button } from 'primereact/button';\nimport { RegisteredComponentProps } from '@cratis/scene.react';\nimport { isPointerRevealMode, useLayoutConfig } from '../configuration';\nimport { readString } from './elementProperties';\n\n/**\n * The sidebar's own chrome, inside the panel {@link AppShell} positions.\n *\n * The panel and its contents are deliberately different components. Everything about *where* the sidebar\n * is - translated off-canvas, collapsed to a rail, growing on hover - belongs to the mode and therefore to\n * the shell; everything about *what is in it* belongs to the screen. A template can replace this header\n * wholesale without any of the mode CSS noticing.\n *\n * The pin button only appears in `reveal` and `drawer`, the two modes where the sidebar answers to the\n * pointer and therefore needs a way to be made to stay.\n */\nexport function Sidebar({ element, slots }: RegisteredComponentProps) {\n const { effectiveMode, config, toggleSidebarAnchor } = useLayoutConfig();\n const title = readString(element, 'title');\n const isPinnable = isPointerRevealMode(effectiveMode);\n\n return (\n <>\n <div className='layout-sidebar-header' data-scene-id={element.id}>\n {slots.logo}\n {title && <span className='layout-sidebar-title'>{title}</span>}\n {isPinnable && (\n <Button\n type='button'\n variant='text'\n rounded\n iconOnly\n aria-label={config.isSidebarAnchored ? 'Unpin the menu' : 'Pin the menu open'}\n aria-pressed={config.isSidebarAnchored}\n onClick={toggleSidebarAnchor}>\n <i className={config.isSidebarAnchored ? 'pi pi-lock' : 'pi pi-lock-open'} aria-hidden='true' />\n </Button>\n )}\n </div>\n {slots.content}\n </>\n );\n}\n"],"names":["Sidebar","element","slots","effectiveMode","config","toggleSidebarAnchor","useLayoutConfig","title","readString","isPinnable","isPointerRevealMode","_jsxs","_Fragment","div","className","data-scene-id","id","logo","_jsx","span","Button","type","variant","rounded","iconOnly","aria-label","isSidebarAnchored","aria-pressed","onClick","i","aria-hidden","content"],"mappings":";;;;;;AAQA;;;;;;;;;;AAUC,IACM,SAASA,OAAAA,CAAQ,EAAEC,OAAO,EAAEC,KAAK,EAA4B,EAAA;AAChE,IAAA,MAAM,EAAEC,aAAa,EAAEC,MAAM,EAAEC,mBAAmB,EAAE,GAAGC,eAAAA,EAAAA;IACvD,MAAMC,KAAAA,GAAQC,WAAWP,OAAAA,EAAS,OAAA,CAAA;AAClC,IAAA,MAAMQ,aAAaC,mBAAAA,CAAoBP,aAAAA,CAAAA;IAEvC,qBACIQ,IAAA,CAAAC,QAAA,EAAA;;0BACID,IAAA,CAACE,KAAAA,EAAAA;gBAAIC,SAAAA,EAAU,uBAAA;AAAwBC,gBAAAA,eAAAA,EAAed,QAAQe,EAAE;;AAC3Dd,oBAAAA,KAAAA,CAAMe,IAAI;AACVV,oBAAAA,KAAAA,kBAASW,GAAA,CAACC,MAAAA,EAAAA;wBAAKL,SAAAA,EAAU,sBAAA;AAAwBP,wBAAAA,QAAAA,EAAAA;;AACjDE,oBAAAA,UAAAA,kBACGS,GAAA,CAACE,MAAAA,EAAAA;wBACGC,IAAAA,EAAK,QAAA;wBACLC,OAAAA,EAAQ,MAAA;wBACRC,OAAO,EAAA,IAAA;wBACPC,QAAQ,EAAA,IAAA;wBACRC,YAAAA,EAAYrB,MAAAA,CAAOsB,iBAAiB,GAAG,gBAAA,GAAmB,mBAAA;AAC1DC,wBAAAA,cAAAA,EAAcvB,OAAOsB,iBAAiB;wBACtCE,OAAAA,EAASvB,mBAAAA;AACT,wBAAA,QAAA,gBAAAa,GAAA,CAACW,GAAAA,EAAAA;4BAAEf,SAAAA,EAAWV,MAAAA,CAAOsB,iBAAiB,GAAG,YAAA,GAAe,iBAAA;4BAAmBI,aAAAA,EAAY;;;;;AAIlG5B,YAAAA,KAAAA,CAAM6B;;;AAGnB;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"Topbar.d.ts","sourceRoot":"","sources":["../../../shell/Topbar.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAe/D,wBAAgB,MAAM,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,wBAAwB,+BAyBlE"}
1
+ {"version":3,"file":"Topbar.d.ts","sourceRoot":"","sources":["../../../shell/Topbar.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAe/D,wBAAgB,MAAM,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,wBAAwB,+BA0BlE"}
@@ -25,12 +25,16 @@ import { readBoolean } from './elementProperties.js';
25
25
  children: [
26
26
  showsToggle && /*#__PURE__*/ jsx(Button, {
27
27
  type: "button",
28
- text: true,
28
+ variant: "text",
29
29
  rounded: true,
30
- icon: "pi pi-bars",
30
+ iconOnly: true,
31
31
  "aria-label": config.isSidebarOpen ? 'Close the menu' : 'Open the menu',
32
32
  "aria-expanded": config.isSidebarOpen,
33
- onClick: toggleSidebar
33
+ onClick: toggleSidebar,
34
+ children: /*#__PURE__*/ jsx("i", {
35
+ className: "pi pi-bars",
36
+ "aria-hidden": "true"
37
+ })
34
38
  }),
35
39
  slots.logo,
36
40
  slots.start
@@ -1 +1 @@
1
- {"version":3,"file":"Topbar.js","sources":["../../../shell/Topbar.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 { Button } from 'primereact/button';\nimport { RegisteredComponentProps } from '@cratis/scene.react';\nimport { LayoutMode, useLayoutConfig } from '../configuration';\nimport { readBoolean } from './elementProperties';\n\n/**\n * The fixed strip across the top of the application shell.\n *\n * It owns the one control every mode needs: the sidebar toggle. In `horizontal` mode it also hosts the\n * menu itself, which is why the menu arrives here as a slot rather than being hard-wired into the\n * sidebar - the same navigation markup has to be able to render in two places.\n *\n * The toggle hides itself in the rail modes, where there is nothing to toggle: `slim`, `slim-plus` and\n * `compact` are always showing, `reveal` and `drawer` answer to the pointer and the pin, and `horizontal`\n * has no sidebar at all. A button that does nothing is worse than no button.\n */\nexport function Topbar({ element, slots }: RegisteredComponentProps) {\n const { effectiveMode, config, toggleSidebar } = useLayoutConfig();\n const showsToggle = readBoolean(element, 'showToggle', true) && togglesSidebar(effectiveMode);\n\n return (\n <>\n <div className='layout-topbar-start' data-scene-id={element.id}>\n {showsToggle && (\n <Button\n type='button'\n text\n rounded\n icon='pi pi-bars'\n aria-label={config.isSidebarOpen ? 'Close the menu' : 'Open the menu'}\n aria-expanded={config.isSidebarOpen}\n onClick={toggleSidebar}\n />\n )}\n {slots.logo}\n {slots.start}\n </div>\n {slots.menu}\n <div className='layout-topbar-end'>{slots.end}</div>\n </>\n );\n}\n\nfunction togglesSidebar(mode: LayoutMode): boolean {\n return mode === LayoutMode.Static || mode === LayoutMode.Overlay;\n}\n"],"names":["Topbar","element","slots","effectiveMode","config","toggleSidebar","useLayoutConfig","showsToggle","readBoolean","togglesSidebar","_jsxs","_Fragment","div","className","data-scene-id","id","_jsx","Button","type","text","rounded","icon","aria-label","isSidebarOpen","aria-expanded","onClick","logo","start","menu","end","mode","LayoutMode","Static","Overlay"],"mappings":";;;;;;AAQA;;;;;;;;;;AAUC,IACM,SAASA,MAAAA,CAAO,EAAEC,OAAO,EAAEC,KAAK,EAA4B,EAAA;AAC/D,IAAA,MAAM,EAAEC,aAAa,EAAEC,MAAM,EAAEC,aAAa,EAAE,GAAGC,eAAAA,EAAAA;AACjD,IAAA,MAAMC,WAAAA,GAAcC,WAAAA,CAAYP,OAAAA,EAAS,YAAA,EAAc,SAASQ,cAAAA,CAAeN,aAAAA,CAAAA;IAE/E,qBACIO,IAAA,CAAAC,QAAA,EAAA;;0BACID,IAAA,CAACE,KAAAA,EAAAA;gBAAIC,SAAAA,EAAU,qBAAA;AAAsBC,gBAAAA,eAAAA,EAAeb,QAAQc,EAAE;;AACzDR,oBAAAA,WAAAA,kBACGS,GAAA,CAACC,MAAAA,EAAAA;wBACGC,IAAAA,EAAK,QAAA;wBACLC,IAAI,EAAA,IAAA;wBACJC,OAAO,EAAA,IAAA;wBACPC,IAAAA,EAAK,YAAA;wBACLC,YAAAA,EAAYlB,MAAAA,CAAOmB,aAAa,GAAG,gBAAA,GAAmB,eAAA;AACtDC,wBAAAA,eAAAA,EAAepB,OAAOmB,aAAa;wBACnCE,OAAAA,EAASpB;;AAGhBH,oBAAAA,KAAAA,CAAMwB,IAAI;AACVxB,oBAAAA,KAAAA,CAAMyB;;;AAEVzB,YAAAA,KAAAA,CAAM0B,IAAI;0BACXZ,GAAA,CAACJ,KAAAA,EAAAA;gBAAIC,SAAAA,EAAU,mBAAA;AAAqBX,gBAAAA,QAAAA,EAAAA,KAAAA,CAAM2B;;;;AAGtD;AAEA,SAASpB,eAAeqB,IAAgB,EAAA;AACpC,IAAA,OAAOA,SAASC,UAAAA,CAAWC,MAAM,IAAIF,IAAAA,KAASC,WAAWE,OAAO;AACpE;;;;"}
1
+ {"version":3,"file":"Topbar.js","sources":["../../../shell/Topbar.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 { Button } from 'primereact/button';\nimport { RegisteredComponentProps } from '@cratis/scene.react';\nimport { LayoutMode, useLayoutConfig } from '../configuration';\nimport { readBoolean } from './elementProperties';\n\n/**\n * The fixed strip across the top of the application shell.\n *\n * It owns the one control every mode needs: the sidebar toggle. In `horizontal` mode it also hosts the\n * menu itself, which is why the menu arrives here as a slot rather than being hard-wired into the\n * sidebar - the same navigation markup has to be able to render in two places.\n *\n * The toggle hides itself in the rail modes, where there is nothing to toggle: `slim`, `slim-plus` and\n * `compact` are always showing, `reveal` and `drawer` answer to the pointer and the pin, and `horizontal`\n * has no sidebar at all. A button that does nothing is worse than no button.\n */\nexport function Topbar({ element, slots }: RegisteredComponentProps) {\n const { effectiveMode, config, toggleSidebar } = useLayoutConfig();\n const showsToggle = readBoolean(element, 'showToggle', true) && togglesSidebar(effectiveMode);\n\n return (\n <>\n <div className='layout-topbar-start' data-scene-id={element.id}>\n {showsToggle && (\n <Button\n type='button'\n variant='text'\n rounded\n iconOnly\n aria-label={config.isSidebarOpen ? 'Close the menu' : 'Open the menu'}\n aria-expanded={config.isSidebarOpen}\n onClick={toggleSidebar}>\n <i className='pi pi-bars' aria-hidden='true' />\n </Button>\n )}\n {slots.logo}\n {slots.start}\n </div>\n {slots.menu}\n <div className='layout-topbar-end'>{slots.end}</div>\n </>\n );\n}\n\nfunction togglesSidebar(mode: LayoutMode): boolean {\n return mode === LayoutMode.Static || mode === LayoutMode.Overlay;\n}\n"],"names":["Topbar","element","slots","effectiveMode","config","toggleSidebar","useLayoutConfig","showsToggle","readBoolean","togglesSidebar","_jsxs","_Fragment","div","className","data-scene-id","id","_jsx","Button","type","variant","rounded","iconOnly","aria-label","isSidebarOpen","aria-expanded","onClick","i","aria-hidden","logo","start","menu","end","mode","LayoutMode","Static","Overlay"],"mappings":";;;;;;AAQA;;;;;;;;;;AAUC,IACM,SAASA,MAAAA,CAAO,EAAEC,OAAO,EAAEC,KAAK,EAA4B,EAAA;AAC/D,IAAA,MAAM,EAAEC,aAAa,EAAEC,MAAM,EAAEC,aAAa,EAAE,GAAGC,eAAAA,EAAAA;AACjD,IAAA,MAAMC,WAAAA,GAAcC,WAAAA,CAAYP,OAAAA,EAAS,YAAA,EAAc,SAASQ,cAAAA,CAAeN,aAAAA,CAAAA;IAE/E,qBACIO,IAAA,CAAAC,QAAA,EAAA;;0BACID,IAAA,CAACE,KAAAA,EAAAA;gBAAIC,SAAAA,EAAU,qBAAA;AAAsBC,gBAAAA,eAAAA,EAAeb,QAAQc,EAAE;;AACzDR,oBAAAA,WAAAA,kBACGS,GAAA,CAACC,MAAAA,EAAAA;wBACGC,IAAAA,EAAK,QAAA;wBACLC,OAAAA,EAAQ,MAAA;wBACRC,OAAO,EAAA,IAAA;wBACPC,QAAQ,EAAA,IAAA;wBACRC,YAAAA,EAAYlB,MAAAA,CAAOmB,aAAa,GAAG,gBAAA,GAAmB,eAAA;AACtDC,wBAAAA,eAAAA,EAAepB,OAAOmB,aAAa;wBACnCE,OAAAA,EAASpB,aAAAA;AACT,wBAAA,QAAA,gBAAAW,GAAA,CAACU,GAAAA,EAAAA;4BAAEb,SAAAA,EAAU,YAAA;4BAAac,aAAAA,EAAY;;;AAG7CzB,oBAAAA,KAAAA,CAAM0B,IAAI;AACV1B,oBAAAA,KAAAA,CAAM2B;;;AAEV3B,YAAAA,KAAAA,CAAM4B,IAAI;0BACXd,GAAA,CAACJ,KAAAA,EAAAA;gBAAIC,SAAAA,EAAU,mBAAA;AAAqBX,gBAAAA,QAAAA,EAAAA,KAAAA,CAAM6B;;;;AAGtD;AAEA,SAAStB,eAAeuB,IAAgB,EAAA;AACpC,IAAA,OAAOA,SAASC,UAAAA,CAAWC,MAAM,IAAIF,IAAAA,KAASC,WAAWE,OAAO;AACpE;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"UserMenu.d.ts","sourceRoot":"","sources":["../../../shell/UserMenu.tsx"],"names":[],"mappings":"AAQA,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAW/D,wBAAgB,QAAQ,CAAC,EAAE,OAAO,EAAE,EAAE,wBAAwB,+BAiC7D"}
1
+ {"version":3,"file":"UserMenu.d.ts","sourceRoot":"","sources":["../../../shell/UserMenu.tsx"],"names":[],"mappings":"AAMA,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAmB/D,wBAAgB,QAAQ,CAAC,EAAE,OAAO,EAAE,EAAE,wBAAwB,+BA0C7D"}
@@ -1,5 +1,4 @@
1
1
  import { jsxs, jsx } from 'react/jsx-runtime';
2
- import { useRef } from 'react';
3
2
  import { Avatar } from 'primereact/avatar';
4
3
  import { Button } from 'primereact/button';
5
4
  import { Menu } from 'primereact/menu';
@@ -10,10 +9,16 @@ import { readString, readRecords, recordString } from './elementProperties.js';
10
9
  *
11
10
  * The popup is PrimeReact's `Menu` rather than hand-written markup: an overlay that positions itself,
12
11
  * traps focus and closes on escape is framework behavior, and re-implementing it in a layout package is
13
- * how a shell ends up with its own subtly broken menu. The shell hand-writes CSS only where PrimeReact 10
12
+ * how a shell ends up with its own subtly broken menu. The shell hand-writes CSS only where PrimeReact
14
13
  * has no primitive at all - the app-shell modes - and uses the library everywhere else.
14
+ *
15
+ * PrimeReact 11 replaced the `model` array with composition, so the entries are rendered here rather than
16
+ * handed over as data - and `primereact/menuitem`, the type that array was made of, went with it, which is
17
+ * why they are mapped into this package's own {@link MenuEntry}. The trade is worth taking: `Menu.Trigger`
18
+ * now owns opening the popup and reporting `aria-haspopup`/`aria-expanded` for it, so the ref, the toggle
19
+ * handler and the hand-maintained aria that used to sit here - and could drift out of step with the popup
20
+ * they described - are gone.
15
21
  */ function UserMenu({ element }) {
16
- const menu = useRef(null);
17
22
  const name = readString(element, 'name');
18
23
  const role = readString(element, 'role');
19
24
  const initials = readString(element, 'initials', name.slice(0, 1).toUpperCase());
@@ -26,9 +31,11 @@ import { readString, readRecords, recordString } from './elementProperties.js';
26
31
  className: "layout-user-menu",
27
32
  "data-scene-id": element.id,
28
33
  children: [
29
- /*#__PURE__*/ jsx(Avatar, {
30
- label: initials,
31
- shape: "circle"
34
+ /*#__PURE__*/ jsx(Avatar.Root, {
35
+ shape: "circle",
36
+ children: /*#__PURE__*/ jsx(Avatar.Fallback, {
37
+ children: initials
38
+ })
32
39
  }),
33
40
  /*#__PURE__*/ jsxs("span", {
34
41
  className: "layout-user-menu-name",
@@ -42,21 +49,41 @@ import { readString, readRecords, recordString } from './elementProperties.js';
42
49
  })
43
50
  ]
44
51
  }),
45
- /*#__PURE__*/ jsx(Menu, {
46
- ref: menu,
47
- model: items,
48
- popup: true,
49
- id: `${element.id}-menu`
50
- }),
51
- /*#__PURE__*/ jsx(Button, {
52
- type: "button",
53
- text: true,
54
- rounded: true,
55
- icon: "pi pi-angle-down",
56
- "aria-label": `Open the menu for ${name}`,
57
- "aria-controls": `${element.id}-menu`,
58
- "aria-haspopup": true,
59
- onClick: (event)=>menu.current?.toggle(event)
52
+ /*#__PURE__*/ jsxs(Menu.Root, {
53
+ children: [
54
+ /*#__PURE__*/ jsx(Menu.Trigger, {
55
+ as: Button,
56
+ variant: "text",
57
+ rounded: true,
58
+ iconOnly: true,
59
+ "aria-label": `Open the menu for ${name}`,
60
+ children: /*#__PURE__*/ jsx("i", {
61
+ className: "pi pi-angle-down",
62
+ "aria-hidden": "true"
63
+ })
64
+ }),
65
+ /*#__PURE__*/ jsx(Menu.Portal, {
66
+ children: /*#__PURE__*/ jsx(Menu.Positioner, {
67
+ children: /*#__PURE__*/ jsx(Menu.Popup, {
68
+ children: /*#__PURE__*/ jsx(Menu.List, {
69
+ children: items.map((item)=>/*#__PURE__*/ jsxs(Menu.Item, {
70
+ as: "a",
71
+ href: item.url,
72
+ children: [
73
+ item.icon && /*#__PURE__*/ jsx("i", {
74
+ className: item.icon,
75
+ "aria-hidden": "true"
76
+ }),
77
+ /*#__PURE__*/ jsx("span", {
78
+ children: item.label
79
+ })
80
+ ]
81
+ }, item.label))
82
+ })
83
+ })
84
+ })
85
+ })
86
+ ]
60
87
  })
61
88
  ]
62
89
  });
@@ -1 +1 @@
1
- {"version":3,"file":"UserMenu.js","sources":["../../../shell/UserMenu.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 { useRef } from 'react';\nimport { Avatar } from 'primereact/avatar';\nimport { Button } from 'primereact/button';\nimport { Menu as PrimeMenu } from 'primereact/menu';\nimport { MenuItem as PrimeMenuItem } from 'primereact/menuitem';\nimport { RegisteredComponentProps } from '@cratis/scene.react';\nimport { readRecords, readString, recordString } from './elementProperties';\n\n/**\n * The signed-in user's avatar and menu.\n *\n * The popup is PrimeReact's `Menu` rather than hand-written markup: an overlay that positions itself,\n * traps focus and closes on escape is framework behavior, and re-implementing it in a layout package is\n * how a shell ends up with its own subtly broken menu. The shell hand-writes CSS only where PrimeReact 10\n * has no primitive at all - the app-shell modes - and uses the library everywhere else.\n */\nexport function UserMenu({ element }: RegisteredComponentProps) {\n const menu = useRef<PrimeMenu>(null);\n const name = readString(element, 'name');\n const role = readString(element, 'role');\n const initials = readString(element, 'initials', name.slice(0, 1).toUpperCase());\n const items = readRecords(element, 'items').map(\n (item): PrimeMenuItem => ({\n label: recordString(item, 'label'),\n icon: recordString(item, 'icon') || undefined,\n url: recordString(item, 'targetScreen') ? `#/${recordString(item, 'targetScreen')}` : undefined,\n }),\n );\n\n return (\n <div className='layout-user-menu' data-scene-id={element.id}>\n <Avatar label={initials} shape='circle' />\n <span className='layout-user-menu-name'>\n <span>{name}</span>\n {role && <span className='layout-user-menu-role'>{role}</span>}\n </span>\n <PrimeMenu ref={menu} model={items} popup id={`${element.id}-menu`} />\n <Button\n type='button'\n text\n rounded\n icon='pi pi-angle-down'\n aria-label={`Open the menu for ${name}`}\n aria-controls={`${element.id}-menu`}\n aria-haspopup\n onClick={event => menu.current?.toggle(event)}\n />\n </div>\n );\n}\n"],"names":["UserMenu","element","menu","useRef","name","readString","role","initials","slice","toUpperCase","items","readRecords","map","item","label","recordString","icon","undefined","url","_jsxs","div","className","data-scene-id","id","_jsx","Avatar","shape","span","PrimeMenu","ref","model","popup","Button","type","text","rounded","aria-label","aria-controls","aria-haspopup","onClick","event","current","toggle"],"mappings":";;;;;;;AAWA;;;;;;;AAOC,IACM,SAASA,QAAAA,CAAS,EAAEC,OAAO,EAA4B,EAAA;AAC1D,IAAA,MAAMC,OAAOC,MAAAA,CAAkB,IAAA,CAAA;IAC/B,MAAMC,IAAAA,GAAOC,WAAWJ,OAAAA,EAAS,MAAA,CAAA;IACjC,MAAMK,IAAAA,GAAOD,WAAWJ,OAAAA,EAAS,MAAA,CAAA;IACjC,MAAMM,QAAAA,GAAWF,WAAWJ,OAAAA,EAAS,UAAA,EAAYG,KAAKI,KAAK,CAAC,CAAA,EAAG,CAAA,CAAA,CAAGC,WAAW,EAAA,CAAA;IAC7E,MAAMC,KAAAA,GAAQC,YAAYV,OAAAA,EAAS,OAAA,CAAA,CAASW,GAAG,CAC3C,CAACC,QAAyB;AACtBC,YAAAA,KAAAA,EAAOC,aAAaF,IAAAA,EAAM,OAAA,CAAA;YAC1BG,IAAAA,EAAMD,YAAAA,CAAaF,MAAM,MAAA,CAAA,IAAWI,SAAAA;YACpCC,GAAAA,EAAKH,YAAAA,CAAaF,MAAM,cAAA,CAAA,GAAkB,CAAC,EAAE,EAAEE,YAAAA,CAAaF,IAAAA,EAAM,cAAA,CAAA,CAAA,CAAiB,GAAGI;SAC1F,CAAA,CAAA;AAGJ,IAAA,qBACIE,IAAA,CAACC,KAAAA,EAAAA;QAAIC,SAAAA,EAAU,kBAAA;AAAmBC,QAAAA,eAAAA,EAAerB,QAAQsB,EAAE;;0BACvDC,GAAA,CAACC,MAAAA,EAAAA;gBAAOX,KAAAA,EAAOP,QAAAA;gBAAUmB,KAAAA,EAAM;;0BAC/BP,IAAA,CAACQ,MAAAA,EAAAA;gBAAKN,SAAAA,EAAU,uBAAA;;kCACZG,GAAA,CAACG,MAAAA,EAAAA;AAAMvB,wBAAAA,QAAAA,EAAAA;;AACNE,oBAAAA,IAAAA,kBAAQkB,GAAA,CAACG,MAAAA,EAAAA;wBAAKN,SAAAA,EAAU,uBAAA;AAAyBf,wBAAAA,QAAAA,EAAAA;;;;0BAEtDkB,GAAA,CAACI,IAAAA,EAAAA;gBAAUC,GAAAA,EAAK3B,IAAAA;gBAAM4B,KAAAA,EAAOpB,KAAAA;gBAAOqB,KAAK,EAAA,IAAA;AAACR,gBAAAA,EAAAA,EAAI,CAAA,EAAGtB,OAAAA,CAAQsB,EAAE,CAAC,KAAK;;0BACjEC,GAAA,CAACQ,MAAAA,EAAAA;gBACGC,IAAAA,EAAK,QAAA;gBACLC,IAAI,EAAA,IAAA;gBACJC,OAAO,EAAA,IAAA;gBACPnB,IAAAA,EAAK,kBAAA;gBACLoB,YAAAA,EAAY,CAAC,kBAAkB,EAAEhC,IAAAA,CAAAA,CAAM;AACvCiC,gBAAAA,eAAAA,EAAe,CAAA,EAAGpC,OAAAA,CAAQsB,EAAE,CAAC,KAAK,CAAC;gBACnCe,eAAa,EAAA,IAAA;AACbC,gBAAAA,OAAAA,EAASC,CAAAA,KAAAA,GAAStC,IAAAA,CAAKuC,OAAO,EAAEC,MAAAA,CAAOF,KAAAA;;;;AAIvD;;;;"}
1
+ {"version":3,"file":"UserMenu.js","sources":["../../../shell/UserMenu.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 { Avatar } from 'primereact/avatar';\nimport { Button } from 'primereact/button';\nimport { Menu as PrimeMenu } from 'primereact/menu';\nimport { RegisteredComponentProps } from '@cratis/scene.react';\nimport { MenuEntry } from './MenuEntry';\nimport { readRecords, readString, recordString } from './elementProperties';\n\n/**\n * The signed-in user's avatar and menu.\n *\n * The popup is PrimeReact's `Menu` rather than hand-written markup: an overlay that positions itself,\n * traps focus and closes on escape is framework behavior, and re-implementing it in a layout package is\n * how a shell ends up with its own subtly broken menu. The shell hand-writes CSS only where PrimeReact\n * has no primitive at all - the app-shell modes - and uses the library everywhere else.\n *\n * PrimeReact 11 replaced the `model` array with composition, so the entries are rendered here rather than\n * handed over as data - and `primereact/menuitem`, the type that array was made of, went with it, which is\n * why they are mapped into this package's own {@link MenuEntry}. The trade is worth taking: `Menu.Trigger`\n * now owns opening the popup and reporting `aria-haspopup`/`aria-expanded` for it, so the ref, the toggle\n * handler and the hand-maintained aria that used to sit here - and could drift out of step with the popup\n * they described - are gone.\n */\nexport function UserMenu({ element }: RegisteredComponentProps) {\n const name = readString(element, 'name');\n const role = readString(element, 'role');\n const initials = readString(element, 'initials', name.slice(0, 1).toUpperCase());\n const items = readRecords(element, 'items').map(\n (item): MenuEntry => ({\n label: recordString(item, 'label'),\n icon: recordString(item, 'icon') || undefined,\n url: recordString(item, 'targetScreen') ? `#/${recordString(item, 'targetScreen')}` : undefined,\n }),\n );\n\n return (\n <div className='layout-user-menu' data-scene-id={element.id}>\n <Avatar.Root shape='circle'>\n <Avatar.Fallback>{initials}</Avatar.Fallback>\n </Avatar.Root>\n <span className='layout-user-menu-name'>\n <span>{name}</span>\n {role && <span className='layout-user-menu-role'>{role}</span>}\n </span>\n <PrimeMenu.Root>\n <PrimeMenu.Trigger as={Button} variant='text' rounded iconOnly aria-label={`Open the menu for ${name}`}>\n <i className='pi pi-angle-down' aria-hidden='true' />\n </PrimeMenu.Trigger>\n <PrimeMenu.Portal>\n <PrimeMenu.Positioner>\n <PrimeMenu.Popup>\n <PrimeMenu.List>\n {items.map(item => (\n <PrimeMenu.Item key={item.label} as='a' href={item.url}>\n {item.icon && <i className={item.icon} aria-hidden='true' />}\n <span>{item.label}</span>\n </PrimeMenu.Item>\n ))}\n </PrimeMenu.List>\n </PrimeMenu.Popup>\n </PrimeMenu.Positioner>\n </PrimeMenu.Portal>\n </PrimeMenu.Root>\n </div>\n );\n}\n"],"names":["UserMenu","element","name","readString","role","initials","slice","toUpperCase","items","readRecords","map","item","label","recordString","icon","undefined","url","_jsxs","div","className","data-scene-id","id","_jsx","Avatar","Root","shape","Fallback","span","PrimeMenu","Trigger","as","Button","variant","rounded","iconOnly","aria-label","i","aria-hidden","Portal","Positioner","Popup","List","Item","href"],"mappings":";;;;;;AAUA;;;;;;;;;;;;;;AAcC,IACM,SAASA,QAAAA,CAAS,EAAEC,OAAO,EAA4B,EAAA;IAC1D,MAAMC,IAAAA,GAAOC,WAAWF,OAAAA,EAAS,MAAA,CAAA;IACjC,MAAMG,IAAAA,GAAOD,WAAWF,OAAAA,EAAS,MAAA,CAAA;IACjC,MAAMI,QAAAA,GAAWF,WAAWF,OAAAA,EAAS,UAAA,EAAYC,KAAKI,KAAK,CAAC,CAAA,EAAG,CAAA,CAAA,CAAGC,WAAW,EAAA,CAAA;IAC7E,MAAMC,KAAAA,GAAQC,YAAYR,OAAAA,EAAS,OAAA,CAAA,CAASS,GAAG,CAC3C,CAACC,QAAqB;AAClBC,YAAAA,KAAAA,EAAOC,aAAaF,IAAAA,EAAM,OAAA,CAAA;YAC1BG,IAAAA,EAAMD,YAAAA,CAAaF,MAAM,MAAA,CAAA,IAAWI,SAAAA;YACpCC,GAAAA,EAAKH,YAAAA,CAAaF,MAAM,cAAA,CAAA,GAAkB,CAAC,EAAE,EAAEE,YAAAA,CAAaF,IAAAA,EAAM,cAAA,CAAA,CAAA,CAAiB,GAAGI;SAC1F,CAAA,CAAA;AAGJ,IAAA,qBACIE,IAAA,CAACC,KAAAA,EAAAA;QAAIC,SAAAA,EAAU,kBAAA;AAAmBC,QAAAA,eAAAA,EAAenB,QAAQoB,EAAE;;AACvD,0BAAAC,GAAA,CAACC,OAAOC,IAAI,EAAA;gBAACC,KAAAA,EAAM,QAAA;wCACfH,GAAA,CAACC,OAAOG,QAAQ,EAAA;AAAErB,oBAAAA,QAAAA,EAAAA;;;0BAEtBY,IAAA,CAACU,MAAAA,EAAAA;gBAAKR,SAAAA,EAAU,uBAAA;;kCACZG,GAAA,CAACK,MAAAA,EAAAA;AAAMzB,wBAAAA,QAAAA,EAAAA;;AACNE,oBAAAA,IAAAA,kBAAQkB,GAAA,CAACK,MAAAA,EAAAA;wBAAKR,SAAAA,EAAU,uBAAA;AAAyBf,wBAAAA,QAAAA,EAAAA;;;;AAEtD,0BAAAa,IAAA,CAACW,KAAUJ,IAAI,EAAA;;AACX,kCAAAF,GAAA,CAACM,KAAUC,OAAO,EAAA;wBAACC,EAAAA,EAAIC,MAAAA;wBAAQC,OAAAA,EAAQ,MAAA;wBAAOC,OAAO,EAAA,IAAA;wBAACC,QAAQ,EAAA,IAAA;wBAACC,YAAAA,EAAY,CAAC,kBAAkB,EAAEjC,IAAAA,CAAAA,CAAM;AAClG,wBAAA,QAAA,gBAAAoB,GAAA,CAACc,GAAAA,EAAAA;4BAAEjB,SAAAA,EAAU,kBAAA;4BAAmBkB,aAAAA,EAAY;;;AAEhD,kCAAAf,GAAA,CAACM,KAAUU,MAAM,EAAA;gDACbhB,GAAA,CAACM,KAAUW,UAAU,EAAA;oDACjBjB,GAAA,CAACM,KAAUY,KAAK,EAAA;wDACZlB,GAAA,CAACM,KAAUa,IAAI,EAAA;AACVjC,oCAAAA,QAAAA,EAAAA,KAAAA,CAAME,GAAG,CAACC,CAAAA,IAAAA,iBACPM,IAAA,CAACW,KAAUc,IAAI,EAAA;4CAAkBZ,EAAAA,EAAG,GAAA;AAAIa,4CAAAA,IAAAA,EAAMhC,KAAKK,GAAG;;gDACjDL,IAAAA,CAAKG,IAAI,kBAAIQ,GAAA,CAACc,GAAAA,EAAAA;AAAEjB,oDAAAA,SAAAA,EAAWR,KAAKG,IAAI;oDAAEuB,aAAAA,EAAY;;8DACnDf,GAAA,CAACK,MAAAA,EAAAA;AAAMhB,oDAAAA,QAAAA,EAAAA,IAAAA,CAAKC;;;AAFKD,yCAAAA,EAAAA,IAAAA,CAAKC,KAAK,CAAA;;;;;;;;;AAYnE;;;;"}
@@ -1,4 +1,5 @@
1
1
  export * from './elementProperties';
2
+ export * from './MenuEntry';
2
3
  export * from './ThemeOption';
3
4
  export * from './AppShell';
4
5
  export * from './FullPageShell';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../shell/index.ts"],"names":[],"mappings":"AAGA,cAAc,qBAAqB,CAAC;AACpC,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../shell/index.ts"],"names":[],"mappings":"AAGA,cAAc,qBAAqB,CAAC;AACpC,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC"}
@@ -1,4 +1,5 @@
1
1
  export * from './elementProperties';
2
+ export * from './MenuEntry';
2
3
  export * from './ThemeOption';
3
4
  export * from './AppShell';
4
5
  export * from './FullPageShell';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../shell/index.ts"],"names":[],"mappings":"AAGA,cAAc,qBAAqB,CAAC;AACpC,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../shell/index.ts"],"names":[],"mappings":"AAGA,cAAc,qBAAqB,CAAC;AACpC,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC"}