@k2b/ui 0.22.0 → 0.24.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 (117) hide show
  1. package/dist/browser/content/Calendar.js +1122 -1065
  2. package/dist/browser/content/Calendar.js.map +1 -1
  3. package/dist/browser/content/CalendarDayView.js +1187 -0
  4. package/dist/browser/content/CalendarDayView.js.map +1 -0
  5. package/dist/browser/content/CalendarWeekView.js +1593 -0
  6. package/dist/browser/content/CalendarWeekView.js.map +1 -0
  7. package/dist/browser/content/ChartExplorer.js +174 -82
  8. package/dist/browser/content/ChartExplorer.js.map +1 -1
  9. package/dist/browser/content/ChartFilterControls.js +90 -33
  10. package/dist/browser/content/ChartFilterControls.js.map +1 -1
  11. package/dist/browser/content/DataTable.js +235 -197
  12. package/dist/browser/content/DataTable.js.map +1 -1
  13. package/dist/browser/content/calendar-day-scroll.js +111 -0
  14. package/dist/browser/content/calendar-day-scroll.js.map +1 -0
  15. package/dist/browser/content/calendar-days.js +408 -0
  16. package/dist/browser/content/calendar-days.js.map +1 -0
  17. package/dist/browser/content/calendar-dialogs.js +236 -0
  18. package/dist/browser/content/calendar-dialogs.js.map +1 -0
  19. package/dist/browser/content/calendar-messages.js +210 -2
  20. package/dist/browser/content/calendar-messages.js.map +1 -1
  21. package/dist/browser/content/calendar-pointer.js +15 -3
  22. package/dist/browser/content/calendar-pointer.js.map +1 -1
  23. package/dist/browser/content/calendar-shared.js +328 -0
  24. package/dist/browser/content/calendar-shared.js.map +1 -0
  25. package/dist/browser/content/calendar-time-view.js +1654 -0
  26. package/dist/browser/content/calendar-time-view.js.map +1 -0
  27. package/dist/browser/content/chart-messages.js +10 -0
  28. package/dist/browser/content/chart-messages.js.map +1 -1
  29. package/dist/browser/content/index.js.map +1 -1
  30. package/dist/browser/inputs/Combobox.js +0 -1
  31. package/dist/browser/inputs/Combobox.js.map +1 -1
  32. package/dist/browser/layout/AppWorkspace.js +125 -97
  33. package/dist/browser/layout/AppWorkspace.js.map +1 -1
  34. package/dist/browser/layout/Navigation.js +18 -3
  35. package/dist/browser/layout/Navigation.js.map +1 -1
  36. package/dist/browser/layout/PageTitle.js +18 -1
  37. package/dist/browser/layout/PageTitle.js.map +1 -1
  38. package/dist/browser/layout/SidebarSwitcher.js +505 -0
  39. package/dist/browser/layout/SidebarSwitcher.js.map +1 -0
  40. package/dist/browser/layout/app-workspace-controller.js +174 -86
  41. package/dist/browser/layout/app-workspace-controller.js.map +1 -1
  42. package/dist/browser/layout/index.js +1 -0
  43. package/dist/browser/layout/index.js.map +1 -1
  44. package/dist/browser/layout/navigation-model.js +1 -0
  45. package/dist/browser/layout/navigation-model.js.map +1 -1
  46. package/dist/browser/surfaces/StatCell.js +18 -6
  47. package/dist/browser/surfaces/StatCell.js.map +1 -1
  48. package/dist/ssr/content/Calendar.js +553 -341
  49. package/dist/ssr/content/Calendar.js.map +1 -1
  50. package/dist/ssr/content/CalendarDayView.js +800 -0
  51. package/dist/ssr/content/CalendarDayView.js.map +1 -0
  52. package/dist/ssr/content/CalendarWeekView.js +1090 -0
  53. package/dist/ssr/content/CalendarWeekView.js.map +1 -0
  54. package/dist/ssr/content/ChartExplorer.js +93 -34
  55. package/dist/ssr/content/ChartExplorer.js.map +1 -1
  56. package/dist/ssr/content/ChartFilterControls.js +49 -7
  57. package/dist/ssr/content/ChartFilterControls.js.map +1 -1
  58. package/dist/ssr/content/DataTable.js +88 -66
  59. package/dist/ssr/content/DataTable.js.map +1 -1
  60. package/dist/ssr/content/calendar-day-scroll.js +111 -0
  61. package/dist/ssr/content/calendar-day-scroll.js.map +1 -0
  62. package/dist/ssr/content/calendar-days.js +408 -0
  63. package/dist/ssr/content/calendar-days.js.map +1 -0
  64. package/dist/ssr/content/calendar-dialogs.js +159 -0
  65. package/dist/ssr/content/calendar-dialogs.js.map +1 -0
  66. package/dist/ssr/content/calendar-messages.js +210 -2
  67. package/dist/ssr/content/calendar-messages.js.map +1 -1
  68. package/dist/ssr/content/calendar-pointer.js +15 -3
  69. package/dist/ssr/content/calendar-pointer.js.map +1 -1
  70. package/dist/ssr/content/calendar-shared.js +261 -0
  71. package/dist/ssr/content/calendar-shared.js.map +1 -0
  72. package/dist/ssr/content/calendar-time-view.js +1311 -0
  73. package/dist/ssr/content/calendar-time-view.js.map +1 -0
  74. package/dist/ssr/content/chart-messages.js +10 -0
  75. package/dist/ssr/content/chart-messages.js.map +1 -1
  76. package/dist/ssr/content/index.js.map +1 -1
  77. package/dist/ssr/inputs/Combobox.js.map +1 -1
  78. package/dist/ssr/layout/AppWorkspace.js +40 -29
  79. package/dist/ssr/layout/AppWorkspace.js.map +1 -1
  80. package/dist/ssr/layout/Navigation.js +12 -2
  81. package/dist/ssr/layout/Navigation.js.map +1 -1
  82. package/dist/ssr/layout/PageTitle.js +18 -1
  83. package/dist/ssr/layout/PageTitle.js.map +1 -1
  84. package/dist/ssr/layout/SidebarSwitcher.js +271 -0
  85. package/dist/ssr/layout/SidebarSwitcher.js.map +1 -0
  86. package/dist/ssr/layout/app-workspace-controller.js +174 -86
  87. package/dist/ssr/layout/app-workspace-controller.js.map +1 -1
  88. package/dist/ssr/layout/index.js +1 -0
  89. package/dist/ssr/layout/index.js.map +1 -1
  90. package/dist/ssr/layout/navigation-model.js +1 -0
  91. package/dist/ssr/layout/navigation-model.js.map +1 -1
  92. package/dist/ssr/surfaces/StatCell.js +2 -2
  93. package/dist/ssr/surfaces/StatCell.js.map +1 -1
  94. package/dist/styles.css +1 -1
  95. package/dist/types/content/Calendar.d.ts +95 -1
  96. package/dist/types/content/CalendarDayView.d.ts +7 -0
  97. package/dist/types/content/CalendarWeekView.d.ts +7 -0
  98. package/dist/types/content/ChartExplorer.d.ts +36 -1
  99. package/dist/types/content/ChartFilterControls.d.ts +6 -1
  100. package/dist/types/content/DataTable.d.ts +14 -0
  101. package/dist/types/content/calendar-day-scroll.d.ts +47 -0
  102. package/dist/types/content/calendar-days.d.ts +192 -0
  103. package/dist/types/content/calendar-dialogs.d.ts +22 -0
  104. package/dist/types/content/calendar-messages.d.ts +99 -0
  105. package/dist/types/content/calendar-pointer.d.ts +9 -0
  106. package/dist/types/content/calendar-shared.d.ts +69 -0
  107. package/dist/types/content/calendar-time-view.d.ts +252 -0
  108. package/dist/types/content/chart-messages.d.ts +5 -0
  109. package/dist/types/content/index.d.ts +2 -2
  110. package/dist/types/layout/AppWorkspace.d.ts +27 -3
  111. package/dist/types/layout/PageTitle.d.ts +2 -1
  112. package/dist/types/layout/SidebarSwitcher.d.ts +65 -0
  113. package/dist/types/layout/app-workspace-controller.d.ts +9 -1
  114. package/dist/types/layout/index.d.ts +1 -0
  115. package/dist/types/layout/navigation-model.d.ts +4 -0
  116. package/dist/types/surfaces/StatCell.d.ts +5 -0
  117. package/package.json +3 -3
@@ -3,9 +3,12 @@ import { createComponent as _$createComponent } from "solid-js/web";
3
3
  import { memo as _$memo } from "solid-js/web";
4
4
  import { ssrAttribute as _$ssrAttribute } from "solid-js/web";
5
5
  import { escape as _$escape } from "solid-js/web";
6
- var _tmpl$ = ["<div class=\"k2b-chart-explorer__dimension\" role=\"group\"", ">", "<output class=\"k2b-chart-explorer__dimension-value\" for=\"", "\">", "</output><div id=\"", "\" class=\"k2b-chart-explorer__steps\">", "</div></div>"],
7
- _tmpl$2 = ["<div class=\"k2b-chart-explorer__legend\">", "<div class=\"k2b-chart-explorer__status\" role=\"status\">", "", "</div></div>"],
8
- _tmpl$3 = ["<span", ">", "</span>"];
6
+ var _tmpl$ = ["<div class=\"k2b-chart-explorer__dimension\" role=\"group\"", ">", "<output class=\"k2b-chart-explorer__dimension-value\" for=\"", "\"", "><span aria-hidden=\"true\">", "</span><span>", "</span></output><div id=\"", "\" class=\"k2b-chart-explorer__steps\">", "</div></div>"],
7
+ _tmpl$2 = "<i class=\"ti ti-pin\" aria-hidden=\"true\"></i>",
8
+ _tmpl$3 = ["<span>", "</span>"],
9
+ _tmpl$4 = "<i class=\"ti ti-x\" aria-hidden=\"true\"></i>",
10
+ _tmpl$5 = ["<div class=\"k2b-chart-explorer__legend\">", "", "<div class=\"k2b-chart-explorer__status\" role=\"status\">", "", "</div></div>"],
11
+ _tmpl$6 = ["<span", ">", "</span>"];
9
12
  import { createEffect, createSignal, createUniqueId, For, Show } from "solid-js";
10
13
  import { Button } from "../actions/Button";
11
14
  import { FilterChip } from "../actions/FilterChip";
@@ -28,6 +31,8 @@ export function ChartFilterControls(props) {
28
31
  const [keyboardSteps, setKeyboardSteps] = createSignal(false);
29
32
  let pointerFocus = false;
30
33
  const stepLabel = key => props.steps?.find(step => step.key === key)?.label ?? key ?? "";
34
+ // The step name reserves the width of the longest one, so stepping never resizes the slider under the finger.
35
+ const widestStep = () => props.steps?.reduce((widest, step) => [...step.label].length > [...widest].length ? step.label : widest, "") ?? "";
31
36
  return [_$createComponent(Show, {
32
37
  get when() {
33
38
  return props.steps?.length;
@@ -62,21 +67,21 @@ export function ChartFilterControls(props) {
62
67
  step: step.key
63
68
  });
64
69
  }
65
- })), `${_$escape(id, true)}-dimension`, _$escape(stepLabel(props.request.step)), `${_$escape(id, true)}-steps`, _$escape(_$createComponent(For, {
70
+ })), `${_$escape(id, true)}-dimension`, _$ssrAttribute("title", _$escape(stepLabel(props.request.step), true), false), _$escape(widestStep()), _$escape(stepLabel(props.request.step)), `${_$escape(id, true)}-steps`, _$escape(_$createComponent(For, {
66
71
  get each() {
67
72
  return props.steps;
68
73
  },
69
- children: step => _$ssr(_tmpl$3, _$ssrAttribute("data-current", step.key === props.request.step ? "true" : _$escape(undefined, true), false), _$escape(step.label))
74
+ children: step => _$ssr(_tmpl$6, _$ssrAttribute("data-current", step.key === props.request.step ? "true" : _$escape(undefined, true), false), _$escape(step.label))
70
75
  })));
71
76
  }
72
- }), _$ssr(_tmpl$2, _$escape(_$createComponent(Show, {
77
+ }), _$ssr(_tmpl$5, _$escape(_$createComponent(Show, {
73
78
  get when() {
74
79
  return props.series?.length;
75
80
  },
76
81
  get children() {
77
82
  return _$createComponent(FilterChip, {
78
83
  get label() {
79
- return chartMessages().chartSeries;
84
+ return props.seriesLabel ?? chartMessages().chartSeries;
80
85
  },
81
86
  icon: "ti ti-chart-dots",
82
87
  get disabled() {
@@ -107,6 +112,43 @@ export function ChartFilterControls(props) {
107
112
  })
108
113
  });
109
114
  }
115
+ })), _$escape(_$createComponent(Show, {
116
+ get when() {
117
+ return _$memo(() => !!props.compare)() && props.steps?.length;
118
+ },
119
+ get children() {
120
+ return _$createComponent(Button, {
121
+ variant: "secondary",
122
+ "class": "k2b-chart-explorer__pin",
123
+ get disabled() {
124
+ return props.disabled || props.request.referenceStep === undefined && props.request.step === undefined;
125
+ },
126
+ get ["aria-label"]() {
127
+ return _$memo(() => props.request.referenceStep === undefined)() ? undefined : `${chartMessages().chartRemoveComparison}: ${stepLabel(props.request.referenceStep)}`;
128
+ },
129
+ onClick: () => props.onRequest({
130
+ ...props.request,
131
+ referenceStep: props.request.referenceStep === undefined ? props.request.step : undefined
132
+ }),
133
+ get children() {
134
+ return [_$createComponent(Show, {
135
+ get when() {
136
+ return props.request.referenceStep === undefined;
137
+ },
138
+ get children() {
139
+ return _$ssr(_tmpl$2);
140
+ }
141
+ }), _$ssr(_tmpl$3, props.request.referenceStep === undefined ? _$escape(chartMessages().chartPinReference) : `${_$escape(chartMessages().chartReference)}: ${_$escape(stepLabel(props.request.referenceStep))}`), _$createComponent(Show, {
142
+ get when() {
143
+ return props.request.referenceStep !== undefined;
144
+ },
145
+ get children() {
146
+ return _$ssr(_tmpl$4);
147
+ }
148
+ })];
149
+ }
150
+ });
151
+ }
110
152
  })), _$escape(_$createComponent(Show, {
111
153
  get when() {
112
154
  return props.failed;
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["content/ChartFilterControls.tsx"],"sourcesContent":["import { createEffect, createSignal, createUniqueId, For, Show } from \"solid-js\";\nimport { Button } from \"../actions/Button\";\nimport { FilterChip } from \"../actions/FilterChip\";\nimport { Slider } from \"../inputs/ChoiceInputs\";\nimport { useUiMessages } from \"../intl/messages\";\nimport type { ChartExplorerRequest } from \"./chart-explorer\";\nimport { useChartMessages } from \"./chart-messages\";\n\nexport type ChartFilterControlsProps = {\n request: ChartExplorerRequest;\n displayedRequest: ChartExplorerRequest;\n steps?: readonly { key: string; label: string }[];\n series?: readonly { key: string; label: string; color: string }[];\n dimensionLabel?: string;\n disabled?: boolean;\n failed?: boolean;\n onRequest: (request: ChartExplorerRequest) => void;\n onRetry?: () => void;\n};\n\n/** Shared controls for a standalone explorer or an atomic group of charts. */\nexport function ChartFilterControls(props: ChartFilterControlsProps) {\n const validateOptions = () => {\n for (const items of [props.steps, props.series]) {\n const keys = items?.map((item) => item.key) ?? [];\n if (keys.some((key) => !key) || new Set(keys).size !== keys.length)\n throw new Error(\"Chart control options require nonempty unique keys\");\n }\n };\n validateOptions();\n createEffect(validateOptions);\n const messages = useUiMessages();\n const chartMessages = useChartMessages();\n const id = `k2b-chart-controls-${createUniqueId()}`;\n const [keyboardSteps, setKeyboardSteps] = createSignal(false);\n let pointerFocus = false;\n const stepLabel = (key: string | undefined) => props.steps?.find((step) => step.key === key)?.label ?? key ?? \"\";\n return (\n <>\n <Show when={props.steps?.length}>\n <div\n class=\"k2b-chart-explorer__dimension\"\n role=\"group\"\n aria-label={props.dimensionLabel ?? messages().range}\n data-keyboard={keyboardSteps() ? \"true\" : undefined}\n onPointerDown={() => {\n pointerFocus = true;\n setKeyboardSteps(false);\n }}\n onKeyDown={() => {\n pointerFocus = false;\n setKeyboardSteps(true);\n }}\n onFocusIn={(event) => {\n if (!pointerFocus && event.target.matches(\":focus-visible\")) setKeyboardSteps(true);\n }}\n onFocusOut={() => {\n pointerFocus = false;\n setKeyboardSteps(false);\n }}\n >\n <Slider\n id={`${id}-dimension`}\n showValue={false}\n aria-describedby={`${id}-steps`}\n label={props.dimensionLabel ?? messages().range}\n min={0}\n max={Math.max(0, (props.steps?.length ?? 1) - 1)}\n step={1}\n value={Math.max(0, props.steps?.findIndex((step) => step.key === props.request.step) ?? 0)}\n disabled={props.disabled || (props.steps?.length ?? 0) < 2}\n formatValue={(index) => props.steps?.[index]?.label ?? \"\"}\n aria-valuetext={stepLabel(props.request.step)}\n onValueChange={(index) => {\n const step = props.steps?.[index];\n if (step) props.onRequest({ ...props.request, step: step.key });\n }}\n />\n <output class=\"k2b-chart-explorer__dimension-value\" for={`${id}-dimension`}>\n {stepLabel(props.request.step)}\n </output>\n <div id={`${id}-steps`} class=\"k2b-chart-explorer__steps\">\n <For each={props.steps}>\n {(step) => <span data-current={step.key === props.request.step ? \"true\" : undefined}>{step.label}</span>}\n </For>\n </div>\n </div>\n </Show>\n <div class=\"k2b-chart-explorer__legend\">\n <Show when={props.series?.length}>\n <FilterChip\n label={chartMessages().chartSeries}\n icon=\"ti ti-chart-dots\"\n disabled={props.disabled}\n value={props.request.visibleKeys ?? props.series?.map((item) => item.key) ?? []}\n defaultValue={props.series?.map((item) => item.key) ?? []}\n isActive={props.request.visibleKeys !== undefined && props.request.visibleKeys.length !== props.series?.length}\n options={[\n { multiple: true, options: (props.series ?? []).map((item) => ({ value: item.key, label: item.label, color: item.color })) },\n ]}\n onValueChange={(visibleKeys) => props.onRequest({ ...props.request, visibleKeys })}\n />\n </Show>\n <div class=\"k2b-chart-explorer__status\" role=\"status\">\n <Show when={props.failed}>\n {messages().couldNotLoadData}{\" \"}\n <Button variant=\"text\" size=\"sm\" onClick={props.onRetry}>\n {messages().retry}\n </Button>\n </Show>\n <Show when={props.failed}>\n · {chartMessages().chartPreviousData}\n <Show when={props.steps?.length}>: {stepLabel(props.displayedRequest.step)}</Show>\n </Show>\n </div>\n </div>\n </>\n );\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["content/ChartFilterControls.tsx"],"sourcesContent":["import { createEffect, createSignal, createUniqueId, For, Show } from \"solid-js\";\nimport { Button } from \"../actions/Button\";\nimport { FilterChip } from \"../actions/FilterChip\";\nimport { Slider } from \"../inputs/ChoiceInputs\";\nimport { useUiMessages } from \"../intl/messages\";\nimport type { ChartExplorerRequest } from \"./chart-explorer\";\nimport { useChartMessages } from \"./chart-messages\";\n\nexport type ChartFilterControlsProps = {\n request: ChartExplorerRequest;\n displayedRequest: ChartExplorerRequest;\n steps?: readonly { key: string; label: string }[];\n /** Series to filter; `color` shows a swatch and belongs only to series the chart colors that way. */\n series?: readonly { key: string; label: string; color?: string }[];\n dimensionLabel?: string;\n /** Label of the series filter, such as the column the series come from; defaults to the inherited series label. */\n seriesLabel?: string;\n /** Offer pinning the current step as a reference for comparison. */\n compare?: boolean;\n disabled?: boolean;\n failed?: boolean;\n onRequest: (request: ChartExplorerRequest) => void;\n onRetry?: () => void;\n};\n\n/** Shared controls for a standalone explorer or an atomic group of charts. */\nexport function ChartFilterControls(props: ChartFilterControlsProps) {\n const validateOptions = () => {\n for (const items of [props.steps, props.series]) {\n const keys = items?.map((item) => item.key) ?? [];\n if (keys.some((key) => !key) || new Set(keys).size !== keys.length)\n throw new Error(\"Chart control options require nonempty unique keys\");\n }\n };\n validateOptions();\n createEffect(validateOptions);\n const messages = useUiMessages();\n const chartMessages = useChartMessages();\n const id = `k2b-chart-controls-${createUniqueId()}`;\n const [keyboardSteps, setKeyboardSteps] = createSignal(false);\n let pointerFocus = false;\n const stepLabel = (key: string | undefined) => props.steps?.find((step) => step.key === key)?.label ?? key ?? \"\";\n // The step name reserves the width of the longest one, so stepping never resizes the slider under the finger.\n const widestStep = () =>\n props.steps?.reduce((widest, step) => ([...step.label].length > [...widest].length ? step.label : widest), \"\") ?? \"\";\n return (\n <>\n <Show when={props.steps?.length}>\n <div\n class=\"k2b-chart-explorer__dimension\"\n role=\"group\"\n aria-label={props.dimensionLabel ?? messages().range}\n data-keyboard={keyboardSteps() ? \"true\" : undefined}\n onPointerDown={() => {\n pointerFocus = true;\n setKeyboardSteps(false);\n }}\n onKeyDown={() => {\n pointerFocus = false;\n setKeyboardSteps(true);\n }}\n onFocusIn={(event) => {\n if (!pointerFocus && event.target.matches(\":focus-visible\")) setKeyboardSteps(true);\n }}\n onFocusOut={() => {\n pointerFocus = false;\n setKeyboardSteps(false);\n }}\n >\n <Slider\n id={`${id}-dimension`}\n showValue={false}\n aria-describedby={`${id}-steps`}\n label={props.dimensionLabel ?? messages().range}\n min={0}\n max={Math.max(0, (props.steps?.length ?? 1) - 1)}\n step={1}\n value={Math.max(0, props.steps?.findIndex((step) => step.key === props.request.step) ?? 0)}\n disabled={props.disabled || (props.steps?.length ?? 0) < 2}\n formatValue={(index) => props.steps?.[index]?.label ?? \"\"}\n aria-valuetext={stepLabel(props.request.step)}\n onValueChange={(index) => {\n const step = props.steps?.[index];\n if (step) props.onRequest({ ...props.request, step: step.key });\n }}\n />\n <output class=\"k2b-chart-explorer__dimension-value\" for={`${id}-dimension`} title={stepLabel(props.request.step)}>\n <span aria-hidden=\"true\">{widestStep()}</span>\n <span>{stepLabel(props.request.step)}</span>\n </output>\n <div id={`${id}-steps`} class=\"k2b-chart-explorer__steps\">\n <For each={props.steps}>\n {(step) => <span data-current={step.key === props.request.step ? \"true\" : undefined}>{step.label}</span>}\n </For>\n </div>\n </div>\n </Show>\n <div class=\"k2b-chart-explorer__legend\">\n <Show when={props.series?.length}>\n <FilterChip\n label={props.seriesLabel ?? chartMessages().chartSeries}\n icon=\"ti ti-chart-dots\"\n disabled={props.disabled}\n value={props.request.visibleKeys ?? props.series?.map((item) => item.key) ?? []}\n defaultValue={props.series?.map((item) => item.key) ?? []}\n isActive={props.request.visibleKeys !== undefined && props.request.visibleKeys.length !== props.series?.length}\n options={[\n { multiple: true, options: (props.series ?? []).map((item) => ({ value: item.key, label: item.label, color: item.color })) },\n ]}\n onValueChange={(visibleKeys) => props.onRequest({ ...props.request, visibleKeys })}\n />\n </Show>\n <Show when={props.compare && props.steps?.length}>\n <Button\n variant=\"secondary\"\n class=\"k2b-chart-explorer__pin\"\n disabled={props.disabled || (props.request.referenceStep === undefined && props.request.step === undefined)}\n aria-label={\n props.request.referenceStep === undefined\n ? undefined\n : `${chartMessages().chartRemoveComparison}: ${stepLabel(props.request.referenceStep)}`\n }\n onClick={() =>\n props.onRequest({\n ...props.request,\n referenceStep: props.request.referenceStep === undefined ? props.request.step : undefined,\n })\n }\n >\n <Show when={props.request.referenceStep === undefined}>\n <i class=\"ti ti-pin\" aria-hidden=\"true\" />\n </Show>\n <span>\n {props.request.referenceStep === undefined\n ? chartMessages().chartPinReference\n : `${chartMessages().chartReference}: ${stepLabel(props.request.referenceStep)}`}\n </span>\n <Show when={props.request.referenceStep !== undefined}>\n <i class=\"ti ti-x\" aria-hidden=\"true\" />\n </Show>\n </Button>\n </Show>\n <div class=\"k2b-chart-explorer__status\" role=\"status\">\n <Show when={props.failed}>\n {messages().couldNotLoadData}{\" \"}\n <Button variant=\"text\" size=\"sm\" onClick={props.onRetry}>\n {messages().retry}\n </Button>\n </Show>\n <Show when={props.failed}>\n · {chartMessages().chartPreviousData}\n <Show when={props.steps?.length}>: {stepLabel(props.displayedRequest.step)}</Show>\n </Show>\n </div>\n </div>\n </>\n );\n}\n"],"mappings":"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","ignoreList":[]}
@@ -6,22 +6,24 @@ import { ssr as _$ssr } from "solid-js/web";
6
6
  import { escape as _$escape } from "solid-js/web";
7
7
  var _tmpl$ = ["<span class=\"k2b-data-table__header-title\">", "</span>"],
8
8
  _tmpl$2 = ["<span class=\"k2b-data-table__header-subtitle\">", "</span>"],
9
- _tmpl$3 = ["<div class=\"k2b-data-table__header-content\"", ">", "</div>"],
10
- _tmpl$4 = ["<a", " class=\"k2b-data-table__header-content k2b-data-table__sort\"", "><span class=\"k2b-data-table__header-line\">", "<i class=\"", "\"", " aria-hidden=\"true\"></i></span></a>"],
11
- _tmpl$5 = ["<tr aria-hidden=\"true\"><td class=\"k2b-data-table__fill\"", "></td></tr>"],
12
- _tmpl$6 = "<div class=\"k2b-data-table__sentinel\" aria-hidden=\"true\"></div>",
13
- _tmpl$7 = ["<div role=\"region\"", " tabindex=\"0\" class=\"", "\"", "><table", "><thead class=\"k2b-data-table__head\"", "><tr class=\"k2b-data-table__head-row\">", "</tr></thead><tbody>", "</tbody>", "</table>", "</div>"],
14
- _tmpl$8 = ["<th scope=\"col\" class=\"", "\"", ">", "</th>"],
15
- _tmpl$9 = ["<tr><td class=\"k2b-data-table__empty\"", ">", "</td></tr>"],
16
- _tmpl$0 = ["<tr class=\"", "\"", ">", "</tr>"],
17
- _tmpl$1 = ["<td class=\"", "\"", "><div", ">", "</div></td>"],
18
- _tmpl$10 = ["<tfoot class=\"k2b-data-table__foot\" data-sticky=\"true\"><tr class=\"k2b-data-table__foot-row\">", "</tr></tfoot>"],
19
- _tmpl$11 = ["<td class=\"k2b-data-table__footer-cell\"", ">", "</td>"],
20
- _tmpl$12 = ["<div class=\"k2b-data-table__scrollbar\"", " aria-hidden=\"true\"><span style=\"", "\"></span></div>"],
21
- _tmpl$13 = ["<div class=\"", "\">", "</div>"],
22
- _tmpl$14 = ["<span", ">", "</span>"],
23
- _tmpl$15 = ["<footer class=\"", "\">", "</footer>"];
24
- import { createContext, createEffect, createMemo, createSignal, createUniqueId, For, onCleanup, onMount, Show, useContext } from "solid-js";
9
+ _tmpl$3 = ["<span class=\"k2b-data-table__header-line\">", "<i class=\"", "\"", " aria-hidden=\"true\"></i></span>"],
10
+ _tmpl$4 = ["<a", " class=\"k2b-data-table__header-content k2b-data-table__sort\"", ">", "</a>"],
11
+ _tmpl$5 = ["<button type=\"button\" class=\"k2b-data-table__header-content k2b-data-table__sort\"", ">", "</button>"],
12
+ _tmpl$6 = ["<div class=\"k2b-data-table__header-content\"", ">", "</div>"],
13
+ _tmpl$7 = ["<tr aria-hidden=\"true\"><td class=\"k2b-data-table__fill\"", "></td></tr>"],
14
+ _tmpl$8 = "<div class=\"k2b-data-table__sentinel\" aria-hidden=\"true\"></div>",
15
+ _tmpl$9 = ["<div role=\"region\"", " tabindex=\"0\" class=\"", "\"", "><table", "><thead class=\"k2b-data-table__head\"", "><tr class=\"k2b-data-table__head-row\">", "</tr></thead><tbody>", "</tbody>", "</table>", "</div>"],
16
+ _tmpl$0 = ["<th scope=\"col\" class=\"", "\"", ">", "</th>"],
17
+ _tmpl$1 = ["<tr><td class=\"k2b-data-table__empty\"", ">", "</td></tr>"],
18
+ _tmpl$10 = ["<tr class=\"", "\"", ">", "</tr>"],
19
+ _tmpl$11 = ["<td class=\"", "\"", "><div", ">", "</div></td>"],
20
+ _tmpl$12 = ["<tfoot class=\"k2b-data-table__foot\" data-sticky=\"true\"><tr class=\"k2b-data-table__foot-row\">", "</tr></tfoot>"],
21
+ _tmpl$13 = ["<td class=\"k2b-data-table__footer-cell\"", ">", "</td>"],
22
+ _tmpl$14 = ["<div class=\"k2b-data-table__scrollbar\"", " aria-hidden=\"true\"><span style=\"", "\"></span></div>"],
23
+ _tmpl$15 = ["<div class=\"", "\">", "</div>"],
24
+ _tmpl$16 = ["<span", ">", "</span>"],
25
+ _tmpl$17 = ["<footer class=\"", "\">", "</footer>"];
26
+ import { createContext, createEffect, createMemo, createSignal, createUniqueId, For, Match, onCleanup, onMount, Show, Switch, useContext } from "solid-js";
25
27
  import { Dynamic } from "solid-js/web";
26
28
  import { suppressTextSelection } from "../internal/text-selection";
27
29
  import { useLocale } from "../intl/locale";
@@ -188,61 +190,60 @@ function DataTableRoot(props) {
188
190
  if (col.value) return row[col.value];
189
191
  return undefined;
190
192
  };
191
- const columnAlignments = createMemo(() => {
192
- const alignments = new Map();
193
+ const columnPresentation = createMemo(() => {
194
+ const presentation = new Map();
193
195
  for (const col of props.columns) {
194
- if (col.align) {
195
- alignments.set(col.id, col.align);
196
- continue;
197
- }
198
- let align = "left";
199
- for (const row of props.rows) {
200
- const value = valueOf(row, col);
201
- if (value === null || value === undefined || value === "") continue;
202
- align = typeof value === "number" || typeof value === "bigint" ? "right" : "left";
203
- break;
196
+ let numeric = false;
197
+ let date = false;
198
+ if (col.align === undefined || col.nowrap === undefined) {
199
+ for (const row of props.rows) {
200
+ const value = valueOf(row, col);
201
+ if (value === null || value === undefined || value === "") continue;
202
+ numeric = typeof value === "number" || typeof value === "bigint";
203
+ date = value instanceof Date;
204
+ break;
205
+ }
204
206
  }
205
- alignments.set(col.id, align);
207
+ presentation.set(col.id, {
208
+ align: col.align ?? (numeric ? "right" : "left"),
209
+ nowrap: col.nowrap ?? (numeric || date)
210
+ });
206
211
  }
207
- return alignments;
212
+ return presentation;
208
213
  });
209
214
 
210
215
  /** `data-align` mirrors Cloud's `text-left/center/right` on the same cell. */
211
216
  const alignAttr = col => {
212
- const align = columnAlignments().get(col.id) ?? "left";
217
+ const align = columnPresentation().get(col.id)?.align ?? "left";
213
218
  return align === "left" ? undefined : align;
214
219
  };
220
+ const nowrapAttr = col => columnPresentation().get(col.id)?.nowrap ? "true" : undefined;
215
221
  const sortKeyOf = col => col.sortable === true ? col.id : typeof col.sortable === "string" ? col.sortable : null;
216
222
 
217
223
  /**
218
- * Sorting is a link, not a handler: these tables are server-rendered, so the
219
- * order belongs in the URL. Clicking the active column flips its direction.
224
+ * Sorting is a link by default: server-rendered tables keep the order in the
225
+ * URL. Client tables pass onSortChange instead. Clicking the active column
226
+ * flips its direction.
220
227
  */
221
- const sortLinkFor = col => {
222
- const key = sortKeyOf(col);
223
- if (!key || !props.sortHref) return null;
224
- const active = props.sort?.key === key;
225
- const direction = active && props.sort?.direction === "desc" ? "asc" : "desc";
226
- return {
227
- href: props.sortHref({
228
- key,
229
- direction
230
- }),
231
- active,
232
- direction
233
- };
234
- };
228
+ const nextSortFor = key => ({
229
+ key,
230
+ direction: props.sort?.key === key && props.sort?.direction === "desc" ? "asc" : "desc"
231
+ });
235
232
 
236
233
  /** Only a sortable column carries a sort state; the rest carry none at all. */
237
234
  const ariaSortFor = col => {
238
235
  const key = sortKeyOf(col);
239
- if (!key || !props.sortHref && !props.renderHeader) return undefined;
236
+ if (!key || !props.sortHref && !props.onSortChange && !props.renderHeader) return undefined;
240
237
  if (props.sort?.key !== key) return "none";
241
238
  return props.sort?.direction === "asc" ? "ascending" : "descending";
242
239
  };
243
240
  const renderHeaderDefault = col => {
244
- const sort = sortLinkFor(col);
245
- const title = [_$ssr(_tmpl$, _$escape(renderColumnPart(col.header, col))), _$createComponent(Show, {
241
+ const key = sortKeyOf(col);
242
+ // Only how a column sorts decides the element. The order lives in its attributes, so a header button keeps
243
+ // keyboard focus when a click sorts the table and the reader can press it again to reverse the order.
244
+ const mode = createMemo(() => !key ? null : props.sortHref ? "link" : props.onSortChange ? "button" : null);
245
+ const active = () => key !== null && props.sort?.key === key;
246
+ const title = () => [_$ssr(_tmpl$, _$escape(renderColumnPart(col.header, col))), _$createComponent(Show, {
246
247
  get when() {
247
248
  return col.subtitle !== undefined;
248
249
  },
@@ -250,8 +251,29 @@ function DataTableRoot(props) {
250
251
  return _$ssr(_tmpl$2, _$escape(renderColumnPart(col.subtitle, col)));
251
252
  }
252
253
  })];
253
- if (!sort) return _$ssr(_tmpl$3, _$ssrAttribute("data-align", _$escape(alignAttr(col), true), false), _$escape(title));
254
- return _$ssr(_tmpl$4, _$ssrAttribute("href", _$escape(sort.href, true), false), _$ssrAttribute("data-align", _$escape(alignAttr(col), true), false), _$escape(title), `k2b-data-table__sort-icon ti ${props.sort?.direction === "asc" && sort.active ? "ti-arrow-up" : "ti-arrow-down"}`, _$ssrAttribute("data-active", sort.active ? "true" : _$escape(undefined, true), false));
254
+ const line = () => _$ssr(_tmpl$3, _$escape(title()), `k2b-data-table__sort-icon ti ${active() && props.sort?.direction === "asc" ? "ti-arrow-up" : "ti-arrow-down"}`, _$ssrAttribute("data-active", active() ? "true" : _$escape(undefined, true), false));
255
+ return _$createComponent(Switch, {
256
+ get fallback() {
257
+ return _$ssr(_tmpl$6, _$ssrAttribute("data-align", _$escape(alignAttr(col), true), false), _$escape(title()));
258
+ },
259
+ get children() {
260
+ return [_$createComponent(Match, {
261
+ get when() {
262
+ return mode() === "link";
263
+ },
264
+ get children() {
265
+ return _$ssr(_tmpl$4, _$ssrAttribute("href", key ? _$escape(props.sortHref?.(nextSortFor(key)), true) : _$escape(undefined, true), false), _$ssrAttribute("data-align", _$escape(alignAttr(col), true), false), _$escape(line()));
266
+ }
267
+ }), _$createComponent(Match, {
268
+ get when() {
269
+ return mode() === "button";
270
+ },
271
+ get children() {
272
+ return _$ssr(_tmpl$5, _$ssrAttribute("data-align", _$escape(alignAttr(col), true), false), _$escape(line()));
273
+ }
274
+ })];
275
+ }
276
+ });
255
277
  };
256
278
  const renderValueDefault = value => defaultRender(value, locale(), messages());
257
279
  const renderCellDefault = (row, col) => renderValueDefault(valueOf(row, col));
@@ -354,11 +376,11 @@ function DataTableRoot(props) {
354
376
  },
355
377
  onMouseLeave: () => setHoveredColumn(null),
356
378
  get children() {
357
- return [_$ssr(_tmpl$7, _$ssrAttribute("aria-label", labelledBy() ? _$escape(undefined, true) : _$escape(props.ariaLabel ?? dataTableMessages().dataTable, true), false) + _$ssrAttribute("aria-labelledby", _$escape(labelledBy(), true), false), `k2b-table-wrap${props.scrollClass ? ` ${_$escape(props.scrollClass, true)}` : ""}`, _$ssrAttribute("data-density", props.density === "compact" ? "compact" : _$escape(undefined, true), false) + _$ssrAttribute("data-has-footer", props.footer ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-surface", _$escape(surface(), true), false) + _$ssrAttribute("data-scroll-preserve", _$escape(props.scrollPreserveKey || undefined, true), false), _$ssrAttribute("class", _$escape(tableClass(), true), false) + _$ssrAttribute("data-fill", props.fillHeight ? "true" : _$escape(undefined, true), false), _$ssrAttribute("data-sticky", props.stickyHeader === false ? _$escape(undefined, true) : "true", false), _$escape(_$createComponent(For, {
379
+ return [_$ssr(_tmpl$9, _$ssrAttribute("aria-label", labelledBy() ? _$escape(undefined, true) : _$escape(props.ariaLabel ?? dataTableMessages().dataTable, true), false) + _$ssrAttribute("aria-labelledby", _$escape(labelledBy(), true), false), `k2b-table-wrap${props.scrollClass ? ` ${_$escape(props.scrollClass, true)}` : ""}`, _$ssrAttribute("data-density", props.density === "compact" ? "compact" : _$escape(undefined, true), false) + _$ssrAttribute("data-has-footer", props.footer ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-surface", _$escape(surface(), true), false) + _$ssrAttribute("data-scroll-preserve", _$escape(props.scrollPreserveKey || undefined, true), false), _$ssrAttribute("class", _$escape(tableClass(), true), false) + _$ssrAttribute("data-fill", props.fillHeight ? "true" : _$escape(undefined, true), false), _$ssrAttribute("data-sticky", props.stickyHeader === false ? _$escape(undefined, true) : "true", false), _$escape(_$createComponent(For, {
358
380
  get each() {
359
381
  return props.columns;
360
382
  },
361
- children: (col, index) => _$ssr(_tmpl$8, `${_$escape(col.headerClass ?? "", true)} ${_$escape(col.class ?? "", true)}`, _$ssrAttribute("data-align", _$escape(alignAttr(col), true), false) + _$ssrAttribute("data-highlighted", _$escape(columnHighlighted(index()), true), false) + _$ssrAttribute("aria-sort", _$escape(ariaSortFor(col), true), false), props.renderHeader ? _$escape(props.renderHeader({
383
+ children: (col, index) => _$ssr(_tmpl$0, `${_$escape(col.headerClass ?? "", true)} ${_$escape(col.class ?? "", true)}`, _$ssrAttribute("data-align", _$escape(alignAttr(col), true), false) + _$ssrAttribute("data-highlighted", _$escape(columnHighlighted(index()), true), false) + _$ssrAttribute("aria-sort", _$escape(ariaSortFor(col), true), false), props.renderHeader ? _$escape(props.renderHeader({
362
384
  col,
363
385
  render: () => renderHeaderDefault(col)
364
386
  })) : _$escape(renderHeaderDefault(col)))
@@ -367,7 +389,7 @@ function DataTableRoot(props) {
367
389
  return props.rows.length > 0;
368
390
  },
369
391
  get fallback() {
370
- return _$ssr(_tmpl$9, _$ssrAttribute("colspan", _$escape(props.columns.length, true), false), _$escape(_$createComponent(Placeholder, {
392
+ return _$ssr(_tmpl$1, _$ssrAttribute("colspan", _$escape(props.columns.length, true), false), _$escape(_$createComponent(Placeholder, {
371
393
  get description() {
372
394
  return props.empty ?? dataTableMessages().noRecords;
373
395
  }
@@ -381,13 +403,13 @@ function DataTableRoot(props) {
381
403
  children: row => {
382
404
  const id = () => rowId(row);
383
405
  const isSelected = () => props.selection ? props.selection.selected().has(id() ?? "") : props.selectedRowId && id() === props.selectedRowId;
384
- return _$ssr(_tmpl$0, `k2b-data-table__row ${_$escape(rowClass(row), true)}`, _$ssrAttribute("data-hover", shouldHoverRows() ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-clickable", shouldHoverRows() && isInteractive() ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-selected", isSelected() ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("aria-selected", props.selection ? !!isSelected() : _$escape(undefined, true), false) + _$ssrAttribute("tabindex", props.selection ? props.selection.focused() === id() ? 0 : -1 : isInteractive() ? 0 : _$escape(undefined, true), false), _$escape(_$createComponent(For, {
406
+ return _$ssr(_tmpl$10, `k2b-data-table__row ${_$escape(rowClass(row), true)}`, _$ssrAttribute("data-hover", shouldHoverRows() ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-clickable", shouldHoverRows() && isInteractive() ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-selected", isSelected() ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("aria-selected", props.selection ? !!isSelected() : _$escape(undefined, true), false) + _$ssrAttribute("tabindex", props.selection ? props.selection.focused() === id() ? 0 : -1 : isInteractive() ? 0 : _$escape(undefined, true), false), _$escape(_$createComponent(For, {
385
407
  get each() {
386
408
  return props.columns;
387
409
  },
388
410
  children: (col, index) => {
389
411
  const value = () => valueOf(row, col);
390
- return _$ssr(_tmpl$1, `${_$escape(col.cellClass ?? "", true)} ${_$escape(col.class ?? "", true)}`, _$ssrAttribute("data-align", _$escape(alignAttr(col), true), false) + _$ssrAttribute("data-valign", props.verticalAlign && props.verticalAlign !== "middle" ? _$escape(props.verticalAlign, true) : _$escape(undefined, true), false) + _$ssrAttribute("data-highlighted", _$escape(columnHighlighted(index()), true), false), _$ssrAttribute("class", _$escape(cellContentClass(), true), false), props.renderCell ? _$escape(props.renderCell({
412
+ return _$ssr(_tmpl$11, `${_$escape(col.cellClass ?? "", true)} ${_$escape(col.class ?? "", true)}`, _$ssrAttribute("data-nowrap", _$escape(nowrapAttr(col), true), false) + _$ssrAttribute("data-align", _$escape(alignAttr(col), true), false) + _$ssrAttribute("data-valign", props.verticalAlign && props.verticalAlign !== "middle" ? _$escape(props.verticalAlign, true) : _$escape(undefined, true), false) + _$ssrAttribute("data-highlighted", _$escape(columnHighlighted(index()), true), false), _$ssrAttribute("class", _$escape(cellContentClass(), true), false), props.renderCell ? _$escape(props.renderCell({
391
413
  row,
392
414
  col,
393
415
  value: value(),
@@ -404,7 +426,7 @@ function DataTableRoot(props) {
404
426
  return props.fillHeight;
405
427
  },
406
428
  get children() {
407
- return _$ssr(_tmpl$5, _$ssrAttribute("colspan", _$escape(props.columns.length, true), false));
429
+ return _$ssr(_tmpl$7, _$ssrAttribute("colspan", _$escape(props.columns.length, true), false));
408
430
  }
409
431
  })];
410
432
  }
@@ -412,13 +434,13 @@ function DataTableRoot(props) {
412
434
  get when() {
413
435
  return props.footer;
414
436
  },
415
- children: footer => _$ssr(_tmpl$10, _$escape(_$createComponent(For, {
437
+ children: footer => _$ssr(_tmpl$12, _$escape(_$createComponent(For, {
416
438
  get each() {
417
439
  return props.columns;
418
440
  },
419
441
  children: (col, index) => {
420
442
  const value = () => footer().values?.[col.id];
421
- return _$ssr(_tmpl$11, _$ssrAttribute("data-align", _$escape(alignAttr(col), true), false) + _$ssrAttribute("data-highlighted", _$escape(columnHighlighted(index()), true), false), footer().renderCell ? _$escape(footer().renderCell({
443
+ return _$ssr(_tmpl$13, _$ssrAttribute("data-nowrap", _$escape(nowrapAttr(col), true), false) + _$ssrAttribute("data-align", _$escape(alignAttr(col), true), false) + _$ssrAttribute("data-highlighted", _$escape(columnHighlighted(index()), true), false), footer().renderCell ? _$escape(footer().renderCell({
422
444
  col,
423
445
  value: value(),
424
446
  render: renderValueDefault
@@ -430,11 +452,11 @@ function DataTableRoot(props) {
430
452
  return shouldRenderLoadMoreSentinel();
431
453
  },
432
454
  get children() {
433
- return _$ssr(_tmpl$6);
455
+ return _$ssr(_tmpl$8);
434
456
  }
435
457
  }))), _$createComponent(For, {
436
458
  each: ["y", "x"],
437
- children: axis => _$ssr(_tmpl$12, _$ssrAttribute("data-axis", _$escape(axis, true), false) + _$ssrAttribute("data-overflow", scrollbars()[axis].overflow ? "true" : _$escape(undefined, true), false), _$ssrStyleProperty("--k2b-data-table-scroll-offset:", `${_$escape(scrollbars()[axis].offset, true)}px`) + _$ssrStyleProperty(";--k2b-data-table-scroll-size:", `${_$escape(scrollbars()[axis].size, true)}px`))
459
+ children: axis => _$ssr(_tmpl$14, _$ssrAttribute("data-axis", _$escape(axis, true), false) + _$ssrAttribute("data-overflow", scrollbars()[axis].overflow ? "true" : _$escape(undefined, true), false), _$ssrStyleProperty("--k2b-data-table-scroll-offset:", `${_$escape(scrollbars()[axis].offset, true)}px`) + _$ssrStyleProperty(";--k2b-data-table-scroll-size:", `${_$escape(scrollbars()[axis].size, true)}px`))
438
460
  })];
439
461
  }
440
462
  });
@@ -467,9 +489,9 @@ const DataTablePanel = props => {
467
489
  const DataTableHeader = props => {
468
490
  const panel = useContext(DataTablePanelContext);
469
491
  panel?.registerHeading();
470
- return _$ssr(_tmpl$13, `k2b-data-panel__header ${_$escape(props.class ?? "", true)}`, _$escape(_$createComponent(PanelHeader, {
492
+ return _$ssr(_tmpl$15, `k2b-data-panel__header ${_$escape(props.class ?? "", true)}`, _$escape(_$createComponent(PanelHeader, {
471
493
  get title() {
472
- return _$ssr(_tmpl$14, _$ssrAttribute("id", _$escape(panel?.headingId, true), false), _$escape(props.title));
494
+ return _$ssr(_tmpl$16, _$ssrAttribute("id", _$escape(panel?.headingId, true), false), _$escape(props.title));
473
495
  },
474
496
  get subtitle() {
475
497
  return props.subtitle;
@@ -485,8 +507,8 @@ const DataTableHeader = props => {
485
507
  }
486
508
  })));
487
509
  };
488
- const DataTableControls = props => _$ssr(_tmpl$13, `k2b-data-panel__controls ${_$escape(props.class ?? "", true)}`, _$escape(props.children));
489
- const DataTablePanelFooter = props => _$ssr(_tmpl$15, `k2b-data-panel__footer ${_$escape(props.class ?? "", true)}`, _$escape(props.children));
510
+ const DataTableControls = props => _$ssr(_tmpl$15, `k2b-data-panel__controls ${_$escape(props.class ?? "", true)}`, _$escape(props.children));
511
+ const DataTablePanelFooter = props => _$ssr(_tmpl$17, `k2b-data-panel__footer ${_$escape(props.class ?? "", true)}`, _$escape(props.children));
490
512
  const DataTable = DataTableRoot;
491
513
  DataTable.Panel = DataTablePanel;
492
514
  DataTable.Header = DataTableHeader;