@k2b/ui 0.22.0 → 0.23.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 (98) hide show
  1. package/dist/browser/content/Calendar.js +1086 -1049
  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 +1571 -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 +199 -171
  12. package/dist/browser/content/DataTable.js.map +1 -1
  13. package/dist/browser/content/calendar-day-scroll.js +98 -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 +1649 -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 +123 -97
  33. package/dist/browser/layout/AppWorkspace.js.map +1 -1
  34. package/dist/browser/layout/PageTitle.js +4 -1
  35. package/dist/browser/layout/PageTitle.js.map +1 -1
  36. package/dist/browser/layout/app-workspace-controller.js +164 -86
  37. package/dist/browser/layout/app-workspace-controller.js.map +1 -1
  38. package/dist/browser/surfaces/StatCell.js +18 -6
  39. package/dist/browser/surfaces/StatCell.js.map +1 -1
  40. package/dist/ssr/content/Calendar.js +524 -335
  41. package/dist/ssr/content/Calendar.js.map +1 -1
  42. package/dist/ssr/content/CalendarDayView.js +800 -0
  43. package/dist/ssr/content/CalendarDayView.js.map +1 -0
  44. package/dist/ssr/content/CalendarWeekView.js +1069 -0
  45. package/dist/ssr/content/CalendarWeekView.js.map +1 -0
  46. package/dist/ssr/content/ChartExplorer.js +93 -34
  47. package/dist/ssr/content/ChartExplorer.js.map +1 -1
  48. package/dist/ssr/content/ChartFilterControls.js +49 -7
  49. package/dist/ssr/content/ChartFilterControls.js.map +1 -1
  50. package/dist/ssr/content/DataTable.js +69 -51
  51. package/dist/ssr/content/DataTable.js.map +1 -1
  52. package/dist/ssr/content/calendar-day-scroll.js +98 -0
  53. package/dist/ssr/content/calendar-day-scroll.js.map +1 -0
  54. package/dist/ssr/content/calendar-days.js +408 -0
  55. package/dist/ssr/content/calendar-days.js.map +1 -0
  56. package/dist/ssr/content/calendar-dialogs.js +159 -0
  57. package/dist/ssr/content/calendar-dialogs.js.map +1 -0
  58. package/dist/ssr/content/calendar-messages.js +210 -2
  59. package/dist/ssr/content/calendar-messages.js.map +1 -1
  60. package/dist/ssr/content/calendar-pointer.js +15 -3
  61. package/dist/ssr/content/calendar-pointer.js.map +1 -1
  62. package/dist/ssr/content/calendar-shared.js +261 -0
  63. package/dist/ssr/content/calendar-shared.js.map +1 -0
  64. package/dist/ssr/content/calendar-time-view.js +1306 -0
  65. package/dist/ssr/content/calendar-time-view.js.map +1 -0
  66. package/dist/ssr/content/chart-messages.js +10 -0
  67. package/dist/ssr/content/chart-messages.js.map +1 -1
  68. package/dist/ssr/content/index.js.map +1 -1
  69. package/dist/ssr/inputs/Combobox.js.map +1 -1
  70. package/dist/ssr/layout/AppWorkspace.js +38 -29
  71. package/dist/ssr/layout/AppWorkspace.js.map +1 -1
  72. package/dist/ssr/layout/PageTitle.js +4 -1
  73. package/dist/ssr/layout/PageTitle.js.map +1 -1
  74. package/dist/ssr/layout/app-workspace-controller.js +164 -86
  75. package/dist/ssr/layout/app-workspace-controller.js.map +1 -1
  76. package/dist/ssr/surfaces/StatCell.js +2 -2
  77. package/dist/ssr/surfaces/StatCell.js.map +1 -1
  78. package/dist/styles.css +1 -1
  79. package/dist/types/content/Calendar.d.ts +91 -0
  80. package/dist/types/content/CalendarDayView.d.ts +7 -0
  81. package/dist/types/content/CalendarWeekView.d.ts +7 -0
  82. package/dist/types/content/ChartExplorer.d.ts +36 -1
  83. package/dist/types/content/ChartFilterControls.d.ts +6 -1
  84. package/dist/types/content/DataTable.d.ts +5 -0
  85. package/dist/types/content/calendar-day-scroll.d.ts +42 -0
  86. package/dist/types/content/calendar-days.d.ts +192 -0
  87. package/dist/types/content/calendar-dialogs.d.ts +22 -0
  88. package/dist/types/content/calendar-messages.d.ts +99 -0
  89. package/dist/types/content/calendar-pointer.d.ts +9 -0
  90. package/dist/types/content/calendar-shared.d.ts +69 -0
  91. package/dist/types/content/calendar-time-view.d.ts +252 -0
  92. package/dist/types/content/chart-messages.d.ts +5 -0
  93. package/dist/types/content/index.d.ts +2 -2
  94. package/dist/types/layout/AppWorkspace.d.ts +25 -3
  95. package/dist/types/layout/PageTitle.d.ts +2 -1
  96. package/dist/types/layout/app-workspace-controller.d.ts +9 -1
  97. package/dist/types/surfaces/StatCell.d.ts +5 -0
  98. package/package.json +1 -1
@@ -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":";;;;;;;;;;;AAAA,SAAS,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,GAAG,EAAE,IAAI,QAAQ,UAAU;AAChF,SAAS,MAAM,QAAQ,mBAAmB;AAC1C,SAAS,UAAU,QAAQ,uBAAuB;AAClD,SAAS,MAAM,QAAQ,wBAAwB;AAC/C,SAAS,aAAa,QAAQ,kBAAkB;AAEhD,SAAS,gBAAgB,QAAQ,kBAAkB;AAmBnD;AACA,OAAO,SAAS,mBAAmB,CAAC,KAA+B,EAAE;EACnE,MAAM,eAAe,GAAG,MAAM;IAC5B,KAAK,MAAM,KAAK,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE;MAC/C,MAAM,IAAI,GAAG,KAAK,EAAE,GAAG,CAAE,IAAI,IAAK,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE;MACjD,IAAI,IAAI,CAAC,IAAI,CAAE,GAAG,IAAK,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,MAAM,EAChE,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC;IACzE;EACF,CAAC;EACD,eAAe,CAAC,CAAC;EACjB,YAAY,CAAC,eAAe,CAAC;EAC7B,MAAM,QAAQ,GAAG,aAAa,CAAC,CAAC;EAChC,MAAM,aAAa,GAAG,gBAAgB,CAAC,CAAC;EACxC,MAAM,EAAE,GAAG,sBAAsB,cAAc,CAAC,CAAC,EAAE;EACnD,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,YAAY,CAAC,KAAK,CAAC;EAC7D,IAAI,YAAY,GAAG,KAAK;EACxB,MAAM,SAAS,GAAI,GAAuB,IAAK,KAAK,CAAC,KAAK,EAAE,IAAI,CAAE,IAAI,IAAK,IAAI,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE,KAAK,IAAI,GAAG,IAAI,EAAE;EAChH;EACA,MAAM,UAAU,GAAG,MACjB,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,MAAM,EAAE,IAAI,KAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,GAAG,MAAO,EAAE,EAAE,CAAC,IAAI,EAAE;EACtH,0BAEK,IAAI;IAAA,IAAC,IAAI;MAAA,OAAE,KAAK,CAAC,KAAK,EAAE,MAAM;IAAA;IAAA;MAAA,2DAIf,KAAK,CAAC,cAAc,IAAI,QAAQ,CAAC,CAAC,CAAC,KAAK,kDACrC,aAAa,CAAC,CAAC,GAAG,MAAM,YAAG,SAAS,4CAiBlD,MAAM;QACL,EAAE,EAAE,GAAG,EAAE,YAAY;QACrB,SAAS,EAAE,KAAK;QAAA,oBACE,GAAG,EAAE,QAAQ;QAAA,IAC/B,KAAK;UAAA,OAAE,KAAK,CAAC,cAAc,IAAI,QAAQ,CAAC,CAAC,CAAC,KAAK;QAAA;QAC/C,GAAG,EAAE,CAAC;QAAA,IACN,GAAG;UAAA,OAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;QAAA;QAChD,IAAI,EAAE,CAAC;QAAA,IACP,KAAK;UAAA,OAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,EAAE,SAAS,CAAE,IAAI,IAAK,IAAI,CAAC,GAAG,KAAK,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAAA;QAAA,IAC1F,QAAQ;UAAA,OAAE,KAAK,CAAC,QAAQ,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC,IAAI,CAAC;QAAA;QAC1D,WAAW,EAAG,KAAK,IAAK,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,EAAE,KAAK,IAAI,EAAE;QAAA;UAAA,OACzC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QAAA;QAC7C,aAAa,EAAG,KAAK,IAAK;UACxB,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC;UACjC,IAAI,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC;YAAE,GAAG,KAAK,CAAC,OAAO;YAAE,IAAI,EAAE,IAAI,CAAC;UAAI,CAAC,CAAC;QACjE;MAAC,KAEsD,YAAG,EAAE,mBAAY,mCAAS,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,0BACpF,UAAU,CAAC,CAAC,YAC/B,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAE7B,YAAG,EAAE,eAAQ,6BACnB,GAAG;QAAA,IAAC,IAAI;UAAA,OAAE,KAAK,CAAC,KAAK;QAAA;QAAA,UAClB,IAAI,kDAAyB,IAAI,CAAC,GAAG,KAAK,KAAK,CAAC,OAAO,CAAC,IAAI,GAAG,MAAM,YAAG,SAAS,0BAAG,IAAI,CAAC,KAAK;MAAQ;IAAA;EAAA,8CAM7G,IAAI;IAAA,IAAC,IAAI;MAAA,OAAE,KAAK,CAAC,MAAM,EAAE,MAAM;IAAA;IAAA;MAAA,yBAC7B,UAAU;QAAA,IACT,KAAK;UAAA,OAAE,KAAK,CAAC,WAAW,IAAI,aAAa,CAAC,CAAC,CAAC,WAAW;QAAA;QACvD,IAAI;QAAA,IACJ,QAAQ;UAAA,OAAE,KAAK,CAAC,QAAQ;QAAA;QAAA,IACxB,KAAK;UAAA,OAAE,KAAK,CAAC,OAAO,CAAC,WAAW,IAAI,KAAK,CAAC,MAAM,EAAE,GAAG,CAAE,IAAI,IAAK,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE;QAAA;QAAA,IAC/E,YAAY;UAAA,OAAE,KAAK,CAAC,MAAM,EAAE,GAAG,CAAE,IAAI,IAAK,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE;QAAA;QAAA,IACzD,QAAQ;UAAA,OAAE,kBAAK,CAAC,OAAO,CAAC,WAAW,KAAK,SAAS,OAAI,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE,MAAM;QAAA;QAAA,IAC9G,OAAO;UAAA,OAAE,CACP;YAAE,QAAQ,EAAE,IAAI;YAAE,OAAO,EAAE,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,EAAE,GAAG,CAAE,IAAI,KAAM;cAAE,KAAK,EAAE,IAAI,CAAC,GAAG;cAAE,KAAK,EAAE,IAAI,CAAC,KAAK;cAAE,KAAK,EAAE,IAAI,CAAC;YAAM,CAAC,CAAC;UAAE,CAAC,CAC7H;QAAA;QACD,aAAa,EAAG,WAAW,IAAK,KAAK,CAAC,SAAS,CAAC;UAAE,GAAG,KAAK,CAAC,OAAO;UAAE;QAAY,CAAC;MAAC;IAAA;EAAA,gCAGrF,IAAI;IAAA,IAAC,IAAI;MAAA,OAAE,oBAAK,CAAC,OAAO,OAAI,KAAK,CAAC,KAAK,EAAE,MAAM;IAAA;IAAA;MAAA,yBAC7C,MAAM;QACL,OAAO;QAAA;QAAA,IAEP,QAAQ;UAAA,OAAE,KAAK,CAAC,QAAQ,IAAK,KAAK,CAAC,OAAO,CAAC,aAAa,KAAK,SAAS,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,KAAK,SAAU;QAAA;QAAA;UAAA,OAEzG,kBAAK,CAAC,OAAO,CAAC,aAAa,KAAK,SAAS,MACrC,SAAS,GACT,GAAG,aAAa,CAAC,CAAC,CAAC,qBAAqB,KAAK,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE;QAAA;QAE3F,OAAO,EAAE,MACP,KAAK,CAAC,SAAS,CAAC;UACd,GAAG,KAAK,CAAC,OAAO;UAChB,aAAa,EAAE,KAAK,CAAC,OAAO,CAAC,aAAa,KAAK,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,GAAG;QAClF,CAAC,CAAC;QAAA;UAAA,0BAGH,IAAI;YAAA,IAAC,IAAI;cAAA,OAAE,KAAK,CAAC,OAAO,CAAC,aAAa,KAAK,SAAS;YAAA;YAAA;cAAA;YAAA;UAAA,mBAIlD,KAAK,CAAC,OAAO,CAAC,aAAa,KAAK,SAAS,YACtC,aAAa,CAAC,CAAC,CAAC,iBAAiB,IACjC,YAAG,aAAa,CAAC,CAAC,CAAC,cAAc,eAAK,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,GAAE,qBAEnF,IAAI;YAAA,IAAC,IAAI;cAAA,OAAE,KAAK,CAAC,OAAO,CAAC,aAAa,KAAK,SAAS;YAAA;YAAA;cAAA;YAAA;UAAA;QAAA;MAAA;IAAA;EAAA,gCAMtD,IAAI;IAAA,IAAC,IAAI;MAAA,OAAE,KAAK,CAAC,MAAM;IAAA;IAAA;MAAA,QACrB,QAAQ,CAAC,CAAC,CAAC,gBAAgB,EAAE,GAAG,oBAChC,MAAM;QAAC,OAAO;QAAQ,IAAI;QAAA,IAAM,OAAO;UAAA,OAAE,KAAK,CAAC,OAAO;QAAA;QAAA;UAAA,OACpD,QAAQ,CAAC,CAAC,CAAC,KAAK;QAAA;MAAA;IAAA;EAAA,gCAGpB,IAAI;IAAA,IAAC,IAAI;MAAA,OAAE,KAAK,CAAC,MAAM;IAAA;IAAA;MAAA,cACnB,aAAa,CAAC,CAAC,CAAC,iBAAiB,oBACnC,IAAI;QAAA,IAAC,IAAI;UAAA,OAAE,KAAK,CAAC,KAAK,EAAE,MAAM;QAAA;QAAA;UAAA,cAAK,SAAS,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC;QAAA;MAAA;IAAA;EAAA;AAMtF","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";
@@ -215,34 +217,29 @@ function DataTableRoot(props) {
215
217
  const sortKeyOf = col => col.sortable === true ? col.id : typeof col.sortable === "string" ? col.sortable : null;
216
218
 
217
219
  /**
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.
220
+ * Sorting is a link by default: server-rendered tables keep the order in the
221
+ * URL. Client tables pass onSortChange instead. Clicking the active column
222
+ * flips its direction.
220
223
  */
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
- };
224
+ const nextSortFor = key => ({
225
+ key,
226
+ direction: props.sort?.key === key && props.sort?.direction === "desc" ? "asc" : "desc"
227
+ });
235
228
 
236
229
  /** Only a sortable column carries a sort state; the rest carry none at all. */
237
230
  const ariaSortFor = col => {
238
231
  const key = sortKeyOf(col);
239
- if (!key || !props.sortHref && !props.renderHeader) return undefined;
232
+ if (!key || !props.sortHref && !props.onSortChange && !props.renderHeader) return undefined;
240
233
  if (props.sort?.key !== key) return "none";
241
234
  return props.sort?.direction === "asc" ? "ascending" : "descending";
242
235
  };
243
236
  const renderHeaderDefault = col => {
244
- const sort = sortLinkFor(col);
245
- const title = [_$ssr(_tmpl$, _$escape(renderColumnPart(col.header, col))), _$createComponent(Show, {
237
+ const key = sortKeyOf(col);
238
+ // Only how a column sorts decides the element. The order lives in its attributes, so a header button keeps
239
+ // keyboard focus when a click sorts the table and the reader can press it again to reverse the order.
240
+ const mode = createMemo(() => !key ? null : props.sortHref ? "link" : props.onSortChange ? "button" : null);
241
+ const active = () => key !== null && props.sort?.key === key;
242
+ const title = () => [_$ssr(_tmpl$, _$escape(renderColumnPart(col.header, col))), _$createComponent(Show, {
246
243
  get when() {
247
244
  return col.subtitle !== undefined;
248
245
  },
@@ -250,8 +247,29 @@ function DataTableRoot(props) {
250
247
  return _$ssr(_tmpl$2, _$escape(renderColumnPart(col.subtitle, col)));
251
248
  }
252
249
  })];
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));
250
+ 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));
251
+ return _$createComponent(Switch, {
252
+ get fallback() {
253
+ return _$ssr(_tmpl$6, _$ssrAttribute("data-align", _$escape(alignAttr(col), true), false), _$escape(title()));
254
+ },
255
+ get children() {
256
+ return [_$createComponent(Match, {
257
+ get when() {
258
+ return mode() === "link";
259
+ },
260
+ get children() {
261
+ 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()));
262
+ }
263
+ }), _$createComponent(Match, {
264
+ get when() {
265
+ return mode() === "button";
266
+ },
267
+ get children() {
268
+ return _$ssr(_tmpl$5, _$ssrAttribute("data-align", _$escape(alignAttr(col), true), false), _$escape(line()));
269
+ }
270
+ })];
271
+ }
272
+ });
255
273
  };
256
274
  const renderValueDefault = value => defaultRender(value, locale(), messages());
257
275
  const renderCellDefault = (row, col) => renderValueDefault(valueOf(row, col));
@@ -354,11 +372,11 @@ function DataTableRoot(props) {
354
372
  },
355
373
  onMouseLeave: () => setHoveredColumn(null),
356
374
  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, {
375
+ 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
376
  get each() {
359
377
  return props.columns;
360
378
  },
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({
379
+ 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
380
  col,
363
381
  render: () => renderHeaderDefault(col)
364
382
  })) : _$escape(renderHeaderDefault(col)))
@@ -367,7 +385,7 @@ function DataTableRoot(props) {
367
385
  return props.rows.length > 0;
368
386
  },
369
387
  get fallback() {
370
- return _$ssr(_tmpl$9, _$ssrAttribute("colspan", _$escape(props.columns.length, true), false), _$escape(_$createComponent(Placeholder, {
388
+ return _$ssr(_tmpl$1, _$ssrAttribute("colspan", _$escape(props.columns.length, true), false), _$escape(_$createComponent(Placeholder, {
371
389
  get description() {
372
390
  return props.empty ?? dataTableMessages().noRecords;
373
391
  }
@@ -381,13 +399,13 @@ function DataTableRoot(props) {
381
399
  children: row => {
382
400
  const id = () => rowId(row);
383
401
  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, {
402
+ 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
403
  get each() {
386
404
  return props.columns;
387
405
  },
388
406
  children: (col, index) => {
389
407
  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({
408
+ return _$ssr(_tmpl$11, `${_$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({
391
409
  row,
392
410
  col,
393
411
  value: value(),
@@ -404,7 +422,7 @@ function DataTableRoot(props) {
404
422
  return props.fillHeight;
405
423
  },
406
424
  get children() {
407
- return _$ssr(_tmpl$5, _$ssrAttribute("colspan", _$escape(props.columns.length, true), false));
425
+ return _$ssr(_tmpl$7, _$ssrAttribute("colspan", _$escape(props.columns.length, true), false));
408
426
  }
409
427
  })];
410
428
  }
@@ -412,13 +430,13 @@ function DataTableRoot(props) {
412
430
  get when() {
413
431
  return props.footer;
414
432
  },
415
- children: footer => _$ssr(_tmpl$10, _$escape(_$createComponent(For, {
433
+ children: footer => _$ssr(_tmpl$12, _$escape(_$createComponent(For, {
416
434
  get each() {
417
435
  return props.columns;
418
436
  },
419
437
  children: (col, index) => {
420
438
  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({
439
+ return _$ssr(_tmpl$13, _$ssrAttribute("data-align", _$escape(alignAttr(col), true), false) + _$ssrAttribute("data-highlighted", _$escape(columnHighlighted(index()), true), false), footer().renderCell ? _$escape(footer().renderCell({
422
440
  col,
423
441
  value: value(),
424
442
  render: renderValueDefault
@@ -430,11 +448,11 @@ function DataTableRoot(props) {
430
448
  return shouldRenderLoadMoreSentinel();
431
449
  },
432
450
  get children() {
433
- return _$ssr(_tmpl$6);
451
+ return _$ssr(_tmpl$8);
434
452
  }
435
453
  }))), _$createComponent(For, {
436
454
  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`))
455
+ 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
456
  })];
439
457
  }
440
458
  });
@@ -467,9 +485,9 @@ const DataTablePanel = props => {
467
485
  const DataTableHeader = props => {
468
486
  const panel = useContext(DataTablePanelContext);
469
487
  panel?.registerHeading();
470
- return _$ssr(_tmpl$13, `k2b-data-panel__header ${_$escape(props.class ?? "", true)}`, _$escape(_$createComponent(PanelHeader, {
488
+ return _$ssr(_tmpl$15, `k2b-data-panel__header ${_$escape(props.class ?? "", true)}`, _$escape(_$createComponent(PanelHeader, {
471
489
  get title() {
472
- return _$ssr(_tmpl$14, _$ssrAttribute("id", _$escape(panel?.headingId, true), false), _$escape(props.title));
490
+ return _$ssr(_tmpl$16, _$ssrAttribute("id", _$escape(panel?.headingId, true), false), _$escape(props.title));
473
491
  },
474
492
  get subtitle() {
475
493
  return props.subtitle;
@@ -485,8 +503,8 @@ const DataTableHeader = props => {
485
503
  }
486
504
  })));
487
505
  };
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));
506
+ const DataTableControls = props => _$ssr(_tmpl$15, `k2b-data-panel__controls ${_$escape(props.class ?? "", true)}`, _$escape(props.children));
507
+ const DataTablePanelFooter = props => _$ssr(_tmpl$17, `k2b-data-panel__footer ${_$escape(props.class ?? "", true)}`, _$escape(props.children));
490
508
  const DataTable = DataTableRoot;
491
509
  DataTable.Panel = DataTablePanel;
492
510
  DataTable.Header = DataTableHeader;