@plumile/ui 0.1.114 → 0.1.116

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 (72) hide show
  1. package/lib/esm/admin/templates/admin_shell_layout/AdminShellLayout.js +15 -14
  2. package/lib/esm/admin/templates/admin_shell_layout/AdminShellLayout.js.map +1 -1
  3. package/lib/esm/atomic/atoms/modal/Modal.js +14 -14
  4. package/lib/esm/atomic/atoms/modal/Modal.js.map +1 -1
  5. package/lib/esm/atomic/molecules/markdown/components/MarkdownLink.css.js +0 -1
  6. package/lib/esm/atomic/molecules/markdown/components/MarkdownTableCell.css.js +1 -0
  7. package/lib/esm/backoffice/organisms/backoffice_data_table/BackofficeDataTable.js +59 -56
  8. package/lib/esm/backoffice/organisms/backoffice_data_table/BackofficeDataTable.js.map +1 -1
  9. package/lib/esm/backoffice/organisms/backoffice_data_table/backofficeDataTable.css.js +2 -2
  10. package/lib/esm/backoffice/organisms/backoffice_data_table/backofficeDataTable.css.js.map +1 -1
  11. package/lib/esm/backoffice/organisms/backoffice_virtualized_connection_table/BackofficeVirtualizedConnectionTable.js +3 -2
  12. package/lib/esm/backoffice/organisms/backoffice_virtualized_connection_table/BackofficeVirtualizedConnectionTable.js.map +1 -1
  13. package/lib/esm/backoffice/templates/detail_page_template/DetailPageTemplate.js +42 -39
  14. package/lib/esm/backoffice/templates/detail_page_template/DetailPageTemplate.js.map +1 -1
  15. package/lib/esm/backoffice/templates/detail_page_template/detailPageTemplate.css.js +3 -3
  16. package/lib/esm/backoffice/templates/detail_page_template/detailPageTemplate.css.js.map +1 -1
  17. package/lib/esm/backoffice/templates/list_page_template/ListPageTemplate.js +45 -29
  18. package/lib/esm/backoffice/templates/list_page_template/ListPageTemplate.js.map +1 -1
  19. package/lib/esm/backoffice/templates/list_page_template/listPageTemplate.css.js +73 -13
  20. package/lib/esm/backoffice/templates/list_page_template/listPageTemplate.css.js.map +1 -1
  21. package/lib/esm/components/data-table/DataTable.css.js +52 -52
  22. package/lib/esm/components/data-table/DataTable.css.js.map +1 -1
  23. package/lib/esm/components/data-table/DataTable.js +43 -39
  24. package/lib/esm/components/data-table/DataTable.js.map +1 -1
  25. package/lib/esm/components/data-table/ResponsiveRecordList.css.js +7 -7
  26. package/lib/esm/components/data-table/ResponsiveRecordList.css.js.map +1 -1
  27. package/lib/esm/components/data-table/ResponsiveRecordList.js +86 -61
  28. package/lib/esm/components/data-table/ResponsiveRecordList.js.map +1 -1
  29. package/lib/esm/components/data-table/VirtualizedConnectionTable.js +158 -142
  30. package/lib/esm/components/data-table/VirtualizedConnectionTable.js.map +1 -1
  31. package/lib/esm/components/layout/AppShell.js +2 -1
  32. package/lib/esm/components/layout/AppShell.js.map +1 -1
  33. package/lib/esm/components/layout/PageShell.css.js +8 -8
  34. package/lib/esm/components/layout/PageShell.css.js.map +1 -1
  35. package/lib/esm/components/layout/PageShell.js +115 -107
  36. package/lib/esm/components/layout/PageShell.js.map +1 -1
  37. package/lib/esm/focus/focusable.js +1 -1
  38. package/lib/esm/focus/focusable.js.map +1 -1
  39. package/lib/esm/style.css +1 -1
  40. package/lib/types/admin/templates/admin_shell_layout/AdminShellLayout.d.ts +3 -2
  41. package/lib/types/admin/templates/admin_shell_layout/AdminShellLayout.d.ts.map +1 -1
  42. package/lib/types/atomic/atoms/modal/Modal.d.ts.map +1 -1
  43. package/lib/types/backoffice/organisms/backoffice_data_table/BackofficeDataTable.d.ts +3 -2
  44. package/lib/types/backoffice/organisms/backoffice_data_table/BackofficeDataTable.d.ts.map +1 -1
  45. package/lib/types/backoffice/organisms/backoffice_data_table/backofficeDataTable.css.d.ts +1 -0
  46. package/lib/types/backoffice/organisms/backoffice_data_table/backofficeDataTable.css.d.ts.map +1 -1
  47. package/lib/types/backoffice/organisms/backoffice_virtualized_connection_table/BackofficeVirtualizedConnectionTable.d.ts +3 -2
  48. package/lib/types/backoffice/organisms/backoffice_virtualized_connection_table/BackofficeVirtualizedConnectionTable.d.ts.map +1 -1
  49. package/lib/types/backoffice/templates/detail_page_template/DetailPageTemplate.d.ts.map +1 -1
  50. package/lib/types/backoffice/templates/detail_page_template/detailPageTemplate.css.d.ts +5 -0
  51. package/lib/types/backoffice/templates/detail_page_template/detailPageTemplate.css.d.ts.map +1 -1
  52. package/lib/types/backoffice/templates/list_page_template/ListPageTemplate.d.ts +1 -0
  53. package/lib/types/backoffice/templates/list_page_template/ListPageTemplate.d.ts.map +1 -1
  54. package/lib/types/backoffice/templates/list_page_template/listPageTemplate.css.d.ts +17 -2
  55. package/lib/types/backoffice/templates/list_page_template/listPageTemplate.css.d.ts.map +1 -1
  56. package/lib/types/components/data-table/DataTable.css.d.ts +2 -0
  57. package/lib/types/components/data-table/DataTable.css.d.ts.map +1 -1
  58. package/lib/types/components/data-table/DataTable.d.ts +5 -2
  59. package/lib/types/components/data-table/DataTable.d.ts.map +1 -1
  60. package/lib/types/components/data-table/ResponsiveRecordList.css.d.ts +2 -0
  61. package/lib/types/components/data-table/ResponsiveRecordList.css.d.ts.map +1 -1
  62. package/lib/types/components/data-table/ResponsiveRecordList.d.ts +1 -1
  63. package/lib/types/components/data-table/ResponsiveRecordList.d.ts.map +1 -1
  64. package/lib/types/components/data-table/VirtualizedConnectionTable.d.ts +3 -2
  65. package/lib/types/components/data-table/VirtualizedConnectionTable.d.ts.map +1 -1
  66. package/lib/types/components/layout/AppShell.d.ts +3 -2
  67. package/lib/types/components/layout/AppShell.d.ts.map +1 -1
  68. package/lib/types/components/layout/PageShell.css.d.ts +3 -0
  69. package/lib/types/components/layout/PageShell.css.d.ts.map +1 -1
  70. package/lib/types/components/layout/PageShell.d.ts +3 -1
  71. package/lib/types/components/layout/PageShell.d.ts.map +1 -1
  72. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"PageShell.css.js","names":[],"sources":["../../../../src/components/layout/PageShell.css.ts"],"sourcesContent":["import { style } from '@vanilla-extract/css';\nimport { recipe } from '@vanilla-extract/recipes';\n\nimport { sprinkles } from '../../theme/sprinkles.css.js';\nimport { vars } from '../../theme/themeContract.js';\n\nconst MOBILE_MEDIA_QUERY = 'screen and (max-width: 1023px)';\n\nexport const shell = sprinkles({\n display: 'flex',\n width: 'full',\n backgroundColor: 'background',\n backgroundImage: 'pageShellSurface',\n});\n\nexport const page = sprinkles({\n paddingLeft: 2,\n paddingRight: 2,\n paddingTop: 2,\n paddingBottom: 2,\n height: {\n base: 'screen',\n max1023: 'auto',\n },\n flex: 1,\n minWidth: 0,\n});\n\nexport const pageWithSidePanel = sprinkles({\n display: 'flex',\n alignItems: 'stretch',\n gap: {\n base: 0,\n max1023: 3,\n },\n minWidth: 0,\n flexDirection: {\n base: 'row',\n max1023: 'column',\n },\n height: {\n base: 'full',\n max1023: 'auto',\n },\n});\n\nexport const sidebarColumn = sprinkles({\n position: 'sticky',\n top: 0,\n height: 'screen',\n flexShrink: 0,\n display: 'flex',\n overflow: 'hidden',\n});\n\nexport const sidebarColumnMobile = style({\n '@media': {\n [MOBILE_MEDIA_QUERY]: {\n position: 'fixed',\n top: 0,\n left: 0,\n bottom: 0,\n width: '20rem',\n maxWidth: '85vw',\n transform: 'translateX(-100%)',\n transitionProperty: 'transform',\n transitionDuration: vars.transitionDuration[200],\n transitionTimingFunction: vars.transitionTimingFunction.ease,\n zIndex: vars.zIndex[30],\n backgroundColor: vars.colors.surface,\n borderRight: `1px solid ${vars.colors.borderSubtle}`,\n },\n },\n});\n\nexport const sidebarColumnMobileOpen = style({\n '@media': {\n [MOBILE_MEDIA_QUERY]: {\n transform: 'translateX(0)',\n },\n },\n});\n\nexport const sidebarInner = style([\n sprinkles({\n display: 'flex',\n height: 'full',\n }),\n {\n '@media': {\n [MOBILE_MEDIA_QUERY]: {\n paddingTop: '3.75rem',\n },\n },\n },\n]);\n\nexport const mobileSidebarBackdrop = style({\n display: 'none',\n '@media': {\n [MOBILE_MEDIA_QUERY]: {\n display: 'block',\n position: 'fixed',\n inset: 0,\n backgroundColor: 'rgba(15, 23, 42, 0.32)',\n opacity: 0,\n pointerEvents: 'none',\n transitionProperty: 'opacity',\n transitionDuration: vars.transitionDuration[200],\n transitionTimingFunction: vars.transitionTimingFunction.ease,\n zIndex: vars.zIndex[20],\n },\n },\n});\n\nexport const mobileSidebarBackdropOpen = style({\n '@media': {\n [MOBILE_MEDIA_QUERY]: {\n opacity: 1,\n pointerEvents: 'auto',\n },\n },\n});\n\nexport const mobileSidebarToggle = sprinkles({\n display: {\n base: 'none',\n max1023: 'inline-flex',\n },\n alignItems: 'center',\n justifyContent: 'center',\n width: 10,\n height: 10,\n borderRadius: 'lg',\n borderStyle: 'solid',\n borderWidth: 'default',\n borderColor: 'border',\n backgroundColor: 'surface',\n color: 'text',\n cursor: 'pointer',\n flexShrink: 0,\n});\n\nexport const desktopSidebarToggle = style([\n sprinkles({\n display: {\n base: 'inline-flex',\n max1023: 'none',\n },\n alignItems: 'center',\n justifyContent: 'center',\n width: 10,\n height: 10,\n borderRadius: 'lg',\n borderStyle: 'solid',\n borderWidth: 'default',\n borderColor: 'border',\n backgroundColor: 'surface',\n color: 'text',\n cursor: 'pointer',\n flexShrink: 0,\n transitionProperty: 'default',\n transitionDuration: 150,\n transitionTimingFunction: 'ease',\n }),\n {\n selectors: {\n '&:hover': {\n borderColor: vars.colors.primaryLight,\n backgroundColor: vars.colors.surfaceMuted,\n color: vars.colors.primary,\n },\n '&:focus-visible': {\n outline: `2px solid ${vars.colors.primary}`,\n outlineOffset: '2px',\n },\n },\n },\n]);\n\nexport const mobileSidebarClose = sprinkles({\n display: {\n base: 'none',\n max1023: 'inline-flex',\n },\n position: {\n base: 'static',\n max1023: 'absolute',\n },\n right: {\n base: 0,\n max1023: 3,\n },\n top: {\n base: 0,\n max1023: 3,\n },\n zIndex: 40,\n alignItems: 'center',\n justifyContent: 'center',\n width: 10,\n height: 10,\n borderRadius: 'lg',\n borderStyle: 'solid',\n borderWidth: 'default',\n borderColor: 'border',\n backgroundColor: 'surface',\n color: 'text',\n cursor: 'pointer',\n});\n\nexport const mainColumn = sprinkles({\n flex: 1,\n height: 'full',\n minWidth: 0,\n minHeight: 0,\n display: 'flex',\n flexDirection: 'column',\n backgroundColor: 'surface',\n overflow: 'hidden',\n borderRadius: 'lg',\n borderWidth: 'default',\n borderStyle: 'solid',\n borderColor: 'borderSubtle',\n boxShadow: 'inkSoft',\n});\n\nexport const mainColumnWithSidePanel = sprinkles({\n height: {\n base: 'full',\n max1023: 'auto',\n },\n});\n\nexport const sidePanel = sprinkles({\n display: 'flex',\n flexDirection: 'column',\n minHeight: 0,\n height: {\n base: 'full',\n max1023: 'auto',\n },\n});\n\nexport const sidePanelSurface = sprinkles({\n flex: 'none',\n backgroundColor: 'surface',\n borderRadius: 'xl',\n borderWidth: 'default',\n borderStyle: 'solid',\n borderColor: 'borderSubtle',\n});\n\nexport const sidePanelResizable = style({\n minWidth: '360px',\n maxWidth: '50vw',\n});\n\nexport const sidePanelResizer = style([\n sprinkles({\n alignSelf: 'stretch',\n backgroundColor: 'transparent',\n cursor: 'col-resize',\n flex: 'none',\n minWidth: 4,\n position: 'relative',\n width: 4,\n }),\n {\n selectors: {\n '&::after': {\n content: '',\n position: 'absolute',\n top: '50%',\n left: '50%',\n width: '4px',\n height: '96px',\n transform: 'translate(-50%, -50%)',\n borderRadius: vars.borderRadius.full,\n backgroundColor: vars.colors.border,\n boxShadow: vars.boxShadow.sm,\n transitionProperty: 'default',\n transitionDuration: vars.transitionDuration[120],\n transitionTimingFunction: vars.transitionTimingFunction.ease,\n },\n '&:hover::after, &[data-active=\"true\"]::after': {\n backgroundColor: vars.colors.primary,\n boxShadow: `0 0 0 1px ${vars.colors.primaryLight}`,\n },\n '&:focus-visible': {\n outline: `2px solid ${vars.colors.primary}`,\n outlineOffset: '2px',\n },\n },\n },\n]);\n\nexport const sidePanelResizerHiddenOnMobile = sprinkles({\n display: {\n base: 'block',\n max1023: 'none',\n },\n});\n\nexport const header = sprinkles({\n position: 'sticky',\n top: 0,\n zIndex: 10,\n display: 'flex',\n flexDirection: 'column',\n gap: 3,\n backgroundColor: 'surface',\n borderWidth: 0,\n borderStyle: 'solid',\n borderBottomWidth: 'default',\n borderBottomColor: 'borderSubtle',\n paddingLeft: 5,\n paddingRight: 5,\n paddingBottom: 2,\n paddingTop: 3,\n});\n\nexport const headerRow = sprinkles({\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'flex-start',\n justifyContent: 'space-between',\n gap: 4,\n width: 'full',\n});\n\nexport const headerLeading = sprinkles({\n display: 'flex',\n alignItems: 'center',\n gap: 3,\n flex: 1,\n minWidth: 0,\n});\n\nexport const breadcrumbNav = sprinkles({\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n minWidth: 0,\n});\n\nexport const breadcrumbList = sprinkles({\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'center',\n columnGap: 2,\n rowGap: 1,\n listStyleType: 'none',\n margin: 0,\n padding: 0,\n color: 'textSecondary',\n fontSize: 'xs',\n});\n\nexport const breadcrumbItem = sprinkles({\n display: 'flex',\n alignItems: 'center',\n gap: 1,\n maxWidth: '12rem',\n});\n\nexport const breadcrumbLink = style([\n sprinkles({\n color: 'text',\n textDecoration: 'none',\n fontWeight: 'medium',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n }),\n {\n selectors: {\n '&:hover': {\n color: vars.colors['blue-600'],\n },\n },\n },\n]);\n\nexport const breadcrumbCurrent = sprinkles({\n color: 'text',\n fontWeight: 'semibold',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n});\n\nexport const breadcrumbSeparator = sprinkles({\n color: 'borderLight',\n fontSize: 'xs',\n});\n\nexport const actionGroup = sprinkles({\n display: 'flex',\n flexWrap: 'wrap',\n gap: 2,\n justifyContent: 'flex-end',\n});\n\nexport const secondaryAction = sprinkles({\n display: 'inline-flex',\n});\n\nexport const tabsRow = sprinkles({\n width: 'full',\n display: 'flex',\n flexWrap: 'wrap',\n gap: 2,\n});\n\nconst tabBase = style([\n sprinkles({\n alignItems: 'center',\n backgroundColor: 'surfaceMuted',\n borderRadius: 'lg',\n color: 'textSecondary',\n display: 'inline-flex',\n fontSize: 'sm',\n fontWeight: 'medium',\n paddingBlock: 1.5,\n paddingInline: 3,\n textDecoration: 'none',\n transitionProperty: 'default',\n transitionDuration: 150,\n transitionTimingFunction: 'ease',\n }),\n {\n selectors: {\n '&:hover': {\n color: vars.colors.text,\n },\n },\n },\n]);\n\nexport const tabRecipe = recipe({\n base: tabBase,\n variants: {\n state: {\n default: {},\n active: sprinkles({\n backgroundColor: 'blue-500',\n color: 'white',\n boxShadow: 'sm',\n }),\n },\n mode: {\n link: {},\n static: sprinkles({\n cursor: 'default',\n }),\n },\n },\n defaultVariants: {\n state: 'default',\n mode: 'link',\n },\n});\n\nexport const content = sprinkles({\n flex: 1,\n minHeight: 0,\n display: 'flex',\n flexDirection: 'column',\n overflow: 'auto',\n padding: {\n base: 4,\n max1023: 3,\n },\n});\n"],"mappings":""}
1
+ {"version":3,"file":"PageShell.css.js","names":[],"sources":["../../../../src/components/layout/PageShell.css.ts"],"sourcesContent":["import { style } from '@vanilla-extract/css';\nimport { recipe } from '@vanilla-extract/recipes';\n\nimport { sprinkles } from '../../theme/sprinkles.css.js';\nimport { vars } from '../../theme/themeContract.js';\n\nconst MOBILE_MEDIA_QUERY = 'screen and (max-width: 1023px)';\n\nexport const shell = sprinkles({\n display: 'flex',\n width: 'full',\n backgroundColor: 'background',\n backgroundImage: 'pageShellSurface',\n});\n\nexport const page = sprinkles({\n paddingLeft: 2,\n paddingRight: 2,\n paddingTop: 2,\n paddingBottom: 2,\n height: {\n base: 'screen',\n max1023: 'auto',\n },\n flex: 1,\n minWidth: 0,\n});\n\nexport const pageContained = sprinkles({\n height: 'screen',\n minHeight: 0,\n overflow: 'hidden',\n});\n\nexport const pageWithSidePanel = sprinkles({\n display: 'flex',\n alignItems: 'stretch',\n gap: {\n base: 0,\n max1023: 3,\n },\n minWidth: 0,\n flexDirection: {\n base: 'row',\n max1023: 'column',\n },\n height: {\n base: 'full',\n max1023: 'auto',\n },\n});\n\nexport const sidebarColumn = sprinkles({\n position: 'sticky',\n top: 0,\n height: 'screen',\n flexShrink: 0,\n display: 'flex',\n overflow: 'hidden',\n});\n\nexport const sidebarColumnMobile = style({\n '@media': {\n [MOBILE_MEDIA_QUERY]: {\n position: 'fixed',\n top: 0,\n left: 0,\n bottom: 0,\n width: '20rem',\n maxWidth: '85vw',\n transform: 'translateX(-100%)',\n transitionProperty: 'transform',\n transitionDuration: vars.transitionDuration[200],\n transitionTimingFunction: vars.transitionTimingFunction.ease,\n zIndex: vars.zIndex[30],\n backgroundColor: vars.colors.surface,\n borderRight: `1px solid ${vars.colors.borderSubtle}`,\n },\n },\n});\n\nexport const sidebarColumnMobileOpen = style({\n '@media': {\n [MOBILE_MEDIA_QUERY]: {\n transform: 'translateX(0)',\n },\n },\n});\n\nexport const sidebarInner = style([\n sprinkles({\n display: 'flex',\n height: 'full',\n }),\n {\n '@media': {\n [MOBILE_MEDIA_QUERY]: {\n paddingTop: '3.75rem',\n },\n },\n },\n]);\n\nexport const mobileSidebarBackdrop = style({\n display: 'none',\n '@media': {\n [MOBILE_MEDIA_QUERY]: {\n display: 'block',\n position: 'fixed',\n inset: 0,\n backgroundColor: 'rgba(15, 23, 42, 0.32)',\n opacity: 0,\n pointerEvents: 'none',\n transitionProperty: 'opacity',\n transitionDuration: vars.transitionDuration[200],\n transitionTimingFunction: vars.transitionTimingFunction.ease,\n zIndex: vars.zIndex[20],\n },\n },\n});\n\nexport const mobileSidebarBackdropOpen = style({\n '@media': {\n [MOBILE_MEDIA_QUERY]: {\n opacity: 1,\n pointerEvents: 'auto',\n },\n },\n});\n\nexport const mobileSidebarToggle = sprinkles({\n display: {\n base: 'none',\n max1023: 'inline-flex',\n },\n alignItems: 'center',\n justifyContent: 'center',\n width: 10,\n height: 10,\n borderRadius: 'lg',\n borderStyle: 'solid',\n borderWidth: 'default',\n borderColor: 'border',\n backgroundColor: 'surface',\n color: 'text',\n cursor: 'pointer',\n flexShrink: 0,\n});\n\nexport const desktopSidebarToggle = style([\n sprinkles({\n display: {\n base: 'inline-flex',\n max1023: 'none',\n },\n alignItems: 'center',\n justifyContent: 'center',\n width: 10,\n height: 10,\n borderRadius: 'lg',\n borderStyle: 'solid',\n borderWidth: 'default',\n borderColor: 'border',\n backgroundColor: 'surface',\n color: 'text',\n cursor: 'pointer',\n flexShrink: 0,\n transitionProperty: 'default',\n transitionDuration: 150,\n transitionTimingFunction: 'ease',\n }),\n {\n selectors: {\n '&:hover': {\n borderColor: vars.colors.primaryLight,\n backgroundColor: vars.colors.surfaceMuted,\n color: vars.colors.primary,\n },\n '&:focus-visible': {\n outline: `2px solid ${vars.colors.primary}`,\n outlineOffset: '2px',\n },\n },\n },\n]);\n\nexport const mobileSidebarClose = sprinkles({\n display: {\n base: 'none',\n max1023: 'inline-flex',\n },\n position: {\n base: 'static',\n max1023: 'absolute',\n },\n right: {\n base: 0,\n max1023: 3,\n },\n top: {\n base: 0,\n max1023: 3,\n },\n zIndex: 40,\n alignItems: 'center',\n justifyContent: 'center',\n width: 10,\n height: 10,\n borderRadius: 'lg',\n borderStyle: 'solid',\n borderWidth: 'default',\n borderColor: 'border',\n backgroundColor: 'surface',\n color: 'text',\n cursor: 'pointer',\n});\n\nexport const mainColumn = sprinkles({\n flex: 1,\n height: 'full',\n minWidth: 0,\n minHeight: 0,\n display: 'flex',\n flexDirection: 'column',\n backgroundColor: 'surface',\n overflow: 'hidden',\n borderRadius: 'lg',\n borderWidth: 'default',\n borderStyle: 'solid',\n borderColor: 'borderSubtle',\n boxShadow: 'inkSoft',\n});\n\nexport const mainColumnContained = sprinkles({\n minHeight: 0,\n overflow: 'hidden',\n});\n\nexport const mainColumnWithSidePanel = sprinkles({\n height: {\n base: 'full',\n max1023: 'auto',\n },\n});\n\nexport const sidePanel = sprinkles({\n display: 'flex',\n flexDirection: 'column',\n minHeight: 0,\n height: {\n base: 'full',\n max1023: 'auto',\n },\n});\n\nexport const sidePanelSurface = sprinkles({\n flex: 'none',\n backgroundColor: 'surface',\n borderRadius: 'xl',\n borderWidth: 'default',\n borderStyle: 'solid',\n borderColor: 'borderSubtle',\n});\n\nexport const sidePanelResizable = style({\n minWidth: '360px',\n maxWidth: '50vw',\n});\n\nexport const sidePanelResizer = style([\n sprinkles({\n alignSelf: 'stretch',\n backgroundColor: 'transparent',\n cursor: 'col-resize',\n flex: 'none',\n minWidth: 4,\n position: 'relative',\n width: 4,\n }),\n {\n selectors: {\n '&::after': {\n content: '',\n position: 'absolute',\n top: '50%',\n left: '50%',\n width: '4px',\n height: '96px',\n transform: 'translate(-50%, -50%)',\n borderRadius: vars.borderRadius.full,\n backgroundColor: vars.colors.border,\n boxShadow: vars.boxShadow.sm,\n transitionProperty: 'default',\n transitionDuration: vars.transitionDuration[120],\n transitionTimingFunction: vars.transitionTimingFunction.ease,\n },\n '&:hover::after, &[data-active=\"true\"]::after': {\n backgroundColor: vars.colors.primary,\n boxShadow: `0 0 0 1px ${vars.colors.primaryLight}`,\n },\n '&:focus-visible': {\n outline: `2px solid ${vars.colors.primary}`,\n outlineOffset: '2px',\n },\n },\n },\n]);\n\nexport const sidePanelResizerHiddenOnMobile = sprinkles({\n display: {\n base: 'block',\n max1023: 'none',\n },\n});\n\nexport const header = sprinkles({\n position: 'sticky',\n top: 0,\n zIndex: 10,\n display: 'flex',\n flexDirection: 'column',\n gap: 3,\n backgroundColor: 'surface',\n borderWidth: 0,\n borderStyle: 'solid',\n borderBottomWidth: 'default',\n borderBottomColor: 'borderSubtle',\n paddingLeft: 5,\n paddingRight: 5,\n paddingBottom: 2,\n paddingTop: 3,\n});\n\nexport const headerRow = sprinkles({\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'flex-start',\n justifyContent: 'space-between',\n gap: 4,\n width: 'full',\n});\n\nexport const headerLeading = sprinkles({\n display: 'flex',\n alignItems: 'center',\n gap: 3,\n flex: 1,\n minWidth: 0,\n});\n\nexport const breadcrumbNav = sprinkles({\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n minWidth: 0,\n});\n\nexport const breadcrumbList = sprinkles({\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'center',\n columnGap: 2,\n rowGap: 1,\n listStyleType: 'none',\n margin: 0,\n padding: 0,\n color: 'textSecondary',\n fontSize: 'xs',\n});\n\nexport const breadcrumbItem = sprinkles({\n display: 'flex',\n alignItems: 'center',\n gap: 1,\n maxWidth: '12rem',\n});\n\nexport const breadcrumbLink = style([\n sprinkles({\n color: 'text',\n textDecoration: 'none',\n fontWeight: 'medium',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n }),\n {\n selectors: {\n '&:hover': {\n color: vars.colors['blue-600'],\n },\n },\n },\n]);\n\nexport const breadcrumbCurrent = sprinkles({\n color: 'text',\n fontWeight: 'semibold',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n});\n\nexport const breadcrumbSeparator = sprinkles({\n color: 'borderLight',\n fontSize: 'xs',\n});\n\nexport const actionGroup = sprinkles({\n display: 'flex',\n flexWrap: 'wrap',\n gap: 2,\n justifyContent: 'flex-end',\n});\n\nexport const secondaryAction = sprinkles({\n display: 'inline-flex',\n});\n\nexport const tabsRow = sprinkles({\n width: 'full',\n display: 'flex',\n flexWrap: 'wrap',\n gap: 2,\n});\n\nconst tabBase = style([\n sprinkles({\n alignItems: 'center',\n backgroundColor: 'surfaceMuted',\n borderRadius: 'lg',\n color: 'textSecondary',\n display: 'inline-flex',\n fontSize: 'sm',\n fontWeight: 'medium',\n paddingBlock: 1.5,\n paddingInline: 3,\n textDecoration: 'none',\n transitionProperty: 'default',\n transitionDuration: 150,\n transitionTimingFunction: 'ease',\n }),\n {\n selectors: {\n '&:hover': {\n color: vars.colors.text,\n },\n },\n },\n]);\n\nexport const tabRecipe = recipe({\n base: tabBase,\n variants: {\n state: {\n default: {},\n active: sprinkles({\n backgroundColor: 'blue-500',\n color: 'white',\n boxShadow: 'sm',\n }),\n },\n mode: {\n link: {},\n static: sprinkles({\n cursor: 'default',\n }),\n },\n },\n defaultVariants: {\n state: 'default',\n mode: 'link',\n },\n});\n\nexport const content = sprinkles({\n flex: 1,\n minHeight: 0,\n display: 'flex',\n flexDirection: 'column',\n overflow: 'auto',\n padding: {\n base: 4,\n max1023: 3,\n },\n});\n\nexport const contentContained = sprinkles({\n overflow: 'hidden',\n minHeight: 0,\n});\n"],"mappings":""}
@@ -1,13 +1,13 @@
1
1
  import { cx as e } from "../../theme/tools.js";
2
2
  import { useUiTranslation as t } from "../../i18n/useUiTranslation.js";
3
3
  import { ModalCloseSvg as n } from "../../icons/ModalCloseSvg.js";
4
- import { actionGroup as r, breadcrumbCurrent as i, breadcrumbItem as a, breadcrumbLink as o, breadcrumbList as s, breadcrumbNav as c, breadcrumbSeparator as ee, content as te, header as ne, headerLeading as re, headerRow as ie, mainColumn as ae, mainColumnWithSidePanel as oe, mobileSidebarBackdrop as se, mobileSidebarBackdropOpen as ce, page as le, pageWithSidePanel as ue, secondaryAction as l, shell as de, sidePanel as fe, sidePanelResizable as pe, sidePanelResizer as me, sidePanelResizerHiddenOnMobile as he, sidePanelSurface as ge, tabRecipe as _e, tabsRow as ve } from "./PageShell.css.js";
4
+ import { actionGroup as r, breadcrumbCurrent as i, breadcrumbItem as a, breadcrumbLink as o, breadcrumbList as s, breadcrumbNav as c, breadcrumbSeparator as ee, content as te, contentContained as ne, header as re, headerLeading as ie, headerRow as ae, mainColumn as oe, mainColumnContained as se, mainColumnWithSidePanel as ce, mobileSidebarBackdrop as le, mobileSidebarBackdropOpen as ue, page as de, pageContained as fe, pageWithSidePanel as pe, secondaryAction as l, shell as me, sidePanel as he, sidePanelResizable as ge, sidePanelResizer as _e, sidePanelResizerHiddenOnMobile as ve, sidePanelSurface as ye, tabRecipe as be, tabsRow as xe } from "./PageShell.css.js";
5
5
  import { MenuSvg as u } from "../../icons/MenuSvg.js";
6
6
  import { useCallback as d, useEffect as f, useRef as p, useState as m } from "react";
7
7
  import { jsx as h, jsxs as g } from "react/jsx-runtime";
8
8
  import _ from "@plumile/router/routing/Link.js";
9
9
  //#region src/components/layout/PageShell.tsx
10
- var ye = 520, v = 360, y = .5, b = 480, be = 1024, x = "plumile:page-shell:side-panel-width", xe = "a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex=\"-1\"])", S = () => {
10
+ var Se = 520, v = 360, y = .5, b = 480, Ce = 1024, x = "plumile:page-shell:side-panel-width", we = "a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex=\"-1\"])", S = () => {
11
11
  if (typeof window > "u") return null;
12
12
  try {
13
13
  let e = window.localStorage.getItem(x);
@@ -24,28 +24,30 @@ var ye = 520, v = 360, y = .5, b = 480, be = 1024, x = "plumile:page-shell:side-
24
24
  }, w = (e) => {
25
25
  let t = e;
26
26
  return typeof window < "u" && (t = window.innerWidth), t * y;
27
- }, T = (e, t) => typeof e.isActive == "boolean" ? e.isActive : e.href != null && t != null ? t === e.href : !1, E = ({ actions: y, breadcrumb: x, breadcrumbSlot: E, children: D, contentClassName: Se, desktopSidebarOpen: O = !0, mobileSidebar: Ce, onOpenDesktopSidebar: we, openDesktopSidebarLabel: Te, sidebar: k, sidePanel: A, tabs: j }) => {
28
- let { t: M } = t(), N = A != null, P = p(null), F = p(null), I = p(null), L = p(null), R = p(null), z = p(null), [B, V] = m(() => S() ?? ye), H = p(B), [Ee, U] = m(!1), [W, De] = m(!1), [G, K] = m(!1), q = d(() => {
29
- K(!1);
30
- }, []), Oe = d(() => {
27
+ }, T = (e, t) => typeof e.isActive == "boolean" ? e.isActive : e.href != null && t != null ? t === e.href : !1, E = ({ actions: y, breadcrumb: x, breadcrumbSlot: E, children: D, contentClassName: Te, contentScrollMode: Ee = "page", desktopSidebarOpen: O = !0, mobileSidebar: De, onOpenDesktopSidebar: Oe, openDesktopSidebarLabel: ke, sidebar: k, sidePanel: A, tabs: j }) => {
28
+ let { t: M } = t(), N = A != null, P = Ee === "contained", F = null;
29
+ P && (F = ne);
30
+ let I = p(null), L = p(null), R = p(null), z = p(null), B = p(null), V = p(null), [H, U] = m(() => S() ?? Se), W = p(H), [Ae, G] = m(!1), [K, je] = m(!1), [q, J] = m(!1), Y = d(() => {
31
+ J(!1);
32
+ }, []), Me = d(() => {
31
33
  if (typeof document < "u") {
32
34
  let { activeElement: e } = document;
33
- e instanceof HTMLElement && (R.current = e);
35
+ e instanceof HTMLElement && (B.current = e);
34
36
  }
35
- K(!0);
36
- }, []), J = d((e) => {
37
- let t = P.current;
37
+ J(!0);
38
+ }, []), X = d((e) => {
39
+ let t = I.current;
38
40
  if (t == null) return;
39
41
  let { width: n } = t.getBoundingClientRect(), r = Math.max(0, Math.min(w(n), n - b)), i = Math.min(v, r);
40
42
  r <= 0 && (i = 0);
41
43
  let a = Math.max(i, Math.min(e, Math.max(i, r)));
42
- H.current = a, V(a);
43
- }, []), Y = d((e) => {
44
- if (typeof window > "u" || !N || W) return;
45
- let t = P.current;
44
+ W.current = a, U(a);
45
+ }, []), Z = d((e) => {
46
+ if (typeof window > "u" || !N || K) return;
47
+ let t = I.current;
46
48
  if (t == null) return;
47
- let n = t.getBoundingClientRect(), r = B;
48
- U(!0);
49
+ let n = t.getBoundingClientRect(), r = H;
50
+ G(!0);
49
51
  let i = (t) => {
50
52
  let i = 0;
51
53
  if ("touches" in t) {
@@ -56,54 +58,54 @@ var ye = 520, v = 360, y = .5, b = 480, be = 1024, x = "plumile:page-shell:side-
56
58
  let a = r + (e - i), o = Math.max(0, Math.min(w(n.width), n.width - b)), s = Math.min(v, o);
57
59
  o <= 0 && (s = 0);
58
60
  let c = Math.max(s, Math.min(a, Math.max(s, o)));
59
- H.current = c, V(c);
61
+ W.current = c, U(c);
60
62
  }, a = () => {
61
- U(!1), C(H.current);
62
- let e = z.current;
63
- e?.move != null && (window.removeEventListener("mousemove", e.move), window.removeEventListener("touchmove", e.move)), e?.up != null && (window.removeEventListener("mouseup", e.up), window.removeEventListener("touchend", e.up), window.removeEventListener("touchcancel", e.up)), z.current = null;
63
+ G(!1), C(W.current);
64
+ let e = V.current;
65
+ e?.move != null && (window.removeEventListener("mousemove", e.move), window.removeEventListener("touchmove", e.move)), e?.up != null && (window.removeEventListener("mouseup", e.up), window.removeEventListener("touchend", e.up), window.removeEventListener("touchcancel", e.up)), V.current = null;
64
66
  };
65
- z.current = {
67
+ V.current = {
66
68
  move: i,
67
69
  up: a
68
70
  }, window.addEventListener("mousemove", i), window.addEventListener("touchmove", i, { passive: !1 }), window.addEventListener("mouseup", a), window.addEventListener("touchend", a), window.addEventListener("touchcancel", a);
69
71
  }, [
70
72
  N,
71
- W,
72
- B
73
+ K,
74
+ H
73
75
  ]);
74
76
  f(() => {
75
- H.current = B;
76
- }, [B]), f(() => {
77
+ W.current = H;
78
+ }, [H]), f(() => {
77
79
  if (typeof window > "u") return () => {};
78
- let e = window.matchMedia(`(max-width: ${be - 1}px)`), t = () => {
79
- De(e.matches);
80
+ let e = window.matchMedia(`(max-width: ${Ce - 1}px)`), t = () => {
81
+ je(e.matches);
80
82
  };
81
83
  return t(), e.addEventListener("change", t), () => {
82
84
  e.removeEventListener("change", t);
83
85
  };
84
86
  }, []), f(() => {
85
- N && J(B);
87
+ N && X(H);
86
88
  }, [
87
89
  N,
88
- B,
89
- J
90
+ H,
91
+ X
90
92
  ]), f(() => {
91
- !W && G && q();
93
+ !K && q && Y();
92
94
  }, [
95
+ Y,
93
96
  q,
94
- G,
95
- W
97
+ K
96
98
  ]), f(() => {
97
- if (!G) return () => {};
99
+ if (!q) return () => {};
98
100
  let e = (e) => {
99
101
  if (e.key === "Escape") {
100
- q();
102
+ Y();
101
103
  return;
102
104
  }
103
105
  if (e.key !== "Tab") return;
104
- let t = F.current;
106
+ let t = L.current;
105
107
  if (t == null) return;
106
- let n = Array.from(t.querySelectorAll(xe)).filter((e) => e.offsetParent != null || e === document.activeElement), r = n[0], i = n[n.length - 1];
108
+ let n = Array.from(t.querySelectorAll(we)).filter((e) => e.offsetParent != null || e === document.activeElement), r = n[0], i = n[n.length - 1];
107
109
  if (r == null || i == null) {
108
110
  e.preventDefault();
109
111
  return;
@@ -113,19 +115,19 @@ var ye = 520, v = 360, y = .5, b = 480, be = 1024, x = "plumile:page-shell:side-
113
115
  return;
114
116
  }
115
117
  !e.shiftKey && document.activeElement === i && (e.preventDefault(), r.focus());
116
- }, t = I.current;
117
- return L.current?.focus(), window.addEventListener("keydown", e), () => {
118
+ }, t = R.current;
119
+ return z.current?.focus(), window.addEventListener("keydown", e), () => {
118
120
  window.removeEventListener("keydown", e);
119
- let n = R.current;
120
- n != null && document.contains(n) ? n.focus() : t?.focus(), R.current = null;
121
+ let n = B.current;
122
+ n != null && document.contains(n) ? n.focus() : t?.focus(), B.current = null;
121
123
  };
122
- }, [q, G]), f(() => () => {
123
- let e = z.current;
124
+ }, [Y, q]), f(() => () => {
125
+ let e = V.current;
124
126
  e?.move != null && (window.removeEventListener("mousemove", e.move), window.removeEventListener("touchmove", e.move)), e?.up != null && (window.removeEventListener("mouseup", e.up), window.removeEventListener("touchend", e.up), window.removeEventListener("touchcancel", e.up));
125
127
  }, []);
126
- let X;
127
- typeof window < "u" && (X = window.location.pathname);
128
- let ke = () => {
128
+ let Q;
129
+ typeof window < "u" && (Q = window.location.pathname);
130
+ let Ne = () => {
129
131
  if (E != null) return /* @__PURE__ */ h("div", {
130
132
  className: c,
131
133
  children: E
@@ -163,7 +165,7 @@ var ye = 520, v = 360, y = .5, b = 480, be = 1024, x = "plumile:page-shell:side-
163
165
  children: e
164
166
  })
165
167
  });
166
- }, Ae = () => {
168
+ }, Pe = () => {
167
169
  if (y == null || y.main == null && (y.secondary ?? []).length === 0) return null;
168
170
  let e = y.secondary ?? [], t = null;
169
171
  return y.main != null && (t = /* @__PURE__ */ h("div", {
@@ -176,14 +178,14 @@ var ye = 520, v = 360, y = .5, b = 480, be = 1024, x = "plumile:page-shell:side-
176
178
  children: e
177
179
  }, `secondary-${t}`)), t]
178
180
  });
179
- }, je = () => j == null || j.length === 0 ? null : /* @__PURE__ */ h("div", {
180
- className: ve,
181
+ }, Fe = () => j == null || j.length === 0 ? null : /* @__PURE__ */ h("div", {
182
+ className: xe,
181
183
  children: j.map((e) => {
182
- let t = T(e, X), n = "default";
184
+ let t = T(e, Q), n = "default";
183
185
  t && (n = "active");
184
186
  let r = "link";
185
187
  e.href ?? (r = "static");
186
- let i = _e({
188
+ let i = be({
187
189
  state: n,
188
190
  mode: r
189
191
  }), a = e.id, o;
@@ -198,75 +200,75 @@ var ye = 520, v = 360, y = .5, b = 480, be = 1024, x = "plumile:page-shell:side-
198
200
  children: e.label
199
201
  }, a);
200
202
  })
201
- }), Me = d((e) => {
202
- if (!W && (e.key === "ArrowLeft" || e.key === "ArrowRight")) {
203
+ }), Ie = d((e) => {
204
+ if (!K && (e.key === "ArrowLeft" || e.key === "ArrowRight")) {
203
205
  e.preventDefault();
204
206
  let t = 16;
205
- e.key === "ArrowRight" && (t = -16), J(B + t), C(H.current);
207
+ e.key === "ArrowRight" && (t = -16), X(H + t), C(W.current);
206
208
  }
207
209
  }, [
208
- J,
209
- W,
210
- B
211
- ]), Z = null;
210
+ X,
211
+ K,
212
+ H
213
+ ]), Le = null;
212
214
  if (N) {
213
- let t = [fe, ge], n;
214
- W || (t.push(pe), n = { width: `${B}px` }), Z = /* @__PURE__ */ h("aside", {
215
+ let t = [he, ye], n;
216
+ K || (t.push(ge), n = { width: `${H}px` }), Le = /* @__PURE__ */ h("aside", {
215
217
  className: e(...t),
216
218
  style: n,
217
219
  children: A
218
220
  });
219
221
  }
220
- let Q = null;
222
+ let Re = null;
221
223
  if (N) {
222
224
  let t = "false";
223
- Ee && (t = "true");
224
- let n = v, r = Math.max(v, B), i = P.current;
225
+ Ae && (t = "true");
226
+ let n = v, r = Math.max(v, H), i = I.current;
225
227
  if (i != null) {
226
228
  let { width: e } = i.getBoundingClientRect(), t = Math.max(0, Math.min(w(e), e - b));
227
229
  n = Math.min(v, t), t <= 0 && (n = 0), r = Math.max(n, t);
228
230
  }
229
- Q = /* @__PURE__ */ h("div", {
230
- className: e(me, he),
231
+ Re = /* @__PURE__ */ h("div", {
232
+ className: e(_e, ve),
231
233
  role: "separator",
232
234
  "aria-orientation": "vertical",
233
235
  "aria-label": M("layout.pageShell.resizeSidePanel"),
234
236
  "aria-valuemin": Math.round(n),
235
237
  "aria-valuemax": Math.round(r),
236
- "aria-valuenow": Math.round(B),
238
+ "aria-valuenow": Math.round(H),
237
239
  tabIndex: 0,
238
240
  "data-active": t,
239
241
  onMouseDown: (e) => {
240
- e.preventDefault(), Y(e.clientX);
242
+ e.preventDefault(), Z(e.clientX);
241
243
  },
242
244
  onTouchStart: (e) => {
243
245
  let t = e.touches[0];
244
- t != null && Y(t.clientX);
246
+ t != null && Z(t.clientX);
245
247
  },
246
- onKeyDown: Me
248
+ onKeyDown: Ie
247
249
  });
248
250
  }
249
- let Ne = k;
250
- W && (Ne = Ce ?? k);
251
- let Pe = O || W, $ = Te;
251
+ let ze = k;
252
+ K && (ze = De ?? k);
253
+ let Be = O || K, $ = ke;
252
254
  return $ ??= M("navigation.pageShell.openNavigation"), /* @__PURE__ */ g("div", {
253
- className: de,
255
+ className: me,
254
256
  children: [
255
257
  /* @__PURE__ */ h("div", {
256
- className: e(se, { [ce]: W && G }),
258
+ className: e(le, { [ue]: K && q }),
257
259
  "aria-hidden": "true",
258
- onClick: q
260
+ onClick: Y
259
261
  }),
260
- Pe && /* @__PURE__ */ g("div", {
261
- ref: F,
262
- className: e("_1kley2d3 txvbqbpty txvbqbt7y txvbqbcx7 txvbqbaj7 txvbqb9ip txvbqbl7g", "_1kley2d4", { _1kley2d5: W && G }),
263
- "aria-hidden": W && !G,
264
- inert: W && !G,
262
+ Be && /* @__PURE__ */ g("div", {
263
+ ref: L,
264
+ className: e("_1kley2d4 txvbqbpty txvbqbt7y txvbqbcx7 txvbqbaj7 txvbqb9ip txvbqbl7g", "_1kley2d5", { _1kley2d6: K && q }),
265
+ "aria-hidden": K && !q,
266
+ inert: K && !q,
265
267
  children: [/* @__PURE__ */ h("button", {
266
- ref: L,
268
+ ref: z,
267
269
  type: "button",
268
- className: "_1kley2dd txvbqb9hy txvbqb9jn txvbqbpu7 txvbqbpte txvbqbpug txvbqbpve txvbqbt7y txvbqbt8w txvbqbuwg txvbqbcp txvbqbdoy txvbqbtyp txvbqbc7p txvbqb1rp txvbqb1qg txvbqb1cp txvbqbwg txvbqbv41 txvbqbv9z txvbqbv",
269
- onClick: q,
270
+ className: "_1kley2de txvbqb9hy txvbqb9jn txvbqbpu7 txvbqbpte txvbqbpug txvbqbpve txvbqbt7y txvbqbt8w txvbqbuwg txvbqbcp txvbqbdoy txvbqbtyp txvbqbc7p txvbqb1rp txvbqb1qg txvbqb1cp txvbqbwg txvbqbv41 txvbqbv9z txvbqbv",
271
+ onClick: Y,
270
272
  "aria-label": M("navigation.pageShell.closeNavigation"),
271
273
  children: /* @__PURE__ */ h(n, {
272
274
  width: 18,
@@ -274,29 +276,35 @@ var ye = 520, v = 360, y = .5, b = 480, be = 1024, x = "plumile:page-shell:side-
274
276
  "aria-hidden": "true"
275
277
  })
276
278
  }), /* @__PURE__ */ h("div", {
277
- className: "_1kley2d7 _1kley2d6 txvbqb9ip txvbqbcgg",
278
- children: Ne
279
+ className: "_1kley2d8 _1kley2d7 txvbqb9ip txvbqbcgg",
280
+ children: ze
279
281
  })]
280
282
  }),
281
283
  /* @__PURE__ */ g("div", {
282
- ref: P,
283
- className: e(le, { [ue]: N }),
284
- "aria-hidden": W && G,
285
- inert: W && G,
284
+ ref: I,
285
+ className: e(de, {
286
+ [pe]: N,
287
+ [fe]: P
288
+ }),
289
+ "aria-hidden": K && q,
290
+ inert: K && q,
286
291
  children: [
287
292
  /* @__PURE__ */ g("div", {
288
- className: e(ae, { [oe]: N }),
293
+ className: e(oe, {
294
+ [ce]: N,
295
+ [se]: P
296
+ }),
289
297
  children: [/* @__PURE__ */ g("div", {
290
- className: ne,
298
+ className: re,
291
299
  children: [/* @__PURE__ */ g("div", {
292
- className: ie,
300
+ className: ae,
293
301
  children: [/* @__PURE__ */ g("div", {
294
- className: re,
302
+ className: ie,
295
303
  children: [
296
- !W && !O && /* @__PURE__ */ h("button", {
304
+ !K && !O && /* @__PURE__ */ h("button", {
297
305
  type: "button",
298
- className: "_1kley2dc _1kley2db txvbqb9jg txvbqb9i5 txvbqbcp txvbqbdoy txvbqbtyp txvbqbc7p txvbqb1rp txvbqb1qg txvbqb1cp txvbqbwg txvbqbv41 txvbqbv9z txvbqbv txvbqbaj7 txvbqb77 txvbqb6x txvbqb7k",
299
- onClick: we,
306
+ className: "_1kley2dd _1kley2dc txvbqb9jg txvbqb9i5 txvbqbcp txvbqbdoy txvbqbtyp txvbqbc7p txvbqb1rp txvbqb1qg txvbqb1cp txvbqbwg txvbqbv41 txvbqbv9z txvbqbv txvbqbaj7 txvbqb77 txvbqb6x txvbqb7k",
307
+ onClick: Oe,
300
308
  "aria-label": $,
301
309
  title: $,
302
310
  children: /* @__PURE__ */ h(u, {
@@ -305,12 +313,12 @@ var ye = 520, v = 360, y = .5, b = 480, be = 1024, x = "plumile:page-shell:side-
305
313
  "aria-hidden": "true"
306
314
  })
307
315
  }),
308
- W && /* @__PURE__ */ h("button", {
309
- ref: I,
316
+ K && /* @__PURE__ */ h("button", {
317
+ ref: R,
310
318
  type: "button",
311
- className: "_1kley2da txvbqb9hy txvbqb9jn txvbqbcp txvbqbdoy txvbqbtyp txvbqbc7p txvbqb1rp txvbqb1qg txvbqb1cp txvbqbwg txvbqbv41 txvbqbv9z txvbqbv txvbqbaj7",
312
- onClick: Oe,
313
- "aria-expanded": G,
319
+ className: "_1kley2db txvbqb9hy txvbqb9jn txvbqbcp txvbqbdoy txvbqbtyp txvbqbc7p txvbqb1rp txvbqb1qg txvbqb1cp txvbqbwg txvbqbv41 txvbqbv9z txvbqbv txvbqbaj7",
320
+ onClick: Me,
321
+ "aria-expanded": q,
314
322
  "aria-label": M("navigation.pageShell.openNavigation"),
315
323
  children: /* @__PURE__ */ h(u, {
316
324
  width: 18,
@@ -318,17 +326,17 @@ var ye = 520, v = 360, y = .5, b = 480, be = 1024, x = "plumile:page-shell:side-
318
326
  "aria-hidden": "true"
319
327
  })
320
328
  }),
321
- ke()
329
+ Ne()
322
330
  ]
323
- }), Ae()]
324
- }), je()]
331
+ }), Pe()]
332
+ }), Fe()]
325
333
  }), /* @__PURE__ */ h("div", {
326
- className: e(te, Se),
334
+ className: e(te, F, Te),
327
335
  children: D
328
336
  })]
329
337
  }),
330
- Q,
331
- Z
338
+ Re,
339
+ Le
332
340
  ]
333
341
  })
334
342
  ]
@@ -1 +1 @@
1
- {"version":3,"file":"PageShell.js","names":[],"sources":["../../../../src/components/layout/PageShell.tsx"],"sourcesContent":["import Link from '@plumile/router/routing/Link.js';\nimport {\n useCallback,\n useEffect,\n useRef,\n useState,\n type JSX,\n type ReactNode,\n type KeyboardEvent,\n type CSSProperties,\n} from 'react';\n\nimport * as styles from './PageShell.css.js';\nimport { MenuSvg } from '../../icons/MenuSvg.js';\nimport { ModalCloseSvg } from '../../icons/ModalCloseSvg.js';\nimport { cx } from '../../theme/tools.js';\nimport { useUiTranslation } from '../../i18n/useUiTranslation.js';\n\nexport type BreadcrumbItem = {\n label: ReactNode;\n href?: string;\n};\n\nexport type PageShellTab = {\n id: string;\n label: ReactNode;\n href?: string;\n isActive?: boolean;\n};\n\nexport type PageShellActions = {\n main?: ReactNode;\n secondary?: ReactNode[];\n};\n\nconst DEFAULT_SIDE_PANEL_WIDTH = 520;\nconst MIN_SIDE_PANEL_WIDTH = 360;\nconst MAX_SIDE_PANEL_RATIO = 0.5;\nconst MIN_MAIN_WIDTH = 480;\nconst SPLIT_BREAKPOINT = 1024;\nconst SIDE_PANEL_WIDTH_STORAGE_KEY = 'plumile:page-shell:side-panel-width';\nconst FOCUSABLE_SELECTOR =\n 'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n\nconst readStoredSidePanelWidth = (): number | null => {\n if (typeof window === 'undefined') {\n return null;\n }\n\n try {\n const stored = window.localStorage.getItem(SIDE_PANEL_WIDTH_STORAGE_KEY);\n if (stored == null) {\n return null;\n }\n const parsed = Number(stored);\n if (!Number.isFinite(parsed) || parsed <= 0) {\n return null;\n }\n return parsed;\n } catch {\n return null;\n }\n};\n\nconst persistSidePanelWidth = (width: number): void => {\n if (typeof window === 'undefined') {\n return;\n }\n\n try {\n window.localStorage.setItem(SIDE_PANEL_WIDTH_STORAGE_KEY, String(width));\n } catch {\n // ignore quota / permission errors\n }\n};\n\nconst resolveMaxSidePanelWidth = (containerWidth: number): number => {\n let viewWidth = containerWidth;\n if (typeof window !== 'undefined') {\n viewWidth = window.innerWidth;\n }\n return viewWidth * MAX_SIDE_PANEL_RATIO;\n};\n\ntype ResizeMoveHandler = (event: MouseEvent | TouchEvent) => void;\ntype ResizeUpHandler = () => void;\ntype ActiveResizeHandlers = {\n move?: ResizeMoveHandler | null;\n up?: ResizeUpHandler | null;\n};\n\ntype Props = {\n sidebar: ReactNode;\n mobileSidebar?: ReactNode;\n desktopSidebarOpen?: boolean;\n onOpenDesktopSidebar?: () => void;\n openDesktopSidebarLabel?: string;\n children: ReactNode;\n breadcrumb?: BreadcrumbItem[];\n breadcrumbSlot?: ReactNode;\n tabs?: PageShellTab[];\n actions?: PageShellActions;\n sidePanel?: ReactNode;\n contentClassName?: string;\n};\n\nconst resolveIsActive = (tab: PageShellTab, pathname?: string): boolean => {\n if (typeof tab.isActive === 'boolean') {\n return tab.isActive;\n }\n\n if (tab.href != null && pathname != null) {\n return pathname === tab.href;\n }\n\n return false;\n};\n\nexport const PageShell = ({\n actions,\n breadcrumb,\n breadcrumbSlot,\n children,\n contentClassName,\n desktopSidebarOpen = true,\n mobileSidebar,\n onOpenDesktopSidebar,\n openDesktopSidebarLabel,\n sidebar,\n sidePanel,\n tabs,\n}: Props): JSX.Element => {\n const { t } = useUiTranslation();\n const hasSidePanel = sidePanel != null;\n const pageRef = useRef<HTMLDivElement | null>(null);\n const mobileSidebarRef = useRef<HTMLDivElement | null>(null);\n const mobileSidebarToggleRef = useRef<HTMLButtonElement | null>(null);\n const mobileSidebarCloseRef = useRef<HTMLButtonElement | null>(null);\n const mobileSidebarPreviousFocusRef = useRef<HTMLElement | null>(null);\n const activeResizeHandlersRef = useRef<ActiveResizeHandlers | null>(null);\n const [sidePanelWidth, setSidePanelWidth] = useState(() => {\n const stored = readStoredSidePanelWidth();\n return stored ?? DEFAULT_SIDE_PANEL_WIDTH;\n });\n const sidePanelWidthSnapshotRef = useRef(sidePanelWidth);\n const [isResizingPanel, setIsResizingPanel] = useState(false);\n const [isStackedLayout, setIsStackedLayout] = useState(false);\n const [isMobileSidebarOpen, setIsMobileSidebarOpen] = useState(false);\n\n const closeMobileSidebar = useCallback(() => {\n setIsMobileSidebarOpen(false);\n }, []);\n\n const openMobileSidebar = useCallback(() => {\n if (typeof document !== 'undefined') {\n const { activeElement } = document;\n if (activeElement instanceof HTMLElement) {\n mobileSidebarPreviousFocusRef.current = activeElement;\n }\n }\n setIsMobileSidebarOpen(true);\n }, []);\n\n const clampSidePanelWidth = useCallback((candidateWidth: number): void => {\n const container = pageRef.current;\n if (container == null) {\n return;\n }\n\n const { width } = container.getBoundingClientRect();\n const maxWidth = Math.max(\n 0,\n Math.min(resolveMaxSidePanelWidth(width), width - MIN_MAIN_WIDTH),\n );\n const minWidth = Math.min(MIN_SIDE_PANEL_WIDTH, maxWidth);\n let safeMin = minWidth;\n if (maxWidth <= 0) {\n safeMin = 0;\n }\n const safeMax = Math.max(safeMin, maxWidth);\n const clampedWidth = Math.max(safeMin, Math.min(candidateWidth, safeMax));\n sidePanelWidthSnapshotRef.current = clampedWidth;\n setSidePanelWidth(clampedWidth);\n }, []);\n\n const startResizing = useCallback(\n (startClientX: number): void => {\n if (typeof window === 'undefined') {\n return;\n }\n\n if (!hasSidePanel || isStackedLayout) {\n return;\n }\n\n const container = pageRef.current;\n if (container == null) {\n return;\n }\n\n const rect = container.getBoundingClientRect();\n const currentWidth = sidePanelWidth;\n setIsResizingPanel(true);\n\n const moveHandler: ResizeMoveHandler = (event) => {\n let clientX = 0;\n if ('touches' in event) {\n const touch = event.touches[0];\n if (touch == null) {\n return;\n }\n clientX = touch.clientX;\n } else {\n clientX = event.clientX;\n }\n\n const deltaX = startClientX - clientX;\n const nextWidth = currentWidth + deltaX;\n\n const maxWidth = Math.max(\n 0,\n Math.min(\n resolveMaxSidePanelWidth(rect.width),\n rect.width - MIN_MAIN_WIDTH,\n ),\n );\n const minWidth = Math.min(MIN_SIDE_PANEL_WIDTH, maxWidth);\n let safeMin = minWidth;\n if (maxWidth <= 0) {\n safeMin = 0;\n }\n const safeMax = Math.max(safeMin, maxWidth);\n\n const clampedWidth = Math.max(safeMin, Math.min(nextWidth, safeMax));\n sidePanelWidthSnapshotRef.current = clampedWidth;\n setSidePanelWidth(clampedWidth);\n };\n\n const upHandler: ResizeUpHandler = () => {\n setIsResizingPanel(false);\n persistSidePanelWidth(sidePanelWidthSnapshotRef.current);\n const handlers = activeResizeHandlersRef.current;\n if (handlers?.move != null) {\n window.removeEventListener('mousemove', handlers.move);\n window.removeEventListener('touchmove', handlers.move);\n }\n if (handlers?.up != null) {\n window.removeEventListener('mouseup', handlers.up);\n window.removeEventListener('touchend', handlers.up);\n window.removeEventListener('touchcancel', handlers.up);\n }\n activeResizeHandlersRef.current = null;\n };\n\n activeResizeHandlersRef.current = { move: moveHandler, up: upHandler };\n\n window.addEventListener('mousemove', moveHandler);\n window.addEventListener('touchmove', moveHandler, { passive: false });\n window.addEventListener('mouseup', upHandler);\n window.addEventListener('touchend', upHandler);\n window.addEventListener('touchcancel', upHandler);\n },\n [hasSidePanel, isStackedLayout, sidePanelWidth],\n );\n\n useEffect(() => {\n sidePanelWidthSnapshotRef.current = sidePanelWidth;\n }, [sidePanelWidth]);\n\n useEffect(() => {\n if (typeof window === 'undefined') {\n return () => {};\n }\n const mediaQuery = window.matchMedia(\n `(max-width: ${SPLIT_BREAKPOINT - 1}px)`,\n );\n const handleMediaChange = () => {\n setIsStackedLayout(mediaQuery.matches);\n };\n\n handleMediaChange();\n mediaQuery.addEventListener('change', handleMediaChange);\n\n return () => {\n mediaQuery.removeEventListener('change', handleMediaChange);\n };\n }, []);\n\n useEffect(() => {\n if (hasSidePanel) {\n clampSidePanelWidth(sidePanelWidth);\n }\n }, [hasSidePanel, sidePanelWidth, clampSidePanelWidth]);\n\n useEffect(() => {\n if (!isStackedLayout && isMobileSidebarOpen) {\n closeMobileSidebar();\n }\n }, [closeMobileSidebar, isMobileSidebarOpen, isStackedLayout]);\n\n useEffect(() => {\n if (!isMobileSidebarOpen) {\n return () => {};\n }\n\n const handleEscape = (event: globalThis.KeyboardEvent) => {\n if (event.key === 'Escape') {\n closeMobileSidebar();\n return;\n }\n\n if (event.key !== 'Tab') {\n return;\n }\n\n const sidebarElement = mobileSidebarRef.current;\n if (sidebarElement == null) {\n return;\n }\n\n const focusableElements = Array.from(\n sidebarElement.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR),\n ).filter((element) => {\n return (\n element.offsetParent != null || element === document.activeElement\n );\n });\n\n const firstElement = focusableElements[0];\n const lastElement = focusableElements[focusableElements.length - 1];\n\n if (firstElement == null || lastElement == null) {\n event.preventDefault();\n return;\n }\n\n if (event.shiftKey && document.activeElement === firstElement) {\n event.preventDefault();\n lastElement.focus();\n return;\n }\n\n if (!event.shiftKey && document.activeElement === lastElement) {\n event.preventDefault();\n firstElement.focus();\n }\n };\n\n const fallbackFocusElement = mobileSidebarToggleRef.current;\n mobileSidebarCloseRef.current?.focus();\n\n window.addEventListener('keydown', handleEscape);\n return () => {\n window.removeEventListener('keydown', handleEscape);\n const previousFocus = mobileSidebarPreviousFocusRef.current;\n if (previousFocus != null && document.contains(previousFocus)) {\n previousFocus.focus();\n } else {\n fallbackFocusElement?.focus();\n }\n mobileSidebarPreviousFocusRef.current = null;\n };\n }, [closeMobileSidebar, isMobileSidebarOpen]);\n\n useEffect(() => {\n return () => {\n const handlers = activeResizeHandlersRef.current;\n if (handlers?.move != null) {\n window.removeEventListener('mousemove', handlers.move);\n window.removeEventListener('touchmove', handlers.move);\n }\n if (handlers?.up != null) {\n window.removeEventListener('mouseup', handlers.up);\n window.removeEventListener('touchend', handlers.up);\n window.removeEventListener('touchcancel', handlers.up);\n }\n };\n }, []);\n\n let currentPath: string | undefined;\n if (typeof window !== 'undefined') {\n currentPath = window.location.pathname;\n }\n\n const renderBreadcrumb = (): JSX.Element | null => {\n if (breadcrumbSlot != null) {\n return <div className={styles.breadcrumbNav}>{breadcrumbSlot}</div>;\n }\n\n if (breadcrumb == null || breadcrumb.length === 0) {\n return null;\n }\n\n const items = breadcrumb.flatMap((item, index) => {\n const isLast = index === breadcrumb.length - 1;\n const key = `${item.href ?? 'crumb'}-${index}`;\n let content: JSX.Element;\n if (item.href != null && !isLast) {\n content = (\n <Link to={item.href} className={styles.breadcrumbLink}>\n {item.label}\n </Link>\n );\n } else {\n let breadcrumbClass = styles.breadcrumbLink;\n if (isLast) {\n breadcrumbClass = styles.breadcrumbCurrent;\n }\n content = <span className={breadcrumbClass}>{item.label}</span>;\n }\n\n const renderedItem = (\n <li key={key} className={styles.breadcrumbItem}>\n {content}\n </li>\n );\n\n if (isLast) {\n return [renderedItem];\n }\n\n return [\n renderedItem,\n <li\n key={`${key}-sep`}\n className={styles.breadcrumbSeparator}\n aria-hidden=\"true\"\n >\n /\n </li>,\n ];\n });\n\n return (\n <nav\n className={styles.breadcrumbNav}\n aria-label={t('navigation.breadcrumb')}\n >\n <ol className={styles.breadcrumbList}>{items}</ol>\n </nav>\n );\n };\n\n const renderActions = (): JSX.Element | null => {\n if (\n actions == null ||\n (actions.main == null && (actions.secondary ?? []).length === 0)\n ) {\n return null;\n }\n\n const secondaryNodes = actions.secondary ?? [];\n\n let mainActionNode: JSX.Element | null = null;\n if (actions.main != null) {\n mainActionNode = (\n <div className={styles.secondaryAction}>{actions.main}</div>\n );\n }\n\n return (\n <div className={styles.actionGroup}>\n {secondaryNodes.map((node, index) => {\n return (\n <div key={`secondary-${index}`} className={styles.secondaryAction}>\n {node}\n </div>\n );\n })}\n {mainActionNode}\n </div>\n );\n };\n\n const renderTabs = (): JSX.Element | null => {\n if (tabs == null || tabs.length === 0) {\n return null;\n }\n\n return (\n <div className={styles.tabsRow}>\n {tabs.map((tab) => {\n const isActive = resolveIsActive(tab, currentPath);\n let tabState: 'default' | 'active' = 'default';\n if (isActive) {\n tabState = 'active';\n }\n let tabMode: 'static' | 'link' = 'link';\n if (tab.href == null) {\n tabMode = 'static';\n }\n const className = styles.tabRecipe({\n state: tabState,\n mode: tabMode,\n });\n const key = tab.id;\n let ariaCurrent: 'page' | undefined;\n if (isActive) {\n ariaCurrent = 'page';\n }\n\n if (tab.href != null) {\n return (\n <Link\n key={key}\n to={tab.href}\n className={className}\n aria-current={ariaCurrent}\n >\n {tab.label}\n </Link>\n );\n }\n\n return (\n <span key={key} className={className} aria-current={ariaCurrent}>\n {tab.label}\n </span>\n );\n })}\n </div>\n );\n };\n\n const handleResizerKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDivElement>) => {\n if (isStackedLayout) {\n return;\n }\n if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') {\n event.preventDefault();\n let delta = 16;\n if (event.key === 'ArrowRight') {\n delta = -16;\n }\n clampSidePanelWidth(sidePanelWidth + delta);\n persistSidePanelWidth(sidePanelWidthSnapshotRef.current);\n }\n },\n [clampSidePanelWidth, isStackedLayout, sidePanelWidth],\n );\n\n let sidePanelNode: JSX.Element | null = null;\n if (hasSidePanel) {\n const sidePanelClasses = [styles.sidePanel, styles.sidePanelSurface];\n let sidePanelStyle: CSSProperties | undefined;\n if (!isStackedLayout) {\n sidePanelClasses.push(styles.sidePanelResizable);\n sidePanelStyle = {\n width: `${sidePanelWidth}px`,\n };\n }\n sidePanelNode = (\n <aside className={cx(...sidePanelClasses)} style={sidePanelStyle}>\n {sidePanel}\n </aside>\n );\n }\n\n let resizerNode: JSX.Element | null = null;\n if (hasSidePanel) {\n let resizerActive = 'false';\n if (isResizingPanel) {\n resizerActive = 'true';\n }\n let resizerMin = MIN_SIDE_PANEL_WIDTH;\n let resizerMax = Math.max(MIN_SIDE_PANEL_WIDTH, sidePanelWidth);\n const pageElement = pageRef.current;\n if (pageElement != null) {\n const { width } = pageElement.getBoundingClientRect();\n const maxWidth = Math.max(\n 0,\n Math.min(resolveMaxSidePanelWidth(width), width - MIN_MAIN_WIDTH),\n );\n resizerMin = Math.min(MIN_SIDE_PANEL_WIDTH, maxWidth);\n if (maxWidth <= 0) {\n resizerMin = 0;\n }\n resizerMax = Math.max(resizerMin, maxWidth);\n }\n resizerNode = (\n <div\n className={cx(\n styles.sidePanelResizer,\n styles.sidePanelResizerHiddenOnMobile,\n )}\n role=\"separator\"\n aria-orientation=\"vertical\"\n aria-label={t('layout.pageShell.resizeSidePanel')}\n aria-valuemin={Math.round(resizerMin)}\n aria-valuemax={Math.round(resizerMax)}\n aria-valuenow={Math.round(sidePanelWidth)}\n tabIndex={0}\n data-active={resizerActive}\n onMouseDown={(event) => {\n event.preventDefault();\n startResizing(event.clientX);\n }}\n onTouchStart={(event) => {\n const touch = event.touches[0];\n if (touch != null) {\n startResizing(touch.clientX);\n }\n }}\n onKeyDown={handleResizerKeyDown}\n />\n );\n }\n\n let sidebarContent = sidebar;\n if (isStackedLayout) {\n sidebarContent = mobileSidebar ?? sidebar;\n }\n const shouldRenderDesktopSidebar = desktopSidebarOpen || isStackedLayout;\n let resolvedOpenDesktopSidebarLabel = openDesktopSidebarLabel;\n resolvedOpenDesktopSidebarLabel ??= t('navigation.pageShell.openNavigation');\n\n return (\n <div className={styles.shell}>\n <div\n className={cx(styles.mobileSidebarBackdrop, {\n [styles.mobileSidebarBackdropOpen]:\n isStackedLayout && isMobileSidebarOpen,\n })}\n aria-hidden=\"true\"\n onClick={closeMobileSidebar}\n />\n {shouldRenderDesktopSidebar && (\n <div\n ref={mobileSidebarRef}\n className={cx(styles.sidebarColumn, styles.sidebarColumnMobile, {\n [styles.sidebarColumnMobileOpen]:\n isStackedLayout && isMobileSidebarOpen,\n })}\n aria-hidden={isStackedLayout && !isMobileSidebarOpen}\n inert={isStackedLayout && !isMobileSidebarOpen}\n >\n <button\n ref={mobileSidebarCloseRef}\n type=\"button\"\n className={styles.mobileSidebarClose}\n onClick={closeMobileSidebar}\n aria-label={t('navigation.pageShell.closeNavigation')}\n >\n <ModalCloseSvg width={18} height={18} aria-hidden=\"true\" />\n </button>\n <div className={styles.sidebarInner}>{sidebarContent}</div>\n </div>\n )}\n <div\n ref={pageRef}\n className={cx(styles.page, {\n [styles.pageWithSidePanel]: hasSidePanel,\n })}\n aria-hidden={isStackedLayout && isMobileSidebarOpen}\n inert={isStackedLayout && isMobileSidebarOpen}\n >\n <div\n className={cx(styles.mainColumn, {\n [styles.mainColumnWithSidePanel]: hasSidePanel,\n })}\n >\n <div className={styles.header}>\n <div className={styles.headerRow}>\n <div className={styles.headerLeading}>\n {!isStackedLayout && !desktopSidebarOpen && (\n <button\n type=\"button\"\n className={styles.desktopSidebarToggle}\n onClick={onOpenDesktopSidebar}\n aria-label={resolvedOpenDesktopSidebarLabel}\n title={resolvedOpenDesktopSidebarLabel}\n >\n <MenuSvg width={18} height={18} aria-hidden=\"true\" />\n </button>\n )}\n {isStackedLayout && (\n <button\n ref={mobileSidebarToggleRef}\n type=\"button\"\n className={styles.mobileSidebarToggle}\n onClick={openMobileSidebar}\n aria-expanded={isMobileSidebarOpen}\n aria-label={t('navigation.pageShell.openNavigation')}\n >\n <MenuSvg width={18} height={18} aria-hidden=\"true\" />\n </button>\n )}\n {renderBreadcrumb()}\n </div>\n {renderActions()}\n </div>\n {renderTabs()}\n </div>\n <div className={cx(styles.content, contentClassName)}>{children}</div>\n </div>\n {resizerNode}\n {sidePanelNode}\n </div>\n </div>\n );\n};\n\nexport const __test = {\n readStoredSidePanelWidth,\n resolveMaxSidePanelWidth,\n resolveIsActive,\n} as const;\n"],"mappings":"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"}
1
+ {"version":3,"file":"PageShell.js","names":[],"sources":["../../../../src/components/layout/PageShell.tsx"],"sourcesContent":["import Link from '@plumile/router/routing/Link.js';\nimport {\n useCallback,\n useEffect,\n useRef,\n useState,\n type JSX,\n type ReactNode,\n type KeyboardEvent,\n type CSSProperties,\n} from 'react';\n\nimport * as styles from './PageShell.css.js';\nimport { MenuSvg } from '../../icons/MenuSvg.js';\nimport { ModalCloseSvg } from '../../icons/ModalCloseSvg.js';\nimport { cx } from '../../theme/tools.js';\nimport { useUiTranslation } from '../../i18n/useUiTranslation.js';\n\nexport type BreadcrumbItem = {\n label: ReactNode;\n href?: string;\n};\n\nexport type PageShellTab = {\n id: string;\n label: ReactNode;\n href?: string;\n isActive?: boolean;\n};\n\nexport type PageShellActions = {\n main?: ReactNode;\n secondary?: ReactNode[];\n};\n\nexport type PageShellContentScrollMode = 'page' | 'contained';\n\nconst DEFAULT_SIDE_PANEL_WIDTH = 520;\nconst MIN_SIDE_PANEL_WIDTH = 360;\nconst MAX_SIDE_PANEL_RATIO = 0.5;\nconst MIN_MAIN_WIDTH = 480;\nconst SPLIT_BREAKPOINT = 1024;\nconst SIDE_PANEL_WIDTH_STORAGE_KEY = 'plumile:page-shell:side-panel-width';\nconst FOCUSABLE_SELECTOR =\n 'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n\nconst readStoredSidePanelWidth = (): number | null => {\n if (typeof window === 'undefined') {\n return null;\n }\n\n try {\n const stored = window.localStorage.getItem(SIDE_PANEL_WIDTH_STORAGE_KEY);\n if (stored == null) {\n return null;\n }\n const parsed = Number(stored);\n if (!Number.isFinite(parsed) || parsed <= 0) {\n return null;\n }\n return parsed;\n } catch {\n return null;\n }\n};\n\nconst persistSidePanelWidth = (width: number): void => {\n if (typeof window === 'undefined') {\n return;\n }\n\n try {\n window.localStorage.setItem(SIDE_PANEL_WIDTH_STORAGE_KEY, String(width));\n } catch {\n // ignore quota / permission errors\n }\n};\n\nconst resolveMaxSidePanelWidth = (containerWidth: number): number => {\n let viewWidth = containerWidth;\n if (typeof window !== 'undefined') {\n viewWidth = window.innerWidth;\n }\n return viewWidth * MAX_SIDE_PANEL_RATIO;\n};\n\ntype ResizeMoveHandler = (event: MouseEvent | TouchEvent) => void;\ntype ResizeUpHandler = () => void;\ntype ActiveResizeHandlers = {\n move?: ResizeMoveHandler | null;\n up?: ResizeUpHandler | null;\n};\n\ntype Props = {\n sidebar: ReactNode;\n mobileSidebar?: ReactNode;\n desktopSidebarOpen?: boolean;\n onOpenDesktopSidebar?: () => void;\n openDesktopSidebarLabel?: string;\n children: ReactNode;\n breadcrumb?: BreadcrumbItem[];\n breadcrumbSlot?: ReactNode;\n tabs?: PageShellTab[];\n actions?: PageShellActions;\n sidePanel?: ReactNode;\n contentClassName?: string;\n contentScrollMode?: PageShellContentScrollMode;\n};\n\nconst resolveIsActive = (tab: PageShellTab, pathname?: string): boolean => {\n if (typeof tab.isActive === 'boolean') {\n return tab.isActive;\n }\n\n if (tab.href != null && pathname != null) {\n return pathname === tab.href;\n }\n\n return false;\n};\n\nexport const PageShell = ({\n actions,\n breadcrumb,\n breadcrumbSlot,\n children,\n contentClassName,\n contentScrollMode = 'page',\n desktopSidebarOpen = true,\n mobileSidebar,\n onOpenDesktopSidebar,\n openDesktopSidebarLabel,\n sidebar,\n sidePanel,\n tabs,\n}: Props): JSX.Element => {\n const { t } = useUiTranslation();\n const hasSidePanel = sidePanel != null;\n const isContainedScroll = contentScrollMode === 'contained';\n let containedContentClassName: string | null = null;\n if (isContainedScroll) {\n containedContentClassName = styles.contentContained;\n }\n const pageRef = useRef<HTMLDivElement | null>(null);\n const mobileSidebarRef = useRef<HTMLDivElement | null>(null);\n const mobileSidebarToggleRef = useRef<HTMLButtonElement | null>(null);\n const mobileSidebarCloseRef = useRef<HTMLButtonElement | null>(null);\n const mobileSidebarPreviousFocusRef = useRef<HTMLElement | null>(null);\n const activeResizeHandlersRef = useRef<ActiveResizeHandlers | null>(null);\n const [sidePanelWidth, setSidePanelWidth] = useState(() => {\n const stored = readStoredSidePanelWidth();\n return stored ?? DEFAULT_SIDE_PANEL_WIDTH;\n });\n const sidePanelWidthSnapshotRef = useRef(sidePanelWidth);\n const [isResizingPanel, setIsResizingPanel] = useState(false);\n const [isStackedLayout, setIsStackedLayout] = useState(false);\n const [isMobileSidebarOpen, setIsMobileSidebarOpen] = useState(false);\n\n const closeMobileSidebar = useCallback(() => {\n setIsMobileSidebarOpen(false);\n }, []);\n\n const openMobileSidebar = useCallback(() => {\n if (typeof document !== 'undefined') {\n const { activeElement } = document;\n if (activeElement instanceof HTMLElement) {\n mobileSidebarPreviousFocusRef.current = activeElement;\n }\n }\n setIsMobileSidebarOpen(true);\n }, []);\n\n const clampSidePanelWidth = useCallback((candidateWidth: number): void => {\n const container = pageRef.current;\n if (container == null) {\n return;\n }\n\n const { width } = container.getBoundingClientRect();\n const maxWidth = Math.max(\n 0,\n Math.min(resolveMaxSidePanelWidth(width), width - MIN_MAIN_WIDTH),\n );\n const minWidth = Math.min(MIN_SIDE_PANEL_WIDTH, maxWidth);\n let safeMin = minWidth;\n if (maxWidth <= 0) {\n safeMin = 0;\n }\n const safeMax = Math.max(safeMin, maxWidth);\n const clampedWidth = Math.max(safeMin, Math.min(candidateWidth, safeMax));\n sidePanelWidthSnapshotRef.current = clampedWidth;\n setSidePanelWidth(clampedWidth);\n }, []);\n\n const startResizing = useCallback(\n (startClientX: number): void => {\n if (typeof window === 'undefined') {\n return;\n }\n\n if (!hasSidePanel || isStackedLayout) {\n return;\n }\n\n const container = pageRef.current;\n if (container == null) {\n return;\n }\n\n const rect = container.getBoundingClientRect();\n const currentWidth = sidePanelWidth;\n setIsResizingPanel(true);\n\n const moveHandler: ResizeMoveHandler = (event) => {\n let clientX = 0;\n if ('touches' in event) {\n const touch = event.touches[0];\n if (touch == null) {\n return;\n }\n clientX = touch.clientX;\n } else {\n clientX = event.clientX;\n }\n\n const deltaX = startClientX - clientX;\n const nextWidth = currentWidth + deltaX;\n\n const maxWidth = Math.max(\n 0,\n Math.min(\n resolveMaxSidePanelWidth(rect.width),\n rect.width - MIN_MAIN_WIDTH,\n ),\n );\n const minWidth = Math.min(MIN_SIDE_PANEL_WIDTH, maxWidth);\n let safeMin = minWidth;\n if (maxWidth <= 0) {\n safeMin = 0;\n }\n const safeMax = Math.max(safeMin, maxWidth);\n\n const clampedWidth = Math.max(safeMin, Math.min(nextWidth, safeMax));\n sidePanelWidthSnapshotRef.current = clampedWidth;\n setSidePanelWidth(clampedWidth);\n };\n\n const upHandler: ResizeUpHandler = () => {\n setIsResizingPanel(false);\n persistSidePanelWidth(sidePanelWidthSnapshotRef.current);\n const handlers = activeResizeHandlersRef.current;\n if (handlers?.move != null) {\n window.removeEventListener('mousemove', handlers.move);\n window.removeEventListener('touchmove', handlers.move);\n }\n if (handlers?.up != null) {\n window.removeEventListener('mouseup', handlers.up);\n window.removeEventListener('touchend', handlers.up);\n window.removeEventListener('touchcancel', handlers.up);\n }\n activeResizeHandlersRef.current = null;\n };\n\n activeResizeHandlersRef.current = { move: moveHandler, up: upHandler };\n\n window.addEventListener('mousemove', moveHandler);\n window.addEventListener('touchmove', moveHandler, { passive: false });\n window.addEventListener('mouseup', upHandler);\n window.addEventListener('touchend', upHandler);\n window.addEventListener('touchcancel', upHandler);\n },\n [hasSidePanel, isStackedLayout, sidePanelWidth],\n );\n\n useEffect(() => {\n sidePanelWidthSnapshotRef.current = sidePanelWidth;\n }, [sidePanelWidth]);\n\n useEffect(() => {\n if (typeof window === 'undefined') {\n return () => {};\n }\n const mediaQuery = window.matchMedia(\n `(max-width: ${SPLIT_BREAKPOINT - 1}px)`,\n );\n const handleMediaChange = () => {\n setIsStackedLayout(mediaQuery.matches);\n };\n\n handleMediaChange();\n mediaQuery.addEventListener('change', handleMediaChange);\n\n return () => {\n mediaQuery.removeEventListener('change', handleMediaChange);\n };\n }, []);\n\n useEffect(() => {\n if (hasSidePanel) {\n clampSidePanelWidth(sidePanelWidth);\n }\n }, [hasSidePanel, sidePanelWidth, clampSidePanelWidth]);\n\n useEffect(() => {\n if (!isStackedLayout && isMobileSidebarOpen) {\n closeMobileSidebar();\n }\n }, [closeMobileSidebar, isMobileSidebarOpen, isStackedLayout]);\n\n useEffect(() => {\n if (!isMobileSidebarOpen) {\n return () => {};\n }\n\n const handleEscape = (event: globalThis.KeyboardEvent) => {\n if (event.key === 'Escape') {\n closeMobileSidebar();\n return;\n }\n\n if (event.key !== 'Tab') {\n return;\n }\n\n const sidebarElement = mobileSidebarRef.current;\n if (sidebarElement == null) {\n return;\n }\n\n const focusableElements = Array.from(\n sidebarElement.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR),\n ).filter((element) => {\n return (\n element.offsetParent != null || element === document.activeElement\n );\n });\n\n const firstElement = focusableElements[0];\n const lastElement = focusableElements[focusableElements.length - 1];\n\n if (firstElement == null || lastElement == null) {\n event.preventDefault();\n return;\n }\n\n if (event.shiftKey && document.activeElement === firstElement) {\n event.preventDefault();\n lastElement.focus();\n return;\n }\n\n if (!event.shiftKey && document.activeElement === lastElement) {\n event.preventDefault();\n firstElement.focus();\n }\n };\n\n const fallbackFocusElement = mobileSidebarToggleRef.current;\n mobileSidebarCloseRef.current?.focus();\n\n window.addEventListener('keydown', handleEscape);\n return () => {\n window.removeEventListener('keydown', handleEscape);\n const previousFocus = mobileSidebarPreviousFocusRef.current;\n if (previousFocus != null && document.contains(previousFocus)) {\n previousFocus.focus();\n } else {\n fallbackFocusElement?.focus();\n }\n mobileSidebarPreviousFocusRef.current = null;\n };\n }, [closeMobileSidebar, isMobileSidebarOpen]);\n\n useEffect(() => {\n return () => {\n const handlers = activeResizeHandlersRef.current;\n if (handlers?.move != null) {\n window.removeEventListener('mousemove', handlers.move);\n window.removeEventListener('touchmove', handlers.move);\n }\n if (handlers?.up != null) {\n window.removeEventListener('mouseup', handlers.up);\n window.removeEventListener('touchend', handlers.up);\n window.removeEventListener('touchcancel', handlers.up);\n }\n };\n }, []);\n\n let currentPath: string | undefined;\n if (typeof window !== 'undefined') {\n currentPath = window.location.pathname;\n }\n\n const renderBreadcrumb = (): JSX.Element | null => {\n if (breadcrumbSlot != null) {\n return <div className={styles.breadcrumbNav}>{breadcrumbSlot}</div>;\n }\n\n if (breadcrumb == null || breadcrumb.length === 0) {\n return null;\n }\n\n const items = breadcrumb.flatMap((item, index) => {\n const isLast = index === breadcrumb.length - 1;\n const key = `${item.href ?? 'crumb'}-${index}`;\n let content: JSX.Element;\n if (item.href != null && !isLast) {\n content = (\n <Link to={item.href} className={styles.breadcrumbLink}>\n {item.label}\n </Link>\n );\n } else {\n let breadcrumbClass = styles.breadcrumbLink;\n if (isLast) {\n breadcrumbClass = styles.breadcrumbCurrent;\n }\n content = <span className={breadcrumbClass}>{item.label}</span>;\n }\n\n const renderedItem = (\n <li key={key} className={styles.breadcrumbItem}>\n {content}\n </li>\n );\n\n if (isLast) {\n return [renderedItem];\n }\n\n return [\n renderedItem,\n <li\n key={`${key}-sep`}\n className={styles.breadcrumbSeparator}\n aria-hidden=\"true\"\n >\n /\n </li>,\n ];\n });\n\n return (\n <nav\n className={styles.breadcrumbNav}\n aria-label={t('navigation.breadcrumb')}\n >\n <ol className={styles.breadcrumbList}>{items}</ol>\n </nav>\n );\n };\n\n const renderActions = (): JSX.Element | null => {\n if (\n actions == null ||\n (actions.main == null && (actions.secondary ?? []).length === 0)\n ) {\n return null;\n }\n\n const secondaryNodes = actions.secondary ?? [];\n\n let mainActionNode: JSX.Element | null = null;\n if (actions.main != null) {\n mainActionNode = (\n <div className={styles.secondaryAction}>{actions.main}</div>\n );\n }\n\n return (\n <div className={styles.actionGroup}>\n {secondaryNodes.map((node, index) => {\n return (\n <div key={`secondary-${index}`} className={styles.secondaryAction}>\n {node}\n </div>\n );\n })}\n {mainActionNode}\n </div>\n );\n };\n\n const renderTabs = (): JSX.Element | null => {\n if (tabs == null || tabs.length === 0) {\n return null;\n }\n\n return (\n <div className={styles.tabsRow}>\n {tabs.map((tab) => {\n const isActive = resolveIsActive(tab, currentPath);\n let tabState: 'default' | 'active' = 'default';\n if (isActive) {\n tabState = 'active';\n }\n let tabMode: 'static' | 'link' = 'link';\n if (tab.href == null) {\n tabMode = 'static';\n }\n const className = styles.tabRecipe({\n state: tabState,\n mode: tabMode,\n });\n const key = tab.id;\n let ariaCurrent: 'page' | undefined;\n if (isActive) {\n ariaCurrent = 'page';\n }\n\n if (tab.href != null) {\n return (\n <Link\n key={key}\n to={tab.href}\n className={className}\n aria-current={ariaCurrent}\n >\n {tab.label}\n </Link>\n );\n }\n\n return (\n <span key={key} className={className} aria-current={ariaCurrent}>\n {tab.label}\n </span>\n );\n })}\n </div>\n );\n };\n\n const handleResizerKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDivElement>) => {\n if (isStackedLayout) {\n return;\n }\n if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') {\n event.preventDefault();\n let delta = 16;\n if (event.key === 'ArrowRight') {\n delta = -16;\n }\n clampSidePanelWidth(sidePanelWidth + delta);\n persistSidePanelWidth(sidePanelWidthSnapshotRef.current);\n }\n },\n [clampSidePanelWidth, isStackedLayout, sidePanelWidth],\n );\n\n let sidePanelNode: JSX.Element | null = null;\n if (hasSidePanel) {\n const sidePanelClasses = [styles.sidePanel, styles.sidePanelSurface];\n let sidePanelStyle: CSSProperties | undefined;\n if (!isStackedLayout) {\n sidePanelClasses.push(styles.sidePanelResizable);\n sidePanelStyle = {\n width: `${sidePanelWidth}px`,\n };\n }\n sidePanelNode = (\n <aside className={cx(...sidePanelClasses)} style={sidePanelStyle}>\n {sidePanel}\n </aside>\n );\n }\n\n let resizerNode: JSX.Element | null = null;\n if (hasSidePanel) {\n let resizerActive = 'false';\n if (isResizingPanel) {\n resizerActive = 'true';\n }\n let resizerMin = MIN_SIDE_PANEL_WIDTH;\n let resizerMax = Math.max(MIN_SIDE_PANEL_WIDTH, sidePanelWidth);\n const pageElement = pageRef.current;\n if (pageElement != null) {\n const { width } = pageElement.getBoundingClientRect();\n const maxWidth = Math.max(\n 0,\n Math.min(resolveMaxSidePanelWidth(width), width - MIN_MAIN_WIDTH),\n );\n resizerMin = Math.min(MIN_SIDE_PANEL_WIDTH, maxWidth);\n if (maxWidth <= 0) {\n resizerMin = 0;\n }\n resizerMax = Math.max(resizerMin, maxWidth);\n }\n resizerNode = (\n <div\n className={cx(\n styles.sidePanelResizer,\n styles.sidePanelResizerHiddenOnMobile,\n )}\n role=\"separator\"\n aria-orientation=\"vertical\"\n aria-label={t('layout.pageShell.resizeSidePanel')}\n aria-valuemin={Math.round(resizerMin)}\n aria-valuemax={Math.round(resizerMax)}\n aria-valuenow={Math.round(sidePanelWidth)}\n tabIndex={0}\n data-active={resizerActive}\n onMouseDown={(event) => {\n event.preventDefault();\n startResizing(event.clientX);\n }}\n onTouchStart={(event) => {\n const touch = event.touches[0];\n if (touch != null) {\n startResizing(touch.clientX);\n }\n }}\n onKeyDown={handleResizerKeyDown}\n />\n );\n }\n\n let sidebarContent = sidebar;\n if (isStackedLayout) {\n sidebarContent = mobileSidebar ?? sidebar;\n }\n const shouldRenderDesktopSidebar = desktopSidebarOpen || isStackedLayout;\n let resolvedOpenDesktopSidebarLabel = openDesktopSidebarLabel;\n resolvedOpenDesktopSidebarLabel ??= t('navigation.pageShell.openNavigation');\n\n return (\n <div className={styles.shell}>\n <div\n className={cx(styles.mobileSidebarBackdrop, {\n [styles.mobileSidebarBackdropOpen]:\n isStackedLayout && isMobileSidebarOpen,\n })}\n aria-hidden=\"true\"\n onClick={closeMobileSidebar}\n />\n {shouldRenderDesktopSidebar && (\n <div\n ref={mobileSidebarRef}\n className={cx(styles.sidebarColumn, styles.sidebarColumnMobile, {\n [styles.sidebarColumnMobileOpen]:\n isStackedLayout && isMobileSidebarOpen,\n })}\n aria-hidden={isStackedLayout && !isMobileSidebarOpen}\n inert={isStackedLayout && !isMobileSidebarOpen}\n >\n <button\n ref={mobileSidebarCloseRef}\n type=\"button\"\n className={styles.mobileSidebarClose}\n onClick={closeMobileSidebar}\n aria-label={t('navigation.pageShell.closeNavigation')}\n >\n <ModalCloseSvg width={18} height={18} aria-hidden=\"true\" />\n </button>\n <div className={styles.sidebarInner}>{sidebarContent}</div>\n </div>\n )}\n <div\n ref={pageRef}\n className={cx(styles.page, {\n [styles.pageWithSidePanel]: hasSidePanel,\n [styles.pageContained]: isContainedScroll,\n })}\n aria-hidden={isStackedLayout && isMobileSidebarOpen}\n inert={isStackedLayout && isMobileSidebarOpen}\n >\n <div\n className={cx(styles.mainColumn, {\n [styles.mainColumnWithSidePanel]: hasSidePanel,\n [styles.mainColumnContained]: isContainedScroll,\n })}\n >\n <div className={styles.header}>\n <div className={styles.headerRow}>\n <div className={styles.headerLeading}>\n {!isStackedLayout && !desktopSidebarOpen && (\n <button\n type=\"button\"\n className={styles.desktopSidebarToggle}\n onClick={onOpenDesktopSidebar}\n aria-label={resolvedOpenDesktopSidebarLabel}\n title={resolvedOpenDesktopSidebarLabel}\n >\n <MenuSvg width={18} height={18} aria-hidden=\"true\" />\n </button>\n )}\n {isStackedLayout && (\n <button\n ref={mobileSidebarToggleRef}\n type=\"button\"\n className={styles.mobileSidebarToggle}\n onClick={openMobileSidebar}\n aria-expanded={isMobileSidebarOpen}\n aria-label={t('navigation.pageShell.openNavigation')}\n >\n <MenuSvg width={18} height={18} aria-hidden=\"true\" />\n </button>\n )}\n {renderBreadcrumb()}\n </div>\n {renderActions()}\n </div>\n {renderTabs()}\n </div>\n <div\n className={cx(\n styles.content,\n containedContentClassName,\n contentClassName,\n )}\n >\n {children}\n </div>\n </div>\n {resizerNode}\n {sidePanelNode}\n </div>\n </div>\n );\n};\n\nexport const __test = {\n readStoredSidePanelWidth,\n resolveMaxSidePanelWidth,\n resolveIsActive,\n} as const;\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  //#region src/focus/focusable.ts
2
2
  var e = "[data-initial-focus], [autofocus]", t = [
3
- "input:not([type=\"hidden\"]):not([type=\"button\"]):not([type=\"submit\"]):not([type=\"reset\"]):not([type=\"file\"]):not([disabled])",
3
+ "input:not([type=\"hidden\"]):not([type=\"button\"]):not([type=\"submit\"]):not([type=\"reset\"]):not([type=\"file\"]):not([type=\"checkbox\"]):not([type=\"radio\"]):not([disabled])",
4
4
  "textarea:not([disabled])",
5
5
  "[contenteditable=\"true\"]"
6
6
  ].join(","), n = [