@serkonda7/solid-components 0.0.6 → 0.0.8
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 +1 -0
- package/dist/combobox.d.ts +48 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +356 -121
- package/dist/styles.css +218 -0
- package/package.json +4 -3
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
|
+
- `Combobox` - searchable, accessible dropdown with keyboard navigation, option icons, a detail column, and an optional "Add …" entry.
|
|
29
30
|
|
|
30
31
|
For the full API, examples, and agent notes, see [docs.md](docs.md).
|
|
31
32
|
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { Component, JSX } from 'solid-js';
|
|
2
|
+
/** Icon component rendered before an option label, e.g. one from `@tabler/icons-solidjs`. */
|
|
3
|
+
export type ComboboxIcon = Component<{
|
|
4
|
+
size?: number;
|
|
5
|
+
}>;
|
|
6
|
+
/** One `Combobox` entry. */
|
|
7
|
+
export interface ComboboxOption {
|
|
8
|
+
value: number | string;
|
|
9
|
+
label: string;
|
|
10
|
+
/** Secondary text (e.g. the manufacturer), shown muted in a column after the labels. */
|
|
11
|
+
detail?: string;
|
|
12
|
+
/** Glyph shown before the label, in the list and in the closed input. */
|
|
13
|
+
icon?: ComboboxIcon;
|
|
14
|
+
}
|
|
15
|
+
export interface ComboboxProps {
|
|
16
|
+
/** Input id, for pairing with an external `<label for>`. Generated when omitted. */
|
|
17
|
+
id?: string;
|
|
18
|
+
/** Selected option value as a string; `''` means nothing (or the empty entry) is selected. */
|
|
19
|
+
value: string;
|
|
20
|
+
/** Omitted on read-only comboboxes. */
|
|
21
|
+
onChange?: (value: string) => void;
|
|
22
|
+
options: ComboboxOption[];
|
|
23
|
+
/** Label of the empty (`''`) first entry; omit for no empty choice. */
|
|
24
|
+
emptyLabel?: string;
|
|
25
|
+
required?: boolean;
|
|
26
|
+
disabled?: boolean;
|
|
27
|
+
autofocus?: boolean;
|
|
28
|
+
ariaLabel?: string;
|
|
29
|
+
describedBy?: string;
|
|
30
|
+
/** Called whenever the list opens, e.g. to refetch the options. */
|
|
31
|
+
onOpen?: () => unknown;
|
|
32
|
+
/** Pins an "Add …" entry at the end of the list; receives the trimmed search text. */
|
|
33
|
+
onAdd?: (query: string) => void;
|
|
34
|
+
/** Text of the pinned add entry. Defaults to `Add`. */
|
|
35
|
+
addLabel?: string;
|
|
36
|
+
/** Placeholder while open and nothing is selected. Defaults to `Search`. */
|
|
37
|
+
searchLabel?: string;
|
|
38
|
+
/** Shown when no option matches the search. Defaults to `No matching objects`. */
|
|
39
|
+
noMatchesLabel?: string;
|
|
40
|
+
class?: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Searchable dropdown of `options`, with an optional leading empty choice.
|
|
44
|
+
* A text combobox: typing filters the options by label and detail, arrow keys
|
|
45
|
+
* move the highlight (wrapping around), Enter picks it, Escape closes. The
|
|
46
|
+
* input shows the selected label while closed; the value sits in `data-value`.
|
|
47
|
+
*/
|
|
48
|
+
export declare function Combobox(props: ComboboxProps): JSX.Element;
|
package/dist/index.d.ts
CHANGED
|
@@ -4,4 +4,5 @@
|
|
|
4
4
|
* Add components here as they are implemented so consumers can import them
|
|
5
5
|
* from the package root.
|
|
6
6
|
*/
|
|
7
|
+
export { Combobox, type ComboboxIcon, type ComboboxOption, type ComboboxProps, } from './combobox';
|
|
7
8
|
export { DataTable, type DataTableColumn, type DataTableProps, type DataTableSort, type DataTableSortDirection, } from './data-table';
|
package/dist/index.js
CHANGED
|
@@ -1,209 +1,444 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { For as
|
|
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";
|
|
3
|
+
//#region node_modules/@tabler/icons-solidjs/dist/source/defaultAttributes.js
|
|
4
|
+
var x = {
|
|
5
|
+
outline: {
|
|
6
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
7
|
+
width: 24,
|
|
8
|
+
height: 24,
|
|
9
|
+
viewBox: "0 0 24 24",
|
|
10
|
+
fill: "none",
|
|
11
|
+
stroke: "currentColor",
|
|
12
|
+
"stroke-width": 2,
|
|
13
|
+
"stroke-linecap": "round",
|
|
14
|
+
"stroke-linejoin": "round"
|
|
15
|
+
},
|
|
16
|
+
filled: {
|
|
17
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
18
|
+
width: 24,
|
|
19
|
+
height: 24,
|
|
20
|
+
viewBox: "0 0 24 24",
|
|
21
|
+
fill: "currentColor",
|
|
22
|
+
stroke: "none"
|
|
23
|
+
}
|
|
24
|
+
}, S = /*#__PURE__*/ u("<svg>"), C = /*#__PURE__*/ u("<title>"), w = (t, r, i, c) => {
|
|
25
|
+
let u = (i) => {
|
|
26
|
+
let [u, d] = b(i, [
|
|
27
|
+
"color",
|
|
28
|
+
"size",
|
|
29
|
+
"stroke",
|
|
30
|
+
"strokeWidth",
|
|
31
|
+
"title",
|
|
32
|
+
"children",
|
|
33
|
+
"class"
|
|
34
|
+
]), f = x[t], p = u.stroke ?? u.strokeWidth;
|
|
35
|
+
return (() => {
|
|
36
|
+
var i = S();
|
|
37
|
+
return l(i, s(f, d, {
|
|
38
|
+
get width() {
|
|
39
|
+
return o(() => u.size != null)() ? u.size : f.width;
|
|
40
|
+
},
|
|
41
|
+
get height() {
|
|
42
|
+
return o(() => u.size != null)() ? u.size : f.height;
|
|
43
|
+
},
|
|
44
|
+
get class() {
|
|
45
|
+
return `tabler-icon tabler-icon-${r}${u.class ? ` ${u.class}` : ""}`;
|
|
46
|
+
}
|
|
47
|
+
}, () => t === "filled" ? { fill: u.color == null ? "currentColor" : u.color } : {
|
|
48
|
+
stroke: u.color == null ? "currentColor" : u.color,
|
|
49
|
+
"stroke-width": p ?? f["stroke-width"]
|
|
50
|
+
}), !0, !0), a(i, (() => {
|
|
51
|
+
var e = o(() => u.title != null);
|
|
52
|
+
return () => e() && (() => {
|
|
53
|
+
var e = C();
|
|
54
|
+
return a(e, () => u.title), e;
|
|
55
|
+
})();
|
|
56
|
+
})(), null), a(i, () => c.map(([t, r]) => n(e, s({ component: t }, r))), null), a(i, () => u.children, null), i;
|
|
57
|
+
})();
|
|
58
|
+
};
|
|
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 : [{
|
|
63
|
+
value: "",
|
|
64
|
+
label: r.emptyLabel
|
|
65
|
+
}, ...r.options]), R = h(() => r.value === "" ? void 0 : L().find((e) => String(e.value) === r.value)), z = h(() => {
|
|
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(() => {
|
|
70
|
+
r.autofocus === !0 && s?.focus();
|
|
71
|
+
}), m(() => {
|
|
72
|
+
S() && l?.querySelector(`[data-index="${F()}"]`)?.scrollIntoView({ block: "nearest" });
|
|
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()) {
|
|
82
|
+
r.onAdd(w().trim());
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
let t = z()[e];
|
|
86
|
+
t && String(t.value) !== r.value && r.onChange?.(String(t.value));
|
|
87
|
+
}
|
|
88
|
+
function W(e) {
|
|
89
|
+
let t = V();
|
|
90
|
+
S() ? t > 0 && I((F() + e + t) % t) : H();
|
|
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)));
|
|
98
|
+
}
|
|
99
|
+
let K = () => S() ? R()?.label ?? r.emptyLabel ?? r.searchLabel ?? "Search" : r.emptyLabel;
|
|
100
|
+
return (() => {
|
|
101
|
+
var u = k(), m = u.firstChild;
|
|
102
|
+
m.addEventListener("blur", () => C(!1)), m.$$keydown = G, m.$$input = (e) => {
|
|
103
|
+
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, {
|
|
108
|
+
get when() {
|
|
109
|
+
return o(() => !S())() && R()?.icon;
|
|
110
|
+
},
|
|
111
|
+
children: (t) => (() => {
|
|
112
|
+
var r = A();
|
|
113
|
+
return a(r, n(e, {
|
|
114
|
+
get component() {
|
|
115
|
+
return t();
|
|
116
|
+
},
|
|
117
|
+
size: 14
|
|
118
|
+
})), r;
|
|
119
|
+
})()
|
|
120
|
+
}), null), a(u, n(p, {
|
|
121
|
+
get when() {
|
|
122
|
+
return o(() => !S())() && R()?.detail;
|
|
123
|
+
},
|
|
124
|
+
get children() {
|
|
125
|
+
var e = D(), t = e.firstChild, n = t.nextSibling;
|
|
126
|
+
return a(t, () => R()?.label), a(n, () => R()?.detail), e;
|
|
127
|
+
}
|
|
128
|
+
}), null), a(u, n(T, {
|
|
129
|
+
class: "combobox-chevron",
|
|
130
|
+
size: 16,
|
|
131
|
+
"aria-hidden": "true"
|
|
132
|
+
}), null), a(u, n(p, {
|
|
133
|
+
get when() {
|
|
134
|
+
return S();
|
|
135
|
+
},
|
|
136
|
+
get children() {
|
|
137
|
+
var t = O(), o = l;
|
|
138
|
+
return typeof o == "function" ? d(o, t) : l = t, a(t, n(f, {
|
|
139
|
+
get each() {
|
|
140
|
+
return z();
|
|
141
|
+
},
|
|
142
|
+
get fallback() {
|
|
143
|
+
return (() => {
|
|
144
|
+
var e = te();
|
|
145
|
+
return a(e, () => r.noMatchesLabel ?? "No matching objects"), e;
|
|
146
|
+
})();
|
|
147
|
+
},
|
|
148
|
+
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, {
|
|
151
|
+
get when() {
|
|
152
|
+
return t.icon;
|
|
153
|
+
},
|
|
154
|
+
children: (t) => (() => {
|
|
155
|
+
var r = N();
|
|
156
|
+
return a(r, n(e, {
|
|
157
|
+
get component() {
|
|
158
|
+
return t();
|
|
159
|
+
},
|
|
160
|
+
size: 14
|
|
161
|
+
})), r;
|
|
162
|
+
})()
|
|
163
|
+
}), null), a(l, () => t.label, null), a(s, n(p, {
|
|
164
|
+
get when() {
|
|
165
|
+
return t.detail;
|
|
166
|
+
},
|
|
167
|
+
get children() {
|
|
168
|
+
var e = j();
|
|
169
|
+
return a(e, () => t.detail), e;
|
|
170
|
+
}
|
|
171
|
+
}), null), i((e) => {
|
|
172
|
+
var n = x(o()), i = o(), a = String(t.value) === r.value, l = o() === F(), u = t.value === "";
|
|
173
|
+
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
|
+
}, {
|
|
175
|
+
e: void 0,
|
|
176
|
+
t: void 0,
|
|
177
|
+
a: void 0,
|
|
178
|
+
o: void 0,
|
|
179
|
+
i: void 0
|
|
180
|
+
}), s;
|
|
181
|
+
})()
|
|
182
|
+
}), null), a(t, n(p, {
|
|
183
|
+
get when() {
|
|
184
|
+
return r.onAdd;
|
|
185
|
+
},
|
|
186
|
+
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, {
|
|
189
|
+
size: 14,
|
|
190
|
+
"aria-hidden": "true"
|
|
191
|
+
}), null), a(e, () => r.addLabel ?? "Add", null), i((t) => {
|
|
192
|
+
var n = x(B()), r = B(), i = B() === F();
|
|
193
|
+
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
|
+
}, {
|
|
195
|
+
e: void 0,
|
|
196
|
+
t: void 0,
|
|
197
|
+
a: void 0
|
|
198
|
+
}), e;
|
|
199
|
+
}
|
|
200
|
+
}), null), i((e) => {
|
|
201
|
+
var n = !!ne(), r = b();
|
|
202
|
+
return n !== e.e && t.classList.toggle("combobox-list-detail", e.e = n), r !== e.t && c(t, "id", e.t = r), e;
|
|
203
|
+
}, {
|
|
204
|
+
e: void 0,
|
|
205
|
+
t: void 0
|
|
206
|
+
}), t;
|
|
207
|
+
}
|
|
208
|
+
}), 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;
|
|
211
|
+
}, {
|
|
212
|
+
e: void 0,
|
|
213
|
+
t: void 0,
|
|
214
|
+
a: void 0,
|
|
215
|
+
o: void 0,
|
|
216
|
+
i: void 0,
|
|
217
|
+
n: void 0,
|
|
218
|
+
s: void 0,
|
|
219
|
+
h: void 0,
|
|
220
|
+
r: void 0,
|
|
221
|
+
d: void 0,
|
|
222
|
+
l: void 0,
|
|
223
|
+
u: void 0,
|
|
224
|
+
c: void 0,
|
|
225
|
+
w: void 0,
|
|
226
|
+
m: void 0
|
|
227
|
+
}), i(() => m.value = S() ? w() : R()?.label ?? ""), u;
|
|
228
|
+
})();
|
|
229
|
+
}
|
|
230
|
+
r([
|
|
231
|
+
"click",
|
|
232
|
+
"input",
|
|
233
|
+
"keydown",
|
|
234
|
+
"mousedown",
|
|
235
|
+
"mousemove"
|
|
236
|
+
]);
|
|
237
|
+
//#endregion
|
|
3
238
|
//#region src/data-table.tsx
|
|
4
|
-
var
|
|
5
|
-
function
|
|
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) {
|
|
6
241
|
return typeof e == "function" ? e() : e;
|
|
7
242
|
}
|
|
8
|
-
function
|
|
9
|
-
let
|
|
10
|
-
let
|
|
11
|
-
return
|
|
12
|
-
},
|
|
13
|
-
function
|
|
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 = () => {
|
|
245
|
+
let t = l();
|
|
246
|
+
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) {
|
|
14
249
|
return t.sortValue ? t.sortValue(e) : e[t.key];
|
|
15
250
|
}
|
|
16
|
-
function
|
|
251
|
+
function N(e, t) {
|
|
17
252
|
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 });
|
|
18
253
|
}
|
|
19
|
-
let
|
|
20
|
-
let
|
|
21
|
-
if (
|
|
22
|
-
let
|
|
23
|
-
if (!
|
|
24
|
-
let
|
|
25
|
-
return [...
|
|
254
|
+
let P = h(() => {
|
|
255
|
+
let t = r(), n = x();
|
|
256
|
+
if (u || !n) return t;
|
|
257
|
+
let i = e.columns.find((e) => e.key === n);
|
|
258
|
+
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)));
|
|
26
261
|
});
|
|
27
|
-
function
|
|
28
|
-
let
|
|
29
|
-
key:
|
|
30
|
-
direction:
|
|
262
|
+
function q(t) {
|
|
263
|
+
let n = x() === t, r = n && S() === "desc" ? void 0 : {
|
|
264
|
+
key: t,
|
|
265
|
+
direction: n ? "desc" : "asc"
|
|
31
266
|
};
|
|
32
|
-
|
|
267
|
+
u || b(r), e.onSort?.(t), r || e.onSortClear?.(), e.onSortChange?.(r);
|
|
33
268
|
}
|
|
34
|
-
function
|
|
35
|
-
let
|
|
36
|
-
return [...
|
|
269
|
+
function ie(t) {
|
|
270
|
+
let n = new Map(e.columns.map((e, t) => [e.key, t]));
|
|
271
|
+
return [...t].sort((e, t) => (n.get(e) ?? 0) - (n.get(t) ?? 0));
|
|
37
272
|
}
|
|
38
|
-
function
|
|
39
|
-
let
|
|
40
|
-
|
|
273
|
+
function J(t) {
|
|
274
|
+
let n = ie(t);
|
|
275
|
+
e.visibleColumns === void 0 && ee(n), e.onVisibleColumnsChange?.(n);
|
|
41
276
|
}
|
|
42
|
-
function
|
|
43
|
-
let n = new Set(
|
|
44
|
-
t ? n.add(e) : n.delete(e),
|
|
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)));
|
|
45
280
|
}
|
|
46
|
-
function
|
|
47
|
-
|
|
281
|
+
function oe() {
|
|
282
|
+
J(j());
|
|
48
283
|
}
|
|
49
|
-
function
|
|
50
|
-
|
|
284
|
+
function se() {
|
|
285
|
+
J(E());
|
|
51
286
|
}
|
|
52
|
-
let
|
|
53
|
-
|
|
54
|
-
if (!
|
|
287
|
+
let Y = `${_()}-panel`, [X, Z] = g(!1), Q;
|
|
288
|
+
m(() => {
|
|
289
|
+
if (!X() || !C()) return;
|
|
55
290
|
function e(e) {
|
|
56
|
-
|
|
291
|
+
Q && !Q.contains(e.target) && Z(!1);
|
|
57
292
|
}
|
|
58
293
|
function t(e) {
|
|
59
|
-
e.key === "Escape" &&
|
|
294
|
+
e.key === "Escape" && Z(!1);
|
|
60
295
|
}
|
|
61
|
-
document.addEventListener("pointerdown", e), document.addEventListener("keydown", t),
|
|
296
|
+
document.addEventListener("pointerdown", e), document.addEventListener("keydown", t), v(() => {
|
|
62
297
|
document.removeEventListener("pointerdown", e), document.removeEventListener("keydown", t);
|
|
63
298
|
});
|
|
64
299
|
});
|
|
65
|
-
let
|
|
66
|
-
|
|
67
|
-
|
|
300
|
+
let $;
|
|
301
|
+
m(() => {
|
|
302
|
+
$ && ($.indeterminate = l().length > 0 && !T());
|
|
68
303
|
});
|
|
69
|
-
function
|
|
70
|
-
|
|
304
|
+
function ce(t) {
|
|
305
|
+
e.onSelectionChange?.(t ? r().map(e.getRowId) : []);
|
|
71
306
|
}
|
|
72
|
-
function le(
|
|
73
|
-
let r =
|
|
74
|
-
|
|
307
|
+
function le(t, n) {
|
|
308
|
+
let r = e.getRowId(t), i = l(), a = n ? [...i, r] : i.filter((e) => e !== r);
|
|
309
|
+
e.onSelectionChange?.(a);
|
|
75
310
|
}
|
|
76
|
-
function ue(
|
|
77
|
-
return
|
|
311
|
+
function ue(t) {
|
|
312
|
+
return l().includes(e.getRowId(t));
|
|
78
313
|
}
|
|
79
314
|
function de(e) {
|
|
80
|
-
return e.toggleable === !1 ||
|
|
315
|
+
return e.toggleable === !1 || k().has(e.key);
|
|
81
316
|
}
|
|
82
|
-
function fe(
|
|
83
|
-
return
|
|
317
|
+
function fe(t, n) {
|
|
318
|
+
return e.getCell?.(t, n) ?? n.getValue?.(t) ?? null;
|
|
84
319
|
}
|
|
85
320
|
return (() => {
|
|
86
|
-
var
|
|
87
|
-
return
|
|
321
|
+
var l = z(), m = l.firstChild, h = m.firstChild.firstChild, g = h.firstChild, _ = h.nextSibling;
|
|
322
|
+
return a(l, n(p, {
|
|
88
323
|
get when() {
|
|
89
|
-
return
|
|
324
|
+
return C();
|
|
90
325
|
},
|
|
91
326
|
get children() {
|
|
92
|
-
var
|
|
93
|
-
|
|
94
|
-
var
|
|
95
|
-
return typeof
|
|
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, {
|
|
96
331
|
get when() {
|
|
97
|
-
return
|
|
332
|
+
return X();
|
|
98
333
|
},
|
|
99
334
|
get children() {
|
|
100
|
-
var
|
|
101
|
-
return
|
|
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, {
|
|
102
337
|
get each() {
|
|
103
|
-
return
|
|
338
|
+
return e.columns;
|
|
104
339
|
},
|
|
105
340
|
children: (e) => (() => {
|
|
106
|
-
var t =
|
|
107
|
-
return
|
|
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;
|
|
108
343
|
})()
|
|
109
|
-
})),
|
|
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;
|
|
110
345
|
}
|
|
111
|
-
}), null),
|
|
346
|
+
}), null), i(() => c(o, "aria-expanded", X())), t;
|
|
112
347
|
}
|
|
113
|
-
}),
|
|
348
|
+
}), m), a(g, n(p, {
|
|
114
349
|
get when() {
|
|
115
|
-
return
|
|
350
|
+
return w();
|
|
116
351
|
},
|
|
117
352
|
get children() {
|
|
118
|
-
var
|
|
119
|
-
|
|
120
|
-
var
|
|
121
|
-
return typeof
|
|
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;
|
|
122
357
|
}
|
|
123
|
-
}), null),
|
|
358
|
+
}), null), a(g, n(f, {
|
|
124
359
|
get each() {
|
|
125
|
-
return
|
|
360
|
+
return A();
|
|
126
361
|
},
|
|
127
|
-
children: (
|
|
128
|
-
var
|
|
129
|
-
return
|
|
362
|
+
children: (r) => (() => {
|
|
363
|
+
var s = V();
|
|
364
|
+
return a(s, n(p, {
|
|
130
365
|
get when() {
|
|
131
|
-
return
|
|
366
|
+
return o(() => !!r.sortable)() && (!u || e.onSort || e.onSortChange);
|
|
132
367
|
},
|
|
133
368
|
get fallback() {
|
|
134
|
-
return
|
|
369
|
+
return r.label;
|
|
135
370
|
},
|
|
136
371
|
get children() {
|
|
137
|
-
var e =
|
|
138
|
-
return e.$$click = () =>
|
|
139
|
-
var e =
|
|
140
|
-
return () => e() ?
|
|
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" ? "▲" : "▼" : "";
|
|
141
376
|
})()), e;
|
|
142
377
|
}
|
|
143
|
-
})),
|
|
144
|
-
var n =
|
|
145
|
-
return n !==
|
|
378
|
+
})), i((e) => {
|
|
379
|
+
var n = r.class, i = r.sortable ? x() === r.key ? S() === "asc" ? "ascending" : "descending" : "none" : void 0;
|
|
380
|
+
return n !== e.e && t(s, e.e = n), i !== e.t && c(s, "aria-sort", e.t = i), e;
|
|
146
381
|
}, {
|
|
147
382
|
e: void 0,
|
|
148
383
|
t: void 0
|
|
149
|
-
}),
|
|
384
|
+
}), s;
|
|
150
385
|
})()
|
|
151
|
-
}), null),
|
|
386
|
+
}), null), a(g, n(p, {
|
|
152
387
|
get when() {
|
|
153
|
-
return
|
|
388
|
+
return e.rowActions;
|
|
154
389
|
},
|
|
155
390
|
get children() {
|
|
156
|
-
return
|
|
391
|
+
return R();
|
|
157
392
|
}
|
|
158
|
-
}), null),
|
|
393
|
+
}), null), a(_, n(f, {
|
|
159
394
|
get each() {
|
|
160
|
-
return
|
|
395
|
+
return P();
|
|
161
396
|
},
|
|
162
|
-
children: (
|
|
163
|
-
var
|
|
164
|
-
return
|
|
397
|
+
children: (r) => (() => {
|
|
398
|
+
var o = U();
|
|
399
|
+
return a(o, n(p, {
|
|
165
400
|
get when() {
|
|
166
|
-
return
|
|
401
|
+
return w();
|
|
167
402
|
},
|
|
168
403
|
get children() {
|
|
169
|
-
var
|
|
170
|
-
return
|
|
404
|
+
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;
|
|
171
406
|
}
|
|
172
|
-
}), null),
|
|
407
|
+
}), null), a(o, n(f, {
|
|
173
408
|
get each() {
|
|
174
|
-
return
|
|
409
|
+
return A();
|
|
175
410
|
},
|
|
176
|
-
children: (
|
|
177
|
-
var n =
|
|
178
|
-
return
|
|
411
|
+
children: (e) => (() => {
|
|
412
|
+
var n = H();
|
|
413
|
+
return a(n, () => fe(r, e)), i(() => t(n, e.class)), n;
|
|
179
414
|
})()
|
|
180
|
-
}), null),
|
|
415
|
+
}), null), a(o, n(p, {
|
|
181
416
|
get when() {
|
|
182
|
-
return
|
|
417
|
+
return e.rowActions;
|
|
183
418
|
},
|
|
184
419
|
get children() {
|
|
185
|
-
var
|
|
186
|
-
return
|
|
420
|
+
var t = H();
|
|
421
|
+
return a(t, () => e.rowActions?.(r)), t;
|
|
187
422
|
}
|
|
188
|
-
}), null),
|
|
423
|
+
}), null), o;
|
|
189
424
|
})()
|
|
190
|
-
})),
|
|
425
|
+
})), a(l, n(p, {
|
|
191
426
|
get when() {
|
|
192
|
-
return
|
|
427
|
+
return s();
|
|
193
428
|
},
|
|
194
429
|
get children() {
|
|
195
|
-
return
|
|
430
|
+
return e.loadingContent ?? W();
|
|
196
431
|
}
|
|
197
|
-
}), null),
|
|
432
|
+
}), null), a(l, n(p, {
|
|
198
433
|
get when() {
|
|
199
|
-
return
|
|
434
|
+
return o(() => !s())() && (e.empty === void 0 ? r().length === 0 : K(e.empty));
|
|
200
435
|
},
|
|
201
436
|
get children() {
|
|
202
|
-
return
|
|
437
|
+
return e.emptyContent ?? G();
|
|
203
438
|
}
|
|
204
|
-
}), null),
|
|
439
|
+
}), null), i(() => t(l, `data-table-wrap${e.class ? ` ${e.class}` : ""}`)), l;
|
|
205
440
|
})();
|
|
206
441
|
}
|
|
207
|
-
|
|
442
|
+
r(["click"]);
|
|
208
443
|
//#endregion
|
|
209
|
-
export {
|
|
444
|
+
export { P as Combobox, q as DataTable };
|
package/dist/styles.css
CHANGED
|
@@ -137,3 +137,221 @@
|
|
|
137
137
|
clip: rect(0 0 0 0);
|
|
138
138
|
white-space: nowrap;
|
|
139
139
|
}
|
|
140
|
+
|
|
141
|
+
/* Combobox: text input plus an absolutely positioned listbox below it. */
|
|
142
|
+
.combobox {
|
|
143
|
+
position: relative;
|
|
144
|
+
min-width: 0;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.combobox-input {
|
|
148
|
+
box-sizing: border-box;
|
|
149
|
+
width: 100%;
|
|
150
|
+
padding: 0.375rem 1.8rem 0.375rem 0.5rem;
|
|
151
|
+
border: 1px solid
|
|
152
|
+
var(--combobox-border, var(--border, light-dark(#d0d0d0, #3a3e45)));
|
|
153
|
+
border-radius: 0.375rem;
|
|
154
|
+
background: var(
|
|
155
|
+
--combobox-bg,
|
|
156
|
+
var(--surface, light-dark(#ffffff, #1d2024))
|
|
157
|
+
);
|
|
158
|
+
color: inherit;
|
|
159
|
+
font: inherit;
|
|
160
|
+
text-overflow: ellipsis;
|
|
161
|
+
cursor: pointer;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.combobox-open .combobox-input {
|
|
165
|
+
cursor: text;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.combobox-input:disabled {
|
|
169
|
+
cursor: not-allowed;
|
|
170
|
+
opacity: 0.6;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.combobox-with-detail .combobox-input {
|
|
174
|
+
/* The `.combobox-value` overlay renders the label alongside its detail. */
|
|
175
|
+
color: transparent;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.combobox-with-icon .combobox-input {
|
|
179
|
+
padding-left: 1.7rem;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/* Closed-state glyph of the selected option, inside the input's left padding. */
|
|
183
|
+
.combobox-icon {
|
|
184
|
+
position: absolute;
|
|
185
|
+
top: 50%;
|
|
186
|
+
left: 0.55rem;
|
|
187
|
+
display: inline-flex;
|
|
188
|
+
transform: translateY(-50%);
|
|
189
|
+
color: var(
|
|
190
|
+
--combobox-muted,
|
|
191
|
+
var(--text-secondary, light-dark(#616161, #9b9da5))
|
|
192
|
+
);
|
|
193
|
+
pointer-events: none;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.combobox-option-icon {
|
|
197
|
+
display: inline-flex;
|
|
198
|
+
margin-right: 0.4rem;
|
|
199
|
+
vertical-align: -0.15em;
|
|
200
|
+
color: var(
|
|
201
|
+
--combobox-muted,
|
|
202
|
+
var(--text-secondary, light-dark(#616161, #9b9da5))
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
.combobox-chevron {
|
|
207
|
+
position: absolute;
|
|
208
|
+
top: 50%;
|
|
209
|
+
right: 0.5rem;
|
|
210
|
+
transform: translateY(-50%);
|
|
211
|
+
color: var(
|
|
212
|
+
--combobox-muted,
|
|
213
|
+
var(--text-secondary, light-dark(#616161, #9b9da5))
|
|
214
|
+
);
|
|
215
|
+
pointer-events: none;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.combobox-list {
|
|
219
|
+
position: absolute;
|
|
220
|
+
top: calc(100% + 0.2rem);
|
|
221
|
+
left: 0;
|
|
222
|
+
right: 0;
|
|
223
|
+
z-index: 20;
|
|
224
|
+
max-height: 16rem;
|
|
225
|
+
overflow-y: auto;
|
|
226
|
+
margin: 0;
|
|
227
|
+
padding: 0.2rem;
|
|
228
|
+
border: 1px solid
|
|
229
|
+
var(--combobox-border, var(--border, light-dark(#d0d0d0, #3a3e45)));
|
|
230
|
+
border-radius: 0.375rem;
|
|
231
|
+
background: var(
|
|
232
|
+
--combobox-panel-bg,
|
|
233
|
+
var(--surface, light-dark(#ffffff, #1d2024))
|
|
234
|
+
);
|
|
235
|
+
box-shadow: 0 8px 24px rgb(0 0 0 / 12%);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
.combobox-option,
|
|
239
|
+
.combobox-empty {
|
|
240
|
+
padding: 0.3rem 0.5rem;
|
|
241
|
+
border-radius: 0.25rem;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
.combobox-option {
|
|
245
|
+
cursor: pointer;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.combobox-option-label,
|
|
249
|
+
.combobox-detail {
|
|
250
|
+
overflow: hidden;
|
|
251
|
+
text-overflow: ellipsis;
|
|
252
|
+
white-space: nowrap;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
.combobox-detail {
|
|
256
|
+
color: var(
|
|
257
|
+
--combobox-muted,
|
|
258
|
+
var(--text-secondary, light-dark(#616161, #9b9da5))
|
|
259
|
+
);
|
|
260
|
+
font-weight: 400;
|
|
261
|
+
font-size: 0.875em;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/* Closed-state value with detail, overlaid on the (transparent) input text. */
|
|
265
|
+
.combobox-value {
|
|
266
|
+
position: absolute;
|
|
267
|
+
top: 50%;
|
|
268
|
+
left: calc(0.5rem + 1px);
|
|
269
|
+
right: 1.8rem;
|
|
270
|
+
transform: translateY(-50%);
|
|
271
|
+
display: flex;
|
|
272
|
+
align-items: baseline;
|
|
273
|
+
gap: 0.6rem;
|
|
274
|
+
min-width: 0;
|
|
275
|
+
pointer-events: none;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
.combobox-with-icon .combobox-value {
|
|
279
|
+
left: calc(1.7rem + 1px);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
.combobox-value > .combobox-option-label {
|
|
283
|
+
flex: 0 1 auto;
|
|
284
|
+
min-width: 3rem;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
.combobox-value > .combobox-detail {
|
|
288
|
+
flex: 0 1 auto;
|
|
289
|
+
min-width: 0;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
.combobox-option-active {
|
|
293
|
+
background: var(
|
|
294
|
+
--combobox-hover-bg,
|
|
295
|
+
var(--surface-hover, light-dark(#f5f5f5, #292d33))
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
.combobox-option[aria-selected="true"] {
|
|
300
|
+
font-weight: 600;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/* Pinned "Add …" entry below the options, kept in view while scrolling. */
|
|
304
|
+
.combobox-option-add {
|
|
305
|
+
position: sticky;
|
|
306
|
+
bottom: -0.2rem;
|
|
307
|
+
display: flex;
|
|
308
|
+
align-items: center;
|
|
309
|
+
gap: 0.4rem;
|
|
310
|
+
margin-top: 0.2rem;
|
|
311
|
+
border-top: 1px solid
|
|
312
|
+
var(--combobox-border, var(--border, light-dark(#d0d0d0, #3a3e45)));
|
|
313
|
+
border-radius: 0 0 0.25rem 0.25rem;
|
|
314
|
+
background: var(
|
|
315
|
+
--combobox-panel-bg,
|
|
316
|
+
var(--surface, light-dark(#ffffff, #1d2024))
|
|
317
|
+
);
|
|
318
|
+
color: var(--combobox-accent, var(--primary, light-dark(#1a66d6, #6ea8fe)));
|
|
319
|
+
font-weight: 600;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
.combobox-option-add.combobox-option-active {
|
|
323
|
+
background: var(
|
|
324
|
+
--combobox-hover-bg,
|
|
325
|
+
var(--surface-hover, light-dark(#f5f5f5, #292d33))
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
.combobox-option-empty,
|
|
330
|
+
.combobox-empty {
|
|
331
|
+
color: var(
|
|
332
|
+
--combobox-muted,
|
|
333
|
+
var(--text-secondary, light-dark(#616161, #9b9da5))
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/* Options with a detail line up in two columns: the detail starts right
|
|
338
|
+
after the longest label. */
|
|
339
|
+
.combobox-list-detail {
|
|
340
|
+
display: grid;
|
|
341
|
+
grid-template-columns: minmax(0, max-content) minmax(0, 1fr);
|
|
342
|
+
column-gap: 1rem;
|
|
343
|
+
align-content: start;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
.combobox-list-detail > .combobox-option,
|
|
347
|
+
.combobox-list-detail > .combobox-empty {
|
|
348
|
+
display: grid;
|
|
349
|
+
grid-column: 1 / -1;
|
|
350
|
+
grid-template-columns: subgrid;
|
|
351
|
+
align-items: baseline;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
.combobox-list-detail > .combobox-option-add {
|
|
355
|
+
display: flex;
|
|
356
|
+
align-items: center;
|
|
357
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@serkonda7/solid-components",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.8",
|
|
4
4
|
"description": "Reusable components for SolidJS",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "serkonda7",
|
|
@@ -43,13 +43,14 @@
|
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@biomejs/biome": "2.5.14",
|
|
46
|
+
"@tabler/icons-solidjs": "~3.48.0",
|
|
46
47
|
"@types/bun": "1.4.2",
|
|
47
48
|
"@vitest/browser-playwright": "^5.0.2",
|
|
48
|
-
"playwright": "
|
|
49
|
+
"playwright": "~1.63.0",
|
|
49
50
|
"solid-js": "~1.9.15",
|
|
50
51
|
"typescript": "~7.0.2",
|
|
51
52
|
"vite": "~8.3.0",
|
|
52
53
|
"vite-plugin-solid": "~2.11.14",
|
|
53
|
-
"vitest": "
|
|
54
|
+
"vitest": "~5.0.2"
|
|
54
55
|
}
|
|
55
56
|
}
|