@k2b/ui 0.28.0 → 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. package/dist/browser/actions/ContextMenu.js +5 -0
  2. package/dist/browser/actions/ContextMenu.js.map +1 -1
  3. package/dist/browser/actions/DragAndDrop.js +89 -0
  4. package/dist/browser/actions/DragAndDrop.js.map +1 -0
  5. package/dist/browser/actions/GestureMenu.js +26 -3
  6. package/dist/browser/actions/GestureMenu.js.map +1 -1
  7. package/dist/browser/actions/drag-and-drop-messages.js +75 -0
  8. package/dist/browser/actions/drag-and-drop-messages.js.map +1 -0
  9. package/dist/browser/actions/drag-and-drop.js +692 -0
  10. package/dist/browser/actions/drag-and-drop.js.map +1 -0
  11. package/dist/browser/actions/index.js +1 -0
  12. package/dist/browser/actions/index.js.map +1 -1
  13. package/dist/browser/chat/ChatComposer.js +385 -265
  14. package/dist/browser/chat/ChatComposer.js.map +1 -1
  15. package/dist/browser/chat/ChatDecision.js +778 -0
  16. package/dist/browser/chat/ChatDecision.js.map +1 -0
  17. package/dist/browser/chat/ChatPrimitives.js +34 -28
  18. package/dist/browser/chat/ChatPrimitives.js.map +1 -1
  19. package/dist/browser/chat/ChatTimeline.js.map +1 -1
  20. package/dist/browser/chat/chat-messages.js +6 -0
  21. package/dist/browser/chat/chat-messages.js.map +1 -1
  22. package/dist/browser/chat/command-search.js +10 -3
  23. package/dist/browser/chat/command-search.js.map +1 -1
  24. package/dist/browser/chat/index.js +6 -1
  25. package/dist/browser/chat/index.js.map +1 -1
  26. package/dist/browser/chat/types.js.map +1 -1
  27. package/dist/browser/content/Calendar.js +3 -3
  28. package/dist/browser/content/Calendar.js.map +1 -1
  29. package/dist/browser/content/Chart.js +54 -71
  30. package/dist/browser/content/Chart.js.map +1 -1
  31. package/dist/browser/content/FileBrowser.js +2 -2
  32. package/dist/browser/content/FileBrowser.js.map +1 -1
  33. package/dist/browser/content/FileTree.js +42 -36
  34. package/dist/browser/content/FileTree.js.map +1 -1
  35. package/dist/browser/content/FileTypeIcon.js +72 -0
  36. package/dist/browser/content/FileTypeIcon.js.map +1 -0
  37. package/dist/browser/content/FileView.js +2 -2
  38. package/dist/browser/content/FileView.js.map +1 -1
  39. package/dist/browser/content/ReferenceChip.js +162 -0
  40. package/dist/browser/content/ReferenceChip.js.map +1 -0
  41. package/dist/browser/content/calendar-pointer.js +9 -0
  42. package/dist/browser/content/calendar-pointer.js.map +1 -1
  43. package/dist/browser/content/calendar-time-view.js +6 -3
  44. package/dist/browser/content/calendar-time-view.js.map +1 -1
  45. package/dist/browser/content/index.js +2 -0
  46. package/dist/browser/content/index.js.map +1 -1
  47. package/dist/browser/layout/AppOverview.js +1 -1
  48. package/dist/browser/layout/AppOverview.js.map +1 -1
  49. package/dist/browser/layout/AppWorkspace.js +644 -445
  50. package/dist/browser/layout/AppWorkspace.js.map +1 -1
  51. package/dist/browser/layout/PanelDialog.js +88 -86
  52. package/dist/browser/layout/PanelDialog.js.map +1 -1
  53. package/dist/browser/layout/ResizeSeparator.js +81 -0
  54. package/dist/browser/layout/ResizeSeparator.js.map +1 -0
  55. package/dist/browser/layout/SidebarSwitcher.js +9 -2
  56. package/dist/browser/layout/SidebarSwitcher.js.map +1 -1
  57. package/dist/browser/layout/TabBar.js +15 -12
  58. package/dist/browser/layout/TabBar.js.map +1 -1
  59. package/dist/browser/layout/app-workspace-controller.js +130 -17
  60. package/dist/browser/layout/app-workspace-controller.js.map +1 -1
  61. package/dist/browser/layout/index.js +3 -1
  62. package/dist/browser/layout/index.js.map +1 -1
  63. package/dist/browser/layout/resize-separator.js +90 -0
  64. package/dist/browser/layout/resize-separator.js.map +1 -0
  65. package/dist/browser/layout/workspace-messages.js +12 -2
  66. package/dist/browser/layout/workspace-messages.js.map +1 -1
  67. package/dist/browser/surfaces/LinkCard.js +1 -1
  68. package/dist/browser/surfaces/LinkCard.js.map +1 -1
  69. package/dist/browser/surfaces/Placeholder.js +14 -3
  70. package/dist/browser/surfaces/Placeholder.js.map +1 -1
  71. package/dist/browser/surfaces/StatCell.js +23 -0
  72. package/dist/browser/surfaces/StatCell.js.map +1 -1
  73. package/dist/browser/widgets/Widget.js +1 -1
  74. package/dist/browser/widgets/Widget.js.map +1 -1
  75. package/dist/ssr/actions/ContextMenu.js +5 -0
  76. package/dist/ssr/actions/ContextMenu.js.map +1 -1
  77. package/dist/ssr/actions/DragAndDrop.js +63 -0
  78. package/dist/ssr/actions/DragAndDrop.js.map +1 -0
  79. package/dist/ssr/actions/GestureMenu.js +26 -3
  80. package/dist/ssr/actions/GestureMenu.js.map +1 -1
  81. package/dist/ssr/actions/drag-and-drop-messages.js +75 -0
  82. package/dist/ssr/actions/drag-and-drop-messages.js.map +1 -0
  83. package/dist/ssr/actions/drag-and-drop.js +692 -0
  84. package/dist/ssr/actions/drag-and-drop.js.map +1 -0
  85. package/dist/ssr/actions/index.js +1 -0
  86. package/dist/ssr/actions/index.js.map +1 -1
  87. package/dist/ssr/chat/ChatComposer.js +131 -14
  88. package/dist/ssr/chat/ChatComposer.js.map +1 -1
  89. package/dist/ssr/chat/ChatDecision.js +465 -0
  90. package/dist/ssr/chat/ChatDecision.js.map +1 -0
  91. package/dist/ssr/chat/ChatPrimitives.js +2 -2
  92. package/dist/ssr/chat/ChatPrimitives.js.map +1 -1
  93. package/dist/ssr/chat/ChatTimeline.js.map +1 -1
  94. package/dist/ssr/chat/chat-messages.js +6 -0
  95. package/dist/ssr/chat/chat-messages.js.map +1 -1
  96. package/dist/ssr/chat/command-search.js +10 -3
  97. package/dist/ssr/chat/command-search.js.map +1 -1
  98. package/dist/ssr/chat/index.js +6 -1
  99. package/dist/ssr/chat/index.js.map +1 -1
  100. package/dist/ssr/chat/types.js.map +1 -1
  101. package/dist/ssr/content/Calendar.js +3 -3
  102. package/dist/ssr/content/Calendar.js.map +1 -1
  103. package/dist/ssr/content/Chart.js +19 -23
  104. package/dist/ssr/content/Chart.js.map +1 -1
  105. package/dist/ssr/content/FileBrowser.js +2 -2
  106. package/dist/ssr/content/FileBrowser.js.map +1 -1
  107. package/dist/ssr/content/FileTree.js +21 -14
  108. package/dist/ssr/content/FileTree.js.map +1 -1
  109. package/dist/ssr/content/FileTypeIcon.js +50 -0
  110. package/dist/ssr/content/FileTypeIcon.js.map +1 -0
  111. package/dist/ssr/content/FileView.js +2 -2
  112. package/dist/ssr/content/FileView.js.map +1 -1
  113. package/dist/ssr/content/ReferenceChip.js +121 -0
  114. package/dist/ssr/content/ReferenceChip.js.map +1 -0
  115. package/dist/ssr/content/calendar-pointer.js +9 -0
  116. package/dist/ssr/content/calendar-pointer.js.map +1 -1
  117. package/dist/ssr/content/calendar-time-view.js +6 -3
  118. package/dist/ssr/content/calendar-time-view.js.map +1 -1
  119. package/dist/ssr/content/index.js +2 -0
  120. package/dist/ssr/content/index.js.map +1 -1
  121. package/dist/ssr/layout/AppOverview.js +1 -1
  122. package/dist/ssr/layout/AppOverview.js.map +1 -1
  123. package/dist/ssr/layout/AppWorkspace.js +272 -95
  124. package/dist/ssr/layout/AppWorkspace.js.map +1 -1
  125. package/dist/ssr/layout/PanelDialog.js +7 -6
  126. package/dist/ssr/layout/PanelDialog.js.map +1 -1
  127. package/dist/ssr/layout/ResizeSeparator.js +45 -0
  128. package/dist/ssr/layout/ResizeSeparator.js.map +1 -0
  129. package/dist/ssr/layout/SidebarSwitcher.js +9 -2
  130. package/dist/ssr/layout/SidebarSwitcher.js.map +1 -1
  131. package/dist/ssr/layout/TabBar.js +1 -1
  132. package/dist/ssr/layout/TabBar.js.map +1 -1
  133. package/dist/ssr/layout/app-workspace-controller.js +130 -17
  134. package/dist/ssr/layout/app-workspace-controller.js.map +1 -1
  135. package/dist/ssr/layout/index.js +3 -1
  136. package/dist/ssr/layout/index.js.map +1 -1
  137. package/dist/ssr/layout/resize-separator.js +90 -0
  138. package/dist/ssr/layout/resize-separator.js.map +1 -0
  139. package/dist/ssr/layout/workspace-messages.js +12 -2
  140. package/dist/ssr/layout/workspace-messages.js.map +1 -1
  141. package/dist/ssr/surfaces/LinkCard.js +1 -1
  142. package/dist/ssr/surfaces/LinkCard.js.map +1 -1
  143. package/dist/ssr/surfaces/Placeholder.js +4 -2
  144. package/dist/ssr/surfaces/Placeholder.js.map +1 -1
  145. package/dist/ssr/surfaces/StatCell.js +23 -0
  146. package/dist/ssr/surfaces/StatCell.js.map +1 -1
  147. package/dist/ssr/widgets/Widget.js +1 -1
  148. package/dist/ssr/widgets/Widget.js.map +1 -1
  149. package/dist/styles.css +1 -1
  150. package/dist/types/actions/ContextMenu.d.ts +1 -0
  151. package/dist/types/actions/DragAndDrop.d.ts +29 -0
  152. package/dist/types/actions/drag-and-drop-messages.d.ts +35 -0
  153. package/dist/types/actions/drag-and-drop.d.ts +36 -0
  154. package/dist/types/actions/index.d.ts +2 -0
  155. package/dist/types/chat/ChatComposer.d.ts +19 -1
  156. package/dist/types/chat/ChatDecision.d.ts +133 -0
  157. package/dist/types/chat/ChatPrimitives.d.ts +4 -1
  158. package/dist/types/chat/ChatTimeline.d.ts +2 -1
  159. package/dist/types/chat/chat-messages.d.ts +3 -0
  160. package/dist/types/chat/command-search.d.ts +3 -0
  161. package/dist/types/chat/index.d.ts +23 -1
  162. package/dist/types/chat/types.d.ts +54 -1
  163. package/dist/types/content/Chart.d.ts +9 -3
  164. package/dist/types/content/FileTypeIcon.d.ts +27 -0
  165. package/dist/types/content/ReferenceChip.d.ts +49 -0
  166. package/dist/types/content/calendar-pointer.d.ts +6 -0
  167. package/dist/types/content/index.d.ts +3 -0
  168. package/dist/types/layout/AppWorkspace.d.ts +5 -3
  169. package/dist/types/layout/ResizeSeparator.d.ts +9 -0
  170. package/dist/types/layout/TabBar.d.ts +7 -0
  171. package/dist/types/layout/app-workspace-controller.d.ts +2 -0
  172. package/dist/types/layout/index.d.ts +3 -1
  173. package/dist/types/layout/resize-separator.d.ts +18 -0
  174. package/dist/types/layout/workspace-messages.d.ts +5 -0
  175. package/dist/types/surfaces/StatCell.d.ts +6 -0
  176. package/package.json +2 -2
@@ -5,11 +5,9 @@ import { createComponent as _$createComponent } from "solid-js/web";
5
5
  import { ssr as _$ssr } from "solid-js/web";
6
6
  import { escape as _$escape } from "solid-js/web";
7
7
  var _tmpl$ = ["<i class=\"", "\" aria-hidden=\"true\"></i>"],
8
- _tmpl$2 = "<span class=\"k2b-chart__anchor\" aria-hidden=\"true\"></span>",
9
- _tmpl$3 = ["<span", " role=\"tooltip\" popover=\"manual\" data-instant=\"true\" class=\"k2b-tooltip k2b-chart__tooltip\"></span>"],
10
- _tmpl$4 = ["<div class=\"k2b-chart__controls\">", "", "", "</div>"],
11
- _tmpl$5 = ["<div class=\"", "\"", " style=\"", "\" role=\"group\"", "><div class=\"k2b-chart__svg\"", " style=\"", "\">", "</div>", "", "</div>"],
12
- _tmpl$6 = ["<div class=\"", "\" style=\"", "\">", "</div>"];
8
+ _tmpl$2 = ["<div class=\"k2b-chart__controls\">", "", "", "</div>"],
9
+ _tmpl$3 = ["<div class=\"", "\"", " data-interactive=\"true\" style=\"", "\" role=\"group\"", " tabindex=\"0\"><div class=\"k2b-chart__svg\"", " style=\"", "\">", "</div><span class=\"k2b-chart__anchor\" aria-hidden=\"true\"></span><span", " role=\"tooltip\" popover=\"manual\" data-instant=\"true\" class=\"k2b-tooltip k2b-chart__tooltip\"></span>", "</div>"],
10
+ _tmpl$4 = ["<div class=\"", "\" style=\"", "\">", "</div>"];
13
11
  import { charts } from "@k2b/stdlib";
14
12
  import { createEffect, createMemo, createSignal, createUniqueId, onCleanup, onMount, Show, splitProps, untrack } from "solid-js";
15
13
  import { isServer } from "solid-js/web";
@@ -47,9 +45,9 @@ import { useViewportMessages } from "./viewport-messages";
47
45
  * **Why so thin.** The props are a discriminated union over each
48
46
  * stdlib chart function — `kind: "line"` brings in exactly the params
49
47
  * `charts.line` expects, `kind: "bar"` brings in `charts.bar`'s, etc.
50
- * Options stay aligned with stdlib without renaming. Shared interactive
51
- * layers add bounded pan / zoom controls to maps and state timelines, plus
52
- * renderer-owned inspection, tooltips and optional selection for all chart kinds.
48
+ * Options stay aligned with stdlib without renaming. Every chart provides
49
+ * renderer-owned inspection, tooltips and optional selection by default.
50
+ * `interactive` adds bounded pan / zoom and reset controls to maps and state timelines.
53
51
  * If stdlib gains a new option, it's automatically available at every
54
52
  * callsite.
55
53
  *
@@ -117,7 +115,7 @@ export const renderChartSvg = (props, width, height, mapViewport, timelineViewpo
117
115
  width,
118
116
  height,
119
117
  viewport: timelineViewport,
120
- interactive: props.interactive
118
+ interactive: true
121
119
  }));
122
120
  }
123
121
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -128,7 +126,7 @@ export const renderChartSvg = (props, width, height, mapViewport, timelineViewpo
128
126
  } : {}),
129
127
  width,
130
128
  height,
131
- inspect: props.interactive === true || props.kind === "line" && props.maxGap !== undefined
129
+ inspect: true
132
130
  });
133
131
  if (props.kind === "line" && props.maxGap !== undefined) {
134
132
  if (props.area || props.errorBand) throw new Error("Chart maxGap does not support area or errorBand fills");
@@ -190,10 +188,15 @@ const Chart = props => {
190
188
  let pendingPointer;
191
189
  const interactiveMap = () => props.kind === "map" && props.interactive === true;
192
190
  const interactiveTimeline = () => props.kind === "stateTimeline" && props.interactive === true;
193
- const interactiveLine = () => props.kind === "line" && props.interactive === true;
194
- const interactive = () => props.interactive === true;
195
191
  const draggable = () => interactiveMap() || interactiveTimeline();
196
192
  const labels = () => props.labels ?? {};
193
+ const accessibleName = () => {
194
+ const override = props.kind === "map" ? labels().interactiveMap : props.kind === "stateTimeline" ? labels().interactiveTimeline : props.kind === "line" ? labels().interactiveLine : labels().interactiveChart;
195
+ const title = "title" in props && typeof props.title === "string" && props.title.trim() ? props.title : undefined;
196
+ const valueLabel = (props.kind === "stat" || props.kind === "gauge") && props.label?.trim() ? props.label : undefined;
197
+ const fallback = props.kind === "map" ? chartMessages().interactiveMap : props.kind === "stateTimeline" ? chartMessages().interactiveTimeline : props.kind === "line" ? chartMessages().interactiveLineChart : chartMessages().interactiveChart;
198
+ return override ?? title ?? valueLabel ?? fallback;
199
+ };
197
200
  const timelineFullDomain = () => props.kind === "stateTimeline" ? stateTimelineDomain(props.rows, props.domain) : [0, 1];
198
201
  createEffect(() => {
199
202
  if (props.kind === "map") {
@@ -380,7 +383,7 @@ const Chart = props => {
380
383
  tooltip: () => chartTooltipRef,
381
384
  anchor: () => lineAnchorRef,
382
385
  kind: () => props.kind,
383
- enabled: interactive,
386
+ enabled: () => !isEmpty(props),
384
387
  select: selection => props.onSelect?.(selection),
385
388
  format: selection => {
386
389
  if (props.tooltip) return props.tooltip(selection);
@@ -438,22 +441,15 @@ const Chart = props => {
438
441
  return !isEmpty(props);
439
442
  },
440
443
  get fallback() {
441
- return _$ssr(_tmpl$6, `k2b-chart k2b-chart__empty ${_$escape(props.class ?? "", true)}`, _$ssrStyle(chartStyle()), _$escape(labels().empty ?? messages().noData));
444
+ return _$ssr(_tmpl$4, `k2b-chart k2b-chart__empty ${_$escape(props.class ?? "", true)}`, _$ssrStyle(chartStyle()), _$escape(labels().empty ?? messages().noData));
442
445
  },
443
446
  get children() {
444
- return _$ssr(_tmpl$5, `k2b-chart ${_$escape(props.class ?? "", true)}`, _$ssrAttribute("data-chart-kind", _$escape(props.kind, true), false) + _$ssrAttribute("data-drag", draggable() ? dragging() ? "active" : "idle" : _$escape(undefined, true), false) + _$ssrAttribute("data-crosshair", !draggable() && interactiveLine() ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-interactive", interactive() ? "true" : _$escape(undefined, true), false), _$ssrStyle(chartStyle()), _$ssrAttribute("aria-label", interactiveMap() ? _$escape(labels().interactiveMap ?? chartMessages().interactiveMap, true) : interactiveTimeline() ? _$escape(labels().interactiveTimeline ?? chartMessages().interactiveTimeline, true) : interactiveLine() ? _$escape(labels().interactiveLine ?? chartMessages().interactiveLineChart, true) : interactive() ? _$escape(labels().interactiveChart ?? chartMessages().interactiveChart, true) : _$escape(undefined, true), false) + _$ssrAttribute("aria-description", interactive() ? _$escape(chartMessages().interactiveChart, true) : _$escape(undefined, true), false) + _$ssrAttribute("tabindex", interactive() ? 0 : _$escape(undefined, true), false), _$ssrAttribute("data-stretch", !preservesAspectRatio(props.kind) ? "true" : _$escape(undefined, true), false), _$ssrStyleProperty("--k2b-chart-width:", `${_$escape(size().width, true)}px`) + _$ssrStyleProperty(";--k2b-chart-height:", `${_$escape(size().height, true)}px`) + _$ssrStyleProperty(";aspect-ratio:", `${_$escape(size().width, true)} / ${_$escape(size().height, true)}`), isServer ? selectedChartSvg(svgMarkup(), props.selected) : svgMarkup(), _$escape(_$createComponent(Show, {
445
- get when() {
446
- return interactive();
447
- },
448
- get children() {
449
- return [_$ssr(_tmpl$2), _$ssr(_tmpl$3, _$ssrAttribute("id", _$escape(chartTooltipId, true), false))];
450
- }
451
- })), _$escape(_$createComponent(Show, {
447
+ return _$ssr(_tmpl$3, `k2b-chart ${_$escape(props.class ?? "", true)}`, _$ssrAttribute("data-chart-kind", _$escape(props.kind, true), false) + _$ssrAttribute("data-drag", draggable() ? dragging() ? "active" : "idle" : _$escape(undefined, true), false) + _$ssrAttribute("data-crosshair", !draggable() && props.kind === "line" ? "true" : _$escape(undefined, true), false), _$ssrStyle(chartStyle()), _$ssrAttribute("aria-label", _$escape(accessibleName(), true), false) + _$ssrAttribute("aria-description", accessibleName() !== chartMessages().interactiveChart ? _$escape(chartMessages().interactiveChart, true) : _$escape(undefined, true), false), _$ssrAttribute("data-stretch", !preservesAspectRatio(props.kind) ? "true" : _$escape(undefined, true), false), _$ssrStyleProperty("--k2b-chart-width:", `${_$escape(size().width, true)}px`) + _$ssrStyleProperty(";--k2b-chart-height:", `${_$escape(size().height, true)}px`) + _$ssrStyleProperty(";aspect-ratio:", `${_$escape(size().width, true)} / ${_$escape(size().height, true)}`), isServer ? selectedChartSvg(svgMarkup(), props.selected) : svgMarkup(), _$ssrAttribute("id", _$escape(chartTooltipId, true), false), _$escape(_$createComponent(Show, {
452
448
  get when() {
453
449
  return draggable();
454
450
  },
455
451
  get children() {
456
- return _$ssr(_tmpl$4, _$escape(control(labels().zoomIn ?? viewportMessages().zoomIn, "+", "ti-plus", () => zoom(1))), _$escape(control(labels().zoomOut ?? viewportMessages().zoomOut, "-", "ti-minus", () => zoom(-1))), _$escape(control(interactiveMap() ? labels().resetMap ?? chartMessages().resetMapView : labels().resetTimeline ?? chartMessages().resetTimelineView, "0", "ti-focus-centered", reset)));
452
+ return _$ssr(_tmpl$2, _$escape(control(labels().zoomIn ?? viewportMessages().zoomIn, "+", "ti-plus", () => zoom(1))), _$escape(control(labels().zoomOut ?? viewportMessages().zoomOut, "-", "ti-minus", () => zoom(-1))), _$escape(control(interactiveMap() ? labels().resetMap ?? chartMessages().resetMapView : labels().resetTimeline ?? chartMessages().resetTimelineView, "0", "ti-focus-centered", reset)));
457
453
  }
458
454
  })));
459
455
  }
@@ -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, 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. Shared interactive\n * layers add bounded pan / zoom controls to maps and state timelines, plus\n * renderer-owned inspection, tooltips and optional selection for all chart kinds.\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 interactive?: boolean;\n onSelect?: (selection: ChartSelection) => void;\n /** Controlled highlight; indices belong to this exact input snapshot. */\n selected?: ChartDatumRef | null;\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\" ? { /** Largest connected X distance; positive, finite, without area/errorBand fills. */ maxGap?: number } : {}) &\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\"\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 ...opts\n } = props as ChartProps & { interactive?: boolean; zoomFocus?: Pick<MapViewport, \"latitude\" | \"longitude\"> };\n if (kind === \"stateTimeline\") {\n return responsiveChartSvg(\n renderStateTimelineSvg({\n ...(opts as StateTimelineChartOptions),\n width,\n height,\n viewport: timelineViewport,\n interactive: props.interactive,\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 ...(kind === \"map\" ? { viewport: DEFAULT_MAP_VIEWPORT } : {}),\n width,\n height,\n inspect: props.interactive === true || (props.kind === \"line\" && props.maxGap !== undefined),\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 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 interactiveLine = () => props.kind === \"line\" && props.interactive === true;\n const interactive = () => props.interactive === true;\n const draggable = () => interactiveMap() || interactiveTimeline();\n const labels = () => props.labels ?? {};\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: interactive,\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-drag={draggable() ? (dragging() ? \"active\" : \"idle\") : undefined}\n data-crosshair={!draggable() && interactiveLine() ? \"true\" : undefined}\n data-interactive={interactive() ? \"true\" : undefined}\n style={chartStyle()}\n role=\"group\"\n aria-label={\n interactiveMap()\n ? (labels().interactiveMap ?? chartMessages().interactiveMap)\n : interactiveTimeline()\n ? (labels().interactiveTimeline ?? chartMessages().interactiveTimeline)\n : interactiveLine()\n ? (labels().interactiveLine ?? chartMessages().interactiveLineChart)\n : interactive()\n ? (labels().interactiveChart ?? chartMessages().interactiveChart)\n : undefined\n }\n aria-description={interactive() ? chartMessages().interactiveChart : undefined}\n tabIndex={interactive() ? 0 : undefined}\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 <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 <Show when={interactive()}>\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>\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, 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\" ? { /** Largest connected X distance; positive, finite, without area/errorBand fills. */ maxGap?: number } : {}) &\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\"\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 ...opts\n } = props as ChartProps & { interactive?: boolean; zoomFocus?: Pick<MapViewport, \"latitude\" | \"longitude\"> };\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 ...(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 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-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 <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":[]}
@@ -272,7 +272,7 @@ export function FileBrowserPanel(props) {
272
272
  },
273
273
  get children() {
274
274
  return _$createComponent(Placeholder, {
275
- icon: "ti ti-loader-2",
275
+ state: "loading",
276
276
  get title() {
277
277
  return fileBrowserMessages().loadingFiles;
278
278
  }
@@ -284,7 +284,7 @@ export function FileBrowserPanel(props) {
284
284
  },
285
285
  get children() {
286
286
  return _$createComponent(Placeholder, {
287
- icon: "ti ti-alert-circle",
287
+ state: "error",
288
288
  get title() {
289
289
  return fileInputMessages().failedLoadFiles;
290
290
  },
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["content/FileBrowser.tsx"],"sourcesContent":["/**\n * FileBrowser — FileTree + FileView over a FileSource adapter. One dialog\n * serves every file surface (conversation VFS, skills, later the Files app):\n * the source decides the capabilities, optional methods enable the matching\n * UI (write → edit/save, remove → delete, rename → rename, upload → upload).\n * Fixed-height IDE-style layout: both panes scroll, the shell never jumps.\n */\nimport { createZip, downloadFileFromContent } from \"@k2b/stdlib/browser\";\nimport { mutation } from \"@k2b/stdlib/solid\";\nimport { createEffect, createMemo, createResource, createSignal, Match, onCleanup, Show, Switch, untrack } from \"solid-js\";\nimport Dropdown from \"../actions/Dropdown\";\nimport { dialogCore } from \"../feedback/dialog-core\";\nimport { prompts } from \"../feedback/prompts\";\nimport { useFileInputMessages } from \"../inputs/file-input-messages\";\nimport { useUiMessages } from \"../intl/messages\";\nimport PanelDialog, { panelDialogOptions } from \"../layout/PanelDialog\";\nimport Placeholder from \"../surfaces/Placeholder\";\nimport FileTree, { type FileTreeEntry } from \"./FileTree\";\nimport FileView, { type FileViewContent, type FileViewRenderer } from \"./FileView\";\nimport { resolveFileBrowserMessages, useFileBrowserMessages } from \"./file-browser-messages\";\n\nexport type FileSource = {\n previewPreferencesKey?: string;\n list(): Promise<FileTreeEntry[]>;\n read(path: string): Promise<FileViewContent>;\n write?(path: string, content: string, encoding?: \"utf8\" | \"base64\"): Promise<void>;\n remove?(path: string): Promise<void>;\n rename?(from: string, to: string): Promise<void>;\n upload?(dirPath: string, files: File[]): Promise<void>;\n downloadHref?(path: string): string | null;\n /** Paths matching this predicate stay read-only even when the source can write (e.g. /input). */\n isReadOnly?(path: string): boolean;\n};\n\nexport type FileBrowserPanelProps = {\n source: FileSource;\n /** Hide every mutating affordance while retaining file selection and downloads. */\n readOnly?: boolean;\n /** Refetch entries when this host-controlled value changes. */\n refreshKey?: unknown;\n /** Preselect a file once entries are loaded. */\n initialPath?: string;\n /** Mirrors file selection into route state when the host needs durable navigation. */\n onSelectedPathChange?: (path: string | null) => void;\n /** Per-instance preview extensions forwarded to FileView. */\n renderers?: readonly FileViewRenderer[];\n /** Optional host copy/policy for leaving an unsaved file. */\n confirmDiscard?: (path: string, nextPath: string | null) => boolean | Promise<boolean>;\n /** Fixed shell height — the panes scroll inside it. */\n class?: string;\n /** Optional imperative refresh used by realtime owners that must await the visible update. */\n registerRefresh?: (refresh: () => Promise<void>) => void | (() => void);\n};\n\nconst parentOf = (path: string): string => {\n const index = path.lastIndexOf(\"/\");\n return index <= 0 ? \"/\" : path.slice(0, index);\n};\n\nexport function FileBrowserPanel(props: FileBrowserPanelProps) {\n const messages = useUiMessages();\n const fileBrowserMessages = useFileBrowserMessages();\n const fileInputMessages = useFileInputMessages();\n // FileSource is an imperative adapter. Its methods may read host signals,\n // but refreshes stay owned by this component (`refetch` / `refreshKey`);\n // tracking those implementation details can otherwise feed a write back\n // into its own list request indefinitely.\n const [entries, { refetch }] = createResource(async () => untrack(() => props.source.list()));\n const [selectedPath, setSelectedPath] = createSignal<string | null>(props.initialPath ?? null);\n const [selectedDirty, setSelectedDirty] = createSignal(false);\n // Folders exist implicitly through file paths — freshly created (still empty)\n // ones live here until their first file makes them real.\n const [pendingFolders, setPendingFolders] = createSignal<string[]>([]);\n let uploadInputRef: HTMLInputElement | undefined;\n let uploadDir = \"/\";\n let previousRefreshKey = props.refreshKey;\n let refreshPreview = async (): Promise<void> => undefined;\n\n createEffect(() => {\n if (!props.registerRefresh) return;\n const unregister = props.registerRefresh(async () => {\n await Promise.all([refetch(), refreshPreview()]);\n });\n if (unregister) onCleanup(unregister);\n });\n\n createEffect(() => {\n const next = props.initialPath ?? null;\n if (!selectedDirty() && next !== selectedPath()) setSelectedPath(next);\n });\n createEffect(() => props.onSelectedPathChange?.(selectedPath()));\n createEffect(() => {\n const refreshKey = props.refreshKey;\n if (Object.is(refreshKey, previousRefreshKey)) return;\n previousRefreshKey = refreshKey;\n void refetch();\n });\n\n const allEntries = createMemo<FileTreeEntry[]>(() => {\n const loaded = entries() ?? [];\n const real = new Set(loaded.map((entry) => entry.path));\n return [\n ...loaded,\n ...pendingFolders()\n .filter((path) => !real.has(path))\n .map((path) => ({ path, kind: \"folder\" as const })),\n ];\n });\n const selectedEntry = createMemo(() => allEntries().find((entry) => entry.path === selectedPath()) ?? null);\n const fileMutation = mutation.create<void, () => Promise<void>>({\n mutation: (work) => work(),\n onSuccess: () => void refetch(),\n onError: (error) => void prompts.error(error.message),\n });\n const pathMutable = (path: string) => !fileMutation.loading() && !props.readOnly && !props.source.isReadOnly?.(path);\n const pathWritable = (path: string) => pathMutable(path) && Boolean(props.source.write);\n const run = (work: () => Promise<void>) => void fileMutation.mutate(work);\n const canLeaveCurrent = async (nextPath: string | null): Promise<boolean> => {\n const current = selectedPath();\n if (nextPath === current || !selectedDirty() || !current) return true;\n if (selectedDirty() && current) {\n const confirmed = props.confirmDiscard\n ? await props.confirmDiscard(current, nextPath)\n : await prompts.confirm(fileBrowserMessages().discardUnsavedFile, {\n title: fileBrowserMessages().discardChanges,\n variant: \"danger\",\n });\n if (!confirmed) return false;\n }\n return true;\n };\n const selectPath = async (nextPath: string | null) => {\n if (!(await canLeaveCurrent(nextPath))) return;\n setSelectedDirty(false);\n setSelectedPath(nextPath);\n };\n\n const removeFile = (path: string) =>\n run(async () => {\n const confirmed = await prompts.confirm(`Delete ${path}?`, { title: \"Delete file\", variant: \"danger\" });\n if (!confirmed) return;\n await props.source.remove!(path);\n setPendingFolders((folders) => folders.filter((candidate) => candidate !== path && !candidate.startsWith(`${path}/`)));\n const selected = selectedPath();\n if (selected === path || selected?.startsWith(`${path}/`)) setSelectedPath(null);\n });\n\n const renameFile = (path: string, nextName: string) =>\n run(async () => {\n const target = `${parentOf(path) === \"/\" ? \"\" : parentOf(path)}/${nextName}`;\n await props.source.rename!(path, target);\n if (selectedPath() === path) setSelectedPath(target);\n });\n\n const createFile = (dirPath: string) =>\n run(async () => {\n const name = await prompts.prompt(fileBrowserMessages().newFileName, \"\", { title: fileBrowserMessages().newFile });\n if (!name || typeof name !== \"string\" || !name.trim() || name.includes(\"/\")) return;\n const path = `${dirPath === \"/\" ? \"\" : dirPath}/${name.trim()}`;\n if (!(await canLeaveCurrent(path))) return;\n await props.source.write!(path, \"\");\n setSelectedDirty(false);\n setSelectedPath(path);\n });\n\n const createFolder = (dirPath: string) =>\n void (async () => {\n const name = await prompts.prompt(fileBrowserMessages().newFolderName, \"\", { title: fileBrowserMessages().newFolder });\n if (!name || typeof name !== \"string\" || !name.trim() || name.includes(\"/\")) return;\n const path = `${dirPath === \"/\" ? \"\" : dirPath}/${name.trim()}`;\n setPendingFolders((folders) => [...folders, path]);\n })();\n\n const pickUpload = (dirPath: string) => {\n uploadDir = dirPath;\n uploadInputRef?.click();\n };\n\n const onUploadPicked = (input: HTMLInputElement) => {\n const files = Array.from(input.files ?? []);\n input.value = \"\";\n if (files.length > 0) run(() => props.source.upload!(uploadDir, files));\n };\n\n const baseName = (path: string) => path.slice(path.lastIndexOf(\"/\") + 1);\n\n /** Concrete file paths behind an entry: the file itself, or everything under a folder. */\n const filesBehind = (path: string): string[] => {\n const list = entries() ?? [];\n if (list.some((entry) => entry.path === path && entry.kind !== \"folder\")) return [path];\n const prefix = `${path}/`;\n return list.filter((entry) => entry.path.startsWith(prefix) && entry.kind !== \"folder\").map((entry) => entry.path);\n };\n\n /** Move a file OR a whole folder subtree (per-file renames preserve the structure). */\n const moveEntry = (path: string, targetDir: string) =>\n run(async () => {\n const destBase = `${targetDir === \"/\" ? \"\" : targetDir}/${baseName(path)}`;\n const files = filesBehind(path);\n if (files.length === 0) {\n // Still-empty pending folder — relocating it is a purely local affair.\n setPendingFolders((folders) => folders.map((candidate) => (candidate === path ? destBase : candidate)));\n return;\n }\n for (const file of files) {\n await props.source.rename!(file, `${destBase}${file.slice(path.length)}`);\n }\n const selected = selectedPath();\n if (selected && (selected === path || selected.startsWith(`${path}/`))) {\n setSelectedPath(`${destBase}${selected.slice(path.length)}`);\n }\n });\n\n const contentBytes = async (path: string): Promise<Uint8Array> => {\n const content = await props.source.read(path);\n return content.encoding === \"utf8\"\n ? new TextEncoder().encode(content.content)\n : Uint8Array.from(atob(content.content), (char) => char.charCodeAt(0));\n };\n\n const downloadEntry = (path: string, isFolder: boolean) =>\n void (async () => {\n try {\n if (!isFolder) {\n const href = props.source.downloadHref?.(path);\n if (href) {\n const anchor = document.createElement(\"a\");\n anchor.href = href;\n anchor.download = baseName(path);\n anchor.click();\n return;\n }\n const content = await props.source.read(path);\n downloadFileFromContent(await contentBytes(path), baseName(path), content.mediaType || \"application/octet-stream\");\n return;\n }\n const files = filesBehind(path);\n if (files.length === 0) throw new Error(fileBrowserMessages().folderEmpty);\n const zipEntries = await Promise.all(\n files.map(async (file) => ({ filename: file.slice(path.length + 1), source: await contentBytes(file) })),\n );\n downloadFileFromContent(await createZip(zipEntries), `${baseName(path) || \"files\"}.zip`, \"application/zip\");\n } catch (error) {\n void prompts.error(error instanceof Error ? error.message : fileBrowserMessages().downloadFailed);\n }\n })();\n\n const treeActions = () => ({\n ...(!props.readOnly && props.source.rename\n ? { rename: (path: string, next: string) => (pathMutable(path) ? renameFile(path, next) : undefined) }\n : {}),\n ...(!props.readOnly && props.source.remove ? { remove: (path: string) => (pathMutable(path) ? removeFile(path) : undefined) } : {}),\n ...(!props.readOnly && props.source.write ? { createFile: (dir: string) => (pathWritable(dir) ? createFile(dir) : undefined) } : {}),\n ...(!props.readOnly && props.source.write\n ? { createFolder: (dir: string) => (pathWritable(dir) ? createFolder(dir) : undefined) }\n : {}),\n ...(!props.readOnly && props.source.rename\n ? { move: (path: string, dir: string) => (pathMutable(path) && pathMutable(dir) ? moveEntry(path, dir) : undefined) }\n : {}),\n download: (path: string, isFolder: boolean) => downloadEntry(path, isFolder),\n });\n\n const addMenuItems = () => [\n ...(pathWritable(\"/\") ? [{ icon: \"ti ti-file-plus\", label: fileBrowserMessages().newFile, action: () => createFile(\"/\") }] : []),\n ...(pathWritable(\"/\") ? [{ icon: \"ti ti-folder-plus\", label: fileBrowserMessages().newFolder, action: () => createFolder(\"/\") }] : []),\n ...(pathMutable(\"/\") && props.source.upload\n ? [{ icon: \"ti ti-upload\", label: fileBrowserMessages().uploadFiles, action: () => pickUpload(\"/\") }]\n : []),\n ];\n\n return (\n <div class={`k2b-content-file-browser ${props.class ?? \"\"}`} data-default-height={props.class ? undefined : \"true\"}>\n <div class=\"k2b-content-file-browser__sidebar\">\n <div class=\"k2b-content-file-browser__header\">\n <p class=\"k2b-content-file-browser__title\">{fileBrowserMessages().files}</p>\n <Show when={addMenuItems().length > 0}>\n <Dropdown.Root position=\"bottom-left\" items={addMenuItems()} label={fileBrowserMessages().addFileFolderUpload}>\n <Dropdown.Trigger\n appearance=\"plain\"\n class=\"k2b-content-file-browser__add\"\n label={fileBrowserMessages().addFileFolderUpload}\n tooltip={messages().add}\n >\n <i class=\"ti ti-plus\" aria-hidden=\"true\" />\n <span class=\"k2b-sr-only\">{fileBrowserMessages().addFileFolderUpload}</span>\n </Dropdown.Trigger>\n </Dropdown.Root>\n </Show>\n </div>\n <Switch>\n <Match when={entries.loading && entries() === undefined}>\n <Placeholder icon=\"ti ti-loader-2\" title={fileBrowserMessages().loadingFiles} />\n </Match>\n <Match when={entries.error}>\n <Placeholder\n icon=\"ti ti-alert-circle\"\n title={fileInputMessages().failedLoadFiles}\n description={String(entries.error?.message ?? entries.error ?? \"\")}\n />\n </Match>\n <Match when={allEntries().length > 0}>\n <FileTree\n class=\"k2b-content-file-browser__tree\"\n entries={allEntries()}\n selectedPath={selectedPath()}\n onSelect={(entry) => void selectPath(entry.path)}\n actions={treeActions()}\n />\n </Match>\n <Match when={true}>\n <Placeholder icon=\"ti ti-folder-open\" title={fileBrowserMessages().noFiles} description={fileBrowserMessages().spaceEmpty} />\n </Match>\n </Switch>\n <input\n ref={uploadInputRef}\n type=\"file\"\n multiple\n class=\"k2b-content-file-browser__upload\"\n onChange={(event) => onUploadPicked(event.currentTarget)}\n />\n </div>\n\n <Switch\n fallback={\n <Placeholder icon=\"ti ti-file\" title={fileBrowserMessages().selectFile} description={fileBrowserMessages().pickFileFromTree} />\n }\n >\n <Match when={selectedEntry()?.kind === \"folder\"}>\n <Placeholder\n icon=\"ti ti-folder\"\n title={fileBrowserMessages().folderSelected}\n description={fileBrowserMessages().chooseFileToPreview}\n />\n </Match>\n <Match when={selectedEntry()}>\n {(entry) => (\n <FileView\n previewPreferencesKey={props.source.previewPreferencesKey}\n file={{ path: entry().path, mediaType: entry().mediaType, size: entry().size }}\n load={() => props.source.read(entry().path)}\n revision={props.refreshKey}\n registerRefresh={(refresh) => {\n refreshPreview = refresh;\n return () => {\n refreshPreview = async () => undefined;\n };\n }}\n renderers={props.renderers}\n onDirtyChange={setSelectedDirty}\n save={\n pathWritable(entry().path)\n ? async (content) => {\n await props.source.write!(entry().path, content);\n await refetch();\n }\n : undefined\n }\n downloadHref={props.source.downloadHref?.(entry().path) ?? null}\n />\n )}\n </Match>\n </Switch>\n </div>\n );\n}\n\n/** Open the file browser as a dialog. Returns when the dialog closes. */\nexport const openFileBrowser = (options: { source: FileSource; title?: string; subtitle?: string; icon?: string }): Promise<void> => {\n const fileBrowserMessages = resolveFileBrowserMessages();\n return dialogCore.open<void>(\n (close) => (\n <PanelDialog>\n <PanelDialog.Header\n title={options.title ?? fileBrowserMessages.files}\n subtitle={options.subtitle}\n icon={options.icon ?? \"ti ti-folder\"}\n close={() => close()}\n />\n <PanelDialog.Body>\n <FileBrowserPanel source={options.source} />\n </PanelDialog.Body>\n </PanelDialog>\n ),\n panelDialogOptions,\n );\n};\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["content/FileBrowser.tsx"],"sourcesContent":["/**\n * FileBrowser — FileTree + FileView over a FileSource adapter. One dialog\n * serves every file surface (conversation VFS, skills, later the Files app):\n * the source decides the capabilities, optional methods enable the matching\n * UI (write → edit/save, remove → delete, rename → rename, upload → upload).\n * Fixed-height IDE-style layout: both panes scroll, the shell never jumps.\n */\nimport { createZip, downloadFileFromContent } from \"@k2b/stdlib/browser\";\nimport { mutation } from \"@k2b/stdlib/solid\";\nimport { createEffect, createMemo, createResource, createSignal, Match, onCleanup, Show, Switch, untrack } from \"solid-js\";\nimport Dropdown from \"../actions/Dropdown\";\nimport { dialogCore } from \"../feedback/dialog-core\";\nimport { prompts } from \"../feedback/prompts\";\nimport { useFileInputMessages } from \"../inputs/file-input-messages\";\nimport { useUiMessages } from \"../intl/messages\";\nimport PanelDialog, { panelDialogOptions } from \"../layout/PanelDialog\";\nimport Placeholder from \"../surfaces/Placeholder\";\nimport FileTree, { type FileTreeEntry } from \"./FileTree\";\nimport FileView, { type FileViewContent, type FileViewRenderer } from \"./FileView\";\nimport { resolveFileBrowserMessages, useFileBrowserMessages } from \"./file-browser-messages\";\n\nexport type FileSource = {\n previewPreferencesKey?: string;\n list(): Promise<FileTreeEntry[]>;\n read(path: string): Promise<FileViewContent>;\n write?(path: string, content: string, encoding?: \"utf8\" | \"base64\"): Promise<void>;\n remove?(path: string): Promise<void>;\n rename?(from: string, to: string): Promise<void>;\n upload?(dirPath: string, files: File[]): Promise<void>;\n downloadHref?(path: string): string | null;\n /** Paths matching this predicate stay read-only even when the source can write (e.g. /input). */\n isReadOnly?(path: string): boolean;\n};\n\nexport type FileBrowserPanelProps = {\n source: FileSource;\n /** Hide every mutating affordance while retaining file selection and downloads. */\n readOnly?: boolean;\n /** Refetch entries when this host-controlled value changes. */\n refreshKey?: unknown;\n /** Preselect a file once entries are loaded. */\n initialPath?: string;\n /** Mirrors file selection into route state when the host needs durable navigation. */\n onSelectedPathChange?: (path: string | null) => void;\n /** Per-instance preview extensions forwarded to FileView. */\n renderers?: readonly FileViewRenderer[];\n /** Optional host copy/policy for leaving an unsaved file. */\n confirmDiscard?: (path: string, nextPath: string | null) => boolean | Promise<boolean>;\n /** Fixed shell height — the panes scroll inside it. */\n class?: string;\n /** Optional imperative refresh used by realtime owners that must await the visible update. */\n registerRefresh?: (refresh: () => Promise<void>) => void | (() => void);\n};\n\nconst parentOf = (path: string): string => {\n const index = path.lastIndexOf(\"/\");\n return index <= 0 ? \"/\" : path.slice(0, index);\n};\n\nexport function FileBrowserPanel(props: FileBrowserPanelProps) {\n const messages = useUiMessages();\n const fileBrowserMessages = useFileBrowserMessages();\n const fileInputMessages = useFileInputMessages();\n // FileSource is an imperative adapter. Its methods may read host signals,\n // but refreshes stay owned by this component (`refetch` / `refreshKey`);\n // tracking those implementation details can otherwise feed a write back\n // into its own list request indefinitely.\n const [entries, { refetch }] = createResource(async () => untrack(() => props.source.list()));\n const [selectedPath, setSelectedPath] = createSignal<string | null>(props.initialPath ?? null);\n const [selectedDirty, setSelectedDirty] = createSignal(false);\n // Folders exist implicitly through file paths — freshly created (still empty)\n // ones live here until their first file makes them real.\n const [pendingFolders, setPendingFolders] = createSignal<string[]>([]);\n let uploadInputRef: HTMLInputElement | undefined;\n let uploadDir = \"/\";\n let previousRefreshKey = props.refreshKey;\n let refreshPreview = async (): Promise<void> => undefined;\n\n createEffect(() => {\n if (!props.registerRefresh) return;\n const unregister = props.registerRefresh(async () => {\n await Promise.all([refetch(), refreshPreview()]);\n });\n if (unregister) onCleanup(unregister);\n });\n\n createEffect(() => {\n const next = props.initialPath ?? null;\n if (!selectedDirty() && next !== selectedPath()) setSelectedPath(next);\n });\n createEffect(() => props.onSelectedPathChange?.(selectedPath()));\n createEffect(() => {\n const refreshKey = props.refreshKey;\n if (Object.is(refreshKey, previousRefreshKey)) return;\n previousRefreshKey = refreshKey;\n void refetch();\n });\n\n const allEntries = createMemo<FileTreeEntry[]>(() => {\n const loaded = entries() ?? [];\n const real = new Set(loaded.map((entry) => entry.path));\n return [\n ...loaded,\n ...pendingFolders()\n .filter((path) => !real.has(path))\n .map((path) => ({ path, kind: \"folder\" as const })),\n ];\n });\n const selectedEntry = createMemo(() => allEntries().find((entry) => entry.path === selectedPath()) ?? null);\n const fileMutation = mutation.create<void, () => Promise<void>>({\n mutation: (work) => work(),\n onSuccess: () => void refetch(),\n onError: (error) => void prompts.error(error.message),\n });\n const pathMutable = (path: string) => !fileMutation.loading() && !props.readOnly && !props.source.isReadOnly?.(path);\n const pathWritable = (path: string) => pathMutable(path) && Boolean(props.source.write);\n const run = (work: () => Promise<void>) => void fileMutation.mutate(work);\n const canLeaveCurrent = async (nextPath: string | null): Promise<boolean> => {\n const current = selectedPath();\n if (nextPath === current || !selectedDirty() || !current) return true;\n if (selectedDirty() && current) {\n const confirmed = props.confirmDiscard\n ? await props.confirmDiscard(current, nextPath)\n : await prompts.confirm(fileBrowserMessages().discardUnsavedFile, {\n title: fileBrowserMessages().discardChanges,\n variant: \"danger\",\n });\n if (!confirmed) return false;\n }\n return true;\n };\n const selectPath = async (nextPath: string | null) => {\n if (!(await canLeaveCurrent(nextPath))) return;\n setSelectedDirty(false);\n setSelectedPath(nextPath);\n };\n\n const removeFile = (path: string) =>\n run(async () => {\n const confirmed = await prompts.confirm(`Delete ${path}?`, { title: \"Delete file\", variant: \"danger\" });\n if (!confirmed) return;\n await props.source.remove!(path);\n setPendingFolders((folders) => folders.filter((candidate) => candidate !== path && !candidate.startsWith(`${path}/`)));\n const selected = selectedPath();\n if (selected === path || selected?.startsWith(`${path}/`)) setSelectedPath(null);\n });\n\n const renameFile = (path: string, nextName: string) =>\n run(async () => {\n const target = `${parentOf(path) === \"/\" ? \"\" : parentOf(path)}/${nextName}`;\n await props.source.rename!(path, target);\n if (selectedPath() === path) setSelectedPath(target);\n });\n\n const createFile = (dirPath: string) =>\n run(async () => {\n const name = await prompts.prompt(fileBrowserMessages().newFileName, \"\", { title: fileBrowserMessages().newFile });\n if (!name || typeof name !== \"string\" || !name.trim() || name.includes(\"/\")) return;\n const path = `${dirPath === \"/\" ? \"\" : dirPath}/${name.trim()}`;\n if (!(await canLeaveCurrent(path))) return;\n await props.source.write!(path, \"\");\n setSelectedDirty(false);\n setSelectedPath(path);\n });\n\n const createFolder = (dirPath: string) =>\n void (async () => {\n const name = await prompts.prompt(fileBrowserMessages().newFolderName, \"\", { title: fileBrowserMessages().newFolder });\n if (!name || typeof name !== \"string\" || !name.trim() || name.includes(\"/\")) return;\n const path = `${dirPath === \"/\" ? \"\" : dirPath}/${name.trim()}`;\n setPendingFolders((folders) => [...folders, path]);\n })();\n\n const pickUpload = (dirPath: string) => {\n uploadDir = dirPath;\n uploadInputRef?.click();\n };\n\n const onUploadPicked = (input: HTMLInputElement) => {\n const files = Array.from(input.files ?? []);\n input.value = \"\";\n if (files.length > 0) run(() => props.source.upload!(uploadDir, files));\n };\n\n const baseName = (path: string) => path.slice(path.lastIndexOf(\"/\") + 1);\n\n /** Concrete file paths behind an entry: the file itself, or everything under a folder. */\n const filesBehind = (path: string): string[] => {\n const list = entries() ?? [];\n if (list.some((entry) => entry.path === path && entry.kind !== \"folder\")) return [path];\n const prefix = `${path}/`;\n return list.filter((entry) => entry.path.startsWith(prefix) && entry.kind !== \"folder\").map((entry) => entry.path);\n };\n\n /** Move a file OR a whole folder subtree (per-file renames preserve the structure). */\n const moveEntry = (path: string, targetDir: string) =>\n run(async () => {\n const destBase = `${targetDir === \"/\" ? \"\" : targetDir}/${baseName(path)}`;\n const files = filesBehind(path);\n if (files.length === 0) {\n // Still-empty pending folder — relocating it is a purely local affair.\n setPendingFolders((folders) => folders.map((candidate) => (candidate === path ? destBase : candidate)));\n return;\n }\n for (const file of files) {\n await props.source.rename!(file, `${destBase}${file.slice(path.length)}`);\n }\n const selected = selectedPath();\n if (selected && (selected === path || selected.startsWith(`${path}/`))) {\n setSelectedPath(`${destBase}${selected.slice(path.length)}`);\n }\n });\n\n const contentBytes = async (path: string): Promise<Uint8Array> => {\n const content = await props.source.read(path);\n return content.encoding === \"utf8\"\n ? new TextEncoder().encode(content.content)\n : Uint8Array.from(atob(content.content), (char) => char.charCodeAt(0));\n };\n\n const downloadEntry = (path: string, isFolder: boolean) =>\n void (async () => {\n try {\n if (!isFolder) {\n const href = props.source.downloadHref?.(path);\n if (href) {\n const anchor = document.createElement(\"a\");\n anchor.href = href;\n anchor.download = baseName(path);\n anchor.click();\n return;\n }\n const content = await props.source.read(path);\n downloadFileFromContent(await contentBytes(path), baseName(path), content.mediaType || \"application/octet-stream\");\n return;\n }\n const files = filesBehind(path);\n if (files.length === 0) throw new Error(fileBrowserMessages().folderEmpty);\n const zipEntries = await Promise.all(\n files.map(async (file) => ({ filename: file.slice(path.length + 1), source: await contentBytes(file) })),\n );\n downloadFileFromContent(await createZip(zipEntries), `${baseName(path) || \"files\"}.zip`, \"application/zip\");\n } catch (error) {\n void prompts.error(error instanceof Error ? error.message : fileBrowserMessages().downloadFailed);\n }\n })();\n\n const treeActions = () => ({\n ...(!props.readOnly && props.source.rename\n ? { rename: (path: string, next: string) => (pathMutable(path) ? renameFile(path, next) : undefined) }\n : {}),\n ...(!props.readOnly && props.source.remove ? { remove: (path: string) => (pathMutable(path) ? removeFile(path) : undefined) } : {}),\n ...(!props.readOnly && props.source.write ? { createFile: (dir: string) => (pathWritable(dir) ? createFile(dir) : undefined) } : {}),\n ...(!props.readOnly && props.source.write\n ? { createFolder: (dir: string) => (pathWritable(dir) ? createFolder(dir) : undefined) }\n : {}),\n ...(!props.readOnly && props.source.rename\n ? { move: (path: string, dir: string) => (pathMutable(path) && pathMutable(dir) ? moveEntry(path, dir) : undefined) }\n : {}),\n download: (path: string, isFolder: boolean) => downloadEntry(path, isFolder),\n });\n\n const addMenuItems = () => [\n ...(pathWritable(\"/\") ? [{ icon: \"ti ti-file-plus\", label: fileBrowserMessages().newFile, action: () => createFile(\"/\") }] : []),\n ...(pathWritable(\"/\") ? [{ icon: \"ti ti-folder-plus\", label: fileBrowserMessages().newFolder, action: () => createFolder(\"/\") }] : []),\n ...(pathMutable(\"/\") && props.source.upload\n ? [{ icon: \"ti ti-upload\", label: fileBrowserMessages().uploadFiles, action: () => pickUpload(\"/\") }]\n : []),\n ];\n\n return (\n <div class={`k2b-content-file-browser ${props.class ?? \"\"}`} data-default-height={props.class ? undefined : \"true\"}>\n <div class=\"k2b-content-file-browser__sidebar\">\n <div class=\"k2b-content-file-browser__header\">\n <p class=\"k2b-content-file-browser__title\">{fileBrowserMessages().files}</p>\n <Show when={addMenuItems().length > 0}>\n <Dropdown.Root position=\"bottom-left\" items={addMenuItems()} label={fileBrowserMessages().addFileFolderUpload}>\n <Dropdown.Trigger\n appearance=\"plain\"\n class=\"k2b-content-file-browser__add\"\n label={fileBrowserMessages().addFileFolderUpload}\n tooltip={messages().add}\n >\n <i class=\"ti ti-plus\" aria-hidden=\"true\" />\n <span class=\"k2b-sr-only\">{fileBrowserMessages().addFileFolderUpload}</span>\n </Dropdown.Trigger>\n </Dropdown.Root>\n </Show>\n </div>\n <Switch>\n <Match when={entries.loading && entries() === undefined}>\n <Placeholder state=\"loading\" title={fileBrowserMessages().loadingFiles} />\n </Match>\n <Match when={entries.error}>\n <Placeholder\n state=\"error\"\n title={fileInputMessages().failedLoadFiles}\n description={String(entries.error?.message ?? entries.error ?? \"\")}\n />\n </Match>\n <Match when={allEntries().length > 0}>\n <FileTree\n class=\"k2b-content-file-browser__tree\"\n entries={allEntries()}\n selectedPath={selectedPath()}\n onSelect={(entry) => void selectPath(entry.path)}\n actions={treeActions()}\n />\n </Match>\n <Match when={true}>\n <Placeholder icon=\"ti ti-folder-open\" title={fileBrowserMessages().noFiles} description={fileBrowserMessages().spaceEmpty} />\n </Match>\n </Switch>\n <input\n ref={uploadInputRef}\n type=\"file\"\n multiple\n class=\"k2b-content-file-browser__upload\"\n onChange={(event) => onUploadPicked(event.currentTarget)}\n />\n </div>\n\n <Switch\n fallback={\n <Placeholder icon=\"ti ti-file\" title={fileBrowserMessages().selectFile} description={fileBrowserMessages().pickFileFromTree} />\n }\n >\n <Match when={selectedEntry()?.kind === \"folder\"}>\n <Placeholder\n icon=\"ti ti-folder\"\n title={fileBrowserMessages().folderSelected}\n description={fileBrowserMessages().chooseFileToPreview}\n />\n </Match>\n <Match when={selectedEntry()}>\n {(entry) => (\n <FileView\n previewPreferencesKey={props.source.previewPreferencesKey}\n file={{ path: entry().path, mediaType: entry().mediaType, size: entry().size }}\n load={() => props.source.read(entry().path)}\n revision={props.refreshKey}\n registerRefresh={(refresh) => {\n refreshPreview = refresh;\n return () => {\n refreshPreview = async () => undefined;\n };\n }}\n renderers={props.renderers}\n onDirtyChange={setSelectedDirty}\n save={\n pathWritable(entry().path)\n ? async (content) => {\n await props.source.write!(entry().path, content);\n await refetch();\n }\n : undefined\n }\n downloadHref={props.source.downloadHref?.(entry().path) ?? null}\n />\n )}\n </Match>\n </Switch>\n </div>\n );\n}\n\n/** Open the file browser as a dialog. Returns when the dialog closes. */\nexport const openFileBrowser = (options: { source: FileSource; title?: string; subtitle?: string; icon?: string }): Promise<void> => {\n const fileBrowserMessages = resolveFileBrowserMessages();\n return dialogCore.open<void>(\n (close) => (\n <PanelDialog>\n <PanelDialog.Header\n title={options.title ?? fileBrowserMessages.files}\n subtitle={options.subtitle}\n icon={options.icon ?? \"ti ti-folder\"}\n close={() => close()}\n />\n <PanelDialog.Body>\n <FileBrowserPanel source={options.source} />\n </PanelDialog.Body>\n </PanelDialog>\n ),\n panelDialogOptions,\n );\n};\n"],"mappings":"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","ignoreList":[]}
@@ -10,7 +10,7 @@ var _tmpl$ = ["<ul class=\"", "\"", " role=\"tree\"", ">", "</ul>"],
10
10
  _tmpl$4 = ["<span class=\"k2b-content-file-tree__badge\">", "</span>"],
11
11
  _tmpl$5 = "<i class=\"ti ti-dots\" aria-hidden=\"true\"></i>",
12
12
  _tmpl$6 = ["<span class=\"k2b-sr-only\">Actions for ", "</span>"],
13
- _tmpl$7 = ["<div", " class=\"k2b-content-file-tree__row\"><button type=\"button\" tabindex=\"-1\" class=\"k2b-content-file-tree__select\" style=\"", "\"", "><i class=\"", "\" aria-hidden=\"true\"></i><span class=\"k2b-content-file-tree__name\">", "</span>", "</button>", "</div>"];
13
+ _tmpl$7 = ["<div", " class=\"k2b-content-file-tree__row\"><button type=\"button\" tabindex=\"-1\" class=\"k2b-content-file-tree__select\" style=\"", "\"", ">", "<span class=\"k2b-content-file-tree__name\">", "</span>", "</button>", "</div>"];
14
14
  /**
15
15
  * FileTree — path-first tree over a flat entry list (folders derived from
16
16
  * paths, explicit folder entries allowed for empty dirs). Capabilities are
@@ -18,19 +18,13 @@ var _tmpl$ = ["<ul class=\"", "\"", " role=\"tree\"", ">", "</ul>"],
18
18
  * pure read-only browser. Context menus render through the platform
19
19
  * ContextMenu. Minimal look: text rows, bevel on selection, no hover motion.
20
20
  */
21
- import { fileIcons } from "@k2b/stdlib";
22
21
  import { createEffect, createMemo, createSignal, For, Show } from "solid-js";
23
22
  import ContextMenu from "../actions/ContextMenu";
24
23
  import Dropdown from "../actions/Dropdown";
25
24
  import { useUiMessages } from "../intl/messages";
25
+ import { FileTypeIcon } from "./FileTypeIcon";
26
26
  import { useFileBrowserMessages } from "./file-browser-messages";
27
27
  import { allFolderPaths, buildTree, flattenVisible, parentOf } from "./file-tree";
28
- /**
29
- * `fileIcons` (and app-supplied entry icons) may carry Tailwind colour classes.
30
- * @k2b/ui ships no Tailwind utilities, so only the `ti-*` glyph is kept — the
31
- * row owns the icon colour.
32
- */
33
- const glyphOnly = icon => icon.split(/\s+/).filter(token => token.startsWith("ti-")).join(" ");
34
28
 
35
29
  /** Presence of a callback enables the matching UI affordance. */
36
30
 
@@ -239,18 +233,31 @@ export default function FileTree(props) {
239
233
  };
240
234
  const isSelected = () => props.selectedPath === currentNode().entry.path;
241
235
  const isDropTarget = () => currentNode().isFolder && dropTarget() === currentNode().entry.path;
242
- const icon = () => currentNode().isFolder ? expanded().has(currentNode().entry.path) ? "ti-folder-open" : "ti-folder" : glyphOnly(currentNode().entry.icon ?? fileIcons.getFileIcon({
243
- name: currentNode().name,
244
- type: "file",
245
- mimeType: currentNode().entry.mediaType ?? "text/plain"
246
- }));
247
236
  const hasItems = () => menuItems(node).length > 0;
248
237
  return _$ssr(_tmpl$3, _$ssrAttribute("tabindex", renamingPath() === node.entry.path ? -1 : focusedPath() === node.entry.path ? 0 : -1, false) + _$ssrAttribute("aria-label", _$escape(currentNode().entry.displayName ?? currentNode().name, true), false) + _$ssrAttribute("aria-level", _$escape(currentNode().depth, true) + 1, false) + _$ssrAttribute("aria-selected", _$escape(isSelected(), true), false) + _$ssrAttribute("aria-expanded", currentNode().isFolder ? _$escape(expanded().has(currentNode().entry.path), true) : _$escape(undefined, true), false) + _$ssrAttribute("aria-haspopup", hasItems() ? "menu" : _$escape(undefined, true), false) + _$ssrAttribute("data-context-open", contextMenuOpen() && contextPath() === node.entry.path ? "true" : _$escape(undefined, true), false), _$escape(_$createComponent(Show, {
249
238
  get when() {
250
239
  return renamingPath() === node.entry.path;
251
240
  },
252
241
  get fallback() {
253
- return _$ssr(_tmpl$7, _$ssrAttribute("data-state", isSelected() ? "selected" : isDropTarget() ? "drop-target" : "idle", false), _$ssrStyleProperty("padding-left:", `${6 + _$escape(currentNode().depth, true) * 14}px`), _$ssrAttribute("title", _$escape(currentNode().entry.path, true), false) + _$ssrAttribute("draggable", _$escape(Boolean(props.actions?.move), true), false), `ti ${_$escape(icon(), true)} k2b-content-file-tree__icon`, _$escape(currentNode().entry.displayName ?? currentNode().name), _$escape(_$createComponent(Show, {
242
+ return _$ssr(_tmpl$7, _$ssrAttribute("data-state", isSelected() ? "selected" : isDropTarget() ? "drop-target" : "idle", false), _$ssrStyleProperty("padding-left:", `${6 + _$escape(currentNode().depth, true) * 14}px`), _$ssrAttribute("title", _$escape(currentNode().entry.path, true), false) + _$ssrAttribute("draggable", _$escape(Boolean(props.actions?.move), true), false), _$escape(_$createComponent(FileTypeIcon, {
243
+ size: "sm",
244
+ "class": "k2b-content-file-tree__icon",
245
+ get name() {
246
+ return currentNode().name;
247
+ },
248
+ get folder() {
249
+ return currentNode().isFolder;
250
+ },
251
+ get open() {
252
+ return _$memo(() => !!currentNode().isFolder)() && expanded().has(currentNode().entry.path);
253
+ },
254
+ get icon() {
255
+ return _$memo(() => !!currentNode().isFolder)() ? undefined : currentNode().entry.icon;
256
+ },
257
+ get mediaType() {
258
+ return currentNode().entry.mediaType ?? "text/plain";
259
+ }
260
+ })), _$escape(currentNode().entry.displayName ?? currentNode().name), _$escape(_$createComponent(Show, {
254
261
  get when() {
255
262
  return currentNode().entry.badge;
256
263
  },