@serkonda7/solid-components 0.0.8 → 0.1.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.
package/README.md CHANGED
@@ -26,6 +26,7 @@ import '@serkonda7/solid-components/styles.css'
26
26
 
27
27
  These components are available:
28
28
  - `DataTable` - generic table with optional sorting, row selection, actions, loading, empty states, and column customizer.
29
+ - `FilterTable` - `DataTable` with filtering: quick search, a grouped filter form, and removable filter pills.
29
30
  - `Combobox` - searchable, accessible dropdown with keyboard navigation, option icons, a detail column, and an optional "Add …" entry.
30
31
 
31
32
  For the full API, examples, and agent notes, see [docs.md](docs.md).
@@ -33,6 +33,8 @@ export interface ComboboxProps {
33
33
  onAdd?: (query: string) => void;
34
34
  /** Text of the pinned add entry. Defaults to `Add`. */
35
35
  addLabel?: string;
36
+ /** Placeholder while closed and nothing is selected; `emptyLabel` takes precedence. */
37
+ placeholder?: string;
36
38
  /** Placeholder while open and nothing is selected. Defaults to `Search`. */
37
39
  searchLabel?: string;
38
40
  /** Shown when no option matches the search. Defaults to `No matching objects`. */
@@ -40,6 +40,8 @@ export interface DataTableProps<TRow> {
40
40
  columnCustomizerTitle?: string;
41
41
  columnCustomizerShowAllLabel?: string;
42
42
  columnCustomizerResetLabel?: string;
43
+ /** Content rendered at the start of the toolbar, before the column customizer. */
44
+ toolbar?: JSX.Element;
43
45
  loading?: boolean | Accessor<boolean>;
44
46
  empty?: boolean | Accessor<boolean>;
45
47
  loadingContent?: JSX.Element;
@@ -0,0 +1,53 @@
1
+ import type { Accessor, JSX } from 'solid-js';
2
+ import { type ComboboxOption } from './combobox';
3
+ import { type DataTableProps } from './data-table';
4
+ export type FilterTableFilterType = 'text' | 'select' | 'boolean';
5
+ /** A filter's value: text for `text`/`boolean` (`'true'`/`'false'`), a list for `select`. */
6
+ export type FilterTableValue = string | string[];
7
+ /**
8
+ * Applied filters by filter key, plus the quick search under `q`. Inactive
9
+ * filters are omitted, so the record maps directly onto URL query params.
10
+ */
11
+ export type FilterTableValues = Record<string, FilterTableValue>;
12
+ export interface FilterTableFilter<TRow> {
13
+ key: string;
14
+ label: string;
15
+ type: FilterTableFilterType;
16
+ /** Fieldset heading in the filter form; ungrouped filters come first. */
17
+ group?: string;
18
+ /** Value matched against; defaults to `row[key]`. May return an array for `select`. */
19
+ getValue?: (row: TRow) => unknown;
20
+ /** Replaces the built-in matching for this filter. */
21
+ match?: (row: TRow, value: FilterTableValue) => boolean;
22
+ /** Choices of a `select` filter; derived from the row values when omitted. */
23
+ options?: ComboboxOption[];
24
+ placeholder?: string;
25
+ }
26
+ export interface FilterTableProps<TRow> extends Omit<DataTableProps<TRow>, 'toolbar'> {
27
+ filters: FilterTableFilter<TRow>[];
28
+ /** Controlled applied filters; pair with `onFilterValuesChange`. */
29
+ filterValues?: FilterTableValues | Accessor<FilterTableValues>;
30
+ defaultFilterValues?: FilterTableValues;
31
+ onFilterValuesChange?: (values: FilterTableValues) => void;
32
+ /** Pass `rows` through unfiltered, e.g. when the server applies `filterValues`. */
33
+ manualFiltering?: boolean;
34
+ /** Shows the quick search input above the table. Defaults to `true`. */
35
+ quickSearch?: boolean;
36
+ /** Text matched by the quick search; defaults to the row's column values. */
37
+ getSearchText?: (row: TRow) => string;
38
+ quickSearchLabel?: string;
39
+ resultsLabel?: string;
40
+ filtersLabel?: string;
41
+ applyLabel?: string;
42
+ resetLabel?: string;
43
+ clearAllLabel?: string;
44
+ anyLabel?: string;
45
+ yesLabel?: string;
46
+ noLabel?: string;
47
+ }
48
+ /**
49
+ * `DataTable` with filtering: a Results tab with a quick search and
50
+ * removable pills for the applied filters, and a Filters tab with a grouped form
51
+ * that is applied on submit.
52
+ */
53
+ export declare function FilterTable<TRow>(props: FilterTableProps<TRow>): JSX.Element;
package/dist/index.d.ts CHANGED
@@ -6,3 +6,4 @@
6
6
  */
7
7
  export { Combobox, type ComboboxIcon, type ComboboxOption, type ComboboxProps, } from './combobox';
8
8
  export { DataTable, type DataTableColumn, type DataTableProps, type DataTableSort, type DataTableSortDirection, } from './data-table';
9
+ export { FilterTable, type FilterTableFilter, type FilterTableFilterType, type FilterTableProps, type FilterTableValue, type FilterTableValues, } from './filter-table';
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Dynamic as e, className as t, createComponent as n, delegateEvents as r, effect as i, insert as a, memo as o, mergeProps as s, setAttribute as c, spread as l, template as u, use as d } from "solid-js/web";
2
- import { For as f, Show as p, createEffect as m, createMemo as h, createSignal as g, createUniqueId as _, onCleanup as v, onMount as y, splitProps as b } from "solid-js";
2
+ import { For as f, Show as p, children as m, createEffect as h, createMemo as g, createSignal as _, createUniqueId as v, on as y, onCleanup as b, onMount as x, splitProps as S } from "solid-js";
3
3
  //#region node_modules/@tabler/icons-solidjs/dist/source/defaultAttributes.js
4
- var x = {
4
+ var C = {
5
5
  outline: {
6
6
  xmlns: "http://www.w3.org/2000/svg",
7
7
  width: 24,
@@ -21,9 +21,9 @@ var x = {
21
21
  fill: "currentColor",
22
22
  stroke: "none"
23
23
  }
24
- }, S = /*#__PURE__*/ u("<svg>"), C = /*#__PURE__*/ u("<title>"), w = (t, r, i, c) => {
24
+ }, w = /*#__PURE__*/ u("<svg>"), T = /*#__PURE__*/ u("<title>"), E = (t, r, i, c) => {
25
25
  let u = (i) => {
26
- let [u, d] = b(i, [
26
+ let [u, d] = S(i, [
27
27
  "color",
28
28
  "size",
29
29
  "stroke",
@@ -31,9 +31,9 @@ var x = {
31
31
  "title",
32
32
  "children",
33
33
  "class"
34
- ]), f = x[t], p = u.stroke ?? u.strokeWidth;
34
+ ]), f = C[t], p = u.stroke ?? u.strokeWidth;
35
35
  return (() => {
36
- var i = S();
36
+ var i = w();
37
37
  return l(i, s(f, d, {
38
38
  get width() {
39
39
  return o(() => u.size != null)() ? u.size : f.width;
@@ -50,66 +50,62 @@ var x = {
50
50
  }), !0, !0), a(i, (() => {
51
51
  var e = o(() => u.title != null);
52
52
  return () => e() && (() => {
53
- var e = C();
53
+ var e = T();
54
54
  return a(e, () => u.title), e;
55
55
  })();
56
56
  })(), null), a(i, () => c.map(([t, r]) => n(e, s({ component: t }, r))), null), a(i, () => u.children, null), i;
57
57
  })();
58
58
  };
59
59
  return u.displayName = `${i}`, u;
60
- }, T = w("outline", "chevron-down", "ChevronDown", [["path", { d: "M6 9l6 6l6 -6" }]]), E = w("outline", "plus", "Plus", [["path", { d: "M12 5l0 14" }], ["path", { d: "M5 12l14 0" }]]), D = /*#__PURE__*/ u("<span class=combobox-value aria-hidden=true><span class=combobox-option-label></span><span class=combobox-detail>"), ee = /*#__PURE__*/ u("<div role=option class=\"combobox-option combobox-option-add\">"), O = /*#__PURE__*/ u("<div class=combobox-list role=listbox>"), k = /*#__PURE__*/ u("<div><input class=combobox-input role=combobox aria-autocomplete=list autocomplete=off>"), A = /*#__PURE__*/ u("<span class=combobox-icon aria-hidden=true>"), te = /*#__PURE__*/ u("<div class=combobox-empty>"), j = /*#__PURE__*/ u("<span class=combobox-detail>"), M = /*#__PURE__*/ u("<div role=option class=combobox-option><span class=combobox-option-label>"), N = /*#__PURE__*/ u("<span class=combobox-option-icon aria-hidden=true>");
61
- function P(r) {
62
- let s, l, u = _(), v = () => r.id ?? u, b = () => `${v()}-listbox`, x = (e) => `${v()}-option-${e}`, [S, C] = g(!1), [w, P] = g(""), [F, I] = g(0), L = h(() => r.emptyLabel === void 0 ? r.options : [{
60
+ }, ee = E("outline", "chevron-down", "ChevronDown", [["path", { d: "M6 9l6 6l6 -6" }]]), D = E("outline", "plus", "Plus", [["path", { d: "M12 5l0 14" }], ["path", { d: "M5 12l14 0" }]]), O = E("outline", "search", "Search", [["path", { d: "M3 10a7 7 0 1 0 14 0a7 7 0 1 0 -14 0" }], ["path", { d: "M21 21l-6 -6" }]]), k = E("outline", "x", "X", [["path", { d: "M18 6l-12 12" }], ["path", { d: "M6 6l12 12" }]]), A = /*#__PURE__*/ u("<span class=combobox-value aria-hidden=true><span class=combobox-option-label></span><span class=combobox-detail>"), j = /*#__PURE__*/ u("<div role=option class=\"combobox-option combobox-option-add\">"), M = /*#__PURE__*/ u("<div class=combobox-list role=listbox>"), te = /*#__PURE__*/ u("<div><input class=combobox-input role=combobox aria-autocomplete=list autocomplete=off>"), N = /*#__PURE__*/ u("<span class=combobox-icon aria-hidden=true>"), P = /*#__PURE__*/ u("<div class=combobox-empty>"), F = /*#__PURE__*/ u("<span class=combobox-detail>"), I = /*#__PURE__*/ u("<div role=option class=combobox-option><span class=combobox-option-label>"), L = /*#__PURE__*/ u("<span class=combobox-option-icon aria-hidden=true>");
61
+ function R(r) {
62
+ let s, l, u = v(), m = () => r.id ?? u, y = () => `${m()}-listbox`, b = (e) => `${m()}-option-${e}`, [S, C] = _(!1), [w, T] = _(""), [E, O] = _(0), k = g(() => r.emptyLabel === void 0 ? r.options : [{
63
63
  value: "",
64
64
  label: r.emptyLabel
65
- }, ...r.options]), R = h(() => r.value === "" ? void 0 : L().find((e) => String(e.value) === r.value)), z = h(() => {
65
+ }, ...r.options]), R = g(() => r.value === "" ? void 0 : k().find((e) => String(e.value) === r.value)), z = g(() => {
66
66
  let e = w().trim().toLowerCase();
67
- return e === "" ? L() : L().filter((t) => t.label.toLowerCase().includes(e) || (t.detail?.toLowerCase().includes(e) ?? !1));
68
- }), ne = () => r.options.some((e) => e.detail !== void 0), B = () => z().length, V = () => z().length + +!!r.onAdd, re = () => !r.disabled && r.onChange !== void 0;
69
- y(() => {
67
+ return e === "" ? k() : k().filter((t) => t.label.toLowerCase().includes(e) || (t.detail?.toLowerCase().includes(e) ?? !1));
68
+ }), B = () => r.options.some((e) => e.detail !== void 0), V = () => z().length, H = () => z().length + +!!r.onAdd, U = () => !r.disabled && r.onChange !== void 0;
69
+ x(() => {
70
70
  r.autofocus === !0 && s?.focus();
71
- }), m(() => {
72
- S() && l?.querySelector(`[data-index="${F()}"]`)?.scrollIntoView({ block: "nearest" });
71
+ }), h(() => {
72
+ S() && l?.querySelector(`[data-index="${E()}"]`)?.scrollIntoView({ block: "nearest" });
73
73
  });
74
- function H() {
75
- if (S() || !re()) return;
76
- P("");
77
- let e = L().findIndex((e) => String(e.value) === r.value);
78
- I(Math.max(e, 0)), C(!0), r.onOpen?.();
79
- }
80
- function U(e) {
81
- if (C(!1), r.onAdd && e === B()) {
74
+ function W() {
75
+ if (S() || !U()) return;
76
+ T("");
77
+ let e = k().findIndex((e) => String(e.value) === r.value);
78
+ O(Math.max(e, 0)), C(!0), r.onOpen?.();
79
+ }
80
+ function G(e) {
81
+ if (C(!1), r.onAdd && e === V()) {
82
82
  r.onAdd(w().trim());
83
83
  return;
84
84
  }
85
85
  let t = z()[e];
86
86
  t && String(t.value) !== r.value && r.onChange?.(String(t.value));
87
87
  }
88
- function W(e) {
89
- let t = V();
90
- S() ? t > 0 && I((F() + e + t) % t) : H();
88
+ function K(e) {
89
+ let t = H();
90
+ S() ? t > 0 && O((E() + e + t) % t) : W();
91
91
  }
92
- function G(e) {
93
- if (e.key === "ArrowDown" || e.key === "ArrowUp") {
94
- e.preventDefault(), W(e.key === "ArrowDown" ? 1 : -1);
95
- return;
96
- }
97
- S() && (e.key === "Enter" ? (e.preventDefault(), U(F())) : e.key === "Escape" && (e.preventDefault(), e.stopPropagation(), C(!1)));
92
+ function q(e) {
93
+ e.key === "ArrowDown" || e.key === "ArrowUp" ? (e.preventDefault(), K(e.key === "ArrowDown" ? 1 : -1)) : S() && (e.key === "Enter" ? (e.preventDefault(), G(E())) : e.key === "Escape" && (e.preventDefault(), e.stopPropagation(), C(!1)));
98
94
  }
99
- let K = () => S() ? R()?.label ?? r.emptyLabel ?? r.searchLabel ?? "Search" : r.emptyLabel;
95
+ let ne = () => S() ? R()?.label ?? r.emptyLabel ?? r.searchLabel ?? "Search" : r.emptyLabel ?? r.placeholder;
100
96
  return (() => {
101
- var u = k(), m = u.firstChild;
102
- m.addEventListener("blur", () => C(!1)), m.$$keydown = G, m.$$input = (e) => {
97
+ var u = te(), h = u.firstChild;
98
+ h.addEventListener("blur", () => C(!1)), h.$$keydown = q, h.$$input = (e) => {
103
99
  let t = e.currentTarget.value;
104
- H(), P(t), I(0);
105
- }, m.$$click = H;
106
- var h = s;
107
- return typeof h == "function" ? d(h, m) : s = m, a(u, n(p, {
100
+ W(), T(t), O(0);
101
+ }, h.$$click = W;
102
+ var g = s;
103
+ return typeof g == "function" ? d(g, h) : s = h, a(u, n(p, {
108
104
  get when() {
109
105
  return o(() => !S())() && R()?.icon;
110
106
  },
111
107
  children: (t) => (() => {
112
- var r = A();
108
+ var r = N();
113
109
  return a(r, n(e, {
114
110
  get component() {
115
111
  return t();
@@ -122,10 +118,10 @@ function P(r) {
122
118
  return o(() => !S())() && R()?.detail;
123
119
  },
124
120
  get children() {
125
- var e = D(), t = e.firstChild, n = t.nextSibling;
121
+ var e = A(), t = e.firstChild, n = t.nextSibling;
126
122
  return a(t, () => R()?.label), a(n, () => R()?.detail), e;
127
123
  }
128
- }), null), a(u, n(T, {
124
+ }), null), a(u, n(ee, {
129
125
  class: "combobox-chevron",
130
126
  size: 16,
131
127
  "aria-hidden": "true"
@@ -134,25 +130,25 @@ function P(r) {
134
130
  return S();
135
131
  },
136
132
  get children() {
137
- var t = O(), o = l;
133
+ var t = M(), o = l;
138
134
  return typeof o == "function" ? d(o, t) : l = t, a(t, n(f, {
139
135
  get each() {
140
136
  return z();
141
137
  },
142
138
  get fallback() {
143
139
  return (() => {
144
- var e = te();
140
+ var e = P();
145
141
  return a(e, () => r.noMatchesLabel ?? "No matching objects"), e;
146
142
  })();
147
143
  },
148
144
  children: (t, o) => (() => {
149
- var s = M(), l = s.firstChild;
150
- return s.$$click = () => U(o()), s.$$mousemove = () => I(o()), s.$$mousedown = (e) => e.preventDefault(), a(l, n(p, {
145
+ var s = I(), l = s.firstChild;
146
+ return s.$$click = () => G(o()), s.$$mousemove = () => O(o()), s.$$mousedown = (e) => e.preventDefault(), a(l, n(p, {
151
147
  get when() {
152
148
  return t.icon;
153
149
  },
154
150
  children: (t) => (() => {
155
- var r = N();
151
+ var r = L();
156
152
  return a(r, n(e, {
157
153
  get component() {
158
154
  return t();
@@ -165,11 +161,11 @@ function P(r) {
165
161
  return t.detail;
166
162
  },
167
163
  get children() {
168
- var e = j();
164
+ var e = F();
169
165
  return a(e, () => t.detail), e;
170
166
  }
171
167
  }), null), i((e) => {
172
- var n = x(o()), i = o(), a = String(t.value) === r.value, l = o() === F(), u = t.value === "";
168
+ var n = b(o()), i = o(), a = String(t.value) === r.value, l = o() === E(), u = t.value === "";
173
169
  return n !== e.e && c(s, "id", e.e = n), i !== e.t && c(s, "data-index", e.t = i), a !== e.a && c(s, "aria-selected", e.a = a), l !== e.o && s.classList.toggle("combobox-option-active", e.o = l), u !== e.i && s.classList.toggle("combobox-option-empty", e.i = u), e;
174
170
  }, {
175
171
  e: void 0,
@@ -184,12 +180,12 @@ function P(r) {
184
180
  return r.onAdd;
185
181
  },
186
182
  get children() {
187
- var e = ee();
188
- return e.$$click = () => U(B()), e.$$mousemove = () => I(B()), e.$$mousedown = (e) => e.preventDefault(), c(e, "aria-selected", !1), a(e, n(E, {
183
+ var e = j();
184
+ return e.$$click = () => G(V()), e.$$mousemove = () => O(V()), e.$$mousedown = (e) => e.preventDefault(), c(e, "aria-selected", !1), a(e, n(D, {
189
185
  size: 14,
190
186
  "aria-hidden": "true"
191
187
  }), null), a(e, () => r.addLabel ?? "Add", null), i((t) => {
192
- var n = x(B()), r = B(), i = B() === F();
188
+ var n = b(V()), r = V(), i = V() === E();
193
189
  return n !== t.e && c(e, "id", t.e = n), r !== t.t && c(e, "data-index", t.t = r), i !== t.a && e.classList.toggle("combobox-option-active", t.a = i), t;
194
190
  }, {
195
191
  e: void 0,
@@ -198,7 +194,7 @@ function P(r) {
198
194
  }), e;
199
195
  }
200
196
  }), null), i((e) => {
201
- var n = !!ne(), r = b();
197
+ var n = !!B(), r = y();
202
198
  return n !== e.e && t.classList.toggle("combobox-list-detail", e.e = n), r !== e.t && c(t, "id", e.t = r), e;
203
199
  }, {
204
200
  e: void 0,
@@ -206,8 +202,8 @@ function P(r) {
206
202
  }), t;
207
203
  }
208
204
  }), null), i((e) => {
209
- var n = r.class ? `combobox ${r.class}` : "combobox", i = !!S(), a = !(S() || !R()?.detail), o = !(S() || R()?.icon === void 0), s = v(), l = S(), d = b(), f = S() && V() > 0 ? x(F()) : void 0, p = r.ariaLabel, h = r.describedBy, g = r.required, _ = r.disabled, y = r.onChange === void 0, C = r.value, w = K();
210
- return n !== e.e && t(u, e.e = n), i !== e.t && u.classList.toggle("combobox-open", e.t = i), a !== e.a && u.classList.toggle("combobox-with-detail", e.a = a), o !== e.o && u.classList.toggle("combobox-with-icon", e.o = o), s !== e.i && c(m, "id", e.i = s), l !== e.n && c(m, "aria-expanded", e.n = l), d !== e.s && c(m, "aria-controls", e.s = d), f !== e.h && c(m, "aria-activedescendant", e.h = f), p !== e.r && c(m, "aria-label", e.r = p), h !== e.d && c(m, "aria-describedby", e.d = h), g !== e.l && (m.required = e.l = g), _ !== e.u && (m.disabled = e.u = _), y !== e.c && (m.readOnly = e.c = y), C !== e.w && c(m, "data-value", e.w = C), w !== e.m && c(m, "placeholder", e.m = w), e;
205
+ var n = r.class ? `combobox ${r.class}` : "combobox", i = !!S(), a = !(S() || !R()?.detail), o = !(S() || R()?.icon === void 0), s = m(), l = S(), d = y(), f = S() && H() > 0 ? b(E()) : void 0, p = r.ariaLabel, g = r.describedBy, _ = r.required, v = r.disabled, x = r.onChange === void 0, C = r.value, w = ne();
206
+ return n !== e.e && t(u, e.e = n), i !== e.t && u.classList.toggle("combobox-open", e.t = i), a !== e.a && u.classList.toggle("combobox-with-detail", e.a = a), o !== e.o && u.classList.toggle("combobox-with-icon", e.o = o), s !== e.i && c(h, "id", e.i = s), l !== e.n && c(h, "aria-expanded", e.n = l), d !== e.s && c(h, "aria-controls", e.s = d), f !== e.h && c(h, "aria-activedescendant", e.h = f), p !== e.r && c(h, "aria-label", e.r = p), g !== e.d && c(h, "aria-describedby", e.d = g), _ !== e.l && (h.required = e.l = _), v !== e.u && (h.disabled = e.u = v), x !== e.c && (h.readOnly = e.c = x), C !== e.w && c(h, "data-value", e.w = C), w !== e.m && c(h, "placeholder", e.m = w), e;
211
207
  }, {
212
208
  e: void 0,
213
209
  t: void 0,
@@ -224,7 +220,7 @@ function P(r) {
224
220
  c: void 0,
225
221
  w: void 0,
226
222
  m: void 0
227
- }), i(() => m.value = S() ? w() : R()?.label ?? ""), u;
223
+ }), i(() => h.value = S() ? w() : R()?.label ?? ""), u;
228
224
  })();
229
225
  }
230
226
  r([
@@ -236,131 +232,147 @@ r([
236
232
  ]);
237
233
  //#endregion
238
234
  //#region src/data-table.tsx
239
- var F = /*#__PURE__*/ u("<div role=dialog class=data-table-customizer-panel><p class=data-table-customizer-title></p><ul class=data-table-customizer-list></ul><div class=data-table-customizer-actions><button type=button></button><button type=button>"), I = /*#__PURE__*/ u("<div class=data-table-toolbar><div class=data-table-customizer><button type=button class=data-table-customizer-button aria-haspopup=dialog><span aria-hidden=true>⚙</span> "), L = /*#__PURE__*/ u("<th class=data-table-checkbox><span class=data-table-visually-hidden>Select rows</span><input type=checkbox>"), R = /*#__PURE__*/ u("<th>Actions"), z = /*#__PURE__*/ u("<div><div class=data-table-scroll><table class=data-table><thead><tr></tr></thead><tbody>"), ne = /*#__PURE__*/ u("<li><label class=data-table-customizer-option><input type=checkbox>"), B = /*#__PURE__*/ u("<button type=button class=data-table-sort><span class=data-table-sort-indicator aria-hidden=true>"), V = /*#__PURE__*/ u("<th>"), re = /*#__PURE__*/ u("<td class=data-table-checkbox><input type=checkbox>"), H = /*#__PURE__*/ u("<td>"), U = /*#__PURE__*/ u("<tr>"), W = /*#__PURE__*/ u("<p class=data-table-status>Loading…"), G = /*#__PURE__*/ u("<p class=data-table-status>No results.");
240
- function K(e) {
235
+ var z = /*#__PURE__*/ u("<div class=data-table-toolbar-start>"), B = /*#__PURE__*/ u("<div role=dialog class=data-table-customizer-panel><p class=data-table-customizer-title></p><ul class=data-table-customizer-list></ul><div class=data-table-customizer-actions><button type=button></button><button type=button>"), V = /*#__PURE__*/ u("<div class=data-table-customizer><button type=button class=data-table-customizer-button aria-haspopup=dialog><span aria-hidden=true>⚙</span> "), H = /*#__PURE__*/ u("<div class=data-table-toolbar>"), U = /*#__PURE__*/ u("<th class=data-table-checkbox><span class=data-table-visually-hidden>Select rows</span><input type=checkbox>"), W = /*#__PURE__*/ u("<th>Actions"), G = /*#__PURE__*/ u("<div><div class=data-table-scroll><table class=data-table><thead><tr></tr></thead><tbody>"), K = /*#__PURE__*/ u("<li><label class=data-table-customizer-option><input type=checkbox>"), q = /*#__PURE__*/ u("<button type=button class=data-table-sort><span class=data-table-sort-indicator aria-hidden=true>"), ne = /*#__PURE__*/ u("<th>"), re = /*#__PURE__*/ u("<td class=data-table-checkbox><input type=checkbox>"), ie = /*#__PURE__*/ u("<td>"), ae = /*#__PURE__*/ u("<tr>"), oe = /*#__PURE__*/ u("<p class=data-table-status>Loading…"), se = /*#__PURE__*/ u("<p class=data-table-status>No results.");
236
+ function J(e) {
241
237
  return typeof e == "function" ? e() : e;
242
238
  }
243
- function q(e) {
244
- let r = h(() => K(e.rows)), s = () => K(e.loading ?? !1), l = () => K(e.selected ?? []), u = e.sortKey !== void 0 || e.sortDirection !== void 0, [y, b] = g(e.defaultSort), x = () => u ? K(e.sortKey ?? void 0) : y()?.key, S = () => u ? K(e.sortDirection ?? "asc") : y()?.direction ?? "asc", C = () => K(e.showColumnCustomizer ?? !1), w = () => e.selected !== void 0 && e.onSelectionChange !== void 0, T = () => {
239
+ function Y(e) {
240
+ let r = g(() => J(e.rows)), s = () => J(e.loading ?? !1), l = () => J(e.selected ?? []), u = e.sortKey !== void 0 || e.sortDirection !== void 0, [y, x] = _(e.defaultSort), S = () => u ? J(e.sortKey ?? void 0) : y()?.key, C = () => u ? J(e.sortDirection ?? "asc") : y()?.direction ?? "asc", w = () => J(e.showColumnCustomizer ?? !1), T = m(() => e.toolbar), E = () => e.selected !== void 0 && e.onSelectionChange !== void 0, ee = () => {
245
241
  let t = l();
246
242
  return r().length > 0 && r().every((n) => t.includes(e.getRowId(n)));
247
- }, E = h(() => e.defaultVisibleColumns ?? e.columns.filter((e) => e.defaultVisible !== !1).map((e) => e.key)), [D, ee] = g(void 0), O = () => e.visibleColumns === void 0 ? D() ?? E() : K(e.visibleColumns), k = h(() => new Set(O())), A = h(() => e.columns.filter((e) => e.toggleable === !1 || k().has(e.key))), te = h(() => e.columns.filter((e) => e.toggleable !== !1)), j = h(() => te().map((e) => e.key));
248
- function M(e, t) {
243
+ }, D = g(() => e.defaultVisibleColumns ?? e.columns.filter((e) => e.defaultVisible !== !1).map((e) => e.key)), [O, k] = _(void 0), A = () => e.visibleColumns === void 0 ? O() ?? D() : J(e.visibleColumns), j = g(() => new Set(A())), M = g(() => e.columns.filter((e) => e.toggleable === !1 || j().has(e.key))), te = g(() => e.columns.filter((e) => e.toggleable !== !1)), N = g(() => te().map((e) => e.key));
244
+ function P(e, t) {
249
245
  return t.sortValue ? t.sortValue(e) : e[t.key];
250
246
  }
251
- function N(e, t) {
247
+ function F(e, t) {
252
248
  return e === t ? 0 : e == null ? -1 : t == null ? 1 : typeof e == "number" && typeof t == "number" ? e - t : String(e).localeCompare(String(t), void 0, { numeric: !0 });
253
249
  }
254
- let P = h(() => {
255
- let t = r(), n = x();
250
+ let I = g(() => {
251
+ let t = r(), n = S();
256
252
  if (u || !n) return t;
257
253
  let i = e.columns.find((e) => e.key === n);
258
254
  if (!i) return t;
259
- let a = S() === "asc" ? 1 : -1;
260
- return [...t].sort((e, t) => a * N(M(e, i), M(t, i)));
255
+ let a = C() === "asc" ? 1 : -1;
256
+ return [...t].sort((e, t) => a * F(P(e, i), P(t, i)));
261
257
  });
262
- function q(t) {
263
- let n = x() === t, r = n && S() === "desc" ? void 0 : {
258
+ function L(t) {
259
+ let n = S() === t, r = n && C() === "desc" ? void 0 : {
264
260
  key: t,
265
261
  direction: n ? "desc" : "asc"
266
262
  };
267
- u || b(r), e.onSort?.(t), r || e.onSortClear?.(), e.onSortChange?.(r);
263
+ u || x(r), e.onSort?.(t), r || e.onSortClear?.(), e.onSortChange?.(r);
268
264
  }
269
- function ie(t) {
265
+ function R(t) {
270
266
  let n = new Map(e.columns.map((e, t) => [e.key, t]));
271
267
  return [...t].sort((e, t) => (n.get(e) ?? 0) - (n.get(t) ?? 0));
272
268
  }
273
- function J(t) {
274
- let n = ie(t);
275
- e.visibleColumns === void 0 && ee(n), e.onVisibleColumnsChange?.(n);
269
+ function Y(t) {
270
+ let n = R(t);
271
+ e.visibleColumns === void 0 && k(n), e.onVisibleColumnsChange?.(n);
276
272
  }
277
- function ae(e, t) {
278
- let n = new Set(O());
279
- t ? n.add(e) : n.delete(e), J(j().filter((e) => n.has(e)));
273
+ function ce(e, t) {
274
+ let n = new Set(A());
275
+ t ? n.add(e) : n.delete(e), Y(N().filter((e) => n.has(e)));
280
276
  }
281
- function oe() {
282
- J(j());
277
+ function le() {
278
+ Y(N());
283
279
  }
284
- function se() {
285
- J(E());
280
+ function ue() {
281
+ Y(D());
286
282
  }
287
- let Y = `${_()}-panel`, [X, Z] = g(!1), Q;
288
- m(() => {
289
- if (!X() || !C()) return;
283
+ let de = `${v()}-panel`, [X, fe] = _(!1), Z;
284
+ h(() => {
285
+ if (!X() || !w()) return;
290
286
  function e(e) {
291
- Q && !Q.contains(e.target) && Z(!1);
287
+ Z && !Z.contains(e.target) && fe(!1);
292
288
  }
293
289
  function t(e) {
294
- e.key === "Escape" && Z(!1);
290
+ e.key === "Escape" && fe(!1);
295
291
  }
296
- document.addEventListener("pointerdown", e), document.addEventListener("keydown", t), v(() => {
292
+ document.addEventListener("pointerdown", e), document.addEventListener("keydown", t), b(() => {
297
293
  document.removeEventListener("pointerdown", e), document.removeEventListener("keydown", t);
298
294
  });
299
295
  });
300
- let $;
301
- m(() => {
302
- $ && ($.indeterminate = l().length > 0 && !T());
296
+ let Q;
297
+ h(() => {
298
+ Q && (Q.indeterminate = l().length > 0 && !ee());
303
299
  });
304
- function ce(t) {
300
+ function pe(t) {
305
301
  e.onSelectionChange?.(t ? r().map(e.getRowId) : []);
306
302
  }
307
- function le(t, n) {
303
+ function me(t, n) {
308
304
  let r = e.getRowId(t), i = l(), a = n ? [...i, r] : i.filter((e) => e !== r);
309
305
  e.onSelectionChange?.(a);
310
306
  }
311
- function ue(t) {
307
+ function he(t) {
312
308
  return l().includes(e.getRowId(t));
313
309
  }
314
- function de(e) {
315
- return e.toggleable === !1 || k().has(e.key);
310
+ function ge(e) {
311
+ return e.toggleable === !1 || j().has(e.key);
316
312
  }
317
- function fe(t, n) {
313
+ function _e(t, n) {
318
314
  return e.getCell?.(t, n) ?? n.getValue?.(t) ?? null;
319
315
  }
320
316
  return (() => {
321
- var l = z(), m = l.firstChild, h = m.firstChild.firstChild, g = h.firstChild, _ = h.nextSibling;
317
+ var l = G(), m = l.firstChild, h = m.firstChild.firstChild, g = h.firstChild, _ = h.nextSibling;
322
318
  return a(l, n(p, {
323
319
  get when() {
324
- return C();
320
+ return w() || T.toArray().length > 0;
325
321
  },
326
322
  get children() {
327
- var t = I(), r = t.firstChild, o = r.firstChild;
328
- o.firstChild.nextSibling;
329
- var s = Q;
330
- return typeof s == "function" ? d(s, r) : Q = r, o.$$click = () => Z((e) => !e), c(o, "aria-controls", Y), a(o, () => e.columnCustomizerLabel ?? "Columns", null), a(r, n(p, {
323
+ var t = H();
324
+ return a(t, n(p, {
331
325
  get when() {
332
- return X();
326
+ return T.toArray().length > 0;
333
327
  },
334
328
  get children() {
335
- var t = F(), r = t.firstChild, o = r.nextSibling, s = o.nextSibling.firstChild, l = s.nextSibling;
336
- return c(t, "id", Y), a(r, () => e.columnCustomizerTitle ?? "Shown columns"), a(o, n(f, {
337
- get each() {
338
- return e.columns;
329
+ var e = z();
330
+ return a(e, T), e;
331
+ }
332
+ }), null), a(t, n(p, {
333
+ get when() {
334
+ return w();
335
+ },
336
+ get children() {
337
+ var t = V(), r = t.firstChild;
338
+ r.firstChild.nextSibling;
339
+ var o = Z;
340
+ return typeof o == "function" ? d(o, t) : Z = t, r.$$click = () => fe((e) => !e), c(r, "aria-controls", de), a(r, () => e.columnCustomizerLabel ?? "Columns", null), a(t, n(p, {
341
+ get when() {
342
+ return X();
339
343
  },
340
- children: (e) => (() => {
341
- var t = ne(), n = t.firstChild, r = n.firstChild;
342
- return r.addEventListener("change", (t) => ae(e.key, t.currentTarget.checked)), a(n, () => e.ariaLabel ?? e.label, null), i(() => r.disabled = e.toggleable === !1), i(() => r.checked = de(e)), t;
343
- })()
344
- })), s.$$click = oe, a(s, () => e.columnCustomizerShowAllLabel ?? "Show all"), l.$$click = se, a(l, () => e.columnCustomizerResetLabel ?? "Reset"), i(() => c(t, "aria-label", e.columnCustomizerTitle ?? "Customize columns")), t;
344
+ get children() {
345
+ var t = B(), r = t.firstChild, o = r.nextSibling, s = o.nextSibling.firstChild, l = s.nextSibling;
346
+ return c(t, "id", de), a(r, () => e.columnCustomizerTitle ?? "Shown columns"), a(o, n(f, {
347
+ get each() {
348
+ return e.columns;
349
+ },
350
+ children: (e) => (() => {
351
+ var t = K(), n = t.firstChild, r = n.firstChild;
352
+ return r.addEventListener("change", (t) => ce(e.key, t.currentTarget.checked)), a(n, () => e.ariaLabel ?? e.label, null), i(() => r.disabled = e.toggleable === !1), i(() => r.checked = ge(e)), t;
353
+ })()
354
+ })), s.$$click = le, a(s, () => e.columnCustomizerShowAllLabel ?? "Show all"), l.$$click = ue, a(l, () => e.columnCustomizerResetLabel ?? "Reset"), i(() => c(t, "aria-label", e.columnCustomizerTitle ?? "Customize columns")), t;
355
+ }
356
+ }), null), i(() => c(r, "aria-expanded", X())), t;
345
357
  }
346
- }), null), i(() => c(o, "aria-expanded", X())), t;
358
+ }), null), t;
347
359
  }
348
360
  }), m), a(g, n(p, {
349
361
  get when() {
350
- return w();
362
+ return E();
351
363
  },
352
364
  get children() {
353
- var t = L(), n = t.firstChild.nextSibling;
354
- n.addEventListener("change", (e) => ce(e.currentTarget.checked));
355
- var r = $;
356
- return typeof r == "function" ? d(r, n) : $ = n, i(() => c(n, "aria-label", e.selectionLabel ?? "Select all rows")), i(() => n.checked = T()), t;
365
+ var t = U(), n = t.firstChild.nextSibling;
366
+ n.addEventListener("change", (e) => pe(e.currentTarget.checked));
367
+ var r = Q;
368
+ return typeof r == "function" ? d(r, n) : Q = n, i(() => c(n, "aria-label", e.selectionLabel ?? "Select all rows")), i(() => n.checked = ee()), t;
357
369
  }
358
370
  }), null), a(g, n(f, {
359
371
  get each() {
360
- return A();
372
+ return M();
361
373
  },
362
374
  children: (r) => (() => {
363
- var s = V();
375
+ var s = ne();
364
376
  return a(s, n(p, {
365
377
  get when() {
366
378
  return o(() => !!r.sortable)() && (!u || e.onSort || e.onSortChange);
@@ -369,14 +381,14 @@ function q(e) {
369
381
  return r.label;
370
382
  },
371
383
  get children() {
372
- var e = B(), t = e.firstChild;
373
- return e.$$click = () => q(r.key), a(e, () => r.label, t), a(t, (() => {
374
- var e = o(() => x() === r.key);
375
- return () => e() ? S() === "asc" ? "▲" : "▼" : "";
384
+ var e = q(), t = e.firstChild;
385
+ return e.$$click = () => L(r.key), a(e, () => r.label, t), a(t, (() => {
386
+ var e = o(() => S() === r.key);
387
+ return () => e() ? C() === "asc" ? "▲" : "▼" : "";
376
388
  })()), e;
377
389
  }
378
390
  })), i((e) => {
379
- var n = r.class, i = r.sortable ? x() === r.key ? S() === "asc" ? "ascending" : "descending" : "none" : void 0;
391
+ var n = r.class, i = r.sortable ? S() === r.key ? C() === "asc" ? "ascending" : "descending" : "none" : void 0;
380
392
  return n !== e.e && t(s, e.e = n), i !== e.t && c(s, "aria-sort", e.t = i), e;
381
393
  }, {
382
394
  e: void 0,
@@ -388,36 +400,36 @@ function q(e) {
388
400
  return e.rowActions;
389
401
  },
390
402
  get children() {
391
- return R();
403
+ return W();
392
404
  }
393
405
  }), null), a(_, n(f, {
394
406
  get each() {
395
- return P();
407
+ return I();
396
408
  },
397
409
  children: (r) => (() => {
398
- var o = U();
410
+ var o = ae();
399
411
  return a(o, n(p, {
400
412
  get when() {
401
- return w();
413
+ return E();
402
414
  },
403
415
  get children() {
404
416
  var t = re(), n = t.firstChild;
405
- return n.addEventListener("change", (e) => le(r, e.currentTarget.checked)), i(() => c(n, "aria-label", `Select row ${e.getRowId(r)}`)), i(() => n.checked = ue(r)), t;
417
+ return n.addEventListener("change", (e) => me(r, e.currentTarget.checked)), i(() => c(n, "aria-label", `Select row ${e.getRowId(r)}`)), i(() => n.checked = he(r)), t;
406
418
  }
407
419
  }), null), a(o, n(f, {
408
420
  get each() {
409
- return A();
421
+ return M();
410
422
  },
411
423
  children: (e) => (() => {
412
- var n = H();
413
- return a(n, () => fe(r, e)), i(() => t(n, e.class)), n;
424
+ var n = ie();
425
+ return a(n, () => _e(r, e)), i(() => t(n, e.class)), n;
414
426
  })()
415
427
  }), null), a(o, n(p, {
416
428
  get when() {
417
429
  return e.rowActions;
418
430
  },
419
431
  get children() {
420
- var t = H();
432
+ var t = ie();
421
433
  return a(t, () => e.rowActions?.(r)), t;
422
434
  }
423
435
  }), null), o;
@@ -427,18 +439,344 @@ function q(e) {
427
439
  return s();
428
440
  },
429
441
  get children() {
430
- return e.loadingContent ?? W();
442
+ return e.loadingContent ?? oe();
431
443
  }
432
444
  }), null), a(l, n(p, {
433
445
  get when() {
434
- return o(() => !s())() && (e.empty === void 0 ? r().length === 0 : K(e.empty));
446
+ return o(() => !s())() && (e.empty === void 0 ? r().length === 0 : J(e.empty));
435
447
  },
436
448
  get children() {
437
- return e.emptyContent ?? G();
449
+ return e.emptyContent ?? se();
438
450
  }
439
451
  }), null), i(() => t(l, `data-table-wrap${e.class ? ` ${e.class}` : ""}`)), l;
440
452
  })();
441
453
  }
442
454
  r(["click"]);
443
455
  //#endregion
444
- export { P as Combobox, q as DataTable };
456
+ //#region src/filter-table.tsx
457
+ var ce = /*#__PURE__*/ u("<input class=filter-table-input type=text>"), le = /*#__PURE__*/ u("<ul class=filter-table-chips>"), ue = /*#__PURE__*/ u("<div class=filter-table-multi>"), de = /*#__PURE__*/ u("<li class=filter-table-chip><button type=button class=filter-table-chip-remove>"), X = /*#__PURE__*/ u("<div class=filter-table-search><input type=search class=filter-table-input>"), fe = /*#__PURE__*/ u("<ul class=filter-table-pills aria-label=\"Applied filters\"><li><button type=button class=\"filter-table-pill filter-table-pill-clear\">"), Z = /*#__PURE__*/ u("<div class=filter-table-toolbar>"), Q = /*#__PURE__*/ u("<li><button type=button class=filter-table-pill>"), pe = /*#__PURE__*/ u("<div><div class=filter-table-tabs role=tablist></div><div role=tabpanel></div><div role=tabpanel><form class=filter-table-form><div class=filter-table-form-actions><button type=button class=filter-table-button></button><button type=submit class=\"filter-table-button filter-table-button-primary\">"), me = /*#__PURE__*/ u("<span class=filter-table-badge>"), he = /*#__PURE__*/ u("<button type=button role=tab class=filter-table-tab>"), ge = /*#__PURE__*/ u("<legend class=filter-table-legend>"), _e = /*#__PURE__*/ u("<fieldset class=filter-table-fieldset>"), ve = /*#__PURE__*/ u("<div class=filter-table-field><label class=filter-table-label>"), ye = "q";
458
+ function be(e) {
459
+ return typeof e == "function" ? e() : e;
460
+ }
461
+ function xe(e) {
462
+ return Array.isArray(e) ? e.length > 0 : (e ?? "").trim() !== "";
463
+ }
464
+ function Se(e) {
465
+ let t = {};
466
+ for (let [n, r] of Object.entries(e)) xe(r) && (t[n] = Array.isArray(r) ? r : r.trim());
467
+ return t;
468
+ }
469
+ function $(e) {
470
+ return typeof e == "string" || typeof e == "number" || typeof e == "boolean" ? String(e) : "";
471
+ }
472
+ function Ce(e) {
473
+ let [r, o] = S(e, [
474
+ "rows",
475
+ "filters",
476
+ "filterValues",
477
+ "defaultFilterValues",
478
+ "onFilterValuesChange",
479
+ "manualFiltering",
480
+ "quickSearch",
481
+ "getSearchText",
482
+ "quickSearchLabel",
483
+ "resultsLabel",
484
+ "filtersLabel",
485
+ "applyLabel",
486
+ "resetLabel",
487
+ "clearAllLabel",
488
+ "anyLabel",
489
+ "yesLabel",
490
+ "noLabel",
491
+ "class"
492
+ ]), l = g(() => be(r.rows)), [u, d] = _(Se(r.defaultFilterValues ?? {})), m = g(() => r.filterValues === void 0 ? u() : Se(be(r.filterValues)));
493
+ function b(e) {
494
+ let t = Se(e);
495
+ r.filterValues === void 0 && d(t), r.onFilterValuesChange?.(t);
496
+ }
497
+ function x(e, t) {
498
+ b({
499
+ ...m(),
500
+ [e]: t
501
+ });
502
+ }
503
+ let C = () => $(m()[ye]), w = g(() => r.filters.filter((e) => xe(m()[e.key])));
504
+ function T(e, t) {
505
+ return t.getValue ? t.getValue(e) : e[t.key];
506
+ }
507
+ function E(e, t, n) {
508
+ if (t.match) return t.match(e, n);
509
+ let r = T(e, t);
510
+ if (t.type === "select") {
511
+ let e = Array.isArray(n) ? n : [n];
512
+ return (Array.isArray(r) ? r : [r]).some((t) => e.includes($(t)));
513
+ }
514
+ return t.type === "boolean" ? !!r == (n === "true") : $(r).toLowerCase().includes($(n).toLowerCase());
515
+ }
516
+ function ee(e) {
517
+ return r.getSearchText ? r.getSearchText(e) : o.columns.map((t) => $(t.sortValue?.(e) ?? e[t.key])).join(" ");
518
+ }
519
+ let D = g(() => {
520
+ if (r.manualFiltering) return l();
521
+ let e = C().toLowerCase(), t = w();
522
+ return l().filter((n) => (e === "" || ee(n).toLowerCase().includes(e)) && t.every((e) => E(n, e, m()[e.key])));
523
+ });
524
+ function A(e) {
525
+ if (e.options) return e.options;
526
+ let t = /* @__PURE__ */ new Set();
527
+ for (let n of l()) {
528
+ let r = T(n, e);
529
+ for (let e of Array.isArray(r) ? r : [r]) {
530
+ let n = $(e);
531
+ n !== "" && t.add(n);
532
+ }
533
+ }
534
+ return [...t].sort((e, t) => e.localeCompare(t, void 0, { numeric: !0 })).map((e) => ({
535
+ value: e,
536
+ label: e
537
+ }));
538
+ }
539
+ function j(e, t) {
540
+ return e.type === "boolean" ? t === "true" ? r.yesLabel ?? "Yes" : r.noLabel ?? "No" : e.type === "select" ? A(e).find((e) => String(e.value) === t)?.label ?? t : t;
541
+ }
542
+ let M = g(() => w().flatMap((e) => {
543
+ let t = m()[e.key];
544
+ return (Array.isArray(t) ? t : [t]).map((t) => ({
545
+ filter: e,
546
+ item: t,
547
+ text: `${e.label}: ${j(e, t)}`
548
+ }));
549
+ }));
550
+ function te(e, t) {
551
+ let n = m()[e.key];
552
+ x(e.key, Array.isArray(n) ? n.filter((e) => e !== t) : "");
553
+ }
554
+ function N() {
555
+ b({ [ye]: C() });
556
+ }
557
+ let [P, F] = _(m());
558
+ h(y(m, (e) => F(e)));
559
+ function I(e) {
560
+ return P()[e];
561
+ }
562
+ function L(e, t) {
563
+ F((n) => ({
564
+ ...n,
565
+ [e]: t
566
+ }));
567
+ }
568
+ let z = g(() => {
569
+ let e = /* @__PURE__ */ new Map([[void 0, []]]);
570
+ for (let t of r.filters) e.set(t.group, [...e.get(t.group) ?? [], t]);
571
+ return [...e.entries()].filter(([, e]) => e.length > 0).map(([e, t]) => ({
572
+ name: e,
573
+ filters: t
574
+ }));
575
+ }), B = v(), V = ["results", "filters"], [H, U] = _("results"), W = (e) => `${B}-tab-${e}`, G = (e) => `${B}-panel-${e}`, K = (e) => `${B}-filter-${e}`;
576
+ function q(e) {
577
+ e === "filters" && F(m()), U(e);
578
+ }
579
+ function ne(e) {
580
+ let t = e.key === "ArrowRight" ? 1 : e.key === "ArrowLeft" ? -1 : 0;
581
+ if (t === 0) return;
582
+ e.preventDefault();
583
+ let n = V[(V.indexOf(H()) + t + V.length) % V.length];
584
+ q(n), document.getElementById(W(n))?.focus();
585
+ }
586
+ function re(e) {
587
+ e.preventDefault(), b(P()), U("results");
588
+ }
589
+ function ie() {
590
+ N(), U("results");
591
+ }
592
+ function ae(e) {
593
+ if (e.type === "text") return (() => {
594
+ var t = ce();
595
+ return t.$$input = (t) => L(e.key, t.currentTarget.value), i((n) => {
596
+ var r = K(e.key), i = e.placeholder;
597
+ return r !== n.e && c(t, "id", n.e = r), i !== n.t && c(t, "placeholder", n.t = i), n;
598
+ }, {
599
+ e: void 0,
600
+ t: void 0
601
+ }), i(() => t.value = $(I(e.key))), t;
602
+ })();
603
+ if (e.type === "boolean") return n(R, {
604
+ get id() {
605
+ return K(e.key);
606
+ },
607
+ get value() {
608
+ return $(I(e.key));
609
+ },
610
+ onChange: (t) => L(e.key, t),
611
+ get emptyLabel() {
612
+ return r.anyLabel ?? "Any";
613
+ },
614
+ get options() {
615
+ return [{
616
+ value: "true",
617
+ label: r.yesLabel ?? "Yes"
618
+ }, {
619
+ value: "false",
620
+ label: r.noLabel ?? "No"
621
+ }];
622
+ }
623
+ });
624
+ let t = () => {
625
+ let t = I(e.key);
626
+ return Array.isArray(t) ? t : [];
627
+ };
628
+ return (() => {
629
+ var o = ue();
630
+ return a(o, n(R, {
631
+ get id() {
632
+ return K(e.key);
633
+ },
634
+ value: "",
635
+ onChange: (n) => L(e.key, [...t(), n]),
636
+ get options() {
637
+ return A(e).filter((e) => !t().includes(String(e.value)));
638
+ },
639
+ get placeholder() {
640
+ return e.placeholder ?? r.anyLabel ?? "Any";
641
+ }
642
+ }), null), a(o, n(p, {
643
+ get when() {
644
+ return t().length > 0;
645
+ },
646
+ get children() {
647
+ var r = le();
648
+ return a(r, n(f, {
649
+ get each() {
650
+ return t();
651
+ },
652
+ children: (r) => (() => {
653
+ var o = de(), s = o.firstChild;
654
+ return a(o, () => j(e, r), s), s.$$click = () => L(e.key, t().filter((e) => e !== r)), a(s, n(k, {
655
+ size: 12,
656
+ "aria-hidden": "true"
657
+ })), i(() => c(s, "aria-label", `Remove ${j(e, r)}`)), o;
658
+ })()
659
+ })), r;
660
+ }
661
+ }), null), o;
662
+ })();
663
+ }
664
+ let oe = (() => {
665
+ var e = Z();
666
+ return a(e, n(p, {
667
+ get when() {
668
+ return r.quickSearch !== !1;
669
+ },
670
+ get children() {
671
+ var e = X(), t = e.firstChild;
672
+ return a(e, n(O, {
673
+ class: "filter-table-search-icon",
674
+ size: 16,
675
+ "aria-hidden": "true"
676
+ }), t), t.$$input = (e) => x(ye, e.currentTarget.value), i((e) => {
677
+ var n = r.quickSearchLabel ?? "Quick search", i = r.quickSearchLabel ?? "Quick search";
678
+ return n !== e.e && c(t, "aria-label", e.e = n), i !== e.t && c(t, "placeholder", e.t = i), e;
679
+ }, {
680
+ e: void 0,
681
+ t: void 0
682
+ }), i(() => t.value = C()), e;
683
+ }
684
+ }), null), a(e, n(p, {
685
+ get when() {
686
+ return M().length > 0;
687
+ },
688
+ get children() {
689
+ var e = fe(), t = e.firstChild, o = t.firstChild;
690
+ return a(e, n(f, {
691
+ get each() {
692
+ return M();
693
+ },
694
+ children: (e) => (() => {
695
+ var t = Q(), r = t.firstChild;
696
+ return r.$$click = () => te(e.filter, e.item), a(r, () => e.text, null), a(r, n(k, {
697
+ size: 12,
698
+ "aria-hidden": "true"
699
+ }), null), i(() => c(r, "aria-label", `Remove filter ${e.text}`)), t;
700
+ })()
701
+ }), t), o.$$click = N, a(o, () => r.clearAllLabel ?? "Clear all"), e;
702
+ }
703
+ }), null), e;
704
+ })();
705
+ return (() => {
706
+ var e = pe(), l = e.firstChild, u = l.nextSibling, d = u.nextSibling, m = d.firstChild, h = m.firstChild, g = h.firstChild, _ = g.nextSibling;
707
+ return a(l, n(f, {
708
+ each: V,
709
+ children: (e) => (() => {
710
+ var t = he();
711
+ return t.$$keydown = ne, t.$$click = () => q(e), a(t, () => e === "results" ? r.resultsLabel ?? "Results" : r.filtersLabel ?? "Filters", null), a(t, n(p, {
712
+ get when() {
713
+ return e === "results" || w().length > 0;
714
+ },
715
+ get children() {
716
+ var t = me();
717
+ return a(t, () => e === "results" ? D().length : w().length), t;
718
+ }
719
+ }), null), i((n) => {
720
+ var r = W(e), i = H() === e, a = G(e), o = H() === e ? 0 : -1;
721
+ return r !== n.e && c(t, "id", n.e = r), i !== n.t && c(t, "aria-selected", n.t = i), a !== n.a && c(t, "aria-controls", n.a = a), o !== n.o && c(t, "tabindex", n.o = o), n;
722
+ }, {
723
+ e: void 0,
724
+ t: void 0,
725
+ a: void 0,
726
+ o: void 0
727
+ }), t;
728
+ })()
729
+ })), a(u, n(Y, s(o, {
730
+ rows: D,
731
+ toolbar: oe
732
+ }))), m.addEventListener("submit", re), a(m, n(f, {
733
+ get each() {
734
+ return z();
735
+ },
736
+ children: (e) => (() => {
737
+ var t = _e();
738
+ return a(t, n(p, {
739
+ get when() {
740
+ return e.name;
741
+ },
742
+ get children() {
743
+ var t = ge();
744
+ return a(t, () => e.name), t;
745
+ }
746
+ }), null), a(t, n(f, {
747
+ get each() {
748
+ return e.filters;
749
+ },
750
+ children: (e) => (() => {
751
+ var t = ve(), n = t.firstChild;
752
+ return a(n, () => e.label), a(t, () => ae(e), null), i(() => c(n, "for", K(e.key))), t;
753
+ })()
754
+ }), null), t;
755
+ })()
756
+ }), h), g.$$click = ie, a(g, n(k, {
757
+ size: 16,
758
+ "aria-hidden": "true"
759
+ }), null), a(g, () => r.resetLabel ?? "Reset", null), a(_, n(O, {
760
+ size: 16,
761
+ "aria-hidden": "true"
762
+ }), null), a(_, () => r.applyLabel ?? "Search", null), i((n) => {
763
+ var i = `filter-table${r.class ? ` ${r.class}` : ""}`, a = G("results"), o = W("results"), s = H() !== "results", l = G("filters"), f = W("filters"), p = H() !== "filters";
764
+ return i !== n.e && t(e, n.e = i), a !== n.t && c(u, "id", n.t = a), o !== n.a && c(u, "aria-labelledby", n.a = o), s !== n.o && (u.hidden = n.o = s), l !== n.i && c(d, "id", n.i = l), f !== n.n && c(d, "aria-labelledby", n.n = f), p !== n.s && (d.hidden = n.s = p), n;
765
+ }, {
766
+ e: void 0,
767
+ t: void 0,
768
+ a: void 0,
769
+ o: void 0,
770
+ i: void 0,
771
+ n: void 0,
772
+ s: void 0
773
+ }), e;
774
+ })();
775
+ }
776
+ r([
777
+ "input",
778
+ "click",
779
+ "keydown"
780
+ ]);
781
+ //#endregion
782
+ export { R as Combobox, Y as DataTable, Ce as FilterTable };
package/dist/styles.css CHANGED
@@ -9,10 +9,17 @@
9
9
 
10
10
  .data-table-toolbar {
11
11
  display: flex;
12
+ align-items: flex-start;
12
13
  justify-content: flex-end;
14
+ gap: 0.5rem;
13
15
  margin-bottom: 0.5rem;
14
16
  }
15
17
 
18
+ .data-table-toolbar-start {
19
+ flex: 1;
20
+ min-width: 0;
21
+ }
22
+
16
23
  .data-table-customizer {
17
24
  position: relative;
18
25
  }
@@ -355,3 +362,288 @@
355
362
  display: flex;
356
363
  align-items: center;
357
364
  }
365
+
366
+ /* FilterTable: Results/Filters tabs around a DataTable. */
367
+ .filter-table-tabs {
368
+ display: flex;
369
+ gap: 0.25rem;
370
+ margin-bottom: 0.75rem;
371
+ border-bottom: 1px solid
372
+ var(--filter-table-border, var(--border, light-dark(#d0d0d0, #3a3e45)));
373
+ }
374
+
375
+ .filter-table-tab {
376
+ display: inline-flex;
377
+ align-items: center;
378
+ gap: 0.4rem;
379
+ margin-bottom: -1px;
380
+ padding: 0.5rem 0.875rem;
381
+ border: 1px solid transparent;
382
+ border-radius: 0.375rem 0.375rem 0 0;
383
+ background: transparent;
384
+ color: var(
385
+ --filter-table-muted,
386
+ var(--text-secondary, light-dark(#616161, #9b9da5))
387
+ );
388
+ font: inherit;
389
+ cursor: pointer;
390
+ }
391
+
392
+ .filter-table-tab:hover {
393
+ background: transparent;
394
+ color: inherit;
395
+ }
396
+
397
+ .filter-table-tab[aria-selected="true"] {
398
+ border-color: var(
399
+ --filter-table-border,
400
+ var(--border, light-dark(#d0d0d0, #3a3e45))
401
+ )
402
+ var(--filter-table-border, var(--border, light-dark(#d0d0d0, #3a3e45)))
403
+ transparent;
404
+ background: var(
405
+ --filter-table-bg,
406
+ var(--surface, light-dark(#ffffff, #1d2024))
407
+ );
408
+ color: inherit;
409
+ font-weight: 600;
410
+ }
411
+
412
+ .filter-table-badge {
413
+ min-width: 1.25rem;
414
+ padding: 0.05rem 0.4rem;
415
+ border-radius: 999px;
416
+ background: var(
417
+ --filter-table-accent,
418
+ var(--primary, light-dark(#1a66d6, #6ea8fe))
419
+ );
420
+ color: light-dark(#ffffff, #10141a);
421
+ font-size: 0.75em;
422
+ font-weight: 600;
423
+ text-align: center;
424
+ }
425
+
426
+ .filter-table-toolbar {
427
+ display: flex;
428
+ flex-wrap: wrap;
429
+ align-items: center;
430
+ gap: 0.5rem;
431
+ }
432
+
433
+ .filter-table-input {
434
+ box-sizing: border-box;
435
+ width: 100%;
436
+ padding: 0.375rem 0.5rem;
437
+ border: 1px solid
438
+ var(--filter-table-border, var(--border, light-dark(#d0d0d0, #3a3e45)));
439
+ border-radius: 0.375rem;
440
+ background: var(
441
+ --filter-table-bg,
442
+ var(--surface, light-dark(#ffffff, #1d2024))
443
+ );
444
+ color: inherit;
445
+ font: inherit;
446
+ }
447
+
448
+ .filter-table-search {
449
+ position: relative;
450
+ flex: 0 1 16rem;
451
+ min-width: 10rem;
452
+ }
453
+
454
+ .filter-table-search .filter-table-input {
455
+ padding-left: 1.9rem;
456
+ }
457
+
458
+ .filter-table-search-icon {
459
+ position: absolute;
460
+ top: 50%;
461
+ left: 0.55rem;
462
+ transform: translateY(-50%);
463
+ color: var(
464
+ --filter-table-muted,
465
+ var(--text-secondary, light-dark(#616161, #9b9da5))
466
+ );
467
+ pointer-events: none;
468
+ }
469
+
470
+ .filter-table-pills,
471
+ .filter-table-chips {
472
+ display: flex;
473
+ flex-wrap: wrap;
474
+ gap: 0.375rem;
475
+ margin: 0;
476
+ padding: 0;
477
+ list-style: none;
478
+ }
479
+
480
+ .filter-table-pill,
481
+ .filter-table-chip {
482
+ display: inline-flex;
483
+ align-items: center;
484
+ gap: 0.3rem;
485
+ padding: 0.2rem 0.55rem;
486
+ border: 1px solid transparent;
487
+ border-radius: 999px;
488
+ background: var(
489
+ --filter-table-pill-bg,
490
+ light-dark(rgb(26 102 214 / 12%), rgb(110 168 254 / 16%))
491
+ );
492
+ color: var(
493
+ --filter-table-accent,
494
+ var(--primary, light-dark(#1a66d6, #6ea8fe))
495
+ );
496
+ font: inherit;
497
+ font-size: 0.8125rem;
498
+ line-height: 1.4;
499
+ }
500
+
501
+ .filter-table-pill {
502
+ cursor: pointer;
503
+ }
504
+
505
+ .filter-table-pill:hover {
506
+ border-color: currentColor;
507
+ background: var(
508
+ --filter-table-pill-bg,
509
+ light-dark(rgb(26 102 214 / 12%), rgb(110 168 254 / 16%))
510
+ );
511
+ }
512
+
513
+ .filter-table-pill-clear {
514
+ background: transparent;
515
+ color: var(
516
+ --filter-table-muted,
517
+ var(--text-secondary, light-dark(#616161, #9b9da5))
518
+ );
519
+ }
520
+
521
+ .filter-table-pill-clear:hover {
522
+ background: transparent;
523
+ }
524
+
525
+ .filter-table-chip-remove {
526
+ display: inline-flex;
527
+ padding: 0;
528
+ border: none;
529
+ background: transparent;
530
+ color: inherit;
531
+ cursor: pointer;
532
+ }
533
+
534
+ .filter-table-chip-remove:hover {
535
+ background: transparent;
536
+ }
537
+
538
+ .filter-table-multi {
539
+ display: grid;
540
+ gap: 0.375rem;
541
+ min-width: 0;
542
+ }
543
+
544
+ .filter-table-form {
545
+ /* Label column width and gap; group headings are indented by both so they
546
+ line up with the inputs. */
547
+ --filter-table-label-width: 9rem;
548
+ --filter-table-label-gap: 1rem;
549
+ display: grid;
550
+ gap: 1.25rem;
551
+ max-width: 40rem;
552
+ }
553
+
554
+ /* Groups are plain sections: a muted heading, separated by a thin rule. */
555
+ .filter-table-fieldset {
556
+ display: grid;
557
+ gap: 0.5rem;
558
+ min-width: 0;
559
+ margin: 0;
560
+ padding: 0;
561
+ border: none;
562
+ }
563
+
564
+ .filter-table-fieldset + .filter-table-fieldset {
565
+ padding-top: 1.25rem;
566
+ border-top: 1px solid
567
+ var(--filter-table-border, var(--border, light-dark(#d0d0d0, #3a3e45)));
568
+ }
569
+
570
+ /* Floated so it lays out as a regular grid item instead of on the border. */
571
+ .filter-table-legend {
572
+ float: left;
573
+ width: 100%;
574
+ margin-bottom: 0.25rem;
575
+ padding: 0 0 0
576
+ calc(var(--filter-table-label-width) + var(--filter-table-label-gap));
577
+ box-sizing: border-box;
578
+ color: var(
579
+ --filter-table-muted,
580
+ var(--text-secondary, light-dark(#616161, #9b9da5))
581
+ );
582
+ font-size: 0.75rem;
583
+ font-weight: 600;
584
+ letter-spacing: 0.04em;
585
+ text-transform: uppercase;
586
+ }
587
+
588
+ /* Labels right-aligned in a column next to their inputs. */
589
+ .filter-table-field {
590
+ display: grid;
591
+ grid-template-columns: var(--filter-table-label-width) minmax(0, 1fr);
592
+ align-items: start;
593
+ gap: var(--filter-table-label-gap);
594
+ }
595
+
596
+ .filter-table-label {
597
+ padding-top: calc(0.375rem + 1px);
598
+ }
599
+
600
+ .filter-table-form-actions {
601
+ display: flex;
602
+ justify-content: flex-end;
603
+ padding-top: 1.25rem;
604
+ border-top: 1px solid
605
+ var(--filter-table-border, var(--border, light-dark(#d0d0d0, #3a3e45)));
606
+ gap: 0.5rem;
607
+ }
608
+
609
+ .filter-table-button {
610
+ display: inline-flex;
611
+ align-items: center;
612
+ gap: 0.375rem;
613
+ }
614
+
615
+ .filter-table-button-primary {
616
+ border-color: var(
617
+ --filter-table-accent,
618
+ var(--primary, light-dark(#1a66d6, #6ea8fe))
619
+ );
620
+ background: var(
621
+ --filter-table-accent,
622
+ var(--primary, light-dark(#1a66d6, #6ea8fe))
623
+ );
624
+ color: light-dark(#ffffff, #10141a);
625
+ font-weight: 600;
626
+ }
627
+
628
+ .filter-table-button-primary:hover {
629
+ filter: brightness(1.1);
630
+ background: var(
631
+ --filter-table-accent,
632
+ var(--primary, light-dark(#1a66d6, #6ea8fe))
633
+ );
634
+ }
635
+
636
+ @media (max-width: 640px) {
637
+ .filter-table-field {
638
+ grid-template-columns: 1fr;
639
+ gap: 0.25rem;
640
+ }
641
+
642
+ .filter-table-label {
643
+ padding-top: 0;
644
+ }
645
+
646
+ .filter-table-legend {
647
+ padding-left: 0;
648
+ }
649
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@serkonda7/solid-components",
3
- "version": "0.0.8",
3
+ "version": "0.1.0",
4
4
  "description": "Reusable components for SolidJS",
5
5
  "license": "MIT",
6
6
  "author": "serkonda7",
@@ -42,15 +42,15 @@
42
42
  "solid-js": ">=1.9.0"
43
43
  },
44
44
  "devDependencies": {
45
- "@biomejs/biome": "2.5.14",
46
- "@tabler/icons-solidjs": "~3.48.0",
45
+ "@biomejs/biome": "2.5.15",
46
+ "@tabler/icons-solidjs": "~3.49.0",
47
47
  "@types/bun": "1.4.2",
48
- "@vitest/browser-playwright": "^5.0.2",
49
- "playwright": "~1.63.0",
50
- "solid-js": "~1.9.15",
48
+ "@vitest/browser-playwright": "~5.0.4",
49
+ "playwright": "~1.64.0",
50
+ "solid-js": "~1.9.17",
51
51
  "typescript": "~7.0.2",
52
- "vite": "~8.3.0",
52
+ "vite": "~8.3.4",
53
53
  "vite-plugin-solid": "~2.11.14",
54
- "vitest": "~5.0.2"
54
+ "vitest": "~5.0.4"
55
55
  }
56
56
  }