kanto-ds 1.3.0 → 1.5.1

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 (134) hide show
  1. package/README.md +10 -10
  2. package/dist/chunks/defaults-CFrjqae2.js +59 -0
  3. package/dist/chunks/{defaults-DKzFsNbv.js.map → defaults-CFrjqae2.js.map} +1 -1
  4. package/dist/chunks/events-r51msXNf.js +22 -0
  5. package/dist/chunks/{events-Bjl5Zmmq.js.map → events-r51msXNf.js.map} +1 -1
  6. package/dist/chunks/floating-B7_Dahpn.js +54 -0
  7. package/dist/chunks/floating-B7_Dahpn.js.map +1 -0
  8. package/dist/chunks/{form-control-CxjBTt1c.js → form-control-B74_EHtG.js} +7 -7
  9. package/dist/chunks/form-control-B74_EHtG.js.map +1 -0
  10. package/dist/chunks/{index-fzPIgxe2.js → index-STEEvEP7.js} +33 -16
  11. package/dist/chunks/index-STEEvEP7.js.map +1 -0
  12. package/dist/chunks/kt-calendar-B_hFdD9V.js +640 -0
  13. package/dist/chunks/kt-calendar-B_hFdD9V.js.map +1 -0
  14. package/dist/chunks/{kt-element-mdd5cXZX.js → kt-element-Djx2JcGl.js} +2 -2
  15. package/dist/chunks/{kt-element-mdd5cXZX.js.map → kt-element-Djx2JcGl.js.map} +1 -1
  16. package/dist/chunks/{listbox-Sm3nvsC6.js → listbox-llcUu_V-.js} +18 -14
  17. package/dist/chunks/{listbox-Sm3nvsC6.js.map → listbox-llcUu_V-.js.map} +1 -1
  18. package/dist/chunks/locale-C5xLkGx5.js +14 -0
  19. package/dist/chunks/locale-C5xLkGx5.js.map +1 -0
  20. package/dist/chunks/position-Cx_ZH5zh.js +39 -0
  21. package/dist/chunks/position-Cx_ZH5zh.js.map +1 -0
  22. package/dist/components/core/kt-avatar/kt-avatar.js +2 -2
  23. package/dist/components/core/kt-badge/kt-badge.js +3 -3
  24. package/dist/components/core/kt-button/kt-button.js +1 -1
  25. package/dist/components/core/kt-card/kt-card.js +2 -2
  26. package/dist/components/core/kt-code/kt-code.js +3 -3
  27. package/dist/components/core/kt-icon/kt-icon.js +2 -2
  28. package/dist/components/core/kt-kbd/kt-kbd.js +1 -1
  29. package/dist/components/core/kt-split-button/kt-split-button.js +4 -4
  30. package/dist/components/data/kt-chart/kt-chart.js +52 -52
  31. package/dist/components/data/kt-chart/kt-chart.js.map +1 -1
  32. package/dist/components/data/kt-meter/kt-meter.js +1 -1
  33. package/dist/components/data/kt-pagination/kt-pagination.js +3 -3
  34. package/dist/components/data/kt-stat/kt-stat.js +1 -1
  35. package/dist/components/data/kt-table/kt-table.d.ts +53 -3
  36. package/dist/components/data/kt-table/kt-table.js +286 -131
  37. package/dist/components/data/kt-table/kt-table.js.map +1 -1
  38. package/dist/components/data/kt-table/window.d.ts +19 -0
  39. package/dist/components/data/kt-timeline/kt-timeline.js +1 -1
  40. package/dist/components/feedback/kt-alert/kt-alert.js +3 -3
  41. package/dist/components/feedback/kt-empty-state/kt-empty-state.js +1 -1
  42. package/dist/components/feedback/kt-progress-bar/kt-progress-bar.js +10 -10
  43. package/dist/components/feedback/kt-progress-bar/kt-progress-bar.js.map +1 -1
  44. package/dist/components/feedback/kt-skeleton/kt-skeleton.js +1 -1
  45. package/dist/components/feedback/kt-toast/kt-toast.js +58 -42
  46. package/dist/components/feedback/kt-toast/kt-toast.js.map +1 -1
  47. package/dist/components/feedback/kt-toast-container/kt-toast-container.js +1 -1
  48. package/dist/components/feedback/kt-tooltip/kt-tooltip.d.ts +20 -0
  49. package/dist/components/feedback/kt-tooltip/kt-tooltip.js +95 -51
  50. package/dist/components/feedback/kt-tooltip/kt-tooltip.js.map +1 -1
  51. package/dist/components/forms/kt-calendar/kt-calendar.d.ts +96 -0
  52. package/dist/components/forms/kt-calendar/kt-calendar.js +13 -0
  53. package/dist/components/forms/kt-calendar/kt-calendar.js.map +1 -0
  54. package/dist/components/forms/kt-checkbox/kt-checkbox.d.ts +75 -0
  55. package/dist/components/forms/kt-checkbox/kt-checkbox.js +212 -0
  56. package/dist/components/forms/kt-checkbox/kt-checkbox.js.map +1 -0
  57. package/dist/components/forms/kt-date-picker/kt-date-picker.d.ts +105 -0
  58. package/dist/components/forms/kt-date-picker/kt-date-picker.js +382 -0
  59. package/dist/components/forms/kt-date-picker/kt-date-picker.js.map +1 -0
  60. package/dist/components/forms/kt-drag-drop/kt-drag-drop.d.ts +9 -0
  61. package/dist/components/forms/kt-drag-drop/kt-drag-drop.js +36 -22
  62. package/dist/components/forms/kt-drag-drop/kt-drag-drop.js.map +1 -1
  63. package/dist/components/forms/kt-form/kt-form.js +11 -10
  64. package/dist/components/forms/kt-form/kt-form.js.map +1 -1
  65. package/dist/components/forms/kt-input/kt-input.d.ts +37 -1
  66. package/dist/components/forms/kt-input/kt-input.js +380 -194
  67. package/dist/components/forms/kt-input/kt-input.js.map +1 -1
  68. package/dist/components/forms/kt-input-menu/kt-input-menu.d.ts +13 -0
  69. package/dist/components/forms/kt-input-menu/kt-input-menu.js +73 -42
  70. package/dist/components/forms/kt-input-menu/kt-input-menu.js.map +1 -1
  71. package/dist/components/forms/kt-label-input/kt-label-input.js +1 -1
  72. package/dist/components/forms/kt-radio-group/kt-radio-group.d.ts +112 -0
  73. package/dist/components/forms/kt-radio-group/kt-radio-group.js +279 -0
  74. package/dist/components/forms/kt-radio-group/kt-radio-group.js.map +1 -0
  75. package/dist/components/forms/kt-select/kt-select.d.ts +13 -0
  76. package/dist/components/forms/kt-select/kt-select.js +87 -56
  77. package/dist/components/forms/kt-select/kt-select.js.map +1 -1
  78. package/dist/components/forms/kt-textarea/kt-textarea.d.ts +9 -0
  79. package/dist/components/forms/kt-textarea/kt-textarea.js +28 -14
  80. package/dist/components/forms/kt-textarea/kt-textarea.js.map +1 -1
  81. package/dist/components/forms/kt-toggle/kt-toggle.d.ts +9 -0
  82. package/dist/components/forms/kt-toggle/kt-toggle.js +43 -29
  83. package/dist/components/forms/kt-toggle/kt-toggle.js.map +1 -1
  84. package/dist/components/navigation/kt-breadcrumb/kt-breadcrumb.js +3 -3
  85. package/dist/components/navigation/kt-header/kt-header.js +3 -3
  86. package/dist/components/navigation/kt-page-header/kt-page-header.js +1 -1
  87. package/dist/components/navigation/kt-segmented-control/kt-segmented-control.d.ts +9 -0
  88. package/dist/components/navigation/kt-segmented-control/kt-segmented-control.js +40 -22
  89. package/dist/components/navigation/kt-segmented-control/kt-segmented-control.js.map +1 -1
  90. package/dist/components/navigation/kt-sub-menu-navigation/kt-sub-menu-navigation.js +3 -3
  91. package/dist/components/navigation/kt-tabs/kt-tabs.js +2 -2
  92. package/dist/components/navigation/kt-toggle-button/kt-toggle-button.js +2 -2
  93. package/dist/components/navigation/kt-toggle-button-group/kt-toggle-button-group.js +13 -7
  94. package/dist/components/navigation/kt-toggle-button-group/kt-toggle-button-group.js.map +1 -1
  95. package/dist/components/overlays/kt-collapsible/kt-collapsible.js +2 -2
  96. package/dist/components/overlays/kt-confirm-dialog/kt-confirm-dialog.js +3 -3
  97. package/dist/components/overlays/kt-dropdown/kt-dropdown.d.ts +7 -5
  98. package/dist/components/overlays/kt-dropdown/kt-dropdown.js +67 -57
  99. package/dist/components/overlays/kt-dropdown/kt-dropdown.js.map +1 -1
  100. package/dist/components/overlays/kt-modal/kt-modal.js +3 -3
  101. package/dist/components/overlays/kt-side-panel/kt-side-panel.js +3 -3
  102. package/dist/custom-elements.json +3526 -741
  103. package/dist/icons/defaults.d.ts +2 -0
  104. package/dist/icons/index.js +1 -1
  105. package/dist/index.d.ts +8 -0
  106. package/dist/index.js +99 -90
  107. package/dist/index.js.map +1 -1
  108. package/dist/internal/countries.d.ts +24 -9
  109. package/dist/internal/date.d.ts +53 -0
  110. package/dist/internal/events.d.ts +5 -0
  111. package/dist/internal/floating.d.ts +48 -0
  112. package/dist/internal/form-control.d.ts +5 -1
  113. package/dist/internal/locale.d.ts +15 -0
  114. package/dist/internal/position.d.ts +27 -0
  115. package/dist/internal/strings.d.ts +25 -0
  116. package/dist/react/index.d.ts +25 -0
  117. package/dist/react/index.js +189 -156
  118. package/dist/react/index.js.map +1 -1
  119. package/dist/react/jsx.d.ts +22 -1
  120. package/dist/strings/index.js +1 -1
  121. package/dist/tokens/base.css +5 -0
  122. package/dist/tokens/responsive.css +1 -0
  123. package/dist/tokens/spacing.css +1 -0
  124. package/dist/vscode.css-custom-data.json +20 -0
  125. package/dist/vscode.html-custom-data.json +221 -9
  126. package/dist/vue/index.d.ts +10 -0
  127. package/dist/vue/index.js +11 -7
  128. package/dist/vue/index.js.map +1 -1
  129. package/dist/web-types.json +514 -12
  130. package/package.json +18 -1
  131. package/dist/chunks/defaults-DKzFsNbv.js +0 -57
  132. package/dist/chunks/events-Bjl5Zmmq.js +0 -18
  133. package/dist/chunks/form-control-CxjBTt1c.js.map +0 -1
  134. package/dist/chunks/index-fzPIgxe2.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  import { css as m, html as r, nothing as o } from "lit";
2
2
  import { property as i } from "lit/decorators.js";
3
- import { K as u, d as c } from "../../../chunks/kt-element-mdd5cXZX.js";
3
+ import { K as u, d as c } from "../../../chunks/kt-element-Djx2JcGl.js";
4
4
  var g = Object.defineProperty, n = (d, t, e, s) => {
5
5
  for (var a = void 0, p = d.length - 1, h; p >= 0; p--)
6
6
  (h = d[p]) && (a = h(t, e, a) || a);
@@ -1,8 +1,8 @@
1
1
  import { css as h, html as m } from "lit";
2
2
  import { property as n } from "lit/decorators.js";
3
- import { K as g, d as c } from "../../../chunks/kt-element-mdd5cXZX.js";
4
- import { e as u } from "../../../chunks/events-Bjl5Zmmq.js";
5
- import { s as i } from "../../../chunks/index-fzPIgxe2.js";
3
+ import { K as g, d as c } from "../../../chunks/kt-element-Djx2JcGl.js";
4
+ import { e as u } from "../../../chunks/events-r51msXNf.js";
5
+ import { s as i } from "../../../chunks/index-STEEvEP7.js";
6
6
  import "../../core/kt-button/kt-button.js";
7
7
  var d = Object.defineProperty, p = (r, a, t, f) => {
8
8
  for (var e = void 0, o = r.length - 1, l; o >= 0; o--)
@@ -1,6 +1,6 @@
1
1
  import { css as h, nothing as l, html as r } from "lit";
2
2
  import { property as e } from "lit/decorators.js";
3
- import { K as c, d as f } from "../../../chunks/kt-element-mdd5cXZX.js";
3
+ import { K as c, d as f } from "../../../chunks/kt-element-Djx2JcGl.js";
4
4
  import "../../core/kt-icon/kt-icon.js";
5
5
  import "../../core/kt-badge/kt-badge.js";
6
6
  import "../../feedback/kt-skeleton/kt-skeleton.js";
@@ -1,5 +1,6 @@
1
- import { type TemplateResult } from 'lit';
1
+ import { type PropertyValues, type TemplateResult } from 'lit';
2
2
  import { KtElement } from '#internal/kt-element';
3
+ import '../../core/kt-icon/kt-icon.js';
3
4
  import '../kt-pagination/kt-pagination.js';
4
5
  export type KtSortDirection = 'asc' | 'desc' | null;
5
6
  export type KtTableRow = Record<string, unknown>;
@@ -45,7 +46,32 @@ export type KtCellRenderer = (row: KtTableRow, column: KtTableColumn) => unknown
45
46
  */
46
47
  export declare class KtTable extends KtElement {
47
48
  static styles: import("lit").CSSResultGroup[];
48
- private page;
49
+ /** The page on screen, from 1. Set it to open on another page. */
50
+ page: number;
51
+ /**
52
+ * For data sorted and paged on a server: `data` is the current page, shown
53
+ * as given. Headers and the pager still update the state and fire their
54
+ * events, and the application loads what they ask for.
55
+ */
56
+ manual: boolean;
57
+ /**
58
+ * Renders only the rows in view, for thousands of rows without paging. The
59
+ * table scrolls inside its own box: give it a height (`kt-table { height:
60
+ * 480px }`). Every row must be the same height — the first one rendered is
61
+ * measured. A page size takes precedence.
62
+ */
63
+ virtual: boolean;
64
+ /** How far the scroller is scrolled. Not `scrollTop`, which the host already has. */
65
+ private scrollOffset;
66
+ /** The scroller's height, and the header's inside it, in px. */
67
+ private viewportHeight;
68
+ private headerHeight;
69
+ /** A body row's height, in px; 0 until one has been measured. */
70
+ private rowHeight;
71
+ private resizeObserver;
72
+ private observed;
73
+ /** In manual mode, how many rows the server holds — what the pager counts. */
74
+ totalRows: number;
49
75
  columns: readonly KtTableColumn[];
50
76
  data: readonly KtTableRow[];
51
77
  selectable: boolean;
@@ -64,8 +90,23 @@ export declare class KtTable extends KtElement {
64
90
  loadingText: string | undefined;
65
91
  /** Accessible name for the table. */
66
92
  label: string;
67
- /** The rows after sorting, before paging. */
93
+ /**
94
+ * BCP 47 locale text is sorted in. Empty means the page's `<html lang>`,
95
+ * then the browser's language.
96
+ */
97
+ locale: string;
98
+ /** The last sort, and what it was computed from. */
99
+ private sortCache;
100
+ /**
101
+ * The rows after sorting, before paging.
102
+ *
103
+ * Sorted once per change of `data`, `sortKey`, `sortDirection` or locale, not on
104
+ * every render: hovering a row or ticking a box re-renders the table, and
105
+ * re-sorting a few thousand rows each time is what made that lag. Assign a
106
+ * new array to `data` rather than changing it in place.
107
+ */
68
108
  get sortedRows(): readonly KtTableRow[];
109
+ private sort;
69
110
  get totalPages(): number;
70
111
  /** The rows actually on screen. */
71
112
  get visibleRows(): readonly KtTableRow[];
@@ -80,6 +121,13 @@ export declare class KtTable extends KtElement {
80
121
  private toggleAll;
81
122
  /** The selected rows themselves, not just their identities. */
82
123
  get selectedRows(): readonly KtTableRow[];
124
+ /** Virtual rendering, unless a page size pages the rows instead. */
125
+ private get isVirtual();
126
+ private onScroll;
127
+ updated(changed: PropertyValues): void;
128
+ disconnectedCallback(): void;
129
+ /** Follows the scroller's height, which the page can change at any time. */
130
+ private observe;
83
131
  private onPageChange;
84
132
  /**
85
133
  * The aria-sort value for a column.
@@ -90,6 +138,8 @@ export declare class KtTable extends KtElement {
90
138
  private sortStateFor;
91
139
  private renderHeaderCell;
92
140
  private renderBody;
141
+ /** `index` counts from the first row of the data, not of the rows rendered. */
142
+ private renderRow;
93
143
  render(): TemplateResult;
94
144
  }
95
145
  declare global {
@@ -1,37 +1,61 @@
1
- import { css as k, html as d, nothing as h } from "lit";
2
- import { state as $, property as n } from "lit/decorators.js";
3
- import { classMap as v } from "lit/directives/class-map.js";
4
- import { styleMap as f } from "lit/directives/style-map.js";
5
- import { K as m, d as S } from "../../../chunks/kt-element-mdd5cXZX.js";
6
- import { e as g } from "../../../chunks/events-Bjl5Zmmq.js";
7
- import { s as u } from "../../../chunks/index-fzPIgxe2.js";
1
+ import { css as k, nothing as d, html as c } from "lit";
2
+ import { property as l, state as f } from "lit/decorators.js";
3
+ import { classMap as S } from "lit/directives/class-map.js";
4
+ import { styleMap as w } from "lit/directives/style-map.js";
5
+ import { K as v, d as R } from "../../../chunks/kt-element-Djx2JcGl.js";
6
+ import { e as g } from "../../../chunks/events-r51msXNf.js";
7
+ import { r as M } from "../../../chunks/locale-C5xLkGx5.js";
8
+ import { s as u } from "../../../chunks/index-STEEvEP7.js";
9
+ import "../../core/kt-icon/kt-icon.js";
8
10
  import "../kt-pagination/kt-pagination.js";
9
- var w = Object.defineProperty, a = (o, t, e, s) => {
10
- for (var i = void 0, c = o.length - 1, l; c >= 0; c--)
11
- (l = o[c]) && (i = l(t, e, i) || i);
12
- return i && w(t, e, i), i;
11
+ const H = 50;
12
+ function z({
13
+ rowCount: r,
14
+ rowHeight: t,
15
+ viewportHeight: e,
16
+ scrollTop: i,
17
+ overscan: s
18
+ }) {
19
+ if (r === 0) return { start: 0, end: 0 };
20
+ if (t <= 0) return { start: 0, end: Math.min(r, H) };
21
+ const h = Math.ceil(e / t), a = Math.min(Math.floor(i / t), Math.max(0, r - h)), p = Math.ceil((i + e) / t);
22
+ return {
23
+ start: Math.max(0, a - s),
24
+ end: Math.min(r, p + s)
25
+ };
26
+ }
27
+ var D = Object.defineProperty, n = (r, t, e, i) => {
28
+ for (var s = void 0, h = r.length - 1, a; h >= 0; h--)
29
+ (a = r[h]) && (s = a(t, e, s) || s);
30
+ return s && D(t, e, s), s;
13
31
  };
14
- const D = new Intl.Collator("en", { numeric: !0, sensitivity: "base" });
15
- function x(o) {
16
- if (typeof o == "string") return o;
17
- if (typeof o == "number" || typeof o == "boolean" || typeof o == "bigint")
18
- return String(o);
32
+ const K = 8, x = /* @__PURE__ */ new Map();
33
+ function C(r) {
34
+ let t = x.get(r);
35
+ return t || (t = new Intl.Collator(r, { numeric: !0, sensitivity: "base" }), x.set(r, t)), t;
36
+ }
37
+ function $(r) {
38
+ if (typeof r == "string") return r;
39
+ if (typeof r == "number" || typeof r == "boolean" || typeof r == "bigint")
40
+ return String(r);
19
41
  try {
20
- return JSON.stringify(o) ?? "";
42
+ return JSON.stringify(r) ?? "";
21
43
  } catch {
22
44
  return "";
23
45
  }
24
46
  }
25
- function y(o) {
26
- return o.id ?? o.uid ?? o;
47
+ function y(r) {
48
+ return r.id ?? r.uid ?? r;
27
49
  }
28
- class r extends m {
50
+ class o extends v {
29
51
  constructor() {
30
- super(...arguments), this.page = 1, this.columns = [], this.data = [], this.selectable = !1, this.selectionMode = "multiple", this.selected = [], this.pageSize = 0, this.loading = !1, this.compact = !1, this.sortKey = null, this.sortDirection = null, this.emptyText = void 0, this.loadingText = void 0, this.label = "";
52
+ super(...arguments), this.page = 1, this.manual = !1, this.virtual = !1, this.scrollOffset = 0, this.viewportHeight = 0, this.headerHeight = 0, this.rowHeight = 0, this.totalRows = 0, this.columns = [], this.data = [], this.selectable = !1, this.selectionMode = "multiple", this.selected = [], this.pageSize = 0, this.loading = !1, this.compact = !1, this.sortKey = null, this.sortDirection = null, this.emptyText = void 0, this.loadingText = void 0, this.label = "", this.locale = "", this.onScroll = (t) => {
53
+ this.scrollOffset = t.currentTarget.scrollTop;
54
+ };
31
55
  }
32
56
  static {
33
57
  this.styles = [
34
- m.styles,
58
+ v.styles,
35
59
  k`
36
60
  :host {
37
61
  display: block;
@@ -89,12 +113,17 @@ class r extends m {
89
113
  }
90
114
 
91
115
  .indicator {
116
+ display: inline-flex;
92
117
  color: var(--color-primary-text);
93
- font-size: 10px;
94
118
  }
95
119
 
96
120
  tbody tr {
97
- transition: background-color 120ms linear;
121
+ transition: background-color var(--duration-instant) linear;
122
+ }
123
+
124
+ table[aria-busy='true'] tbody {
125
+ opacity: 0.5;
126
+ transition: opacity var(--duration-fast) var(--easing-standard);
98
127
  }
99
128
 
100
129
  tbody tr:hover {
@@ -114,6 +143,34 @@ class r extends m {
114
143
  :host([compact]) td {
115
144
  padding: 8px 12px;
116
145
  }
146
+
147
+ /* === VIRTUAL ===
148
+ The table scrolls inside its own box, whose height the page sets,
149
+ and the header stays on top of the rows passing under it. */
150
+ :host([virtual]) {
151
+ display: flex;
152
+ flex-direction: column;
153
+ }
154
+ :host([virtual]) .scroller {
155
+ flex: 1;
156
+ min-height: 0;
157
+ }
158
+ :host([virtual]) thead th {
159
+ position: sticky;
160
+ top: 0;
161
+ z-index: 1;
162
+ background: var(--surface-card);
163
+ }
164
+
165
+ /* Stand-ins for the rows above and below the window: height only. */
166
+ tbody tr.spacer,
167
+ tbody tr.spacer:hover {
168
+ background: none;
169
+ }
170
+ tr.spacer td {
171
+ padding: 0;
172
+ border: none;
173
+ }
117
174
  :host([compact]) th {
118
175
  padding: 10px 12px;
119
176
  }
@@ -149,22 +206,45 @@ class r extends m {
149
206
  `
150
207
  ];
151
208
  }
152
- /** The rows after sorting, before paging. */
209
+ /**
210
+ * The rows after sorting, before paging.
211
+ *
212
+ * Sorted once per change of `data`, `sortKey`, `sortDirection` or locale, not on
213
+ * every render: hovering a row or ticking a box re-renders the table, and
214
+ * re-sorting a few thousand rows each time is what made that lag. Assign a
215
+ * new array to `data` rather than changing it in place.
216
+ */
153
217
  get sortedRows() {
218
+ if (this.manual) return this.data;
219
+ const t = this.sortCache, e = M(this.locale);
220
+ if (t?.data === this.data && t.key === this.sortKey && t.direction === this.sortDirection && t.locale === e)
221
+ return t.rows;
222
+ const i = this.sort(C(e));
223
+ return this.sortCache = {
224
+ data: this.data,
225
+ key: this.sortKey,
226
+ direction: this.sortDirection,
227
+ locale: e,
228
+ rows: i
229
+ }, i;
230
+ }
231
+ sort(t) {
154
232
  if (!this.sortKey || !this.sortDirection) return this.data;
155
- const t = this.sortKey, e = this.sortDirection === "asc" ? 1 : -1;
156
- return [...this.data].sort((s, i) => {
157
- const c = s[t], l = i[t], p = c == null, b = l == null;
158
- return p && b ? 0 : p ? 1 : b ? -1 : typeof c == "number" && typeof l == "number" ? (c - l) * e : D.compare(x(c), x(l)) * e;
233
+ const e = this.sortKey, i = this.sortDirection === "asc" ? 1 : -1;
234
+ return [...this.data].sort((s, h) => {
235
+ const a = s[e], p = h[e], b = a == null, m = p == null;
236
+ return b && m ? 0 : b ? 1 : m ? -1 : typeof a == "number" && typeof p == "number" ? (a - p) * i : t.compare($(a), $(p)) * i;
159
237
  });
160
238
  }
161
239
  get totalPages() {
162
- return this.pageSize <= 0 ? 1 : Math.max(1, Math.ceil(this.data.length / this.pageSize));
240
+ if (this.pageSize <= 0) return 1;
241
+ const t = this.manual ? this.totalRows || this.data.length : this.data.length;
242
+ return Math.max(1, Math.ceil(t / this.pageSize));
163
243
  }
164
244
  /** The rows actually on screen. */
165
245
  get visibleRows() {
166
246
  const t = this.sortedRows;
167
- if (this.pageSize <= 0) return t;
247
+ if (this.pageSize <= 0 || this.manual) return t;
168
248
  const e = Math.min(this.page, this.totalPages);
169
249
  return t.slice((e - 1) * this.pageSize, e * this.pageSize);
170
250
  }
@@ -173,24 +253,50 @@ class r extends m {
173
253
  * press restoring the original order is what makes sorting undoable.
174
254
  */
175
255
  toggleSort(t) {
176
- t.sortable && (this.sortKey !== t.key ? (this.sortKey = t.key, this.sortDirection = "asc") : this.sortDirection === "asc" ? this.sortDirection = "desc" : (this.sortKey = null, this.sortDirection = null), g(this, "kt-sort-change", { key: this.sortKey, direction: this.sortDirection }));
256
+ t.sortable && (this.sortKey !== t.key ? (this.sortKey = t.key, this.sortDirection = "asc") : this.sortDirection === "asc" ? this.sortDirection = "desc" : (this.sortKey = null, this.sortDirection = null), this.manual && (this.page = 1), g(this, "kt-sort-change", { key: this.sortKey, direction: this.sortDirection }));
177
257
  }
178
258
  isSelected(t) {
179
259
  return this.selected.includes(y(t));
180
260
  }
181
261
  toggleSelection(t) {
182
262
  const e = y(t);
183
- this.selectionMode === "single" ? this.selected = this.isSelected(t) ? [] : [e] : this.selected = this.isSelected(t) ? this.selected.filter((s) => s !== e) : [...this.selected, e], g(this, "kt-selection-change", { selected: this.selected, rows: this.selectedRows });
263
+ this.selectionMode === "single" ? this.selected = this.isSelected(t) ? [] : [e] : this.selected = this.isSelected(t) ? this.selected.filter((i) => i !== e) : [...this.selected, e], g(this, "kt-selection-change", { selected: this.selected, rows: this.selectedRows });
184
264
  }
185
265
  /** Selects or clears every row on the current page. */
186
266
  toggleAll() {
187
- const e = this.visibleRows.map(y), s = e.every((i) => this.selected.includes(i));
188
- this.selected = s ? this.selected.filter((i) => !e.includes(i)) : [.../* @__PURE__ */ new Set([...this.selected, ...e])], g(this, "kt-selection-change", { selected: this.selected, rows: this.selectedRows });
267
+ const e = this.visibleRows.map(y), i = e.every((s) => this.selected.includes(s));
268
+ this.selected = i ? this.selected.filter((s) => !e.includes(s)) : [.../* @__PURE__ */ new Set([...this.selected, ...e])], g(this, "kt-selection-change", { selected: this.selected, rows: this.selectedRows });
189
269
  }
190
270
  /** The selected rows themselves, not just their identities. */
191
271
  get selectedRows() {
192
272
  return this.data.filter((t) => this.selected.includes(y(t)));
193
273
  }
274
+ /** Virtual rendering, unless a page size pages the rows instead. */
275
+ get isVirtual() {
276
+ return this.virtual && this.pageSize <= 0;
277
+ }
278
+ // Untyped: the measurements are private, so not among PropertyValues<this>.
279
+ updated(t) {
280
+ if (t.has("compact") && (this.rowHeight = 0), !this.isVirtual) {
281
+ this.observe(void 0);
282
+ return;
283
+ }
284
+ const e = this.shadowRoot?.querySelector(".scroller") ?? void 0;
285
+ this.observe(e);
286
+ const i = this.shadowRoot?.querySelector('tbody tr[part="row"]');
287
+ i && this.rowHeight === 0 && (this.rowHeight = i.getBoundingClientRect().height);
288
+ const s = this.shadowRoot?.querySelector("thead");
289
+ s && (this.headerHeight = s.getBoundingClientRect().height), e && (this.viewportHeight = e.clientHeight);
290
+ }
291
+ disconnectedCallback() {
292
+ super.disconnectedCallback(), this.observe(void 0);
293
+ }
294
+ /** Follows the scroller's height, which the page can change at any time. */
295
+ observe(t) {
296
+ t !== this.observed && (this.resizeObserver?.disconnect(), this.observed = t, !(!t || typeof ResizeObserver > "u") && (this.resizeObserver ??= new ResizeObserver(([e]) => {
297
+ e && (this.viewportHeight = e.target.clientHeight);
298
+ }), this.resizeObserver.observe(t)));
299
+ }
194
300
  onPageChange(t) {
195
301
  t.stopPropagation(), this.page = t.detail.page, g(this, "kt-page-change", { page: this.page });
196
302
  }
@@ -204,74 +310,99 @@ class r extends m {
204
310
  return this.sortKey !== t.key || !this.sortDirection ? "none" : this.sortDirection === "asc" ? "ascending" : "descending";
205
311
  }
206
312
  renderHeaderCell(t) {
207
- const e = t.label ?? t.key, s = this.sortKey === t.key && this.sortDirection !== null;
208
- return d`<th
313
+ const e = t.label ?? t.key, i = this.sortKey === t.key && this.sortDirection !== null;
314
+ return c`<th
209
315
  part="header-cell"
210
316
  scope="col"
211
- style=${f(t.width ? { width: t.width } : {})}
317
+ style=${w(t.width ? { width: t.width } : {})}
212
318
  aria-sort=${this.sortStateFor(t)}
213
319
  >
214
- ${t.sortable ? d`<button type="button" @click=${() => this.toggleSort(t)}>
320
+ ${t.sortable ? c`<button type="button" @click=${() => this.toggleSort(t)}>
215
321
  <span>${e}</span>
216
- <span class="indicator" aria-hidden="true"
217
- >${s ? this.sortDirection === "asc" ? "▲" : "▼" : ""}</span
218
- >
219
- </button>` : d`<span>${e}</span>`}
322
+ <span class="indicator" aria-hidden="true">
323
+ ${i ? c`<kt-icon
324
+ name=${this.sortDirection === "asc" ? "arrow-up" : "arrow-down"}
325
+ size="14"
326
+ ></kt-icon>` : d}
327
+ </span>
328
+ </button>` : c`<span>${e}</span>`}
220
329
  </th>`;
221
330
  }
222
331
  renderBody() {
223
332
  const t = this.visibleRows, e = this.columns.length + (this.selectable ? 1 : 0);
224
- return t.length === 0 ? d`<tr>
333
+ if (t.length === 0)
334
+ return c`<tr>
225
335
  <td colspan=${e}>
226
336
  <div class="placeholder">${this.emptyText ?? u().noData}</div>
227
337
  </td>
228
- </tr>` : d`${t.map((s, i) => {
229
- const c = this.isSelected(s);
230
- return d`<tr
231
- part="row"
232
- class=${v({ selected: c })}
233
- aria-selected=${this.selectable ? String(c) : h}
234
- @click=${() => g(this, "kt-row-click", { row: s, index: i })}
235
- >
236
- ${this.selectable ? d`<td class="select-cell">
237
- <input
238
- type=${this.selectionMode === "single" ? "radio" : "checkbox"}
239
- name=${this.selectionMode === "single" ? "kt-table-selection" : h}
240
- .checked=${c}
241
- aria-label=${u().selectRow}
242
- @click=${(l) => l.stopPropagation()}
243
- @change=${() => this.toggleSelection(s)}
244
- />
245
- </td>` : h}
246
- ${this.columns.map((l) => {
247
- const p = this.renderCell?.(s, l);
248
- return d`<td part="cell" style=${f({ textAlign: l.align ?? "left" })}>
249
- ${p === void 0 ? s[l.key] : p}
250
- </td>`;
251
- })}
252
338
  </tr>`;
253
- })}`;
339
+ if (!this.isVirtual)
340
+ return c`${t.map((a, p) => this.renderRow(a, p))}`;
341
+ const { start: i, end: s } = z({
342
+ rowCount: t.length,
343
+ rowHeight: this.rowHeight,
344
+ viewportHeight: Math.max(0, this.viewportHeight - this.headerHeight),
345
+ scrollTop: Math.max(0, this.scrollOffset - this.headerHeight),
346
+ overscan: K
347
+ }), h = (a) => a > 0 && this.rowHeight > 0 ? c`<tr class="spacer" aria-hidden="true">
348
+ <td colspan=${e} style=${`height: ${a * this.rowHeight}px`}></td>
349
+ </tr>` : d;
350
+ return c`${h(i)}${t.slice(i, s).map((a, p) => this.renderRow(a, i + p))}${h(t.length - s)}`;
351
+ }
352
+ /** `index` counts from the first row of the data, not of the rows rendered. */
353
+ renderRow(t, e) {
354
+ const i = this.isSelected(t);
355
+ return c`<tr
356
+ part="row"
357
+ class=${S({ selected: i })}
358
+ aria-selected=${this.selectable ? String(i) : d}
359
+ aria-rowindex=${this.isVirtual ? e + 2 : d}
360
+ @click=${() => g(this, "kt-row-click", { row: t, index: e })}
361
+ >
362
+ ${this.selectable ? c`<td class="select-cell">
363
+ <input
364
+ type=${this.selectionMode === "single" ? "radio" : "checkbox"}
365
+ name=${this.selectionMode === "single" ? "kt-table-selection" : d}
366
+ .checked=${i}
367
+ aria-label=${u().selectRow}
368
+ @click=${(s) => s.stopPropagation()}
369
+ @change=${() => this.toggleSelection(t)}
370
+ />
371
+ </td>` : d}
372
+ ${this.columns.map((s) => {
373
+ const h = this.renderCell?.(t, s);
374
+ return c`<td part="cell" style=${w({ textAlign: s.align ?? "left" })}>
375
+ ${h === void 0 ? t[s.key] : h}
376
+ </td>`;
377
+ })}
378
+ </tr>`;
254
379
  }
255
380
  render() {
256
- if (this.loading)
257
- return d`<div class="placeholder" role="status" aria-live="polite">
381
+ const t = this.loading && this.manual && this.data.length > 0;
382
+ if (this.loading && !t)
383
+ return c`<div class="placeholder" role="status" aria-live="polite">
258
384
  ${this.loadingText ?? u().loading}
259
385
  </div>`;
260
- const t = this.visibleRows, e = t.length > 0 && t.every((i) => this.isSelected(i)), s = t.some((i) => this.isSelected(i));
261
- return d`<div class="scroller">
262
- <table part="table" aria-label=${this.label || h}>
386
+ const e = this.visibleRows, i = e.length > 0 && e.every((a) => this.isSelected(a)), s = e.some((a) => this.isSelected(a)), h = this.isVirtual;
387
+ return c`<div class="scroller" @scroll=${h ? this.onScroll : d}>
388
+ <table
389
+ part="table"
390
+ aria-label=${this.label || d}
391
+ aria-busy=${t ? "true" : d}
392
+ aria-rowcount=${h ? e.length + 1 : d}
393
+ >
263
394
  <thead>
264
- <tr>
265
- ${this.selectable ? d`<th class="select-cell" scope="col">
266
- ${this.selectionMode === "multiple" ? d`<input
395
+ <tr aria-rowindex=${h ? 1 : d}>
396
+ ${this.selectable ? c`<th class="select-cell" scope="col">
397
+ ${this.selectionMode === "multiple" ? c`<input
267
398
  type="checkbox"
268
- .checked=${e}
269
- .indeterminate=${s && !e}
399
+ .checked=${i}
400
+ .indeterminate=${s && !i}
270
401
  aria-label=${u().selectAll}
271
402
  @change=${this.toggleAll}
272
- />` : h}
273
- </th>` : h}
274
- ${this.columns.map((i) => this.renderHeaderCell(i))}
403
+ />` : d}
404
+ </th>` : d}
405
+ ${this.columns.map((a) => this.renderHeaderCell(a))}
275
406
  </tr>
276
407
  </thead>
277
408
  <tbody>
@@ -280,62 +411,86 @@ class r extends m {
280
411
  </table>
281
412
  </div>
282
413
 
283
- ${this.pageSize > 0 ? d`<footer>
414
+ ${this.pageSize > 0 ? c`<footer>
284
415
  <kt-pagination
285
416
  .page=${Math.min(this.page, this.totalPages)}
286
417
  .totalPages=${this.totalPages}
287
418
  @kt-page-change=${this.onPageChange}
288
419
  ></kt-pagination>
289
- </footer>` : h}`;
420
+ </footer>` : d}`;
290
421
  }
291
422
  }
292
- a([
293
- $()
294
- ], r.prototype, "page");
295
- a([
296
- n({ attribute: !1 })
297
- ], r.prototype, "columns");
298
- a([
299
- n({ attribute: !1 })
300
- ], r.prototype, "data");
301
- a([
302
- n({ type: Boolean, reflect: !0 })
303
- ], r.prototype, "selectable");
304
- a([
305
- n({ type: String, attribute: "selection-mode" })
306
- ], r.prototype, "selectionMode");
307
- a([
308
- n({ attribute: !1 })
309
- ], r.prototype, "selected");
310
- a([
311
- n({ type: Number, attribute: "page-size" })
312
- ], r.prototype, "pageSize");
313
- a([
314
- n({ type: Boolean, reflect: !0 })
315
- ], r.prototype, "loading");
316
- a([
317
- n({ type: Boolean, reflect: !0 })
318
- ], r.prototype, "compact");
319
- a([
320
- n({ type: String, attribute: "sort-key" })
321
- ], r.prototype, "sortKey");
322
- a([
323
- n({ type: String, attribute: "sort-direction" })
324
- ], r.prototype, "sortDirection");
325
- a([
326
- n({ attribute: !1 })
327
- ], r.prototype, "renderCell");
328
- a([
329
- n({ type: String, attribute: "empty-text" })
330
- ], r.prototype, "emptyText");
331
- a([
332
- n({ type: String, attribute: "loading-text" })
333
- ], r.prototype, "loadingText");
334
- a([
335
- n({ type: String })
336
- ], r.prototype, "label");
337
- S("kt-table", r);
423
+ n([
424
+ l({ type: Number })
425
+ ], o.prototype, "page");
426
+ n([
427
+ l({ type: Boolean, reflect: !0 })
428
+ ], o.prototype, "manual");
429
+ n([
430
+ l({ type: Boolean, reflect: !0 })
431
+ ], o.prototype, "virtual");
432
+ n([
433
+ f()
434
+ ], o.prototype, "scrollOffset");
435
+ n([
436
+ f()
437
+ ], o.prototype, "viewportHeight");
438
+ n([
439
+ f()
440
+ ], o.prototype, "headerHeight");
441
+ n([
442
+ f()
443
+ ], o.prototype, "rowHeight");
444
+ n([
445
+ l({ type: Number, attribute: "total-rows" })
446
+ ], o.prototype, "totalRows");
447
+ n([
448
+ l({ attribute: !1 })
449
+ ], o.prototype, "columns");
450
+ n([
451
+ l({ attribute: !1 })
452
+ ], o.prototype, "data");
453
+ n([
454
+ l({ type: Boolean, reflect: !0 })
455
+ ], o.prototype, "selectable");
456
+ n([
457
+ l({ type: String, attribute: "selection-mode" })
458
+ ], o.prototype, "selectionMode");
459
+ n([
460
+ l({ attribute: !1 })
461
+ ], o.prototype, "selected");
462
+ n([
463
+ l({ type: Number, attribute: "page-size" })
464
+ ], o.prototype, "pageSize");
465
+ n([
466
+ l({ type: Boolean, reflect: !0 })
467
+ ], o.prototype, "loading");
468
+ n([
469
+ l({ type: Boolean, reflect: !0 })
470
+ ], o.prototype, "compact");
471
+ n([
472
+ l({ type: String, attribute: "sort-key" })
473
+ ], o.prototype, "sortKey");
474
+ n([
475
+ l({ type: String, attribute: "sort-direction" })
476
+ ], o.prototype, "sortDirection");
477
+ n([
478
+ l({ attribute: !1 })
479
+ ], o.prototype, "renderCell");
480
+ n([
481
+ l({ type: String, attribute: "empty-text" })
482
+ ], o.prototype, "emptyText");
483
+ n([
484
+ l({ type: String, attribute: "loading-text" })
485
+ ], o.prototype, "loadingText");
486
+ n([
487
+ l({ type: String })
488
+ ], o.prototype, "label");
489
+ n([
490
+ l({ type: String })
491
+ ], o.prototype, "locale");
492
+ R("kt-table", o);
338
493
  export {
339
- r as KtTable
494
+ o as KtTable
340
495
  };
341
496
  //# sourceMappingURL=kt-table.js.map