@k2b/ui 0.32.0 → 0.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/base.css +14 -1
- package/dist/browser/actions/ContextMenu.js +13 -0
- package/dist/browser/actions/ContextMenu.js.map +1 -1
- package/dist/browser/actions/Dropdown.js +173 -102
- package/dist/browser/actions/Dropdown.js.map +1 -1
- package/dist/browser/actions/FilterChip.js +113 -56
- package/dist/browser/actions/FilterChip.js.map +1 -1
- package/dist/browser/actions/SelectionToolbar.js +129 -0
- package/dist/browser/actions/SelectionToolbar.js.map +1 -0
- package/dist/browser/actions/filter-messages.js +26 -2
- package/dist/browser/actions/filter-messages.js.map +1 -1
- package/dist/browser/actions/index.js +1 -0
- package/dist/browser/actions/index.js.map +1 -1
- package/dist/browser/actions/menu-rows.js +23 -3
- package/dist/browser/actions/menu-rows.js.map +1 -1
- package/dist/browser/actions/menu-sheet.js +2 -7
- package/dist/browser/actions/menu-sheet.js.map +1 -1
- package/dist/browser/charts.js +6 -0
- package/dist/browser/charts.js.map +1 -0
- package/dist/browser/chat/ChatComposer.js +616 -421
- package/dist/browser/chat/ChatComposer.js.map +1 -1
- package/dist/browser/chat/chat-messages.js +18 -0
- package/dist/browser/chat/chat-messages.js.map +1 -1
- package/dist/browser/chat/composer-document.js +19 -0
- package/dist/browser/chat/composer-document.js.map +1 -1
- package/dist/browser/chat/index.js.map +1 -1
- package/dist/browser/content/Calendar.js +39 -29
- package/dist/browser/content/Calendar.js.map +1 -1
- package/dist/browser/content/CalendarDayView.js +159 -165
- package/dist/browser/content/CalendarDayView.js.map +1 -1
- package/dist/browser/content/Chart.js +8 -0
- package/dist/browser/content/Chart.js.map +1 -1
- package/dist/browser/content/FileGrid.js +231 -9
- package/dist/browser/content/FileGrid.js.map +1 -1
- package/dist/browser/content/FileTypeIcon.js +15 -0
- package/dist/browser/content/FileTypeIcon.js.map +1 -1
- package/dist/browser/content/FileView.js +11 -4
- package/dist/browser/content/FileView.js.map +1 -1
- package/dist/browser/content/MessageRow.js +627 -343
- package/dist/browser/content/MessageRow.js.map +1 -1
- package/dist/browser/content/ReactionBar.js +20 -1
- package/dist/browser/content/ReactionBar.js.map +1 -1
- package/dist/browser/content/calendar-day-scroll.js +4 -3
- package/dist/browser/content/calendar-day-scroll.js.map +1 -1
- package/dist/browser/content/chart-bar.js +476 -0
- package/dist/browser/content/chart-bar.js.map +1 -0
- package/dist/browser/content/file-list-messages.js +52 -0
- package/dist/browser/content/file-list-messages.js.map +1 -0
- package/dist/browser/content/index.js +2 -2
- package/dist/browser/content/index.js.map +1 -1
- package/dist/browser/feedback/Tooltip.js +31 -14
- package/dist/browser/feedback/Tooltip.js.map +1 -1
- package/dist/browser/feedback/dialog-core.js +6 -0
- package/dist/browser/feedback/dialog-core.js.map +1 -1
- package/dist/browser/inputs/ChoiceList.js +178 -0
- package/dist/browser/inputs/ChoiceList.js.map +1 -0
- package/dist/browser/inputs/ChoiceSlider.js +314 -0
- package/dist/browser/inputs/ChoiceSlider.js.map +1 -0
- package/dist/browser/inputs/ChoiceTiles.js +135 -0
- package/dist/browser/inputs/ChoiceTiles.js.map +1 -0
- package/dist/browser/inputs/ColorChoices.js +120 -0
- package/dist/browser/inputs/ColorChoices.js.map +1 -0
- package/dist/browser/inputs/QrScanner.js +95 -13
- package/dist/browser/inputs/QrScanner.js.map +1 -1
- package/dist/browser/inputs/TextInput.js +19 -14
- package/dist/browser/inputs/TextInput.js.map +1 -1
- package/dist/browser/inputs/index.js +4 -0
- package/dist/browser/inputs/index.js.map +1 -1
- package/dist/browser/inputs/qr-messages.js +2 -0
- package/dist/browser/inputs/qr-messages.js.map +1 -1
- package/dist/browser/internal/radio-keys.js +13 -0
- package/dist/browser/internal/radio-keys.js.map +1 -0
- package/dist/browser/intl/shortcut-messages.js +4 -0
- package/dist/browser/intl/shortcut-messages.js.map +1 -1
- package/dist/browser/intl/shortcut.js +4 -0
- package/dist/browser/intl/shortcut.js.map +1 -1
- package/dist/browser/layout/AnchoredPopover.js +180 -0
- package/dist/browser/layout/AnchoredPopover.js.map +1 -0
- package/dist/browser/layout/AppWorkspace.js +684 -532
- package/dist/browser/layout/AppWorkspace.js.map +1 -1
- package/dist/browser/layout/DetailPanel.js +443 -333
- package/dist/browser/layout/DetailPanel.js.map +1 -1
- package/dist/browser/layout/MobileShell.js +231 -42
- package/dist/browser/layout/MobileShell.js.map +1 -1
- package/dist/browser/layout/Settings.js +283 -175
- package/dist/browser/layout/Settings.js.map +1 -1
- package/dist/browser/layout/SidebarRailHint.js +79 -0
- package/dist/browser/layout/SidebarRailHint.js.map +1 -0
- package/dist/browser/layout/SidebarSwitcher.js +79 -66
- package/dist/browser/layout/SidebarSwitcher.js.map +1 -1
- package/dist/browser/layout/TabBar.js +18 -4
- package/dist/browser/layout/TabBar.js.map +1 -1
- package/dist/browser/layout/app-workspace-controller.js +11 -4
- package/dist/browser/layout/app-workspace-controller.js.map +1 -1
- package/dist/browser/layout/detail-panel-messages.js +4 -2
- package/dist/browser/layout/detail-panel-messages.js.map +1 -1
- package/dist/browser/layout/index.js +3 -1
- package/dist/browser/layout/index.js.map +1 -1
- package/dist/browser/layout/scroll-fade.js +32 -5
- package/dist/browser/layout/scroll-fade.js.map +1 -1
- package/dist/browser/layout/settings-messages.js +26 -2
- package/dist/browser/layout/settings-messages.js.map +1 -1
- package/dist/browser/surfaces/Avatar.js +2 -14
- package/dist/browser/surfaces/Avatar.js.map +1 -1
- package/dist/browser/surfaces/DotStrip.js +70 -0
- package/dist/browser/surfaces/DotStrip.js.map +1 -0
- package/dist/browser/surfaces/NoticeCard.js +46 -30
- package/dist/browser/surfaces/NoticeCard.js.map +1 -1
- package/dist/browser/surfaces/ProgressRing.js +3 -0
- package/dist/browser/surfaces/ProgressRing.js.map +1 -1
- package/dist/browser/surfaces/ResourceCard.js +125 -68
- package/dist/browser/surfaces/ResourceCard.js.map +1 -1
- package/dist/browser/surfaces/index.js +2 -0
- package/dist/browser/surfaces/index.js.map +1 -1
- package/dist/browser/surfaces/person-color.js +18 -0
- package/dist/browser/surfaces/person-color.js.map +1 -0
- package/dist/browser/surfaces/resource-messages.js +8 -4
- package/dist/browser/surfaces/resource-messages.js.map +1 -1
- package/dist/browser/widgets/Widget.js +3 -2
- package/dist/browser/widgets/Widget.js.map +1 -1
- package/dist/ssr/actions/ContextMenu.js +9 -0
- package/dist/ssr/actions/ContextMenu.js.map +1 -1
- package/dist/ssr/actions/Dropdown.js +65 -31
- package/dist/ssr/actions/Dropdown.js.map +1 -1
- package/dist/ssr/actions/FilterChip.js +67 -16
- package/dist/ssr/actions/FilterChip.js.map +1 -1
- package/dist/ssr/actions/SelectionToolbar.js +104 -0
- package/dist/ssr/actions/SelectionToolbar.js.map +1 -0
- package/dist/ssr/actions/filter-messages.js +26 -2
- package/dist/ssr/actions/filter-messages.js.map +1 -1
- package/dist/ssr/actions/index.js +1 -0
- package/dist/ssr/actions/index.js.map +1 -1
- package/dist/ssr/actions/menu-rows.js +23 -3
- package/dist/ssr/actions/menu-rows.js.map +1 -1
- package/dist/ssr/actions/menu-sheet.js +2 -7
- package/dist/ssr/actions/menu-sheet.js.map +1 -1
- package/dist/ssr/charts.js +6 -0
- package/dist/ssr/charts.js.map +1 -0
- package/dist/ssr/chat/ChatComposer.js +184 -76
- package/dist/ssr/chat/ChatComposer.js.map +1 -1
- package/dist/ssr/chat/chat-messages.js +18 -0
- package/dist/ssr/chat/chat-messages.js.map +1 -1
- package/dist/ssr/chat/composer-document.js +19 -0
- package/dist/ssr/chat/composer-document.js.map +1 -1
- package/dist/ssr/chat/index.js.map +1 -1
- package/dist/ssr/content/Calendar.js +40 -31
- package/dist/ssr/content/Calendar.js.map +1 -1
- package/dist/ssr/content/CalendarDayView.js +40 -48
- package/dist/ssr/content/CalendarDayView.js.map +1 -1
- package/dist/ssr/content/Chart.js +8 -0
- package/dist/ssr/content/Chart.js.map +1 -1
- package/dist/ssr/content/FileGrid.js +132 -5
- package/dist/ssr/content/FileGrid.js.map +1 -1
- package/dist/ssr/content/FileTypeIcon.js +15 -0
- package/dist/ssr/content/FileTypeIcon.js.map +1 -1
- package/dist/ssr/content/FileView.js +11 -4
- package/dist/ssr/content/FileView.js.map +1 -1
- package/dist/ssr/content/MessageRow.js +274 -91
- package/dist/ssr/content/MessageRow.js.map +1 -1
- package/dist/ssr/content/ReactionBar.js +20 -1
- package/dist/ssr/content/ReactionBar.js.map +1 -1
- package/dist/ssr/content/calendar-day-scroll.js +4 -3
- package/dist/ssr/content/calendar-day-scroll.js.map +1 -1
- package/dist/ssr/content/chart-bar.js +476 -0
- package/dist/ssr/content/chart-bar.js.map +1 -0
- package/dist/ssr/content/file-list-messages.js +52 -0
- package/dist/ssr/content/file-list-messages.js.map +1 -0
- package/dist/ssr/content/index.js +2 -2
- package/dist/ssr/content/index.js.map +1 -1
- package/dist/ssr/feedback/Tooltip.js +31 -14
- package/dist/ssr/feedback/Tooltip.js.map +1 -1
- package/dist/ssr/feedback/dialog-core.js +6 -0
- package/dist/ssr/feedback/dialog-core.js.map +1 -1
- package/dist/ssr/inputs/ChoiceList.js +95 -0
- package/dist/ssr/inputs/ChoiceList.js.map +1 -0
- package/dist/ssr/inputs/ChoiceSlider.js +191 -0
- package/dist/ssr/inputs/ChoiceSlider.js.map +1 -0
- package/dist/ssr/inputs/ChoiceTiles.js +61 -0
- package/dist/ssr/inputs/ChoiceTiles.js.map +1 -0
- package/dist/ssr/inputs/ColorChoices.js +60 -0
- package/dist/ssr/inputs/ColorChoices.js.map +1 -0
- package/dist/ssr/inputs/QrScanner.js +89 -10
- package/dist/ssr/inputs/QrScanner.js.map +1 -1
- package/dist/ssr/inputs/TextInput.js +17 -2
- package/dist/ssr/inputs/TextInput.js.map +1 -1
- package/dist/ssr/inputs/index.js +4 -0
- package/dist/ssr/inputs/index.js.map +1 -1
- package/dist/ssr/inputs/qr-messages.js +2 -0
- package/dist/ssr/inputs/qr-messages.js.map +1 -1
- package/dist/ssr/internal/radio-keys.js +13 -0
- package/dist/ssr/internal/radio-keys.js.map +1 -0
- package/dist/ssr/intl/shortcut-messages.js +4 -0
- package/dist/ssr/intl/shortcut-messages.js.map +1 -1
- package/dist/ssr/intl/shortcut.js +4 -0
- package/dist/ssr/intl/shortcut.js.map +1 -1
- package/dist/ssr/layout/AnchoredPopover.js +142 -0
- package/dist/ssr/layout/AnchoredPopover.js.map +1 -0
- package/dist/ssr/layout/AppWorkspace.js +287 -141
- package/dist/ssr/layout/AppWorkspace.js.map +1 -1
- package/dist/ssr/layout/DetailPanel.js +181 -108
- package/dist/ssr/layout/DetailPanel.js.map +1 -1
- package/dist/ssr/layout/MobileShell.js +118 -24
- package/dist/ssr/layout/MobileShell.js.map +1 -1
- package/dist/ssr/layout/Settings.js +122 -45
- package/dist/ssr/layout/Settings.js.map +1 -1
- package/dist/ssr/layout/SidebarRailHint.js +79 -0
- package/dist/ssr/layout/SidebarRailHint.js.map +1 -0
- package/dist/ssr/layout/SidebarSwitcher.js +13 -3
- package/dist/ssr/layout/SidebarSwitcher.js.map +1 -1
- package/dist/ssr/layout/TabBar.js +11 -3
- package/dist/ssr/layout/TabBar.js.map +1 -1
- package/dist/ssr/layout/app-workspace-controller.js +11 -4
- package/dist/ssr/layout/app-workspace-controller.js.map +1 -1
- package/dist/ssr/layout/detail-panel-messages.js +4 -2
- package/dist/ssr/layout/detail-panel-messages.js.map +1 -1
- package/dist/ssr/layout/index.js +3 -1
- package/dist/ssr/layout/index.js.map +1 -1
- package/dist/ssr/layout/scroll-fade.js +32 -5
- package/dist/ssr/layout/scroll-fade.js.map +1 -1
- package/dist/ssr/layout/settings-messages.js +26 -2
- package/dist/ssr/layout/settings-messages.js.map +1 -1
- package/dist/ssr/surfaces/Avatar.js +2 -14
- package/dist/ssr/surfaces/Avatar.js.map +1 -1
- package/dist/ssr/surfaces/DotStrip.js +31 -0
- package/dist/ssr/surfaces/DotStrip.js.map +1 -0
- package/dist/ssr/surfaces/NoticeCard.js +21 -12
- package/dist/ssr/surfaces/NoticeCard.js.map +1 -1
- package/dist/ssr/surfaces/ProgressRing.js +3 -0
- package/dist/ssr/surfaces/ProgressRing.js.map +1 -1
- package/dist/ssr/surfaces/ResourceCard.js +40 -15
- package/dist/ssr/surfaces/ResourceCard.js.map +1 -1
- package/dist/ssr/surfaces/index.js +2 -0
- package/dist/ssr/surfaces/index.js.map +1 -1
- package/dist/ssr/surfaces/person-color.js +18 -0
- package/dist/ssr/surfaces/person-color.js.map +1 -0
- package/dist/ssr/surfaces/resource-messages.js +8 -4
- package/dist/ssr/surfaces/resource-messages.js.map +1 -1
- package/dist/ssr/widgets/Widget.js +3 -2
- package/dist/ssr/widgets/Widget.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/types/actions/ContextMenu.d.ts +5 -0
- package/dist/types/actions/Dropdown.d.ts +19 -0
- package/dist/types/actions/FilterChip.d.ts +11 -0
- package/dist/types/actions/SelectionToolbar.d.ts +38 -0
- package/dist/types/actions/filter-messages.d.ts +12 -0
- package/dist/types/actions/index.d.ts +2 -0
- package/dist/types/actions/menu-rows.d.ts +7 -2
- package/dist/types/charts.d.ts +5 -0
- package/dist/types/chat/ChatComposer.d.ts +28 -0
- package/dist/types/chat/chat-messages.d.ts +9 -0
- package/dist/types/chat/composer-document.d.ts +5 -0
- package/dist/types/chat/index.d.ts +1 -1
- package/dist/types/content/Calendar.d.ts +7 -0
- package/dist/types/content/Chart.d.ts +2 -1
- package/dist/types/content/FileGrid.d.ts +43 -3
- package/dist/types/content/FileTypeIcon.d.ts +10 -0
- package/dist/types/content/FileView.d.ts +5 -1
- package/dist/types/content/MessageRow.d.ts +66 -2
- package/dist/types/content/calendar-day-scroll.d.ts +2 -1
- package/dist/types/content/chart-bar.d.ts +60 -0
- package/dist/types/content/file-list-messages.d.ts +24 -0
- package/dist/types/content/index.d.ts +4 -4
- package/dist/types/feedback/Tooltip.d.ts +8 -2
- package/dist/types/feedback/dialog-core.d.ts +3 -0
- package/dist/types/inputs/ChoiceList.d.ts +28 -0
- package/dist/types/inputs/ChoiceSlider.d.ts +36 -0
- package/dist/types/inputs/ChoiceTiles.d.ts +25 -0
- package/dist/types/inputs/ColorChoices.d.ts +19 -0
- package/dist/types/inputs/index.d.ts +8 -0
- package/dist/types/inputs/qr-messages.d.ts +1 -0
- package/dist/types/internal/radio-keys.d.ts +5 -0
- package/dist/types/intl/shortcut-messages.d.ts +2 -0
- package/dist/types/layout/AnchoredPopover.d.ts +31 -0
- package/dist/types/layout/AppWorkspace.d.ts +12 -0
- package/dist/types/layout/DetailPanel.d.ts +17 -0
- package/dist/types/layout/MobileShell.d.ts +55 -5
- package/dist/types/layout/Settings.d.ts +22 -0
- package/dist/types/layout/SidebarRailHint.d.ts +26 -0
- package/dist/types/layout/TabBar.d.ts +5 -0
- package/dist/types/layout/detail-panel-messages.d.ts +1 -0
- package/dist/types/layout/index.d.ts +5 -3
- package/dist/types/layout/scroll-fade.d.ts +5 -0
- package/dist/types/layout/settings-messages.d.ts +12 -0
- package/dist/types/surfaces/DotStrip.d.ts +22 -0
- package/dist/types/surfaces/NoticeCard.d.ts +3 -0
- package/dist/types/surfaces/ProgressRing.d.ts +2 -1
- package/dist/types/surfaces/ResourceCard.d.ts +9 -0
- package/dist/types/surfaces/index.d.ts +4 -1
- package/dist/types/surfaces/person-color.d.ts +10 -0
- package/dist/types/surfaces/resource-messages.d.ts +2 -0
- package/dist/types/widgets/Widget.d.ts +3 -2
- package/package.json +7 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["content/Chart.tsx"],"sourcesContent":["import type { MapViewport } from \"@k2b/stdlib\";\nimport { charts } from \"@k2b/stdlib\";\nimport type { JSX } from \"solid-js\";\nimport { createEffect, createMemo, createSignal, createUniqueId, For, onCleanup, onMount, Show, splitProps, untrack } from \"solid-js\";\nimport { isServer } from \"solid-js/web\";\nimport { IconButton } from \"../actions/Button\";\nimport { suppressTextSelection } from \"../internal/text-selection\";\nimport { useLocale } from \"../intl/locale\";\nimport { useUiMessages } from \"../intl/messages\";\nimport type { ChartCursor } from \"./chart-cursor\";\nimport { createChartInspection } from \"./chart-inspection\";\nimport {\n type ChartDatumRef,\n type ChartKind,\n type ChartSelection,\n type ChartTooltipFormatter,\n closeChartInspectionOnOutside,\n} from \"./chart-inspection-core\";\nimport { lineGapsSvg } from \"./chart-line-gaps\";\nimport { DEFAULT_MAP_VIEWPORT, normalizeMapViewport, panMapViewport, zoomMapViewport } from \"./chart-map-viewport\";\nimport { useChartMessages } from \"./chart-messages\";\nimport {\n panStateTimelineViewport,\n renderStateTimelineSvg,\n type StateTimelineChartOptions,\n type StateTimelineDomain,\n stateTimelineDomain,\n stateTimelineHeight,\n zoomStateTimelineViewport,\n} from \"./chart-state-timeline\";\nimport { responsiveChartSvg, responsiveMapSvg, selectedChartSvg } from \"./chart-svg\";\nimport { useViewportMessages } from \"./viewport-messages\";\n\n/**\n * Chart — minimal Solid wrapper around `stdlib.charts`.\n *\n * **Live-update story.** `charts.<kind>(opts)` returns an SVG string;\n * Solid's `innerHTML` is reactive, so any time a prop (signal, store\n * slice, derived value) changes, the SVG re-renders. No manual\n * subscription, no imperative DOM patching. Trade-off: every change\n * is a full SVG re-build, not a diff — fine for dashboard cadences\n * (poll, websocket, store updates). Don't use this for 60fps streaming.\n *\n * **Sizing.** The server and browser render the same logical viewBox. CSS\n * fits Cartesian plots to the container and preserves text/marker sizes;\n * maps fit the whole world and zoom uniformly across the full plot; pies, donuts and gauges retain\n * their aspect ratio. No measurement\n * or hydration redraw is needed. The caller sizes the wrapper, for example\n * `style={{ height: \"14rem\" }}`. State timelines derive their default height\n * from the row count and legend via `stateTimelineHeight()`.\n *\n * **Why so thin.** The props are a discriminated union over each\n * stdlib chart function — `kind: \"line\"` brings in exactly the params\n * `charts.line` expects, `kind: \"bar\"` brings in `charts.bar`'s, etc.\n * Options stay aligned with stdlib without renaming. Every chart provides\n * renderer-owned inspection, tooltips and optional selection by default.\n * `interactive` adds bounded pan / zoom and reset controls to maps and state timelines.\n * If stdlib gains a new option, it's automatically available at every\n * callsite.\n *\n * **Theming.** stdlib charts use `currentColor` for axes / ticks /\n * tick labels — set the wrapping element's `color` and everything\n * inherits. Series colors come from `--stdlib-chart-c1..c8` CSS\n * custom properties; override on the parent for per-chart palettes.\n *\n * ```tsx\n * <Chart kind=\"line\" style={{ height: \"12rem\" }}\n * series={[{ data: points() }]}\n * yAxis={{ format: v => `€${v}k` }} />\n *\n * <Chart kind=\"donut\" style={{ height: \"12rem\" }} data={slices()} />\n *\n * <Chart kind=\"sparkline\" style={{ width: \"6rem\", height: \"1.5rem\" }} data={trend()} />\n *\n * <Chart kind=\"map\" style={{ height: \"16rem\" }} series={locations()} interactive />\n * ```\n */\n\n/** All chart kinds shipped by `stdlib.charts`. */\nexport type { ChartKind } from \"./chart-inspection-core\";\n\nexport type ChartLabels = Partial<{\n empty: string;\n series: string;\n interactiveMap: string;\n interactiveTimeline: string;\n interactiveLine: string;\n interactiveChart: string;\n zoomIn: string;\n zoomOut: string;\n resetMap: string;\n resetTimeline: string;\n}>;\n\n/**\n * Per-kind props: `kind` discriminator + the exact options that\n * `charts.<kind>` accepts, **minus** `width` / `height` (the wrapper\n * owns those — CSS fits a stable coordinate space to the box). Solid's\n * component model handles discriminated unions natively, so callsites\n * get full type safety.\n */\nexport type ChartProps = {\n [K in ChartKind]: {\n kind: K;\n class?: string;\n style?: JSX.CSSProperties | string;\n labels?: ChartLabels;\n /**\n * Navigation for maps and state timelines: pan, zoom and reset controls.\n * Arrows pan; Alt+arrows inspect. Every chart shows tooltips and keyboard\n * inspection without this prop.\n */\n interactive?: boolean;\n onSelect?: (selection: ChartSelection) => void;\n /** Controlled highlight; indices belong to this exact input snapshot. */\n selected?: ChartDatumRef | null;\n /** Customize the always-on tooltip with a title and labeled text rows. */\n tooltip?: ChartTooltipFormatter;\n /** Optional shared X cursor for line charts. */\n cursor?: ChartCursor;\n } & (K extends \"map\"\n ? {\n /** Target when zooming in from the world view. Defaults to Europe (50, 10). */\n zoomFocus?: Pick<MapViewport, \"latitude\" | \"longitude\">;\n }\n : {}) &\n (K extends \"line\"\n ? {\n /** Largest connected X distance; positive, finite, without area/errorBand fills. */ maxGap?: number;\n /** Wrap the legend above the plot inside the caller's total chart height. Requires legend=true. */\n legendPlacement?: \"top-start\";\n }\n : {}) &\n (K extends \"stateTimeline\" ? StateTimelineChartOptions : Omit<Parameters<(typeof charts)[K]>[0], \"width\" | \"height\" | \"inspect\">);\n}[ChartKind];\n\n/** Pure renderer options: component layout, events and inspection are configured elsewhere. */\nexport type ChartRenderOptions = {\n [K in ChartKind]: Omit<\n Extract<ChartProps, { kind: K }>,\n \"class\" | \"style\" | \"labels\" | \"interactive\" | \"onSelect\" | \"selected\" | \"tooltip\" | \"cursor\" | \"legendPlacement\"\n >;\n}[ChartKind];\n\n/** Keep the fixed 28-unit bar-gauge rows inside the shared SSR/browser coordinate space. */\nexport const chartRenderHeight = (props: ChartRenderOptions): number => {\n if (props.kind === \"stateTimeline\") return stateTimelineHeight(props.rows.length, props.legend !== false);\n if (props.kind === \"barGauge\") return Math.max(280, (props.title || props.subtitle ? 42 : 16) + props.data.length * 28 + 14);\n return 280;\n};\n\n/**\n * Internal — strips wrapper-only keys from props and forwards the\n * rest (plus logical size) to `charts[kind]`. The `any` is the\n * price for dispatching one function call across 14 different option\n * types; an explicit per-kind switch would type it but balloon the\n * component for no runtime benefit.\n */\nexport const renderChartSvg = (\n props: ChartProps,\n width: number,\n height: number,\n mapViewport?: MapViewport,\n timelineViewport?: StateTimelineDomain,\n): string => {\n const {\n kind,\n class: _class,\n style: _style,\n labels: _labels,\n interactive: _interactive,\n onSelect: _onSelect,\n selected: _selected,\n tooltip: _tooltip,\n cursor: _cursor,\n zoomFocus: _zoomFocus,\n legendPlacement: _legendPlacement,\n ...opts\n } = props as ChartProps & {\n legendPlacement?: \"top-start\";\n interactive?: boolean;\n zoomFocus?: Pick<MapViewport, \"latitude\" | \"longitude\">;\n };\n if (kind === \"stateTimeline\") {\n return responsiveChartSvg(\n renderStateTimelineSvg({\n ...(opts as StateTimelineChartOptions),\n width,\n height,\n viewport: timelineViewport,\n interactive: true,\n }),\n );\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let svg = (charts[kind] as (o: unknown) => string)({\n ...(opts as any),\n ...(props.kind === \"line\" && props.legend && props.legendPlacement === \"top-start\" ? { legend: false } : {}),\n ...(kind === \"map\" ? { viewport: DEFAULT_MAP_VIEWPORT } : {}),\n width,\n height,\n inspect: true,\n });\n if (props.kind === \"line\" && props.maxGap !== undefined) {\n if (props.area || props.errorBand) throw new Error(\"Chart maxGap does not support area or errorBand fills\");\n svg = lineGapsSvg(svg, props.maxGap, props);\n }\n if (props.kind === \"map\") return responsiveMapSvg(svg, width, height, normalizeMapViewport(mapViewport ?? props.viewport));\n return preservesAspectRatio(kind) ? svg : responsiveChartSvg(svg);\n};\n\nconst preservesAspectRatio = (kind: ChartKind) => kind === \"map\" || kind === \"pie\" || kind === \"donut\" || kind === \"gauge\";\n\n/** Empty-data short-circuit. Kept per-kind because stdlib's payload\n * key differs (series vs data vs groups). We're conservative: only\n * block on truly empty inputs; partially-filled series get rendered\n * as-is and stdlib handles the gaps. */\nconst isEmpty = (props: ChartProps): boolean => {\n if (props.kind === \"line\" || props.kind === \"scatter\") {\n return !props.series?.length || props.series.every((s) => !s.data.length);\n }\n if (props.kind === \"bar\" || props.kind === \"donut\" || props.kind === \"pie\") {\n return !props.data?.length;\n }\n if (props.kind === \"histogram\" || props.kind === \"sparkline\") {\n return !props.data?.length;\n }\n if (props.kind === \"boxplot\") {\n return !props.groups?.length;\n }\n if (props.kind === \"stateTimeline\") {\n return !props.rows?.length || props.rows.every((row) => !row.intervals.length);\n }\n return false;\n};\n\nconst Chart = (props: ChartProps): JSX.Element => {\n const [, drawingProps] = splitProps(props, [\"selected\", \"onSelect\", \"tooltip\", \"cursor\"]);\n const messages = useUiMessages();\n const chartMessages = useChartMessages();\n const viewportMessages = useViewportMessages();\n const locale = useLocale();\n let containerRef: HTMLDivElement | undefined;\n let chartTooltipRef: HTMLSpanElement | undefined;\n let lineAnchorRef: HTMLSpanElement | undefined;\n // One deterministic coordinate space on the server and client. CSS fits the\n // SVG to its box; hydration must never replace it with measured geometry.\n const size = () => ({\n width: 480,\n height: chartRenderHeight(props),\n });\n const topLegend = () => props.kind === \"line\" && props.legend === true && props.legendPlacement === \"top-start\";\n const legendSeries = () => (props.kind === \"line\" ? props.series : []);\n const dimensions = () => containerRef?.getBoundingClientRect() ?? size();\n const initialMapViewport = props.kind === \"map\" ? normalizeMapViewport(props.viewport) : DEFAULT_MAP_VIEWPORT;\n const [mapViewport, setMapViewport] = createSignal<MapViewport>(initialMapViewport);\n const initialTimelineViewport =\n props.kind === \"stateTimeline\" ? stateTimelineDomain(props.rows, props.domain) : ([0, 1] as StateTimelineDomain);\n const [timelineViewport, setTimelineViewport] = createSignal<StateTimelineDomain>(initialTimelineViewport);\n const [dragging, setDragging] = createSignal(false);\n const chartTooltipId = `k2b-chart-tooltip-${createUniqueId()}`;\n let timelineViewportLocallyChanged = false;\n let drag:\n | {\n pointerId: number;\n x: number;\n y: number;\n width: number;\n height: number;\n viewport: MapViewport;\n }\n | undefined;\n let timelineDrag:\n | {\n pointerId: number;\n x: number;\n width: number;\n viewport: StateTimelineDomain;\n }\n | undefined;\n let pointerFrame: number | undefined;\n let pendingPointer: { pointerId: number; clientX: number; clientY: number } | undefined;\n\n const interactiveMap = () => props.kind === \"map\" && props.interactive === true;\n const interactiveTimeline = () => props.kind === \"stateTimeline\" && props.interactive === true;\n const draggable = () => interactiveMap() || interactiveTimeline();\n const labels = () => props.labels ?? {};\n const accessibleName = () => {\n const override =\n props.kind === \"map\"\n ? labels().interactiveMap\n : props.kind === \"stateTimeline\"\n ? labels().interactiveTimeline\n : props.kind === \"line\"\n ? labels().interactiveLine\n : labels().interactiveChart;\n const title = \"title\" in props && typeof props.title === \"string\" && props.title.trim() ? props.title : undefined;\n const valueLabel = (props.kind === \"stat\" || props.kind === \"gauge\") && props.label?.trim() ? props.label : undefined;\n const fallback =\n props.kind === \"map\"\n ? chartMessages().interactiveMap\n : props.kind === \"stateTimeline\"\n ? chartMessages().interactiveTimeline\n : props.kind === \"line\"\n ? chartMessages().interactiveLineChart\n : chartMessages().interactiveChart;\n return override ?? title ?? valueLabel ?? fallback;\n };\n const timelineFullDomain = (): StateTimelineDomain =>\n props.kind === \"stateTimeline\" ? stateTimelineDomain(props.rows, props.domain) : [0, 1];\n\n createEffect(() => {\n if (props.kind === \"map\") {\n setMapViewport(normalizeMapViewport(props.viewport));\n }\n });\n\n createEffect(() => {\n if (props.kind === \"stateTimeline\" && !timelineViewportLocallyChanged) {\n setTimelineViewport(timelineFullDomain());\n }\n });\n\n const updateTimelineViewport = (update: (current: StateTimelineDomain) => StateTimelineDomain) => {\n timelineViewportLocallyChanged = true;\n setTimelineViewport(update);\n };\n\n const mapDimensions = () => {\n const viewportElement = containerRef?.querySelector<SVGSVGElement>(\".stdlib-chart-map-viewport\");\n const matrix = viewportElement?.getScreenCTM?.();\n const box = viewportElement?.viewBox?.baseVal;\n if (matrix && box?.width && box.height) {\n return { width: box.width * Math.hypot(matrix.a, matrix.b), height: box.height * Math.hypot(matrix.c, matrix.d) };\n }\n const rect = viewportElement?.getBoundingClientRect();\n if (rect && rect.width > 0 && rect.height > 0) {\n return { width: rect.width, height: rect.height };\n }\n return dimensions();\n };\n\n const zoom = (delta: number) => {\n closeChartTooltip();\n if (interactiveMap()) {\n setMapViewport((current) => zoomMapViewport(current, delta, props.kind === \"map\" ? props.zoomFocus : undefined));\n } else if (interactiveTimeline()) {\n updateTimelineViewport((current) => zoomStateTimelineViewport(current, timelineFullDomain(), delta));\n }\n };\n\n const reset = () => {\n closeChartTooltip();\n if (interactiveMap() && props.kind === \"map\") {\n setMapViewport(normalizeMapViewport(props.viewport));\n }\n if (interactiveTimeline()) {\n timelineViewportLocallyChanged = false;\n setTimelineViewport(timelineFullDomain());\n }\n };\n\n const handlePointerDown: JSX.EventHandlerUnion<HTMLDivElement, PointerEvent> = (event) => {\n inspection.down(event);\n if (!draggable() || event.button !== 0 || (event.target as Element).closest(\"button, a\")) {\n return;\n }\n closeChartTooltip();\n // The pointer's own pointerup or pointercancel ends the hold.\n suppressTextSelection(event.pointerId);\n if (interactiveTimeline()) {\n timelineDrag = {\n pointerId: event.pointerId,\n x: event.clientX,\n width: Math.max(1, event.currentTarget.getBoundingClientRect().width),\n viewport: timelineViewport(),\n };\n event.currentTarget.setPointerCapture(event.pointerId);\n setDragging(true);\n return;\n }\n const dimensions = mapDimensions();\n drag = {\n pointerId: event.pointerId,\n x: event.clientX,\n y: event.clientY,\n width: dimensions.width,\n height: dimensions.height,\n viewport: mapViewport(),\n };\n event.currentTarget.setPointerCapture(event.pointerId);\n setDragging(true);\n };\n\n const flushPointerMove = () => {\n if (pointerFrame !== undefined) {\n cancelAnimationFrame(pointerFrame);\n pointerFrame = undefined;\n }\n const sample = pendingPointer;\n pendingPointer = undefined;\n if (!sample) return;\n const start = timelineDrag ?? drag;\n if (start && Math.hypot(sample.clientX - start.x, sample.clientY - (\"y\" in start ? start.y : sample.clientY)) <= 6) return;\n const activeTimelineDrag = timelineDrag;\n if (activeTimelineDrag?.pointerId === sample.pointerId) {\n updateTimelineViewport(() =>\n panStateTimelineViewport(\n activeTimelineDrag.viewport,\n timelineFullDomain(),\n sample.clientX - activeTimelineDrag.x,\n activeTimelineDrag.width,\n ),\n );\n return;\n }\n if (!drag || drag.pointerId !== sample.pointerId) return;\n setMapViewport(panMapViewport(drag.viewport, sample.clientX - drag.x, sample.clientY - drag.y, drag.width, drag.height));\n };\n\n const handlePointerMove: JSX.EventHandlerUnion<HTMLDivElement, PointerEvent> = (event) => {\n inspection.move(event);\n if (timelineDrag?.pointerId !== event.pointerId && drag?.pointerId !== event.pointerId) return;\n pendingPointer = { pointerId: event.pointerId, clientX: event.clientX, clientY: event.clientY };\n if (pointerFrame !== undefined) return;\n pointerFrame = requestAnimationFrame(flushPointerMove);\n };\n\n const stopDragging: JSX.EventHandlerUnion<HTMLDivElement, PointerEvent> = (event) => {\n if (pendingPointer?.pointerId === event.pointerId) flushPointerMove();\n if (timelineDrag?.pointerId === event.pointerId) {\n if (event.currentTarget.hasPointerCapture(event.pointerId)) {\n event.currentTarget.releasePointerCapture(event.pointerId);\n }\n timelineDrag = undefined;\n setDragging(false);\n return;\n }\n if (!drag || drag.pointerId !== event.pointerId) return;\n if (event.currentTarget.hasPointerCapture(event.pointerId)) {\n event.currentTarget.releasePointerCapture(event.pointerId);\n }\n drag = undefined;\n setDragging(false);\n };\n\n const handleWheel: JSX.EventHandlerUnion<HTMLDivElement, WheelEvent> = (event) => {\n if (interactiveMap() && (event.ctrlKey || event.metaKey)) {\n event.preventDefault();\n zoom(event.deltaY < 0 ? 1 : -1);\n return;\n }\n if (!interactiveTimeline()) return;\n if (event.ctrlKey || event.metaKey) {\n event.preventDefault();\n const rect = event.currentTarget.getBoundingClientRect();\n const anchor = rect.width > 0 ? (event.clientX - rect.left) / rect.width : 0.5;\n updateTimelineViewport((current) => zoomStateTimelineViewport(current, timelineFullDomain(), event.deltaY < 0 ? 1 : -1, anchor));\n } else if (event.shiftKey) {\n event.preventDefault();\n updateTimelineViewport((current) =>\n panStateTimelineViewport(current, timelineFullDomain(), -event.deltaY, event.currentTarget.getBoundingClientRect().width),\n );\n }\n };\n\n const handleKeyDown: JSX.EventHandlerUnion<HTMLDivElement, KeyboardEvent> = (event) => {\n if (inspection.key(event)) return;\n if (!draggable() || event.target !== containerRef) return;\n if (event.key === \"+\" || event.key === \"=\") {\n event.preventDefault();\n zoom(1);\n return;\n }\n if (event.key === \"-\" || event.key === \"_\") {\n event.preventDefault();\n zoom(-1);\n return;\n }\n if (event.key === \"0\" || event.key === \"Home\") {\n event.preventDefault();\n reset();\n return;\n }\n if (interactiveTimeline() && (event.key === \"ArrowLeft\" || event.key === \"ArrowRight\")) {\n event.preventDefault();\n updateTimelineViewport((current) =>\n panStateTimelineViewport(\n current,\n timelineFullDomain(),\n event.key === \"ArrowLeft\" ? 80 : -80,\n event.currentTarget.getBoundingClientRect().width,\n ),\n );\n return;\n }\n const delta: readonly [number, number] | undefined = {\n ArrowLeft: [40, 0],\n ArrowRight: [-40, 0],\n ArrowUp: [0, 40],\n ArrowDown: [0, -40],\n }[event.key] as readonly [number, number] | undefined;\n if (!delta) return;\n event.preventDefault();\n const dimensions = mapDimensions();\n setMapViewport((current) => panMapViewport(current, delta[0], delta[1], dimensions.width, dimensions.height));\n };\n\n const inspection = createChartInspection({\n container: () => containerRef,\n cursor: () => props.cursor,\n tooltip: () => chartTooltipRef,\n anchor: () => lineAnchorRef,\n kind: () => props.kind,\n enabled: () => !isEmpty(props),\n select: (selection) => props.onSelect?.(selection),\n format: (selection) => {\n if (props.tooltip) return props.tooltip(selection);\n const fields = chartMessages().chartFields;\n const format = new Intl.NumberFormat(locale(), { maximumFractionDigits: 6 });\n return {\n title:\n selection.datum.label ??\n (selection.datum.seriesIndex !== undefined\n ? `${labels().series ?? chartMessages().series} ${selection.datum.seriesIndex + 1}`\n : undefined),\n rows: selection.datum.values.map((field) => ({\n label:\n selection.kind === \"line\" && field.key === \"y\"\n ? (selection.datum.label ?? labels().series ?? chartMessages().series)\n : fields({ key: field.key }),\n value:\n field.formatted ??\n (field.key === \"upperInclusive\"\n ? field.value === \"true\"\n ? messages().yes\n : messages().no\n : typeof field.value === \"number\"\n ? `${format.format(field.value)}${field.key === \"percent\" ? \"%\" : \"\"}`\n : field.value),\n })),\n };\n },\n });\n const closeChartTooltip = () => inspection.close();\n const svgMarkup = createMemo(() =>\n renderChartSvg(\n drawingProps,\n size().width,\n size().height,\n interactiveMap() ? mapViewport() : undefined,\n interactiveTimeline() ? timelineViewport() : undefined,\n ),\n );\n createEffect(() => {\n svgMarkup();\n inspection.invalidate();\n untrack(() => inspection.selectDatum(props.selected));\n });\n\n createEffect(() => inspection.selectDatum(props.selected));\n\n onCleanup(() => {\n inspection.close();\n if (pointerFrame !== undefined) cancelAnimationFrame(pointerFrame);\n pointerFrame = undefined;\n pendingPointer = undefined;\n });\n\n onMount(() => {\n if (!containerRef) return;\n onCleanup(\n closeChartInspectionOnOutside({\n container: () => containerRef,\n tooltip: () => chartTooltipRef,\n close: closeChartTooltip,\n }),\n );\n });\n\n const chartStyle = () =>\n props.style ??\n (props.kind === \"stateTimeline\"\n ? {\n height: `${stateTimelineHeight(props.rows.length, props.legend !== false)}px`,\n }\n : undefined);\n\n const control = (label: string, shortcut: string, icon: string, action: () => void) => (\n <IconButton variant=\"secondary\" label={label} tooltip={`${label} (${shortcut})`} onClick={action}>\n <i class={`ti ${icon}`} aria-hidden=\"true\" />\n </IconButton>\n );\n\n return (\n <Show\n when={!isEmpty(props)}\n fallback={\n <div ref={containerRef} class={`k2b-chart k2b-chart__empty ${props.class ?? \"\"}`} style={chartStyle()}>\n {labels().empty ?? messages().noData}\n </div>\n }\n >\n {/* CSS fits the server-rendered SVG to the caller's box. Only changes\n to chart data/options rebuild the SVG; resizing does not. */}\n <div\n ref={containerRef}\n class={`k2b-chart ${props.class ?? \"\"}`}\n data-chart-kind={props.kind}\n data-legend-placement={topLegend() ? \"top-start\" : undefined}\n data-drag={draggable() ? (dragging() ? \"active\" : \"idle\") : undefined}\n data-crosshair={!draggable() && props.kind === \"line\" ? \"true\" : undefined}\n data-interactive=\"true\"\n style={chartStyle()}\n role=\"group\"\n aria-label={accessibleName()}\n aria-description={accessibleName() !== chartMessages().interactiveChart ? chartMessages().interactiveChart : undefined}\n tabIndex={0}\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={stopDragging}\n onPointerCancel={stopDragging}\n onClick={inspection.click}\n onPointerLeave={inspection.leave}\n onFocusIn={inspection.focus}\n onFocusOut={closeChartTooltip}\n onWheel={handleWheel}\n onKeyDown={handleKeyDown}\n >\n <Show when={topLegend()}>\n <div class=\"k2b-chart__legend\" role=\"group\" aria-label={chartMessages().chartLegend} tabIndex={0}>\n <For each={legendSeries()}>\n {(series, index) => (\n <span class=\"k2b-chart__legend-item\">\n {/* Use the renderer's actual series classes/defaults, including consumer palette overrides. */}\n <svg\n class={`stdlib-chart k2b-chart__legend-swatch ${props.kind === \"line\" ? (props.className ?? \"\") : \"\"}`}\n viewBox=\"0 0 10 10\"\n width=\"10\"\n height=\"10\"\n aria-hidden=\"true\"\n >\n <rect x=\"1\" y=\"1\" width=\"8\" height=\"8\" rx=\"2\" class={`stdlib-chart-series-${index() % 8}`} />\n </svg>\n <span>{series.label && series.label.length > 0 ? series.label : `Series ${index() + 1}`}</span>\n </span>\n )}\n </For>\n </div>\n </Show>\n <div\n class=\"k2b-chart__svg\"\n data-stretch={!preservesAspectRatio(props.kind) ? \"true\" : undefined}\n style={{\n \"--k2b-chart-width\": `${size().width}px`,\n \"--k2b-chart-height\": `${size().height}px`,\n \"aspect-ratio\": `${size().width} / ${size().height}`,\n }}\n innerHTML={isServer ? selectedChartSvg(svgMarkup(), props.selected) : svgMarkup()}\n />\n <span ref={lineAnchorRef} class=\"k2b-chart__anchor\" aria-hidden=\"true\" />\n <span\n id={chartTooltipId}\n ref={chartTooltipRef}\n role=\"tooltip\"\n popover=\"manual\"\n data-instant=\"true\"\n class=\"k2b-tooltip k2b-chart__tooltip\"\n />\n <Show when={draggable()}>\n <div class=\"k2b-chart__controls\">\n {control(labels().zoomIn ?? viewportMessages().zoomIn, \"+\", \"ti-plus\", () => zoom(1))}\n {control(labels().zoomOut ?? viewportMessages().zoomOut, \"-\", \"ti-minus\", () => zoom(-1))}\n {control(\n interactiveMap()\n ? (labels().resetMap ?? chartMessages().resetMapView)\n : (labels().resetTimeline ?? chartMessages().resetTimelineView),\n \"0\",\n \"ti-focus-centered\",\n reset,\n )}\n </div>\n </Show>\n </div>\n </Show>\n );\n};\n\nexport default Chart;\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":[],"sources":["content/Chart.tsx"],"sourcesContent":["import type { MapViewport } from \"@k2b/stdlib\";\nimport { charts } from \"@k2b/stdlib\";\nimport type { JSX } from \"solid-js\";\nimport { createEffect, createMemo, createSignal, createUniqueId, For, onCleanup, onMount, Show, splitProps, untrack } from \"solid-js\";\nimport { isServer } from \"solid-js/web\";\nimport { IconButton } from \"../actions/Button\";\nimport { suppressTextSelection } from \"../internal/text-selection\";\nimport { useLocale } from \"../intl/locale\";\nimport { useUiMessages } from \"../intl/messages\";\nimport { type BarChartOptions, barChartLayout, renderBarChartSvg } from \"./chart-bar\";\nimport type { ChartCursor } from \"./chart-cursor\";\nimport { createChartInspection } from \"./chart-inspection\";\nimport {\n type ChartDatumRef,\n type ChartKind,\n type ChartSelection,\n type ChartTooltipFormatter,\n closeChartInspectionOnOutside,\n} from \"./chart-inspection-core\";\nimport { lineGapsSvg } from \"./chart-line-gaps\";\nimport { DEFAULT_MAP_VIEWPORT, normalizeMapViewport, panMapViewport, zoomMapViewport } from \"./chart-map-viewport\";\nimport { useChartMessages } from \"./chart-messages\";\nimport {\n panStateTimelineViewport,\n renderStateTimelineSvg,\n type StateTimelineChartOptions,\n type StateTimelineDomain,\n stateTimelineDomain,\n stateTimelineHeight,\n zoomStateTimelineViewport,\n} from \"./chart-state-timeline\";\nimport { responsiveChartSvg, responsiveMapSvg, selectedChartSvg } from \"./chart-svg\";\nimport { useViewportMessages } from \"./viewport-messages\";\n\n/**\n * Chart — minimal Solid wrapper around `stdlib.charts`.\n *\n * **Live-update story.** `charts.<kind>(opts)` returns an SVG string;\n * Solid's `innerHTML` is reactive, so any time a prop (signal, store\n * slice, derived value) changes, the SVG re-renders. No manual\n * subscription, no imperative DOM patching. Trade-off: every change\n * is a full SVG re-build, not a diff — fine for dashboard cadences\n * (poll, websocket, store updates). Don't use this for 60fps streaming.\n *\n * **Sizing.** The server and browser render the same logical viewBox. CSS\n * fits Cartesian plots to the container and preserves text/marker sizes;\n * maps fit the whole world and zoom uniformly across the full plot; pies, donuts and gauges retain\n * their aspect ratio. No measurement\n * or hydration redraw is needed. The caller sizes the wrapper, for example\n * `style={{ height: \"14rem\" }}`. State timelines derive their default height\n * from the row count and legend via `stateTimelineHeight()`.\n *\n * **Why so thin.** The props are a discriminated union over each\n * stdlib chart function — `kind: \"line\"` brings in exactly the params\n * `charts.line` expects, `kind: \"bar\"` brings in `charts.bar`'s, etc.\n * Options stay aligned with stdlib without renaming. Every chart provides\n * renderer-owned inspection, tooltips and optional selection by default.\n * `interactive` adds bounded pan / zoom and reset controls to maps and state timelines.\n * If stdlib gains a new option, it's automatically available at every\n * callsite.\n *\n * **Theming.** stdlib charts use `currentColor` for axes / ticks /\n * tick labels — set the wrapping element's `color` and everything\n * inherits. Series colors come from `--stdlib-chart-c1..c8` CSS\n * custom properties; override on the parent for per-chart palettes.\n *\n * ```tsx\n * <Chart kind=\"line\" style={{ height: \"12rem\" }}\n * series={[{ data: points() }]}\n * yAxis={{ format: v => `€${v}k` }} />\n *\n * <Chart kind=\"donut\" style={{ height: \"12rem\" }} data={slices()} />\n *\n * <Chart kind=\"sparkline\" style={{ width: \"6rem\", height: \"1.5rem\" }} data={trend()} />\n *\n * <Chart kind=\"map\" style={{ height: \"16rem\" }} series={locations()} interactive />\n * ```\n */\n\n/** All chart kinds shipped by `stdlib.charts`. */\nexport type { ChartKind } from \"./chart-inspection-core\";\n\nexport type ChartLabels = Partial<{\n empty: string;\n series: string;\n interactiveMap: string;\n interactiveTimeline: string;\n interactiveLine: string;\n interactiveChart: string;\n zoomIn: string;\n zoomOut: string;\n resetMap: string;\n resetTimeline: string;\n}>;\n\n/**\n * Per-kind props: `kind` discriminator + the exact options that\n * `charts.<kind>` accepts, **minus** `width` / `height` (the wrapper\n * owns those — CSS fits a stable coordinate space to the box). Solid's\n * component model handles discriminated unions natively, so callsites\n * get full type safety.\n */\nexport type ChartProps = {\n [K in ChartKind]: {\n kind: K;\n class?: string;\n style?: JSX.CSSProperties | string;\n labels?: ChartLabels;\n /**\n * Navigation for maps and state timelines: pan, zoom and reset controls.\n * Arrows pan; Alt+arrows inspect. Every chart shows tooltips and keyboard\n * inspection without this prop.\n */\n interactive?: boolean;\n onSelect?: (selection: ChartSelection) => void;\n /** Controlled highlight; indices belong to this exact input snapshot. */\n selected?: ChartDatumRef | null;\n /** Customize the always-on tooltip with a title and labeled text rows. */\n tooltip?: ChartTooltipFormatter;\n /** Optional shared X cursor for line charts. */\n cursor?: ChartCursor;\n } & (K extends \"map\"\n ? {\n /** Target when zooming in from the world view. Defaults to Europe (50, 10). */\n zoomFocus?: Pick<MapViewport, \"latitude\" | \"longitude\">;\n }\n : {}) &\n (K extends \"line\"\n ? {\n /** Largest connected X distance; positive, finite, without area/errorBand fills. */ maxGap?: number;\n /** Wrap the legend above the plot inside the caller's total chart height. Requires legend=true. */\n legendPlacement?: \"top-start\";\n }\n : {}) &\n (K extends \"stateTimeline\"\n ? StateTimelineChartOptions\n : K extends \"bar\"\n ? BarChartOptions\n : Omit<Parameters<(typeof charts)[K]>[0], \"width\" | \"height\" | \"inspect\">);\n}[ChartKind];\n\n/** Pure renderer options: component layout, events and inspection are configured elsewhere. */\nexport type ChartRenderOptions = {\n [K in ChartKind]: Omit<\n Extract<ChartProps, { kind: K }>,\n \"class\" | \"style\" | \"labels\" | \"interactive\" | \"onSelect\" | \"selected\" | \"tooltip\" | \"cursor\" | \"legendPlacement\"\n >;\n}[ChartKind];\n\n/** Keep the fixed 28-unit bar-gauge rows inside the shared SSR/browser coordinate space. */\nexport const chartRenderHeight = (props: ChartRenderOptions): number => {\n if (props.kind === \"stateTimeline\") return stateTimelineHeight(props.rows.length, props.legend !== false);\n if (props.kind === \"bar\") return barChartLayout(props).height;\n if (props.kind === \"barGauge\") return Math.max(280, (props.title || props.subtitle ? 42 : 16) + props.data.length * 28 + 14);\n return 280;\n};\n\n/**\n * Internal — strips wrapper-only keys from props and forwards the\n * rest (plus logical size) to `charts[kind]`. The `any` is the\n * price for dispatching one function call across 14 different option\n * types; an explicit per-kind switch would type it but balloon the\n * component for no runtime benefit.\n */\nexport const renderChartSvg = (\n props: ChartProps,\n width: number,\n height: number,\n mapViewport?: MapViewport,\n timelineViewport?: StateTimelineDomain,\n): string => {\n const {\n kind,\n class: _class,\n style: _style,\n labels: _labels,\n interactive: _interactive,\n onSelect: _onSelect,\n selected: _selected,\n tooltip: _tooltip,\n cursor: _cursor,\n zoomFocus: _zoomFocus,\n legendPlacement: _legendPlacement,\n ...opts\n } = props as ChartProps & {\n legendPlacement?: \"top-start\";\n interactive?: boolean;\n zoomFocus?: Pick<MapViewport, \"latitude\" | \"longitude\">;\n };\n if (kind === \"stateTimeline\") {\n return responsiveChartSvg(\n renderStateTimelineSvg({\n ...(opts as StateTimelineChartOptions),\n width,\n height,\n viewport: timelineViewport,\n interactive: true,\n }),\n );\n }\n if (kind === \"bar\") return responsiveChartSvg(renderBarChartSvg({ ...(opts as BarChartOptions), width, height, inspect: true }));\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let svg = (charts[kind] as (o: unknown) => string)({\n ...(opts as any),\n ...(props.kind === \"line\" && props.legend && props.legendPlacement === \"top-start\" ? { legend: false } : {}),\n ...(kind === \"map\" ? { viewport: DEFAULT_MAP_VIEWPORT } : {}),\n width,\n height,\n inspect: true,\n });\n if (props.kind === \"line\" && props.maxGap !== undefined) {\n if (props.area || props.errorBand) throw new Error(\"Chart maxGap does not support area or errorBand fills\");\n svg = lineGapsSvg(svg, props.maxGap, props);\n }\n if (props.kind === \"map\") return responsiveMapSvg(svg, width, height, normalizeMapViewport(mapViewport ?? props.viewport));\n return preservesAspectRatio(kind) ? svg : responsiveChartSvg(svg);\n};\n\nconst preservesAspectRatio = (kind: ChartKind) => kind === \"map\" || kind === \"pie\" || kind === \"donut\" || kind === \"gauge\";\n\n/** Empty-data short-circuit. Kept per-kind because stdlib's payload\n * key differs (series vs data vs groups). We're conservative: only\n * block on truly empty inputs; partially-filled series get rendered\n * as-is and stdlib handles the gaps. */\nconst isEmpty = (props: ChartProps): boolean => {\n if (props.kind === \"line\" || props.kind === \"scatter\") {\n return !props.series?.length || props.series.every((s) => !s.data.length);\n }\n if (props.kind === \"bar\" || props.kind === \"donut\" || props.kind === \"pie\") {\n return !props.data?.length;\n }\n if (props.kind === \"histogram\" || props.kind === \"sparkline\") {\n return !props.data?.length;\n }\n if (props.kind === \"boxplot\") {\n return !props.groups?.length;\n }\n if (props.kind === \"stateTimeline\") {\n return !props.rows?.length || props.rows.every((row) => !row.intervals.length);\n }\n return false;\n};\n\nconst Chart = (props: ChartProps): JSX.Element => {\n const [, drawingProps] = splitProps(props, [\"selected\", \"onSelect\", \"tooltip\", \"cursor\"]);\n const messages = useUiMessages();\n const chartMessages = useChartMessages();\n const viewportMessages = useViewportMessages();\n const locale = useLocale();\n let containerRef: HTMLDivElement | undefined;\n let chartTooltipRef: HTMLSpanElement | undefined;\n let lineAnchorRef: HTMLSpanElement | undefined;\n // One deterministic coordinate space on the server and client. CSS fits the\n // SVG to its box; hydration must never replace it with measured geometry.\n const size = () => ({\n width: 480,\n height: chartRenderHeight(props),\n });\n const topLegend = () => props.kind === \"line\" && props.legend === true && props.legendPlacement === \"top-start\";\n const legendSeries = () => (props.kind === \"line\" ? props.series : []);\n const dimensions = () => containerRef?.getBoundingClientRect() ?? size();\n const initialMapViewport = props.kind === \"map\" ? normalizeMapViewport(props.viewport) : DEFAULT_MAP_VIEWPORT;\n const [mapViewport, setMapViewport] = createSignal<MapViewport>(initialMapViewport);\n const initialTimelineViewport =\n props.kind === \"stateTimeline\" ? stateTimelineDomain(props.rows, props.domain) : ([0, 1] as StateTimelineDomain);\n const [timelineViewport, setTimelineViewport] = createSignal<StateTimelineDomain>(initialTimelineViewport);\n const [dragging, setDragging] = createSignal(false);\n const chartTooltipId = `k2b-chart-tooltip-${createUniqueId()}`;\n let timelineViewportLocallyChanged = false;\n let drag:\n | {\n pointerId: number;\n x: number;\n y: number;\n width: number;\n height: number;\n viewport: MapViewport;\n }\n | undefined;\n let timelineDrag:\n | {\n pointerId: number;\n x: number;\n width: number;\n viewport: StateTimelineDomain;\n }\n | undefined;\n let pointerFrame: number | undefined;\n let pendingPointer: { pointerId: number; clientX: number; clientY: number } | undefined;\n\n const interactiveMap = () => props.kind === \"map\" && props.interactive === true;\n const interactiveTimeline = () => props.kind === \"stateTimeline\" && props.interactive === true;\n const draggable = () => interactiveMap() || interactiveTimeline();\n const labels = () => props.labels ?? {};\n const accessibleName = () => {\n const override =\n props.kind === \"map\"\n ? labels().interactiveMap\n : props.kind === \"stateTimeline\"\n ? labels().interactiveTimeline\n : props.kind === \"line\"\n ? labels().interactiveLine\n : labels().interactiveChart;\n const title = \"title\" in props && typeof props.title === \"string\" && props.title.trim() ? props.title : undefined;\n const valueLabel = (props.kind === \"stat\" || props.kind === \"gauge\") && props.label?.trim() ? props.label : undefined;\n const fallback =\n props.kind === \"map\"\n ? chartMessages().interactiveMap\n : props.kind === \"stateTimeline\"\n ? chartMessages().interactiveTimeline\n : props.kind === \"line\"\n ? chartMessages().interactiveLineChart\n : chartMessages().interactiveChart;\n return override ?? title ?? valueLabel ?? fallback;\n };\n const timelineFullDomain = (): StateTimelineDomain =>\n props.kind === \"stateTimeline\" ? stateTimelineDomain(props.rows, props.domain) : [0, 1];\n\n createEffect(() => {\n if (props.kind === \"map\") {\n setMapViewport(normalizeMapViewport(props.viewport));\n }\n });\n\n createEffect(() => {\n if (props.kind === \"stateTimeline\" && !timelineViewportLocallyChanged) {\n setTimelineViewport(timelineFullDomain());\n }\n });\n\n const updateTimelineViewport = (update: (current: StateTimelineDomain) => StateTimelineDomain) => {\n timelineViewportLocallyChanged = true;\n setTimelineViewport(update);\n };\n\n const mapDimensions = () => {\n const viewportElement = containerRef?.querySelector<SVGSVGElement>(\".stdlib-chart-map-viewport\");\n const matrix = viewportElement?.getScreenCTM?.();\n const box = viewportElement?.viewBox?.baseVal;\n if (matrix && box?.width && box.height) {\n return { width: box.width * Math.hypot(matrix.a, matrix.b), height: box.height * Math.hypot(matrix.c, matrix.d) };\n }\n const rect = viewportElement?.getBoundingClientRect();\n if (rect && rect.width > 0 && rect.height > 0) {\n return { width: rect.width, height: rect.height };\n }\n return dimensions();\n };\n\n const zoom = (delta: number) => {\n closeChartTooltip();\n if (interactiveMap()) {\n setMapViewport((current) => zoomMapViewport(current, delta, props.kind === \"map\" ? props.zoomFocus : undefined));\n } else if (interactiveTimeline()) {\n updateTimelineViewport((current) => zoomStateTimelineViewport(current, timelineFullDomain(), delta));\n }\n };\n\n const reset = () => {\n closeChartTooltip();\n if (interactiveMap() && props.kind === \"map\") {\n setMapViewport(normalizeMapViewport(props.viewport));\n }\n if (interactiveTimeline()) {\n timelineViewportLocallyChanged = false;\n setTimelineViewport(timelineFullDomain());\n }\n };\n\n const handlePointerDown: JSX.EventHandlerUnion<HTMLDivElement, PointerEvent> = (event) => {\n inspection.down(event);\n if (!draggable() || event.button !== 0 || (event.target as Element).closest(\"button, a\")) {\n return;\n }\n closeChartTooltip();\n // The pointer's own pointerup or pointercancel ends the hold.\n suppressTextSelection(event.pointerId);\n if (interactiveTimeline()) {\n timelineDrag = {\n pointerId: event.pointerId,\n x: event.clientX,\n width: Math.max(1, event.currentTarget.getBoundingClientRect().width),\n viewport: timelineViewport(),\n };\n event.currentTarget.setPointerCapture(event.pointerId);\n setDragging(true);\n return;\n }\n const dimensions = mapDimensions();\n drag = {\n pointerId: event.pointerId,\n x: event.clientX,\n y: event.clientY,\n width: dimensions.width,\n height: dimensions.height,\n viewport: mapViewport(),\n };\n event.currentTarget.setPointerCapture(event.pointerId);\n setDragging(true);\n };\n\n const flushPointerMove = () => {\n if (pointerFrame !== undefined) {\n cancelAnimationFrame(pointerFrame);\n pointerFrame = undefined;\n }\n const sample = pendingPointer;\n pendingPointer = undefined;\n if (!sample) return;\n const start = timelineDrag ?? drag;\n if (start && Math.hypot(sample.clientX - start.x, sample.clientY - (\"y\" in start ? start.y : sample.clientY)) <= 6) return;\n const activeTimelineDrag = timelineDrag;\n if (activeTimelineDrag?.pointerId === sample.pointerId) {\n updateTimelineViewport(() =>\n panStateTimelineViewport(\n activeTimelineDrag.viewport,\n timelineFullDomain(),\n sample.clientX - activeTimelineDrag.x,\n activeTimelineDrag.width,\n ),\n );\n return;\n }\n if (!drag || drag.pointerId !== sample.pointerId) return;\n setMapViewport(panMapViewport(drag.viewport, sample.clientX - drag.x, sample.clientY - drag.y, drag.width, drag.height));\n };\n\n const handlePointerMove: JSX.EventHandlerUnion<HTMLDivElement, PointerEvent> = (event) => {\n inspection.move(event);\n if (timelineDrag?.pointerId !== event.pointerId && drag?.pointerId !== event.pointerId) return;\n pendingPointer = { pointerId: event.pointerId, clientX: event.clientX, clientY: event.clientY };\n if (pointerFrame !== undefined) return;\n pointerFrame = requestAnimationFrame(flushPointerMove);\n };\n\n const stopDragging: JSX.EventHandlerUnion<HTMLDivElement, PointerEvent> = (event) => {\n if (pendingPointer?.pointerId === event.pointerId) flushPointerMove();\n if (timelineDrag?.pointerId === event.pointerId) {\n if (event.currentTarget.hasPointerCapture(event.pointerId)) {\n event.currentTarget.releasePointerCapture(event.pointerId);\n }\n timelineDrag = undefined;\n setDragging(false);\n return;\n }\n if (!drag || drag.pointerId !== event.pointerId) return;\n if (event.currentTarget.hasPointerCapture(event.pointerId)) {\n event.currentTarget.releasePointerCapture(event.pointerId);\n }\n drag = undefined;\n setDragging(false);\n };\n\n const handleWheel: JSX.EventHandlerUnion<HTMLDivElement, WheelEvent> = (event) => {\n if (interactiveMap() && (event.ctrlKey || event.metaKey)) {\n event.preventDefault();\n zoom(event.deltaY < 0 ? 1 : -1);\n return;\n }\n if (!interactiveTimeline()) return;\n if (event.ctrlKey || event.metaKey) {\n event.preventDefault();\n const rect = event.currentTarget.getBoundingClientRect();\n const anchor = rect.width > 0 ? (event.clientX - rect.left) / rect.width : 0.5;\n updateTimelineViewport((current) => zoomStateTimelineViewport(current, timelineFullDomain(), event.deltaY < 0 ? 1 : -1, anchor));\n } else if (event.shiftKey) {\n event.preventDefault();\n updateTimelineViewport((current) =>\n panStateTimelineViewport(current, timelineFullDomain(), -event.deltaY, event.currentTarget.getBoundingClientRect().width),\n );\n }\n };\n\n const handleKeyDown: JSX.EventHandlerUnion<HTMLDivElement, KeyboardEvent> = (event) => {\n if (inspection.key(event)) return;\n if (!draggable() || event.target !== containerRef) return;\n if (event.key === \"+\" || event.key === \"=\") {\n event.preventDefault();\n zoom(1);\n return;\n }\n if (event.key === \"-\" || event.key === \"_\") {\n event.preventDefault();\n zoom(-1);\n return;\n }\n if (event.key === \"0\" || event.key === \"Home\") {\n event.preventDefault();\n reset();\n return;\n }\n if (interactiveTimeline() && (event.key === \"ArrowLeft\" || event.key === \"ArrowRight\")) {\n event.preventDefault();\n updateTimelineViewport((current) =>\n panStateTimelineViewport(\n current,\n timelineFullDomain(),\n event.key === \"ArrowLeft\" ? 80 : -80,\n event.currentTarget.getBoundingClientRect().width,\n ),\n );\n return;\n }\n const delta: readonly [number, number] | undefined = {\n ArrowLeft: [40, 0],\n ArrowRight: [-40, 0],\n ArrowUp: [0, 40],\n ArrowDown: [0, -40],\n }[event.key] as readonly [number, number] | undefined;\n if (!delta) return;\n event.preventDefault();\n const dimensions = mapDimensions();\n setMapViewport((current) => panMapViewport(current, delta[0], delta[1], dimensions.width, dimensions.height));\n };\n\n const inspection = createChartInspection({\n container: () => containerRef,\n cursor: () => props.cursor,\n tooltip: () => chartTooltipRef,\n anchor: () => lineAnchorRef,\n kind: () => props.kind,\n enabled: () => !isEmpty(props),\n select: (selection) => props.onSelect?.(selection),\n format: (selection) => {\n if (props.tooltip) return props.tooltip(selection);\n const fields = chartMessages().chartFields;\n const format = new Intl.NumberFormat(locale(), { maximumFractionDigits: 6 });\n return {\n title:\n selection.datum.label ??\n (selection.datum.seriesIndex !== undefined\n ? `${labels().series ?? chartMessages().series} ${selection.datum.seriesIndex + 1}`\n : undefined),\n rows: selection.datum.values.map((field) => ({\n label:\n selection.kind === \"line\" && field.key === \"y\"\n ? (selection.datum.label ?? labels().series ?? chartMessages().series)\n : fields({ key: field.key }),\n value:\n field.formatted ??\n (field.key === \"upperInclusive\"\n ? field.value === \"true\"\n ? messages().yes\n : messages().no\n : typeof field.value === \"number\"\n ? `${format.format(field.value)}${field.key === \"percent\" ? \"%\" : \"\"}`\n : field.value),\n })),\n };\n },\n });\n const closeChartTooltip = () => inspection.close();\n const svgMarkup = createMemo(() =>\n renderChartSvg(\n drawingProps,\n size().width,\n size().height,\n interactiveMap() ? mapViewport() : undefined,\n interactiveTimeline() ? timelineViewport() : undefined,\n ),\n );\n createEffect(() => {\n svgMarkup();\n inspection.invalidate();\n untrack(() => inspection.selectDatum(props.selected));\n });\n\n createEffect(() => inspection.selectDatum(props.selected));\n\n onCleanup(() => {\n inspection.close();\n if (pointerFrame !== undefined) cancelAnimationFrame(pointerFrame);\n pointerFrame = undefined;\n pendingPointer = undefined;\n });\n\n onMount(() => {\n if (!containerRef) return;\n onCleanup(\n closeChartInspectionOnOutside({\n container: () => containerRef,\n tooltip: () => chartTooltipRef,\n close: closeChartTooltip,\n }),\n );\n });\n\n const chartStyle = () =>\n props.style ??\n (props.kind === \"stateTimeline\"\n ? {\n height: `${stateTimelineHeight(props.rows.length, props.legend !== false)}px`,\n }\n : undefined);\n\n const control = (label: string, shortcut: string, icon: string, action: () => void) => (\n <IconButton variant=\"secondary\" label={label} tooltip={`${label} (${shortcut})`} onClick={action}>\n <i class={`ti ${icon}`} aria-hidden=\"true\" />\n </IconButton>\n );\n\n return (\n <Show\n when={!isEmpty(props)}\n fallback={\n <div ref={containerRef} class={`k2b-chart k2b-chart__empty ${props.class ?? \"\"}`} style={chartStyle()}>\n {labels().empty ?? messages().noData}\n </div>\n }\n >\n {/* CSS fits the server-rendered SVG to the caller's box. Only changes\n to chart data/options rebuild the SVG; resizing does not. */}\n <div\n ref={containerRef}\n class={`k2b-chart ${props.class ?? \"\"}`}\n data-chart-kind={props.kind}\n data-legend-placement={topLegend() ? \"top-start\" : undefined}\n data-drag={draggable() ? (dragging() ? \"active\" : \"idle\") : undefined}\n data-crosshair={!draggable() && props.kind === \"line\" ? \"true\" : undefined}\n data-interactive=\"true\"\n style={chartStyle()}\n role=\"group\"\n aria-label={accessibleName()}\n aria-description={accessibleName() !== chartMessages().interactiveChart ? chartMessages().interactiveChart : undefined}\n tabIndex={0}\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={stopDragging}\n onPointerCancel={stopDragging}\n onClick={inspection.click}\n onPointerLeave={inspection.leave}\n onFocusIn={inspection.focus}\n onFocusOut={closeChartTooltip}\n onWheel={handleWheel}\n onKeyDown={handleKeyDown}\n >\n <Show when={topLegend()}>\n <div class=\"k2b-chart__legend\" role=\"group\" aria-label={chartMessages().chartLegend} tabIndex={0}>\n <For each={legendSeries()}>\n {(series, index) => (\n <span class=\"k2b-chart__legend-item\">\n {/* Use the renderer's actual series classes/defaults, including consumer palette overrides. */}\n <svg\n class={`stdlib-chart k2b-chart__legend-swatch ${props.kind === \"line\" ? (props.className ?? \"\") : \"\"}`}\n viewBox=\"0 0 10 10\"\n width=\"10\"\n height=\"10\"\n aria-hidden=\"true\"\n >\n <rect x=\"1\" y=\"1\" width=\"8\" height=\"8\" rx=\"2\" class={`stdlib-chart-series-${index() % 8}`} />\n </svg>\n <span>{series.label && series.label.length > 0 ? series.label : `Series ${index() + 1}`}</span>\n </span>\n )}\n </For>\n </div>\n </Show>\n <div\n class=\"k2b-chart__svg\"\n data-stretch={!preservesAspectRatio(props.kind) ? \"true\" : undefined}\n style={{\n \"--k2b-chart-width\": `${size().width}px`,\n \"--k2b-chart-height\": `${size().height}px`,\n \"aspect-ratio\": `${size().width} / ${size().height}`,\n }}\n innerHTML={isServer ? selectedChartSvg(svgMarkup(), props.selected) : svgMarkup()}\n />\n <span ref={lineAnchorRef} class=\"k2b-chart__anchor\" aria-hidden=\"true\" />\n <span\n id={chartTooltipId}\n ref={chartTooltipRef}\n role=\"tooltip\"\n popover=\"manual\"\n data-instant=\"true\"\n class=\"k2b-tooltip k2b-chart__tooltip\"\n />\n <Show when={draggable()}>\n <div class=\"k2b-chart__controls\">\n {control(labels().zoomIn ?? viewportMessages().zoomIn, \"+\", \"ti-plus\", () => zoom(1))}\n {control(labels().zoomOut ?? viewportMessages().zoomOut, \"-\", \"ti-minus\", () => zoom(-1))}\n {control(\n interactiveMap()\n ? (labels().resetMap ?? chartMessages().resetMapView)\n : (labels().resetTimeline ?? chartMessages().resetTimelineView),\n \"0\",\n \"ti-focus-centered\",\n reset,\n )}\n </div>\n </Show>\n </div>\n </Show>\n );\n};\n\nexport default Chart;\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,23 +1,56 @@
|
|
|
1
1
|
import { template as _$template } from "solid-js/web";
|
|
2
|
+
import { delegateEvents as _$delegateEvents } from "solid-js/web";
|
|
3
|
+
import { getNextMarker as _$getNextMarker } from "solid-js/web";
|
|
2
4
|
import { runHydrationEvents as _$runHydrationEvents } from "solid-js/web";
|
|
3
5
|
import { spread as _$spread } from "solid-js/web";
|
|
4
|
-
import { mergeProps as _$mergeProps } from "solid-js/web";
|
|
5
6
|
import { memo as _$memo } from "solid-js/web";
|
|
6
7
|
import { setAttribute as _$setAttribute } from "solid-js/web";
|
|
7
8
|
import { className as _$className } from "solid-js/web";
|
|
8
9
|
import { effect as _$effect } from "solid-js/web";
|
|
9
10
|
import { getNextElement as _$getNextElement } from "solid-js/web";
|
|
10
11
|
import { insert as _$insert } from "solid-js/web";
|
|
11
|
-
import { createComponent as _$createComponent } from "solid-js/web";
|
|
12
12
|
import { use as _$use } from "solid-js/web";
|
|
13
|
+
import { mergeProps as _$mergeProps } from "solid-js/web";
|
|
14
|
+
import { createComponent as _$createComponent } from "solid-js/web";
|
|
13
15
|
var _tmpl$ = /*#__PURE__*/_$template(`<div role=grid>`),
|
|
14
|
-
_tmpl$2 = /*#__PURE__*/_$template(`<div role=row class=k2b-file-grid__row><div><div class=k2b-file-grid__preview></div><div class=k2b-file-grid__name></div><div class=k2b-file-grid__meta></div><div class=k2b-file-grid__actions>`)
|
|
15
|
-
|
|
16
|
+
_tmpl$2 = /*#__PURE__*/_$template(`<div role=row class=k2b-file-grid__row><div><div class=k2b-file-grid__preview></div><div class=k2b-file-grid__name></div><div class=k2b-file-grid__meta></div><div class=k2b-file-grid__actions>`),
|
|
17
|
+
_tmpl$3 = /*#__PURE__*/_$template(`<div data-open-items=true role=list>`),
|
|
18
|
+
_tmpl$4 = /*#__PURE__*/_$template(`<div role=listitem class=k2b-file-grid__row><div><button type=button class=k2b-file-grid__open></button><div class=k2b-file-grid__preview></div><div class=k2b-file-grid__name></div><div class=k2b-file-grid__meta></div><div class=k2b-file-grid__actions>`),
|
|
19
|
+
_tmpl$5 = /*#__PURE__*/_$template(`<div class=k2b-file-grid-stack__toolbar>`),
|
|
20
|
+
_tmpl$6 = /*#__PURE__*/_$template(`<button type=button class=k2b-file-grid-stack__more aria-expanded=true><span></span><i class="ti ti-chevron-up"aria-hidden=true>`),
|
|
21
|
+
_tmpl$7 = /*#__PURE__*/_$template(`<div class=k2b-file-grid-stack><!$><!/><!$><!/><!$><!/>`),
|
|
22
|
+
_tmpl$8 = /*#__PURE__*/_$template(`<div class=k2b-file-grid-stack__group><div class=k2b-file-grid-stack__label><!$><!/><span class=k2b-file-grid-stack__count></span></div><!$><!/>`),
|
|
23
|
+
_tmpl$9 = /*#__PURE__*/_$template(`<span class=k2b-file-grid-stack__more-meta>`),
|
|
24
|
+
_tmpl$0 = /*#__PURE__*/_$template(`<button type=button class=k2b-file-grid-stack__more aria-expanded=false><span></span><i class="ti ti-chevron-down"aria-hidden=true></i><!$><!/>`);
|
|
25
|
+
import { createEffect, createMemo, createSignal, createUniqueId, For, Index, on, Show } from "solid-js";
|
|
26
|
+
import { useFileListMessages } from "./file-list-messages";
|
|
27
|
+
|
|
28
|
+
/** One part of an open file list, such as its files as rows and its images as tiles. */
|
|
29
|
+
|
|
30
|
+
/** A browser or picker: items are selected, and Enter or a double click opens them. */
|
|
31
|
+
|
|
32
|
+
/** A list without selection, as in a details panel: one click on an item opens it. */
|
|
33
|
+
|
|
16
34
|
/**
|
|
17
35
|
* File presentation only; the host owns data, menus, leases and permissions. Items the selection marks with
|
|
18
36
|
* `isDisabled` stay reachable by keyboard but cannot be selected or opened; say why in `renderMeta`.
|
|
19
37
|
*/
|
|
20
38
|
export function FileGrid(props) {
|
|
39
|
+
return _$createComponent(Show, {
|
|
40
|
+
get when() {
|
|
41
|
+
return props.selection;
|
|
42
|
+
},
|
|
43
|
+
get fallback() {
|
|
44
|
+
return _$createComponent(OpenFileGrid, props);
|
|
45
|
+
},
|
|
46
|
+
children: selection => _$createComponent(SelectableFileGrid, _$mergeProps(props, {
|
|
47
|
+
get selection() {
|
|
48
|
+
return selection();
|
|
49
|
+
}
|
|
50
|
+
}))
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
function SelectableFileGrid(props) {
|
|
21
54
|
let grid;
|
|
22
55
|
// Both clicks of a double-click belong to the item that took the first one. When that click replaced the rows,
|
|
23
56
|
// for example by opening a folder, the item now under the pointer ignores the rest of the gesture.
|
|
@@ -92,22 +125,211 @@ export function FileGrid(props) {
|
|
|
92
125
|
var _v$ = `k2b-file-grid ${props.class ?? ""}`,
|
|
93
126
|
_v$2 = props.size ?? "md",
|
|
94
127
|
_v$3 = props.layout ?? "grid",
|
|
95
|
-
_v$4 = props.
|
|
96
|
-
_v$5 = props.
|
|
128
|
+
_v$4 = props.actionVisibility ?? "always",
|
|
129
|
+
_v$5 = props.label,
|
|
130
|
+
_v$6 = props.selection.multiple;
|
|
97
131
|
_v$ !== _p$.e && _$className(_el$, _p$.e = _v$);
|
|
98
132
|
_v$2 !== _p$.t && _$setAttribute(_el$, "data-size", _p$.t = _v$2);
|
|
99
133
|
_v$3 !== _p$.a && _$setAttribute(_el$, "data-layout", _p$.a = _v$3);
|
|
100
|
-
_v$4 !== _p$.o && _$setAttribute(_el$, "
|
|
101
|
-
_v$5 !== _p$.i && _$setAttribute(_el$, "aria-
|
|
134
|
+
_v$4 !== _p$.o && _$setAttribute(_el$, "data-action-visibility", _p$.o = _v$4);
|
|
135
|
+
_v$5 !== _p$.i && _$setAttribute(_el$, "aria-label", _p$.i = _v$5);
|
|
136
|
+
_v$6 !== _p$.n && _$setAttribute(_el$, "aria-multiselectable", _p$.n = _v$6);
|
|
102
137
|
return _p$;
|
|
103
138
|
}, {
|
|
104
139
|
e: undefined,
|
|
105
140
|
t: undefined,
|
|
106
141
|
a: undefined,
|
|
107
142
|
o: undefined,
|
|
108
|
-
i: undefined
|
|
143
|
+
i: undefined,
|
|
144
|
+
n: undefined
|
|
109
145
|
});
|
|
110
146
|
return _el$;
|
|
111
147
|
})();
|
|
112
148
|
}
|
|
149
|
+
function OpenFileGrid(props) {
|
|
150
|
+
const messages = useFileListMessages();
|
|
151
|
+
const [ownExpanded, setOwnExpanded] = createSignal(false);
|
|
152
|
+
const limited = () => props.limit !== undefined && props.rows.length > props.limit;
|
|
153
|
+
// Without a limit the list is always complete, so its toolbar and groups always apply.
|
|
154
|
+
const full = () => props.limit === undefined || limited() && (props.expanded ?? ownExpanded());
|
|
155
|
+
let more;
|
|
156
|
+
let less;
|
|
157
|
+
let moveFocus = false;
|
|
158
|
+
const toggle = next => {
|
|
159
|
+
moveFocus = true;
|
|
160
|
+
if (props.expanded === undefined) setOwnExpanded(next);
|
|
161
|
+
props.onExpandedChange?.(next);
|
|
162
|
+
};
|
|
163
|
+
// The pressed button leaves with the state it showed; once the new state is there, focus moves to its
|
|
164
|
+
// counterpart, also when a controlling host applies it later.
|
|
165
|
+
createEffect(on(full, open => {
|
|
166
|
+
if (!moveFocus) return;
|
|
167
|
+
moveFocus = false;
|
|
168
|
+
queueMicrotask(() => (open ? less : more)?.focus());
|
|
169
|
+
}, {
|
|
170
|
+
defer: true
|
|
171
|
+
}));
|
|
172
|
+
const groups = createMemo(() => full() && props.groups ? props.groups(props.rows).filter(group => group.rows.length > 0) : [{
|
|
173
|
+
id: "rows",
|
|
174
|
+
label: undefined,
|
|
175
|
+
rows: full() || !limited() ? props.rows : props.rows.slice(0, props.limit)
|
|
176
|
+
}]);
|
|
177
|
+
const list = (group, labelId) => (() => {
|
|
178
|
+
var _el$8 = _$getNextElement(_tmpl$3);
|
|
179
|
+
_$setAttribute(_el$8, "aria-labelledby", labelId);
|
|
180
|
+
_$insert(_el$8, _$createComponent(For, {
|
|
181
|
+
get each() {
|
|
182
|
+
return group().rows;
|
|
183
|
+
},
|
|
184
|
+
children: row => {
|
|
185
|
+
const id = `k2b-file-grid-${createUniqueId()}`;
|
|
186
|
+
return (() => {
|
|
187
|
+
var _el$9 = _$getNextElement(_tmpl$4),
|
|
188
|
+
_el$0 = _el$9.firstChild,
|
|
189
|
+
_el$1 = _el$0.firstChild,
|
|
190
|
+
_el$10 = _el$1.nextSibling,
|
|
191
|
+
_el$11 = _el$10.nextSibling,
|
|
192
|
+
_el$12 = _el$11.nextSibling,
|
|
193
|
+
_el$13 = _el$12.nextSibling;
|
|
194
|
+
_$spread(_el$0, _$mergeProps(() => props.itemProps?.(row), {
|
|
195
|
+
"class": "k2b-file-grid__item"
|
|
196
|
+
}), false, true);
|
|
197
|
+
_el$1.$$contextmenu = () => props.onContextMenu?.(row);
|
|
198
|
+
_el$1.$$click = () => props.onOpen(row);
|
|
199
|
+
_$setAttribute(_el$1, "aria-labelledby", `${id}-name`);
|
|
200
|
+
_$insert(_el$10, () => props.renderPreview(row));
|
|
201
|
+
_$setAttribute(_el$11, "id", `${id}-name`);
|
|
202
|
+
_$insert(_el$11, () => props.renderLabel(row));
|
|
203
|
+
_$setAttribute(_el$12, "id", `${id}-meta`);
|
|
204
|
+
_$insert(_el$12, () => props.renderMeta?.(row));
|
|
205
|
+
_$insert(_el$13, () => props.renderActions?.(row));
|
|
206
|
+
_$effect(() => _$setAttribute(_el$1, "aria-describedby", props.renderMeta ? `${id}-meta` : undefined));
|
|
207
|
+
_$runHydrationEvents();
|
|
208
|
+
return _el$9;
|
|
209
|
+
})();
|
|
210
|
+
}
|
|
211
|
+
}));
|
|
212
|
+
_$effect(_p$ => {
|
|
213
|
+
var _v$7 = `k2b-file-grid ${props.class ?? ""}`,
|
|
214
|
+
_v$8 = props.size ?? "md",
|
|
215
|
+
_v$9 = group().layout === "tiles" ? "tiles" : props.layout ?? "grid",
|
|
216
|
+
_v$0 = props.actionVisibility ?? "always",
|
|
217
|
+
_v$1 = labelId ? undefined : props.label;
|
|
218
|
+
_v$7 !== _p$.e && _$className(_el$8, _p$.e = _v$7);
|
|
219
|
+
_v$8 !== _p$.t && _$setAttribute(_el$8, "data-size", _p$.t = _v$8);
|
|
220
|
+
_v$9 !== _p$.a && _$setAttribute(_el$8, "data-layout", _p$.a = _v$9);
|
|
221
|
+
_v$0 !== _p$.o && _$setAttribute(_el$8, "data-action-visibility", _p$.o = _v$0);
|
|
222
|
+
_v$1 !== _p$.i && _$setAttribute(_el$8, "aria-label", _p$.i = _v$1);
|
|
223
|
+
return _p$;
|
|
224
|
+
}, {
|
|
225
|
+
e: undefined,
|
|
226
|
+
t: undefined,
|
|
227
|
+
a: undefined,
|
|
228
|
+
o: undefined,
|
|
229
|
+
i: undefined
|
|
230
|
+
});
|
|
231
|
+
return _el$8;
|
|
232
|
+
})();
|
|
233
|
+
return (() => {
|
|
234
|
+
var _el$14 = _$getNextElement(_tmpl$7),
|
|
235
|
+
_el$18 = _el$14.firstChild,
|
|
236
|
+
[_el$19, _co$] = _$getNextMarker(_el$18.nextSibling),
|
|
237
|
+
_el$20 = _el$19.nextSibling,
|
|
238
|
+
[_el$21, _co$2] = _$getNextMarker(_el$20.nextSibling),
|
|
239
|
+
_el$22 = _el$21.nextSibling,
|
|
240
|
+
[_el$23, _co$3] = _$getNextMarker(_el$22.nextSibling);
|
|
241
|
+
_$insert(_el$14, _$createComponent(Show, {
|
|
242
|
+
get when() {
|
|
243
|
+
return _$memo(() => !!full())() && props.toolbar;
|
|
244
|
+
},
|
|
245
|
+
get children() {
|
|
246
|
+
var _el$15 = _$getNextElement(_tmpl$5);
|
|
247
|
+
_$insert(_el$15, () => props.toolbar);
|
|
248
|
+
return _el$15;
|
|
249
|
+
}
|
|
250
|
+
}), _el$19, _co$);
|
|
251
|
+
_$insert(_el$14, _$createComponent(Index, {
|
|
252
|
+
get each() {
|
|
253
|
+
return groups();
|
|
254
|
+
},
|
|
255
|
+
children: group => {
|
|
256
|
+
const labelId = `k2b-file-grid-group-${createUniqueId()}`;
|
|
257
|
+
return _$createComponent(Show, {
|
|
258
|
+
get when() {
|
|
259
|
+
return group().label !== undefined;
|
|
260
|
+
},
|
|
261
|
+
get fallback() {
|
|
262
|
+
return list(group);
|
|
263
|
+
},
|
|
264
|
+
get children() {
|
|
265
|
+
var _el$24 = _$getNextElement(_tmpl$8),
|
|
266
|
+
_el$25 = _el$24.firstChild,
|
|
267
|
+
_el$27 = _el$25.firstChild,
|
|
268
|
+
[_el$28, _co$4] = _$getNextMarker(_el$27.nextSibling),
|
|
269
|
+
_el$26 = _el$28.nextSibling,
|
|
270
|
+
_el$29 = _el$25.nextSibling,
|
|
271
|
+
[_el$30, _co$5] = _$getNextMarker(_el$29.nextSibling);
|
|
272
|
+
_$setAttribute(_el$25, "id", labelId);
|
|
273
|
+
_$insert(_el$25, () => group().label, _el$28, _co$4);
|
|
274
|
+
_$insert(_el$26, () => group().rows.length);
|
|
275
|
+
_$insert(_el$24, () => list(group, labelId), _el$30, _co$5);
|
|
276
|
+
return _el$24;
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
}), _el$21, _co$2);
|
|
281
|
+
_$insert(_el$14, _$createComponent(Show, {
|
|
282
|
+
get when() {
|
|
283
|
+
return limited();
|
|
284
|
+
},
|
|
285
|
+
get children() {
|
|
286
|
+
return _$createComponent(Show, {
|
|
287
|
+
get when() {
|
|
288
|
+
return full();
|
|
289
|
+
},
|
|
290
|
+
get fallback() {
|
|
291
|
+
return (() => {
|
|
292
|
+
var _el$31 = _$getNextElement(_tmpl$0),
|
|
293
|
+
_el$32 = _el$31.firstChild,
|
|
294
|
+
_el$33 = _el$32.nextSibling,
|
|
295
|
+
_el$35 = _el$33.nextSibling,
|
|
296
|
+
[_el$36, _co$6] = _$getNextMarker(_el$35.nextSibling);
|
|
297
|
+
_el$31.$$click = () => toggle(true);
|
|
298
|
+
var _ref$3 = more;
|
|
299
|
+
typeof _ref$3 === "function" ? _$use(_ref$3, _el$31) : more = _el$31;
|
|
300
|
+
_$insert(_el$32, () => messages().showAll({
|
|
301
|
+
count: props.rows.length
|
|
302
|
+
}));
|
|
303
|
+
_$insert(_el$31, _$createComponent(Show, {
|
|
304
|
+
get when() {
|
|
305
|
+
return props.moreMeta;
|
|
306
|
+
},
|
|
307
|
+
get children() {
|
|
308
|
+
var _el$34 = _$getNextElement(_tmpl$9);
|
|
309
|
+
_$insert(_el$34, () => props.moreMeta);
|
|
310
|
+
return _el$34;
|
|
311
|
+
}
|
|
312
|
+
}), _el$36, _co$6);
|
|
313
|
+
_$runHydrationEvents();
|
|
314
|
+
return _el$31;
|
|
315
|
+
})();
|
|
316
|
+
},
|
|
317
|
+
get children() {
|
|
318
|
+
var _el$16 = _$getNextElement(_tmpl$6),
|
|
319
|
+
_el$17 = _el$16.firstChild;
|
|
320
|
+
_el$16.$$click = () => toggle(false);
|
|
321
|
+
var _ref$2 = less;
|
|
322
|
+
typeof _ref$2 === "function" ? _$use(_ref$2, _el$16) : less = _el$16;
|
|
323
|
+
_$insert(_el$17, () => messages().showLess);
|
|
324
|
+
_$runHydrationEvents();
|
|
325
|
+
return _el$16;
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
}), _el$23, _co$3);
|
|
330
|
+
_$effect(() => _$setAttribute(_el$14, "data-expanded", full() ? "true" : undefined));
|
|
331
|
+
return _el$14;
|
|
332
|
+
})();
|
|
333
|
+
}
|
|
334
|
+
_$delegateEvents(["click", "contextmenu"]);
|
|
113
335
|
//# sourceMappingURL=FileGrid.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["content/FileGrid.tsx"],"sourcesContent":["import { For, type JSX } from \"solid-js\";\nimport type { CollectionSelection } from \"./collection-selection\";\n\nexport type FileGridProps<T> = {\n rows: readonly T[];\n getRowId: (row: T) => string;\n selection: CollectionSelection;\n label: string;\n size?: \"sm\" | \"md\" | \"lg\";\n /** `list` shows one compact row per item: preview, name, and meta beside each other. Defaults to `grid`. */\n layout?: \"grid\" | \"list\";\n renderPreview: (row: T) => JSX.Element;\n renderLabel: (row: T) => JSX.Element;\n renderMeta?: (row: T) => JSX.Element;\n renderActions?: (row: T) => JSX.Element;\n onRowClick?: (row: T) => void;\n onOpen: (row: T) => void;\n onContextMenu?: (row: T) => void;\n /** Extra attributes for one tile, for example drag-and-drop handlers or data attributes the host styles. */\n itemProps?: (row: T) => JSX.HTMLAttributes<HTMLDivElement>;\n class?: string;\n};\n\n/**\n * File presentation only; the host owns data, menus, leases and permissions. Items the selection marks with\n * `isDisabled` stay reachable by keyboard but cannot be selected or opened; say why in `renderMeta`.\n */\nexport function FileGrid<T>(props: FileGridProps<T>) {\n let grid: HTMLDivElement | undefined;\n // Both clicks of a double-click belong to the item that took the first one. When that click replaced the rows,\n // for example by opening a folder, the item now under the pointer ignores the rest of the gesture.\n let pressed: EventTarget | null | undefined;\n const ownsClick = (event: MouseEvent) => {\n if (event.detail > 1 && pressed !== event.currentTarget) pressed = null;\n else pressed = event.currentTarget;\n return pressed !== null;\n };\n const columns = () => (grid ? Math.max(1, getComputedStyle(grid).gridTemplateColumns.split(\" \").length) : 1);\n const nested = (event: Event) =>\n event.target instanceof Element &&\n !!event.target.closest(\"button,a,input,label,select,textarea,summary,[contenteditable],[role=button],[role=menu]\");\n return (\n <div\n ref={grid}\n class={`k2b-file-grid ${props.class ?? \"\"}`}\n data-size={props.size ?? \"md\"}\n data-layout={props.layout ?? \"grid\"}\n role=\"grid\"\n aria-label={props.label}\n aria-multiselectable={props.selection.multiple}\n >\n <For each={props.rows}>\n {(row) => {\n const id = () => props.getRowId(row);\n const disabled = () => props.selection.isDisabled(id());\n return (\n <div role=\"row\" class=\"k2b-file-grid__row\">\n <div\n {...props.itemProps?.(row)}\n role=\"gridcell\"\n class=\"k2b-file-grid__item\"\n aria-selected={props.selection.selected().has(id())}\n aria-disabled={disabled() || undefined}\n ref={(element) => props.selection.register(id(), element)}\n tabIndex={props.selection.focused() === id() ? 0 : -1}\n onFocus={() => props.selection.markFocused(id())}\n onClick={(event) => {\n if (!nested(event) && ownsClick(event) && !disabled()) {\n props.selection.select(id(), event);\n props.onRowClick?.(row);\n }\n }}\n onDblClick={(event) => {\n if (!nested(event) && pressed !== null && !disabled()) props.onOpen(row);\n }}\n onContextMenu={() => props.onContextMenu?.(row)}\n onKeyDown={(event) => {\n if (nested(event)) return;\n if (props.selection.keyDown(event, id(), columns())) return;\n if (event.key === \"Enter\") {\n event.preventDefault();\n if (!disabled()) props.onOpen(row);\n }\n }}\n >\n <div class=\"k2b-file-grid__preview\">{props.renderPreview(row)}</div>\n <div class=\"k2b-file-grid__name\">{props.renderLabel(row)}</div>\n <div class=\"k2b-file-grid__meta\">{props.renderMeta?.(row)}</div>\n <div class=\"k2b-file-grid__actions\">{props.renderActions?.(row)}</div>\n </div>\n </div>\n );\n }}\n </For>\n </div>\n );\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":[],"sources":["content/FileGrid.tsx"],"sourcesContent":["import { createEffect, createMemo, createSignal, createUniqueId, For, Index, type JSX, on, Show } from \"solid-js\";\nimport type { CollectionSelection } from \"./collection-selection\";\nimport { useFileListMessages } from \"./file-list-messages\";\n\n/** One part of an open file list, such as its files as rows and its images as tiles. */\nexport type FileGridGroup<T> = {\n id: string;\n label: JSX.Element;\n rows: readonly T[];\n /** `tiles` fills each item with its preview and lays the name over it. Defaults to `list`. */\n layout?: \"list\" | \"tiles\";\n};\n\ntype FileGridBaseProps<T> = {\n rows: readonly T[];\n getRowId: (row: T) => string;\n label: string;\n size?: \"sm\" | \"md\" | \"lg\";\n /** `list` shows one compact row per item: preview, name, and meta beside each other. Defaults to `grid`. */\n layout?: \"grid\" | \"list\";\n renderPreview: (row: T) => JSX.Element;\n renderLabel: (row: T) => JSX.Element;\n renderMeta?: (row: T) => JSX.Element;\n renderActions?: (row: T) => JSX.Element;\n /**\n * `progressive` shows the actions on hover, keyboard focus, or an open menu with a mouse or trackpad, and always\n * on touch. Their slot is reserved in both states, so nothing moves. Defaults to `always`.\n */\n actionVisibility?: \"always\" | \"progressive\";\n onOpen: (row: T) => void;\n onContextMenu?: (row: T) => void;\n /** Extra attributes for one tile, for example drag-and-drop handlers or data attributes the host styles. */\n itemProps?: (row: T) => JSX.HTMLAttributes<HTMLDivElement>;\n class?: string;\n};\n\n/** A browser or picker: items are selected, and Enter or a double click opens them. */\nexport type FileGridSelectableProps<T> = FileGridBaseProps<T> & {\n selection: CollectionSelection;\n onRowClick?: (row: T) => void;\n limit?: never;\n expanded?: never;\n onExpandedChange?: never;\n moreMeta?: never;\n toolbar?: never;\n groups?: never;\n};\n\n/** A list without selection, as in a details panel: one click on an item opens it. */\nexport type FileGridOpenProps<T> = FileGridBaseProps<T> & {\n selection?: never;\n onRowClick?: never;\n /** Shows the first `limit` items, then \"Show all N\", which opens the full list in place. Without it, the list is always full. */\n limit?: number;\n /** Controls whether the full list is open. Without it, the list keeps its own state. */\n expanded?: boolean;\n onExpandedChange?: (expanded: boolean) => void;\n /** A quiet note at the end of \"Show all N\", such as how many duplicates were merged. */\n moreMeta?: JSX.Element;\n /** Shown above the full list, such as a count, an arrangement switch, or \"Download all\"; not in the short list. */\n toolbar?: JSX.Element;\n /** How the full list arranges its items, such as files as rows, then images as tiles; the short list stays one list. */\n groups?: (rows: readonly T[]) => readonly FileGridGroup<T>[];\n};\n\nexport type FileGridProps<T> = FileGridSelectableProps<T> | FileGridOpenProps<T>;\n\n/**\n * File presentation only; the host owns data, menus, leases and permissions. Items the selection marks with\n * `isDisabled` stay reachable by keyboard but cannot be selected or opened; say why in `renderMeta`.\n */\nexport function FileGrid<T>(props: FileGridProps<T>) {\n return (\n <Show when={props.selection} fallback={<OpenFileGrid {...(props as FileGridOpenProps<T>)} />}>\n {(selection) => <SelectableFileGrid {...(props as FileGridSelectableProps<T>)} selection={selection()} />}\n </Show>\n );\n}\n\nfunction SelectableFileGrid<T>(props: FileGridSelectableProps<T>) {\n let grid: HTMLDivElement | undefined;\n // Both clicks of a double-click belong to the item that took the first one. When that click replaced the rows,\n // for example by opening a folder, the item now under the pointer ignores the rest of the gesture.\n let pressed: EventTarget | null | undefined;\n const ownsClick = (event: MouseEvent) => {\n if (event.detail > 1 && pressed !== event.currentTarget) pressed = null;\n else pressed = event.currentTarget;\n return pressed !== null;\n };\n const columns = () => (grid ? Math.max(1, getComputedStyle(grid).gridTemplateColumns.split(\" \").length) : 1);\n const nested = (event: Event) =>\n event.target instanceof Element &&\n !!event.target.closest(\"button,a,input,label,select,textarea,summary,[contenteditable],[role=button],[role=menu]\");\n return (\n <div\n ref={grid}\n class={`k2b-file-grid ${props.class ?? \"\"}`}\n data-size={props.size ?? \"md\"}\n data-layout={props.layout ?? \"grid\"}\n data-action-visibility={props.actionVisibility ?? \"always\"}\n role=\"grid\"\n aria-label={props.label}\n aria-multiselectable={props.selection.multiple}\n >\n <For each={props.rows}>\n {(row) => {\n const id = () => props.getRowId(row);\n const disabled = () => props.selection.isDisabled(id());\n return (\n <div role=\"row\" class=\"k2b-file-grid__row\">\n <div\n {...props.itemProps?.(row)}\n role=\"gridcell\"\n class=\"k2b-file-grid__item\"\n aria-selected={props.selection.selected().has(id())}\n aria-disabled={disabled() || undefined}\n ref={(element) => props.selection.register(id(), element)}\n tabIndex={props.selection.focused() === id() ? 0 : -1}\n onFocus={() => props.selection.markFocused(id())}\n onClick={(event) => {\n if (!nested(event) && ownsClick(event) && !disabled()) {\n props.selection.select(id(), event);\n props.onRowClick?.(row);\n }\n }}\n onDblClick={(event) => {\n if (!nested(event) && pressed !== null && !disabled()) props.onOpen(row);\n }}\n onContextMenu={() => props.onContextMenu?.(row)}\n onKeyDown={(event) => {\n if (nested(event)) return;\n if (props.selection.keyDown(event, id(), columns())) return;\n if (event.key === \"Enter\") {\n event.preventDefault();\n if (!disabled()) props.onOpen(row);\n }\n }}\n >\n <div class=\"k2b-file-grid__preview\">{props.renderPreview(row)}</div>\n <div class=\"k2b-file-grid__name\">{props.renderLabel(row)}</div>\n <div class=\"k2b-file-grid__meta\">{props.renderMeta?.(row)}</div>\n <div class=\"k2b-file-grid__actions\">{props.renderActions?.(row)}</div>\n </div>\n </div>\n );\n }}\n </For>\n </div>\n );\n}\n\nfunction OpenFileGrid<T>(props: FileGridOpenProps<T>) {\n const messages = useFileListMessages();\n const [ownExpanded, setOwnExpanded] = createSignal(false);\n const limited = () => props.limit !== undefined && props.rows.length > props.limit;\n // Without a limit the list is always complete, so its toolbar and groups always apply.\n const full = () => props.limit === undefined || (limited() && (props.expanded ?? ownExpanded()));\n let more: HTMLButtonElement | undefined;\n let less: HTMLButtonElement | undefined;\n let moveFocus = false;\n const toggle = (next: boolean) => {\n moveFocus = true;\n if (props.expanded === undefined) setOwnExpanded(next);\n props.onExpandedChange?.(next);\n };\n // The pressed button leaves with the state it showed; once the new state is there, focus moves to its\n // counterpart, also when a controlling host applies it later.\n createEffect(\n on(\n full,\n (open) => {\n if (!moveFocus) return;\n moveFocus = false;\n queueMicrotask(() => (open ? less : more)?.focus());\n },\n { defer: true },\n ),\n );\n const groups = createMemo((): readonly FileGridGroup<T>[] =>\n full() && props.groups\n ? props.groups(props.rows).filter((group) => group.rows.length > 0)\n : [{ id: \"rows\", label: undefined, rows: full() || !limited() ? props.rows : props.rows.slice(0, props.limit) }],\n );\n\n const list = (group: () => FileGridGroup<T>, labelId?: string) => (\n <div\n class={`k2b-file-grid ${props.class ?? \"\"}`}\n data-size={props.size ?? \"md\"}\n data-layout={group().layout === \"tiles\" ? \"tiles\" : (props.layout ?? \"grid\")}\n data-action-visibility={props.actionVisibility ?? \"always\"}\n data-open-items=\"true\"\n role=\"list\"\n aria-label={labelId ? undefined : props.label}\n aria-labelledby={labelId}\n >\n {/* Keyed by the row itself: new data keeps every existing item, its focus, and its state. */}\n <For each={group().rows}>\n {(row) => {\n const id = `k2b-file-grid-${createUniqueId()}`;\n return (\n <div role=\"listitem\" class=\"k2b-file-grid__row\">\n <div {...props.itemProps?.(row)} class=\"k2b-file-grid__item\">\n {/* The whole item opens the file; its actions lie above this layer in their own slot. */}\n <button\n type=\"button\"\n class=\"k2b-file-grid__open\"\n aria-labelledby={`${id}-name`}\n aria-describedby={props.renderMeta ? `${id}-meta` : undefined}\n onClick={() => props.onOpen(row)}\n onContextMenu={() => props.onContextMenu?.(row)}\n />\n <div class=\"k2b-file-grid__preview\">{props.renderPreview(row)}</div>\n <div class=\"k2b-file-grid__name\" id={`${id}-name`}>\n {props.renderLabel(row)}\n </div>\n <div class=\"k2b-file-grid__meta\" id={`${id}-meta`}>\n {props.renderMeta?.(row)}\n </div>\n <div class=\"k2b-file-grid__actions\">{props.renderActions?.(row)}</div>\n </div>\n </div>\n );\n }}\n </For>\n </div>\n );\n\n return (\n <div class=\"k2b-file-grid-stack\" data-expanded={full() ? \"true\" : undefined}>\n <Show when={full() && props.toolbar}>\n <div class=\"k2b-file-grid-stack__toolbar\">{props.toolbar}</div>\n </Show>\n {/* By position: a group that only changes its rows keeps its list, so new data remounts nothing. */}\n <Index each={groups()}>\n {(group) => {\n const labelId = `k2b-file-grid-group-${createUniqueId()}`;\n return (\n <Show when={group().label !== undefined} fallback={list(group)}>\n <div class=\"k2b-file-grid-stack__group\">\n <div class=\"k2b-file-grid-stack__label\" id={labelId}>\n {group().label}\n <span class=\"k2b-file-grid-stack__count\">{group().rows.length}</span>\n </div>\n {list(group, labelId)}\n </div>\n </Show>\n );\n }}\n </Index>\n <Show when={limited()}>\n <Show\n when={full()}\n fallback={\n <button ref={more} type=\"button\" class=\"k2b-file-grid-stack__more\" aria-expanded=\"false\" onClick={() => toggle(true)}>\n <span>{messages().showAll({ count: props.rows.length })}</span>\n <i class=\"ti ti-chevron-down\" aria-hidden=\"true\" />\n <Show when={props.moreMeta}>\n <span class=\"k2b-file-grid-stack__more-meta\">{props.moreMeta}</span>\n </Show>\n </button>\n }\n >\n <button ref={less} type=\"button\" class=\"k2b-file-grid-stack__more\" aria-expanded=\"true\" onClick={() => toggle(false)}>\n <span>{messages().showLess}</span>\n <i class=\"ti ti-chevron-up\" aria-hidden=\"true\" />\n </button>\n </Show>\n </Show>\n </div>\n );\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -5,6 +5,7 @@ import { effect as _$effect } from "solid-js/web";
|
|
|
5
5
|
import { getNextElement as _$getNextElement } from "solid-js/web";
|
|
6
6
|
var _tmpl$ = /*#__PURE__*/_$template(`<span aria-hidden=true><i>`);
|
|
7
7
|
import { fileIcons } from "@k2b/stdlib";
|
|
8
|
+
import { resolveFileListMessages } from "./file-list-messages";
|
|
8
9
|
|
|
9
10
|
/** The colour family a file's icon tile uses. `other` covers code, text, and unknown files. */
|
|
10
11
|
|
|
@@ -25,6 +26,20 @@ export const fileTypeOf = file => {
|
|
|
25
26
|
return category === "pdf" || category === "image" || category === "video" || category === "audio" || category === "archive" ? category : "other";
|
|
26
27
|
};
|
|
27
28
|
|
|
29
|
+
/**
|
|
30
|
+
* The readable kind of a file in `locale`, such as "PDF", "Image", or "Spreadsheet", for a meta line like
|
|
31
|
+
* "PDF · 4.2 MB" instead of a media type. An unknown kind names the file's extension ("ICC"), and a file without
|
|
32
|
+
* one reads "File".
|
|
33
|
+
*/
|
|
34
|
+
export const fileKindLabel = (file, locale) => {
|
|
35
|
+
const t = resolveFileListMessages(locale);
|
|
36
|
+
const type = fileTypeOf(file);
|
|
37
|
+
if (type !== "other") return t[type];
|
|
38
|
+
const dot = file.name.lastIndexOf(".");
|
|
39
|
+
const extension = dot > 0 ? file.name.slice(dot + 1) : "";
|
|
40
|
+
return /^[a-z0-9]+$/i.test(extension) ? extension.toUpperCase() : t.file;
|
|
41
|
+
};
|
|
42
|
+
|
|
28
43
|
/** `fileIcons` adds Tailwind colour utilities that @k2b/ui does not ship; only the `ti-*` glyph is kept. */
|
|
29
44
|
const glyph = props => {
|
|
30
45
|
// `fileIcons` looks names up in plain objects, so a name such as `constructor` returns an inherited member
|