reke-ui 0.1.1 → 0.2.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 (86) hide show
  1. package/README.md +23 -0
  2. package/cli/install-skills.mjs +169 -0
  3. package/custom-elements.json +472 -128
  4. package/dist/__type-checks__/no-lit-in-public-types.d.ts +2 -0
  5. package/dist/__type-checks__/no-lit-in-public-types.d.ts.map +1 -0
  6. package/dist/_virtual/_@oxc-project_runtime@0.137.0/helpers/esm/decorate.js +9 -0
  7. package/dist/components/reke-alert/reke-alert.d.ts.map +1 -1
  8. package/dist/components/reke-alert/reke-alert.js +45 -0
  9. package/dist/components/reke-alert/reke-alert.styles.d.ts.map +1 -1
  10. package/dist/components/reke-alert/reke-alert.styles.js +103 -0
  11. package/dist/components/reke-badge/reke-badge.d.ts +4 -2
  12. package/dist/components/reke-badge/reke-badge.d.ts.map +1 -1
  13. package/dist/components/reke-badge/reke-badge.js +30 -0
  14. package/dist/components/reke-badge/reke-badge.styles.d.ts.map +1 -1
  15. package/dist/components/reke-badge/reke-badge.styles.js +92 -0
  16. package/dist/components/reke-button/reke-button.d.ts.map +1 -1
  17. package/dist/components/reke-button/reke-button.js +53 -0
  18. package/dist/components/reke-button/reke-button.styles.d.ts.map +1 -1
  19. package/dist/components/reke-button/reke-button.styles.js +226 -0
  20. package/dist/components/reke-card/reke-card.d.ts +7 -0
  21. package/dist/components/reke-card/reke-card.d.ts.map +1 -1
  22. package/dist/components/reke-card/reke-card.js +50 -0
  23. package/dist/components/reke-card/reke-card.styles.d.ts.map +1 -1
  24. package/dist/components/reke-card/reke-card.styles.js +147 -0
  25. package/dist/components/reke-checkbox/reke-checkbox.js +57 -0
  26. package/dist/components/reke-checkbox/reke-checkbox.styles.d.ts.map +1 -1
  27. package/dist/components/reke-checkbox/reke-checkbox.styles.js +79 -0
  28. package/dist/components/reke-chip/reke-chip.d.ts.map +1 -1
  29. package/dist/components/reke-chip/reke-chip.js +62 -0
  30. package/dist/components/reke-chip/reke-chip.styles.d.ts.map +1 -1
  31. package/dist/components/reke-chip/reke-chip.styles.js +128 -0
  32. package/dist/components/reke-date-range/reke-date-range.d.ts.map +1 -1
  33. package/dist/components/reke-date-range/reke-date-range.js +326 -0
  34. package/dist/components/reke-date-range/reke-date-range.styles.d.ts.map +1 -1
  35. package/dist/components/reke-date-range/reke-date-range.styles.js +335 -0
  36. package/dist/components/reke-dialog/reke-dialog.d.ts.map +1 -1
  37. package/dist/components/reke-dialog/reke-dialog.js +77 -0
  38. package/dist/components/reke-dialog/reke-dialog.styles.d.ts.map +1 -1
  39. package/dist/components/reke-dialog/reke-dialog.styles.js +132 -0
  40. package/dist/components/reke-file-upload/reke-file-upload.d.ts.map +1 -1
  41. package/dist/components/reke-file-upload/reke-file-upload.js +84 -0
  42. package/dist/components/reke-file-upload/reke-file-upload.styles.js +104 -0
  43. package/dist/components/reke-input/reke-input.js +54 -0
  44. package/dist/components/reke-input/reke-input.styles.d.ts.map +1 -1
  45. package/dist/components/reke-input/reke-input.styles.js +78 -0
  46. package/dist/components/reke-select/reke-select.d.ts.map +1 -1
  47. package/dist/components/reke-select/reke-select.js +89 -0
  48. package/dist/components/reke-select/reke-select.styles.d.ts.map +1 -1
  49. package/dist/components/reke-select/reke-select.styles.js +120 -0
  50. package/dist/components/reke-table/reke-table.d.ts +144 -13
  51. package/dist/components/reke-table/reke-table.d.ts.map +1 -1
  52. package/dist/components/reke-table/reke-table.js +291 -0
  53. package/dist/components/reke-table/reke-table.styles.d.ts.map +1 -1
  54. package/dist/components/reke-table/reke-table.styles.js +265 -0
  55. package/dist/components/reke-textarea/reke-textarea.js +54 -0
  56. package/dist/components/reke-textarea/reke-textarea.styles.js +73 -0
  57. package/dist/components/reke-toast/reke-toast.d.ts.map +1 -1
  58. package/dist/components/reke-toast/reke-toast.js +74 -0
  59. package/dist/components/reke-toast/reke-toast.styles.d.ts.map +1 -1
  60. package/dist/components/reke-toast/reke-toast.styles.js +183 -0
  61. package/dist/components/reke-toggle/reke-toggle.js +50 -0
  62. package/dist/components/reke-toggle/reke-toggle.styles.js +68 -0
  63. package/dist/components/reke-tooltip/reke-tooltip.js +51 -0
  64. package/dist/components/reke-tooltip/reke-tooltip.styles.js +64 -0
  65. package/dist/index.d.ts +23 -23
  66. package/dist/index.d.ts.map +1 -1
  67. package/dist/index.js +18 -0
  68. package/dist/node_modules/lit/directives/ref.js +1 -0
  69. package/dist/node_modules/lit-html/async-directive.js +55 -0
  70. package/dist/node_modules/lit-html/directive-helpers.js +5 -0
  71. package/dist/node_modules/lit-html/directive.js +28 -0
  72. package/dist/node_modules/lit-html/directives/ref.js +30 -0
  73. package/dist/node_modules/lit-html/lit-html.js +234 -0
  74. package/dist/react-bridge/table.d.ts +58 -0
  75. package/dist/react-bridge/table.d.ts.map +1 -0
  76. package/dist/react-bridge/table.js +115 -0
  77. package/dist/react.d.ts +12 -26
  78. package/dist/react.d.ts.map +1 -1
  79. package/dist/react.js +111 -132
  80. package/dist/shared/base-element.js +14 -0
  81. package/dist/shared/tailwind-styles.js +6 -0
  82. package/dist/shared/tailwind.js +4 -0
  83. package/dist/tokens/reke-tokens.css +70 -0
  84. package/package.json +43 -23
  85. package/dist/reke-chip-DexKxhxn.js +0 -3358
  86. package/dist/reke-ui.js +0 -20
@@ -0,0 +1,120 @@
1
+ import { tailwindStyles as e } from "../../shared/tailwind-styles.js";
2
+ import { css as t } from "lit";
3
+ //#region src/components/reke-select/reke-select.styles.ts
4
+ var n = [e, t`
5
+ :host {
6
+ display: inline-block;
7
+ position: relative;
8
+ }
9
+
10
+ :host([disabled]) {
11
+ pointer-events: none;
12
+ opacity: 0.5;
13
+ }
14
+
15
+ .label {
16
+ display: block;
17
+ margin-bottom: var(--reke-space-2xs, 6px);
18
+ font-family: var(--reke-font-mono, 'JetBrains Mono', ui-monospace, monospace);
19
+ font-size: var(--reke-font-size-xs, 12px);
20
+ color: var(--reke-color-text-label, #8A8A8A);
21
+ }
22
+
23
+ .trigger {
24
+ display: flex;
25
+ align-items: center;
26
+ justify-content: space-between;
27
+ width: 100%;
28
+ background: var(--reke-color-input-bg, var(--reke-color-surface, #1A1A1A));
29
+ box-shadow: var(--reke-shadow-input, none);
30
+ color: var(--reke-color-text, #E5E5E5);
31
+ border: 1px solid var(--reke-color-border, #252525);
32
+ border-radius: var(--reke-radius, 4px);
33
+ font-family: var(--reke-font-mono, 'JetBrains Mono', ui-monospace, monospace);
34
+ cursor: pointer;
35
+ outline: none;
36
+ box-sizing: border-box;
37
+ transition: border-color 0.15s ease;
38
+ }
39
+
40
+ .trigger--placeholder {
41
+ color: var(--reke-color-text-muted, #525252);
42
+ }
43
+
44
+ .trigger__chevron {
45
+ font-size: 8px;
46
+ margin-left: 8px;
47
+ flex-shrink: 0;
48
+ }
49
+
50
+ /* === Sizes === */
51
+
52
+ .trigger--sm {
53
+ padding: var(--reke-space-xs, 8px) var(--reke-space-sm, 12px);
54
+ font-size: var(--reke-font-size-xs, 12px);
55
+ }
56
+
57
+ .trigger--md {
58
+ padding: var(--reke-space-sm, 12px) var(--reke-space-md, 16px);
59
+ font-size: var(--reke-font-size-sm, 13px);
60
+ }
61
+
62
+ .trigger--lg {
63
+ padding: var(--reke-space-md, 16px) var(--reke-space-lg, 20px);
64
+ font-size: var(--reke-font-size-md, 14px);
65
+ }
66
+
67
+ .trigger:focus-visible {
68
+ border-color: var(--reke-color-primary, #22C55E);
69
+ outline: 2px solid var(--reke-color-primary, #22C55E);
70
+ outline-offset: -1px;
71
+ }
72
+
73
+ .trigger--error {
74
+ border-color: var(--reke-color-danger, #EF4444);
75
+ }
76
+
77
+ .trigger--error:focus-visible {
78
+ border-color: var(--reke-color-danger, #EF4444);
79
+ outline-color: var(--reke-color-danger, #EF4444);
80
+ }
81
+
82
+ /* === Dropdown === */
83
+
84
+ .dropdown {
85
+ position: absolute;
86
+ top: 100%;
87
+ left: 0;
88
+ right: 0;
89
+ margin: 0;
90
+ margin-top: 4px;
91
+ padding: 0;
92
+ list-style: none;
93
+ background-color: var(--reke-color-surface, #1A1A1A);
94
+ border: 1px solid var(--reke-color-border, #252525);
95
+ border-radius: var(--reke-radius, 4px);
96
+ max-height: 200px;
97
+ overflow-y: auto;
98
+ z-index: 100;
99
+ }
100
+
101
+ /* === Option === */
102
+
103
+ .option {
104
+ padding: var(--reke-space-xs, 8px) var(--reke-space-md, 16px);
105
+ font-family: var(--reke-font-mono, 'JetBrains Mono', ui-monospace, monospace);
106
+ font-size: var(--reke-font-size-sm, 13px);
107
+ color: var(--reke-color-text, #E5E5E5);
108
+ cursor: pointer;
109
+ }
110
+
111
+ .option:hover {
112
+ background-color: var(--reke-color-surface-elevated, #151515);
113
+ }
114
+
115
+ .option--selected {
116
+ color: var(--reke-color-primary, #22C55E);
117
+ }
118
+ `];
119
+ //#endregion
120
+ export { n as styles };
@@ -1,4 +1,4 @@
1
- import { type TemplateResult } from 'lit';
1
+ import { type PropertyValues, type TemplateResult } from 'lit';
2
2
  import { RekeElement } from '../../shared/base-element.js';
3
3
  export interface TableColumn {
4
4
  key: string;
@@ -8,13 +8,25 @@ export interface TableColumn {
8
8
  /** Set to false to disable sorting on this column. Default: true. */
9
9
  sortable?: boolean;
10
10
  /** Custom render function for cell content. Falls back to row[col.key] if omitted. */
11
- render?: (value: unknown, row: TableRow, index: number) => TemplateResult | string;
11
+ render?: (value: unknown, row: TableRow, index: number) => TemplateResult | string | HTMLElement | Node;
12
12
  }
13
13
  export type TableRow = Record<string, unknown>;
14
- export type ExpandedRowRenderer = (row: TableRow, index: number) => TemplateResult;
14
+ /** Stable identifier for a row. */
15
+ export type RowKey = string | number;
16
+ /** Cleanup callback returned by `expandedRowElement`. */
17
+ export type Cleanup = () => void;
18
+ /**
19
+ * Framework-agnostic expand callback.
20
+ * Receives the host element, the row data, and the resolved row key.
21
+ * Mount any framework's content into the host and return a cleanup function
22
+ * (called on collapse, row removal, or table disconnect), or `void`.
23
+ */
24
+ export type ExpandedRowElement = (host: HTMLElement, row: TableRow, key: RowKey) => Cleanup | void;
25
+ /** Resolve a row to a stable identifier. Defaults to `String(index)`. */
26
+ export type GetRowKey = (row: TableRow, index: number) => RowKey;
15
27
  /**
16
28
  * @tag reke-table
17
- * @summary A data table with custom cell rendering, expandable rows, and toolbar/footer slots.
29
+ * @summary A data table with custom cell rendering, framework-agnostic expandable rows, and toolbar/footer slots.
18
30
  *
19
31
  * @slot toolbar - Toolbar area above the table (search, filters, title).
20
32
  * @slot footer - Footer area below the table (pagination, record count).
@@ -22,7 +34,7 @@ export type ExpandedRowRenderer = (row: TableRow, index: number) => TemplateResu
22
34
  *
23
35
  * @fires reke-row-click - Fired when a row is clicked. Detail: `{ row: TableRow, index: number }`.
24
36
  * @fires reke-sort - Fired when a sortable header is clicked. Detail: `{ key: string, direction: 'asc' | 'desc' }`.
25
- * @fires reke-row-expand - Fired when a row is expanded or collapsed. Detail: `{ row: TableRow, index: number, expanded: boolean }`.
37
+ * @fires reke-row-expand - Fired when a row is expanded or collapsed. Detail: `{ row: TableRow, index: number, key: RowKey, expanded: boolean }`.
26
38
  *
27
39
  * @csspart table - The native table element.
28
40
  * @csspart header - The thead element.
@@ -34,11 +46,21 @@ export type ExpandedRowRenderer = (row: TableRow, index: number) => TemplateResu
34
46
  * @csspart footer - The footer wrapper div.
35
47
  * @csspart expand-row - The tr for expanded content.
36
48
  * @csspart expand-content - The td spanning all columns in the expanded row.
49
+ * @csspart expand-toggle-cell - The leading `<td>` that contains the chevron button (only when `expandable`).
50
+ * @csspart expand-toggle-button - The chevron `<button>` itself (only when `expandable`).
37
51
  *
38
52
  * @cssprop [--reke-color-surface=#1A1A1A] - Table background.
39
53
  * @cssprop [--reke-color-border=#252525] - Border and row divider color.
40
54
  * @cssprop [--reke-color-text=#E5E5E5] - Cell text color.
41
55
  * @cssprop [--reke-color-text-muted=#525252] - Header text color.
56
+ * @cssprop [--reke-color-primary=#22C55E] - Chevron focus outline color.
57
+ * @cssprop [--reke-radius=4px] - Chevron button corner radius.
58
+ *
59
+ * Props:
60
+ * - `expandedRowElement`: Framework-agnostic expand render. Receives `(host, row, key)`. Mount any framework. Return cleanup or void.
61
+ * - `getRowKey`: Optional `(row, index) => RowKey`. Defaults to `String(index)`. Use a stable domain id for identity-keyed expand state across sorts.
62
+ * - `expandable`: Opt-in boolean (default `false`). When `true`, `reke-table` prepends a leading toggle column with an accessible chevron `<button>` per row: `aria-expanded` reflects the row's expand state, `aria-controls` points at the expand `<td>`, and `Enter`/`Space` activate the toggle. Consumers can also build their own toggles by leaving `expandable=false` (default) and calling `toggleExpand(key)` directly.
63
+ * - `expandOnRowClick` (attribute `expand-on-row-click`): Opt-in boolean (default `false`). When `true`, clicking anywhere on a row calls `toggleExpand(key)` internally. `reke-row-click` is STILL emitted on every row click. The chevron button calls `stopPropagation()` so chevron clicks do NOT double-toggle. Consumers MUST use EITHER this prop OR their own `reke-row-click` → `toggleExpand` handler, not both. For keyboard / screen-reader users, pair with `expandable`.
42
64
  */
43
65
  export declare class RekeTable extends RekeElement {
44
66
  static styles: import("lit").CSSResult[];
@@ -49,23 +71,132 @@ export declare class RekeTable extends RekeElement {
49
71
  hoverable: boolean;
50
72
  bordered: boolean;
51
73
  borderless: boolean;
74
+ /**
75
+ * Opt-in: when `true`, the table prepends a leading toggle column whose
76
+ * `<button>` calls `toggleExpand(key)`, exposes `aria-expanded` reflecting
77
+ * the expand state, `aria-controls` pointing at the expand `<td>` id
78
+ * (`reke-table-expand-<key>`), and accepts `Enter` / `Space` activation.
79
+ *
80
+ * Defaults to `false` so consumers that already wire their own toggles
81
+ * (chips, links, custom buttons) are unaffected.
82
+ */
83
+ expandable: boolean;
84
+ /**
85
+ * Opt-in: when `true`, clicking anywhere on a row (outside the chevron, if
86
+ * present) calls `toggleExpand(key)` internally using the row's identity
87
+ * key. The `reke-row-click` event is STILL emitted on every row click so
88
+ * consumers can react in addition to the built-in toggle.
89
+ *
90
+ * Default is `false` to preserve non-breaking behavior: existing consumers
91
+ * that wire their own `reke-row-click` → `toggleExpand` handlers are
92
+ * unaffected.
93
+ *
94
+ * A11y note: row clicks are a pointer convenience only. The `<tr>` does NOT
95
+ * receive `role="button"` or `tabindex` (that would be a clickable-row
96
+ * a11y anti-pattern). For keyboard / screen-reader users, pair this prop
97
+ * with `expandable` so the accessible chevron `<button>` is available.
98
+ *
99
+ * Double-wiring caveat: consumers MUST use EITHER `expandOnRowClick` OR
100
+ * their own `reke-row-click` → `toggleExpand` handler — not both — or the
101
+ * row will toggle twice and net to no change.
102
+ *
103
+ * Chevron interaction: the chevron `<button>` calls `stopPropagation()`, so
104
+ * clicking the chevron does NOT trigger the row-click toggle (no double
105
+ * toggle).
106
+ */
107
+ expandOnRowClick: boolean;
52
108
  sortKey: string;
53
109
  sortDirection: 'asc' | 'desc';
54
- /** When set, rows become expandable with a chevron toggle. */
55
- expandedRowRender: ExpandedRowRenderer | null;
56
- /** Set of row indices currently expanded. */
57
- expandedRows: Set<number>;
110
+ /**
111
+ * Framework-agnostic expand callback. Sole expand API.
112
+ *
113
+ * @example Vanilla DOM:
114
+ * expandedRowElement = (host, row, key) => {
115
+ * const node = document.createElement('div');
116
+ * node.textContent = String(row.name);
117
+ * host.appendChild(node);
118
+ * return () => node.remove();
119
+ * };
120
+ *
121
+ * @example React (via the bridge):
122
+ * expandedRowElement = (host, row, key) => {
123
+ * const root = createRoot(host);
124
+ * root.render(<MyContent data={row} />);
125
+ * return () => root.unmount();
126
+ * };
127
+ */
128
+ expandedRowElement: ExpandedRowElement | null;
129
+ /**
130
+ * Resolve a stable identifier for each row.
131
+ * Defaults to `String(index)` — identity-equivalent only when rows are stable.
132
+ * Provide a domain id (e.g. `row => row.id`) to keep expand state across sorts.
133
+ */
134
+ getRowKey?: GetRowKey;
135
+ /** Set of row keys currently expanded. */
136
+ expandedRows: Set<RowKey>;
137
+ /** Host element cached per row key. Survives unrelated re-renders. */
138
+ private _hostCache;
139
+ /** Cleanup cached per row key. Invoked exactly once on collapse / row removal / disconnect. */
140
+ private _cleanupMap;
141
+ /** Keys we have already warned about as duplicates (one-shot per component lifetime). */
142
+ private _warnedDupKeys;
143
+ /** One-shot guard for the numeric-target-with-getRowKey ambiguity warning. */
144
+ private _warnedNumericTarget;
145
+ /** Track which keys are currently mounted in the DOM, to honor the contract that mount happens after `updated()` reconciles. */
146
+ private _mountedKeys;
147
+ /** Latest resolved row map: key → row. Filled during render so callbacks can look up rows. */
148
+ private _keyToRow;
149
+ /** Stable ref callback per row key. One closure per key, reused across renders. */
150
+ private _refCallbacks;
58
151
  private _hasToolbar;
59
152
  private _hasFooter;
153
+ private _resolveKey;
60
154
  private handleHeaderClick;
61
155
  private handleRowClick;
62
- /** Toggle expand state for a row at the given index. */
63
- toggleExpand(index: number): void;
64
- /** Check whether a row at the given index is currently expanded. */
65
- isRowExpanded(index: number): boolean;
156
+ /**
157
+ * Chevron button click handler. Stops propagation so it does NOT also fire
158
+ * the row-level `reke-row-click` event, then toggles the row by key.
159
+ */
160
+ private _handleChevronClick;
161
+ /**
162
+ * Chevron keyboard activation. The element is a native `<button>`, so Enter
163
+ * already fires `click` natively. We still handle it here to keep the
164
+ * keyboard contract explicit and testable across environments where the
165
+ * `KeyboardEvent` is dispatched programmatically (Vitest browser mode tests
166
+ * dispatch raw `keydown`s without the synthesized `click`).
167
+ *
168
+ * For Space we MUST call `preventDefault()` so the page does not scroll.
169
+ */
170
+ private _handleChevronKeydown;
171
+ /**
172
+ * Toggle expand state for a row.
173
+ * Accepts either a numeric `index` into `rows` or a `RowKey` (the value returned by `getRowKey`).
174
+ * When `getRowKey` is unset, indices and keys collapse onto `String(index)`.
175
+ */
176
+ toggleExpand(target: number | RowKey): void;
177
+ /** Check whether a row with the given key is currently expanded. */
178
+ isRowExpanded(key: RowKey): boolean;
66
179
  private _onToolbarSlotChange;
67
180
  private _onFooterSlotChange;
181
+ private _getOrCreateHost;
182
+ /**
183
+ * Return a STABLE ref callback for a given row key. Lit's `ref()` directive accepts a
184
+ * callback `(el: Element | undefined) => void` directly, so no cast is needed. The callback
185
+ * is memoized per key to avoid churning Lit's ref directive on every render.
186
+ */
187
+ private _expandTdRef;
68
188
  private _renderRow;
189
+ willUpdate(_changed: PropertyValues): void;
190
+ private _warnedLegacyApi;
191
+ updated(_changed: PropertyValues): void;
192
+ /**
193
+ * Invoke the cached cleanup for a key, swallowing consumer errors so our own state
194
+ * mutation (`expandedRows`, host/cleanup/ref maps) and `emit` stay consistent even if
195
+ * the consumer's cleanup throws. Deletes the cleanup entry after running.
196
+ */
197
+ private _safeCleanup;
198
+ private _runAllCleanupsAndClear;
199
+ disconnectedCallback(): void;
69
200
  render(): TemplateResult<1>;
70
201
  }
71
202
  declare global {
@@ -1 +1 @@
1
- {"version":3,"file":"reke-table.d.ts","sourceRoot":"","sources":["../../../src/components/reke-table/reke-table.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAGzD,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAG3D,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;IACpC,qEAAqE;IACrE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,sFAAsF;IACtF,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,KAAK,cAAc,GAAG,MAAM,CAAC;CACpF;AAED,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE/C,MAAM,MAAM,mBAAmB,GAAG,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,KAAK,cAAc,CAAC;AAEnF;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBACa,SAAU,SAAQ,WAAW;IACxC,OAAgB,MAAM,4BAAU;IAGhC,OAAO,EAAE,WAAW,EAAE,CAAM;IAG5B,IAAI,EAAE,QAAQ,EAAE,CAAM;IAGtB,OAAO,UAAS;IAGhB,KAAK,UAAS;IAGd,SAAS,UAAS;IAGlB,QAAQ,UAAS;IAGjB,UAAU,UAAS;IAGnB,OAAO,SAAM;IAGb,aAAa,EAAE,KAAK,GAAG,MAAM,CAAS;IAEtC,8DAA8D;IAE9D,iBAAiB,EAAE,mBAAmB,GAAG,IAAI,CAAQ;IAErD,6CAA6C;IAE7C,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,CAAa;IAE7B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,UAAU,CAAS;IAEpC,OAAO,CAAC,iBAAiB;IAYzB,OAAO,CAAC,cAAc;IAItB,wDAAwD;IACxD,YAAY,CAAC,KAAK,EAAE,MAAM;IAa1B,oEAAoE;IACpE,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAIrC,OAAO,CAAC,oBAAoB;IAK5B,OAAO,CAAC,mBAAmB;IAK3B,OAAO,CAAC,UAAU;IAiCT,MAAM;CAoEhB;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,YAAY,EAAE,SAAS,CAAC;KACzB;CACF"}
1
+ {"version":3,"file":"reke-table.d.ts","sourceRoot":"","sources":["../../../src/components/reke-table/reke-table.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,291 @@
1
+ import { RekeElement as e } from "../../shared/base-element.js";
2
+ import { __decorate as t } from "../../_virtual/_@oxc-project_runtime@0.137.0/helpers/esm/decorate.js";
3
+ import { n } from "../../node_modules/lit-html/directives/ref.js";
4
+ import "../../node_modules/lit/directives/ref.js";
5
+ import { styles as r } from "./reke-table.styles.js";
6
+ import { html as i, nothing as a } from "lit";
7
+ import { customElement as o, property as s, state as c } from "lit/decorators.js";
8
+ import { classMap as l } from "lit/directives/class-map.js";
9
+ //#region src/components/reke-table/reke-table.ts
10
+ function u() {
11
+ try {
12
+ let e = {
13
+ BASE_URL: "/",
14
+ DEV: !1,
15
+ MODE: "production",
16
+ PROD: !0,
17
+ SSR: !1
18
+ };
19
+ if (e && typeof e.DEV == "boolean") return e.DEV;
20
+ if (e && typeof e.MODE == "string") return e.MODE !== "production";
21
+ } catch {}
22
+ try {
23
+ let e = globalThis.process;
24
+ if (e?.env?.NODE_ENV) return e.env.NODE_ENV === "development";
25
+ } catch {}
26
+ return !1;
27
+ }
28
+ var d = class extends e {
29
+ constructor(...e) {
30
+ super(...e), this.columns = [], this.rows = [], this.striped = !1, this.dense = !1, this.hoverable = !1, this.bordered = !1, this.borderless = !1, this.expandable = !1, this.expandOnRowClick = !1, this.sortKey = "", this.sortDirection = "asc", this.expandedRowElement = null, this.expandedRows = /* @__PURE__ */ new Set(), this._hostCache = /* @__PURE__ */ new Map(), this._cleanupMap = /* @__PURE__ */ new Map(), this._warnedDupKeys = /* @__PURE__ */ new Set(), this._warnedNumericTarget = !1, this._mountedKeys = /* @__PURE__ */ new Set(), this._keyToRow = /* @__PURE__ */ new Map(), this._refCallbacks = /* @__PURE__ */ new Map(), this._hasToolbar = !1, this._hasFooter = !1, this._warnedLegacyApi = !1;
31
+ }
32
+ static {
33
+ this.styles = r;
34
+ }
35
+ _resolveKey(e, t) {
36
+ return this.getRowKey ? this.getRowKey(e, t) : String(t);
37
+ }
38
+ handleHeaderClick(e) {
39
+ e.sortable !== !1 && (this.sortKey === e.key ? this.sortDirection = this.sortDirection === "asc" ? "desc" : "asc" : (this.sortKey = e.key, this.sortDirection = "asc"), this.emit("reke-sort", {
40
+ key: this.sortKey,
41
+ direction: this.sortDirection
42
+ }));
43
+ }
44
+ handleRowClick(e, t) {
45
+ if (this.emit("reke-row-click", {
46
+ row: e,
47
+ index: t
48
+ }), this.expandOnRowClick) {
49
+ let n = this._resolveKey(e, t);
50
+ this.toggleExpand(n);
51
+ }
52
+ }
53
+ _handleChevronClick(e, t) {
54
+ e.stopPropagation(), this.toggleExpand(t);
55
+ }
56
+ _handleChevronKeydown(e, t) {
57
+ (e.key === "Enter" || e.key === " " || e.key === "Spacebar") && (e.preventDefault(), e.stopPropagation(), this.toggleExpand(t));
58
+ }
59
+ toggleExpand(e) {
60
+ let t, n, r, i = typeof e == "number" && e === Math.trunc(e) && e >= 0 && e < this.rows.length;
61
+ i && this.getRowKey && !this._warnedNumericTarget && u() && (this._warnedNumericTarget = !0, console.warn("[reke-table] toggleExpand received a numeric target while `getRowKey` is set; in-range numeric targets are interpreted as row INDICES, not keys. Pass the resolved key to target by identity.")), i ? (n = e, r = this.rows[n], t = this._resolveKey(r, n)) : (t = e, n = this.rows.findIndex((e, n) => this._resolveKey(e, n) === t), r = n >= 0 ? this.rows[n] : void 0);
62
+ let a = new Set(this.expandedRows), o = !a.has(t);
63
+ o ? a.add(t) : (a.delete(t), this._safeCleanup(t), this._hostCache.delete(t), this._mountedKeys.delete(t), this._refCallbacks.delete(t)), this.expandedRows = a, this.emit("reke-row-expand", {
64
+ row: r,
65
+ index: n,
66
+ key: t,
67
+ expanded: o
68
+ });
69
+ }
70
+ isRowExpanded(e) {
71
+ return this.expandedRows.has(e);
72
+ }
73
+ _onToolbarSlotChange(e) {
74
+ let t = e.target;
75
+ this._hasToolbar = t.assignedNodes({ flatten: !0 }).length > 0;
76
+ }
77
+ _onFooterSlotChange(e) {
78
+ let t = e.target;
79
+ this._hasFooter = t.assignedNodes({ flatten: !0 }).length > 0;
80
+ }
81
+ _getOrCreateHost(e) {
82
+ let t = this._hostCache.get(e);
83
+ return t || (t = document.createElement("div"), t.style.cssText = "display: contents;", this._hostCache.set(e, t)), t;
84
+ }
85
+ _expandTdRef(e) {
86
+ let t = this._refCallbacks.get(e);
87
+ return t || (t = (t) => {
88
+ if (!t) return;
89
+ let n = t, r = this._getOrCreateHost(e);
90
+ r.parentElement !== n && n.appendChild(r);
91
+ }, this._refCallbacks.set(e, t)), t;
92
+ }
93
+ _renderRow(e, t, r) {
94
+ let o = this.expandedRows.has(r), s = `reke-table-expand-${String(r)}`, c = this.columns.length + +!!this.expandable;
95
+ return i`
96
+ <tr
97
+ part="row"
98
+ class="row ${t % 2 == 1 ? "row--even" : ""} ${o ? "row--expanded" : ""}"
99
+ @click=${() => this.handleRowClick(e, t)}
100
+ >
101
+ ${this.expandable ? i`
102
+ <td
103
+ part="expand-toggle-cell"
104
+ class="expand-toggle-cell"
105
+ >
106
+ <button
107
+ type="button"
108
+ part="expand-toggle-button"
109
+ class="expand-toggle-button ${o ? "expand-toggle-button--expanded" : ""}"
110
+ aria-expanded=${o ? "true" : "false"}
111
+ aria-controls=${s}
112
+ aria-label=${o ? "Collapse row" : "Expand row"}
113
+ @click=${(e) => this._handleChevronClick(e, r)}
114
+ @keydown=${(e) => this._handleChevronKeydown(e, r)}
115
+ >
116
+ <span class="expand-toggle-chevron" aria-hidden="true">▶</span>
117
+ </button>
118
+ </td>
119
+ ` : a}
120
+ ${this.columns.map((n) => i`
121
+ <td
122
+ part="cell"
123
+ class="cell"
124
+ data-align=${n.align || "left"}
125
+ >
126
+ ${n.render ? n.render(e[n.key], e, t) : e[n.key] ?? ""}
127
+ </td>
128
+ `)}
129
+ </tr>
130
+ ${this.expandedRowElement && o && this._keyToRow.get(r) === e ? i`
131
+ <tr part="expand-row" class="expand-row">
132
+ <td
133
+ part="expand-content"
134
+ class="expand-content"
135
+ id=${s}
136
+ colspan=${c}
137
+ ${n(this._expandTdRef(r))}
138
+ ></td>
139
+ </tr>
140
+ ` : a}
141
+ `;
142
+ }
143
+ willUpdate(e) {
144
+ let t = u();
145
+ t && this.expandedRowRender != null && !this._warnedLegacyApi && (this._warnedLegacyApi = !0, console.error("[reke-table] `expandedRowRender` was removed. Use `expandedRowElement(host, row, key) => Cleanup | void` instead."));
146
+ let n = /* @__PURE__ */ new Map();
147
+ for (let e = 0; e < this.rows.length; e += 1) {
148
+ let r = this.rows[e], i = this._resolveKey(r, e);
149
+ n.has(i) && t && !this._warnedDupKeys.has(i) && (this._warnedDupKeys.add(i), console.warn(`[reke-table] Duplicate getRowKey value detected: ${JSON.stringify(i)}. Last row with this key wins for expand bookkeeping.`)), n.set(i, r);
150
+ }
151
+ this._keyToRow = n;
152
+ }
153
+ updated(e) {
154
+ if (!this.expandedRowElement) {
155
+ this._runAllCleanupsAndClear();
156
+ for (let e of Array.from(this.expandedRows)) this._keyToRow.has(e) || this.expandedRows.delete(e);
157
+ return;
158
+ }
159
+ let t = /* @__PURE__ */ new Set([...this.expandedRows, ...this._hostCache.keys()]);
160
+ for (let e of t) {
161
+ let t = this._keyToRow.has(e), n = this.expandedRows.has(e);
162
+ t && n || (this._safeCleanup(e), this._hostCache.delete(e), this._mountedKeys.delete(e), this._refCallbacks.delete(e), t || this.expandedRows.delete(e));
163
+ }
164
+ for (let e of this.expandedRows) {
165
+ if (this._mountedKeys.has(e)) continue;
166
+ let t = this._keyToRow.get(e);
167
+ if (!t) continue;
168
+ let n = this._getOrCreateHost(e), r = this.expandedRowElement(n, t, e);
169
+ typeof r == "function" && this._cleanupMap.set(e, r), this._mountedKeys.add(e);
170
+ }
171
+ }
172
+ _safeCleanup(e) {
173
+ let t = this._cleanupMap.get(e);
174
+ if (t) {
175
+ try {
176
+ t();
177
+ } catch {}
178
+ this._cleanupMap.delete(e);
179
+ }
180
+ }
181
+ _runAllCleanupsAndClear() {
182
+ for (let e of this._cleanupMap.values()) try {
183
+ e();
184
+ } catch {}
185
+ this._cleanupMap.clear(), this._hostCache.clear(), this._mountedKeys.clear(), this._refCallbacks.clear();
186
+ }
187
+ disconnectedCallback() {
188
+ super.disconnectedCallback(), this._runAllCleanupsAndClear();
189
+ }
190
+ render() {
191
+ let e = {
192
+ table: !0,
193
+ "table--striped": this.striped,
194
+ "table--dense": this.dense,
195
+ "table--hoverable": this.hoverable,
196
+ "table--bordered": this.bordered
197
+ };
198
+ return i`
199
+ <div class="table-container">
200
+ ${this._hasToolbar ? i`
201
+ <div part="toolbar" class="table-toolbar">
202
+ <slot name="toolbar" @slotchange=${this._onToolbarSlotChange}></slot>
203
+ </div>
204
+ ` : i`<slot name="toolbar" @slotchange=${this._onToolbarSlotChange} style="display:none"></slot>`}
205
+
206
+ <div class="table-wrapper">
207
+ <table part="table" class=${l(e)} role="table">
208
+ <thead part="header">
209
+ <tr>
210
+ ${this.expandable ? i`
211
+ <th
212
+ part="expand-toggle-header-cell"
213
+ class="expand-toggle-header-cell"
214
+ aria-hidden="true"
215
+ ></th>
216
+ ` : a}
217
+ ${this.columns.map((e) => i`
218
+ <th
219
+ part="header-cell"
220
+ class="header-cell ${this.sortKey === e.key ? "header-cell--sorted" : ""} ${e.sortable === !1 ? "header-cell--no-sort" : ""}"
221
+ style=${e.width ? `width: ${e.width}` : ""}
222
+ data-align=${e.align || "left"}
223
+ @click=${() => this.handleHeaderClick(e)}
224
+ >
225
+ <span class="header-content">
226
+ ${e.header}
227
+ ${this.sortKey === e.key ? i`<span class="sort-indicator" aria-hidden="true">${this.sortDirection === "asc" ? "↑" : "↓"}</span>` : a}
228
+ </span>
229
+ </th>
230
+ `)}
231
+ </tr>
232
+ </thead>
233
+ <tbody part="body">
234
+ ${this.rows.map((e, t) => {
235
+ let n = this._resolveKey(e, t);
236
+ return this._renderRow(e, t, n);
237
+ })}
238
+ ${this.rows.length === 0 ? i`
239
+ <tr class="row row--empty">
240
+ <td
241
+ class="cell cell--empty"
242
+ colspan=${this.columns.length + +!!this.expandable}
243
+ >
244
+ <slot name="empty">No data</slot>
245
+ </td>
246
+ </tr>
247
+ ` : a}
248
+ </tbody>
249
+ </table>
250
+ </div>
251
+
252
+ ${this._hasFooter ? i`
253
+ <div part="footer" class="table-footer">
254
+ <slot name="footer" @slotchange=${this._onFooterSlotChange}></slot>
255
+ </div>
256
+ ` : i`<slot name="footer" @slotchange=${this._onFooterSlotChange} style="display:none"></slot>`}
257
+ </div>
258
+ `;
259
+ }
260
+ };
261
+ t([s({ attribute: !1 })], d.prototype, "columns", void 0), t([s({ attribute: !1 })], d.prototype, "rows", void 0), t([s({
262
+ type: Boolean,
263
+ reflect: !0
264
+ })], d.prototype, "striped", void 0), t([s({
265
+ type: Boolean,
266
+ reflect: !0
267
+ })], d.prototype, "dense", void 0), t([s({
268
+ type: Boolean,
269
+ reflect: !0
270
+ })], d.prototype, "hoverable", void 0), t([s({
271
+ type: Boolean,
272
+ reflect: !0
273
+ })], d.prototype, "bordered", void 0), t([s({
274
+ type: Boolean,
275
+ reflect: !0
276
+ })], d.prototype, "borderless", void 0), t([s({
277
+ type: Boolean,
278
+ reflect: !0
279
+ })], d.prototype, "expandable", void 0), t([s({
280
+ type: Boolean,
281
+ reflect: !0,
282
+ attribute: "expand-on-row-click"
283
+ })], d.prototype, "expandOnRowClick", void 0), t([s({
284
+ reflect: !0,
285
+ attribute: "sort-key"
286
+ })], d.prototype, "sortKey", void 0), t([s({
287
+ reflect: !0,
288
+ attribute: "sort-direction"
289
+ })], d.prototype, "sortDirection", void 0), t([s({ attribute: !1 })], d.prototype, "expandedRowElement", void 0), t([s({ attribute: !1 })], d.prototype, "getRowKey", void 0), t([s({ attribute: !1 })], d.prototype, "expandedRows", void 0), t([c()], d.prototype, "_hasToolbar", void 0), t([c()], d.prototype, "_hasFooter", void 0), d = t([o("reke-table")], d);
290
+ //#endregion
291
+ export { d as RekeTable };
@@ -1 +1 @@
1
- {"version":3,"file":"reke-table.styles.d.ts","sourceRoot":"","sources":["../../../src/components/reke-table/reke-table.styles.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,MAAM,2BAyMlB,CAAC"}
1
+ {"version":3,"file":"reke-table.styles.d.ts","sourceRoot":"","sources":["../../../src/components/reke-table/reke-table.styles.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,MAAM,2BAsQlB,CAAC"}