@shlinkio/shlink-frontend-kit 0.7.3 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.js +84 -78
- package/dist/tailwind.d.ts +203 -0
- package/dist/tailwind.js +494 -0
- package/dist/tailwind.preset.css +153 -0
- package/package.json +38 -22
package/README.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
1
|
# Shlink frontend kit
|
|
2
2
|
|
|
3
3
|
React components and utilities for Shlink frontend projects
|
|
4
|
+
|
|
5
|
+
## Tailwind alternatives
|
|
6
|
+
|
|
7
|
+
This library provides some tailwindcss-based components. To use them make sure to import components from `@shlinkio/shlink-frontend-kit/tailwind` and you add the following instructions to your tailwind stylesheet:
|
|
8
|
+
|
|
9
|
+
```css
|
|
10
|
+
@import 'tailwindcss' prefix(tw);
|
|
11
|
+
|
|
12
|
+
/* Add these two lines */
|
|
13
|
+
@source '../node_modules/@shlinkio/shlink-frontend-kit';
|
|
14
|
+
@import '@shlinkio/shlink-frontend-kit/tailwind.preset.css';
|
|
15
|
+
```
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { CardProps } from 'reactstrap';
|
|
2
2
|
import { ChangeEvent } from 'react';
|
|
3
|
+
import { Dispatch } from 'react';
|
|
3
4
|
import { DropdownToggleProps } from 'reactstrap/types/lib/DropdownToggle';
|
|
4
5
|
import { FC } from 'react';
|
|
5
6
|
import { JSX } from 'react/jsx-runtime';
|
|
6
7
|
import { PropsWithChildren } from 'react';
|
|
7
8
|
import { ReactNode } from 'react';
|
|
8
9
|
import { RefObject } from 'react';
|
|
10
|
+
import { SetStateAction } from 'react';
|
|
9
11
|
|
|
10
12
|
declare type BooleanControlProps = PropsWithChildren<{
|
|
11
13
|
checked?: boolean;
|
|
@@ -193,12 +195,14 @@ declare type ToggleResult = [boolean, () => void, () => void, () => void];
|
|
|
193
195
|
|
|
194
196
|
export declare const ToggleSwitch: FC<BooleanControlProps>;
|
|
195
197
|
|
|
196
|
-
export declare const useElementRef: <T>() => RefObject<T | null>;
|
|
198
|
+
export declare const useElementRef: <T extends HTMLElement>() => RefObject<T | null>;
|
|
197
199
|
|
|
198
200
|
export declare const useOrder: <T>(initialOrder: Order<T>) => [Order<T>, (orderField?: T, orderDir?: OrderDir) => void];
|
|
199
201
|
|
|
200
202
|
export declare const useParsedQuery: <T>() => T;
|
|
201
203
|
|
|
204
|
+
export declare const useTheme: (initialTheme?: Theme) => readonly [Theme, Dispatch<SetStateAction<Theme>>];
|
|
205
|
+
|
|
202
206
|
export declare const useTimeoutToggle: (initialValue?: boolean, delay?: number, setTimeout?: ((handler: TimerHandler, timeout?: number, ...arguments: any[]) => number) & typeof globalThis.setTimeout, clearTimeout?: ((id: number | undefined) => void) & typeof globalThis.clearTimeout) => [boolean, () => void];
|
|
203
207
|
|
|
204
208
|
export declare const useToggle: (initialValue?: boolean) => ToggleResult;
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { jsx as o, jsxs as d, Fragment as N } from "react/jsx-runtime";
|
|
2
2
|
import { faCircleNotch as I, faSearch as A, faEllipsisV as E, faSortAmountUp as F, faSortAmountDown as P } from "@fortawesome/free-solid-svg-icons";
|
|
3
|
-
import { FontAwesomeIcon as
|
|
3
|
+
import { FontAwesomeIcon as w } from "@fortawesome/react-fontawesome";
|
|
4
4
|
import { clsx as u } from "clsx";
|
|
5
5
|
import { Card as _, CardHeader as H, CardBody as M, Dropdown as $, DropdownToggle as k, DropdownMenu as S, NavItem as j, NavLink as G, Nav as U, UncontrolledDropdown as q, DropdownItem as g } from "reactstrap";
|
|
6
|
-
import { useId as T, useState as
|
|
7
|
-
import { useLocation as
|
|
8
|
-
const
|
|
6
|
+
import { useId as T, useState as p, useRef as C, useCallback as f, useMemo as Q, Children as V, isValidElement as Y, useEffect as W } from "react";
|
|
7
|
+
import { useLocation as z, NavLink as J } from "react-router";
|
|
8
|
+
const he = ({ className: e, children: r, loading: t = !1, type: n = "default", fullWidth: c = !1 }) => /* @__PURE__ */ o(
|
|
9
9
|
_,
|
|
10
10
|
{
|
|
11
11
|
body: !0,
|
|
@@ -22,18 +22,18 @@ const de = ({ className: e, children: r, loading: t = !1, type: n = "default", f
|
|
|
22
22
|
"text-danger": n === "error"
|
|
23
23
|
}),
|
|
24
24
|
children: [
|
|
25
|
-
t && /* @__PURE__ */ o(
|
|
25
|
+
t && /* @__PURE__ */ o(w, { icon: I, spin: !0 }),
|
|
26
26
|
t && /* @__PURE__ */ o("span", { className: "ms-2", children: r ?? "Loading..." }),
|
|
27
27
|
!t && r
|
|
28
28
|
]
|
|
29
29
|
}
|
|
30
30
|
)
|
|
31
31
|
}
|
|
32
|
-
),
|
|
32
|
+
), X = ({ title: e, children: r, bodyClassName: t, ...n }) => /* @__PURE__ */ d(_, { ...n, children: [
|
|
33
33
|
e && /* @__PURE__ */ o(H, { role: "heading", "aria-level": 4, children: e }),
|
|
34
34
|
/* @__PURE__ */ o(M, { className: t, children: r })
|
|
35
|
-
] }),
|
|
36
|
-
|
|
35
|
+
] }), fe = ({ children: e, type: r, className: t, small: n = !1 }) => /* @__PURE__ */ o(
|
|
36
|
+
X,
|
|
37
37
|
{
|
|
38
38
|
role: "document",
|
|
39
39
|
className: u("text-center", {
|
|
@@ -56,12 +56,12 @@ const de = ({ className: e, children: r, loading: t = !1, type: n = "default", f
|
|
|
56
56
|
/* @__PURE__ */ o("input", { type: "checkbox", className: "form-check-input", id: l, checked: e, onChange: a }),
|
|
57
57
|
/* @__PURE__ */ o("label", { className: "form-check-label", htmlFor: l, children: n })
|
|
58
58
|
] });
|
|
59
|
-
},
|
|
59
|
+
}, pe = (e) => /* @__PURE__ */ o(x, { type: "checkbox", ...e }), be = (e) => /* @__PURE__ */ o(x, { type: "switch", ...e }), Z = ({ children: e, label: r, className: t = "", labelClassName: n = "", noMargin: c = !1, id: s }) => /* @__PURE__ */ d("div", { className: `${t} ${c ? "" : "mb-3"}`, children: [
|
|
60
60
|
/* @__PURE__ */ o("label", { className: `form-label ${n}`, htmlFor: s, children: r }),
|
|
61
61
|
e
|
|
62
|
-
] }),
|
|
62
|
+
] }), we = ({ children: e, value: r, onChange: t, type: n, required: c, placeholder: s, className: l, labelClassName: a }) => {
|
|
63
63
|
const i = T();
|
|
64
|
-
return /* @__PURE__ */ o(
|
|
64
|
+
return /* @__PURE__ */ o(Z, { label: /* @__PURE__ */ d(N, { children: [
|
|
65
65
|
e,
|
|
66
66
|
":"
|
|
67
67
|
] }), className: l, labelClassName: a, id: i, children: /* @__PURE__ */ o(
|
|
@@ -76,13 +76,13 @@ const de = ({ className: e, children: r, loading: t = !1, type: n = "default", f
|
|
|
76
76
|
onChange: (m) => t(m.target.value)
|
|
77
77
|
}
|
|
78
78
|
) });
|
|
79
|
-
},
|
|
80
|
-
let
|
|
79
|
+
}, B = 500;
|
|
80
|
+
let b;
|
|
81
81
|
const v = () => {
|
|
82
|
-
|
|
83
|
-
},
|
|
84
|
-
const [l, a] =
|
|
85
|
-
a(m), v(),
|
|
82
|
+
b !== null && clearTimeout(b), b = null;
|
|
83
|
+
}, ge = ({ onChange: e, className: r, large: t = !0, noBorder: n = !1, initialValue: c = "", setTimeout_: s = setTimeout }) => {
|
|
84
|
+
const [l, a] = p(c), i = (m, h = B) => {
|
|
85
|
+
a(m), v(), b = s(() => {
|
|
86
86
|
e(m), v();
|
|
87
87
|
}, h);
|
|
88
88
|
};
|
|
@@ -100,7 +100,7 @@ const v = () => {
|
|
|
100
100
|
onChange: (m) => i(m.target.value)
|
|
101
101
|
}
|
|
102
102
|
),
|
|
103
|
-
/* @__PURE__ */ o(
|
|
103
|
+
/* @__PURE__ */ o(w, { icon: A, className: "search-field__icon" }),
|
|
104
104
|
/* @__PURE__ */ o(
|
|
105
105
|
"button",
|
|
106
106
|
{
|
|
@@ -113,7 +113,7 @@ const v = () => {
|
|
|
113
113
|
}
|
|
114
114
|
)
|
|
115
115
|
] });
|
|
116
|
-
},
|
|
116
|
+
}, K = (e) => {
|
|
117
117
|
const r = new URLSearchParams(e), t = {};
|
|
118
118
|
return r.forEach((n, c) => {
|
|
119
119
|
if (c.endsWith("[]")) {
|
|
@@ -122,23 +122,23 @@ const v = () => {
|
|
|
122
122
|
} else
|
|
123
123
|
t[c] = n;
|
|
124
124
|
}), t;
|
|
125
|
-
},
|
|
125
|
+
}, Ne = (e) => {
|
|
126
126
|
const r = new URLSearchParams();
|
|
127
127
|
for (const [t, n] of Object.entries(e))
|
|
128
128
|
n !== void 0 && (Array.isArray(n) ? n.forEach((c) => r.append(`${t}[]`, `${c}`)) : r.append(t, `${n}`));
|
|
129
129
|
return r.toString();
|
|
130
|
-
},
|
|
131
|
-
const [r, t] =
|
|
130
|
+
}, ee = (e = !1) => {
|
|
131
|
+
const [r, t] = p(e), n = f(() => t((l) => !l), []), c = f(() => t(!0), []), s = f(() => t(!1), []);
|
|
132
132
|
return [r, n, c, s];
|
|
133
|
-
},
|
|
134
|
-
const [c, s] =
|
|
133
|
+
}, Ce = (e = !1, r = 2e3, t = window.setTimeout, n = window.clearTimeout) => {
|
|
134
|
+
const [c, s] = p(e), l = C(e), a = C(void 0), i = f(() => {
|
|
135
135
|
s(!l.current), a.current && n(a.current), a.current = t(() => s(l.current), r);
|
|
136
136
|
}, [n, r, t]);
|
|
137
137
|
return [c, i];
|
|
138
|
-
},
|
|
139
|
-
const { search: e } =
|
|
140
|
-
return Q(() =>
|
|
141
|
-
},
|
|
138
|
+
}, _e = () => C(null), Oe = () => {
|
|
139
|
+
const { search: e } = z();
|
|
140
|
+
return Q(() => K(e), [e]);
|
|
141
|
+
}, re = ({
|
|
142
142
|
text: e,
|
|
143
143
|
disabled: r = !1,
|
|
144
144
|
className: t,
|
|
@@ -151,7 +151,7 @@ const v = () => {
|
|
|
151
151
|
size: m,
|
|
152
152
|
...h
|
|
153
153
|
}) => {
|
|
154
|
-
const [y, L] =
|
|
154
|
+
const [y, L] = ee(), D = u("dropdown-btn__toggle", t, {
|
|
155
155
|
"btn-block": !i,
|
|
156
156
|
"dropdown-btn__toggle--with-caret": !s
|
|
157
157
|
}), R = { minWidth: a && `${a}px` };
|
|
@@ -159,10 +159,10 @@ const v = () => {
|
|
|
159
159
|
/* @__PURE__ */ o(k, { size: m, caret: !s, className: D, color: "primary", ...h, children: e }),
|
|
160
160
|
/* @__PURE__ */ o(S, { className: "w-100", end: l, style: R, children: n })
|
|
161
161
|
] });
|
|
162
|
-
},
|
|
163
|
-
|
|
162
|
+
}, ve = ({ children: e, minWidth: r, label: t = "Options" }) => /* @__PURE__ */ o(
|
|
163
|
+
re,
|
|
164
164
|
{
|
|
165
|
-
text: /* @__PURE__ */ o(
|
|
165
|
+
text: /* @__PURE__ */ o(w, { className: "px-1", icon: E }),
|
|
166
166
|
"aria-label": t,
|
|
167
167
|
size: "sm",
|
|
168
168
|
minWidth: r,
|
|
@@ -171,8 +171,8 @@ const v = () => {
|
|
|
171
171
|
inline: !0,
|
|
172
172
|
children: e
|
|
173
173
|
}
|
|
174
|
-
),
|
|
175
|
-
if (!Y(n) || n.type !==
|
|
174
|
+
), te = ({ children: e, ...r }) => /* @__PURE__ */ o(j, { children: /* @__PURE__ */ o(G, { className: "nav-pills__nav-link", tag: J, ...r, children: e }) }), ke = ({ children: e, fill: r = !1, className: t = "" }) => /* @__PURE__ */ o(_, { className: `nav-pills__nav p-0 overflow-hidden ${t}`, body: !0, children: /* @__PURE__ */ o(U, { pills: !0, fill: r, children: V.map(e, (n) => {
|
|
175
|
+
if (!Y(n) || n.type !== te)
|
|
176
176
|
throw new Error("Only NavPillItem children are allowed inside NavPills.");
|
|
177
177
|
return n;
|
|
178
178
|
}) }) });
|
|
@@ -182,23 +182,23 @@ function O(e, r, t) {
|
|
|
182
182
|
DESC: void 0
|
|
183
183
|
}[t] : "ASC";
|
|
184
184
|
}
|
|
185
|
-
function
|
|
186
|
-
return typeof e == "object" ?
|
|
185
|
+
function ne(e, r, t) {
|
|
186
|
+
return typeof e == "object" ? ne(e.currentField, e.newField, e.currentOrderDir) : {
|
|
187
187
|
field: r,
|
|
188
188
|
dir: O(e, r, t)
|
|
189
189
|
};
|
|
190
190
|
}
|
|
191
|
-
const
|
|
191
|
+
const Se = (e, { field: r, dir: t }) => !r || !t ? e : e.sort((n, c) => {
|
|
192
192
|
const s = t === "ASC" ? 1 : -1, l = t === "ASC" ? -1 : 1;
|
|
193
193
|
return n[r] > c[r] ? s : l;
|
|
194
|
-
}),
|
|
194
|
+
}), Te = (e) => e.dir ? `${e.field}-${e.dir}` : void 0, xe = (e) => {
|
|
195
195
|
const [r, t] = e.split("-");
|
|
196
196
|
return { field: r, dir: t };
|
|
197
|
-
},
|
|
198
|
-
const [r, t] =
|
|
197
|
+
}, ye = (e) => {
|
|
198
|
+
const [r, t] = p(e), n = f((c, s) => t({ field: c, dir: s }), []);
|
|
199
199
|
return [r, n];
|
|
200
200
|
};
|
|
201
|
-
function
|
|
201
|
+
function Le({ items: e, order: r, onChange: t, isButton: n = !0, right: c = !1, prefixed: s = !0 }) {
|
|
202
202
|
const l = (a) => () => {
|
|
203
203
|
const i = O(a, r.field, r.dir);
|
|
204
204
|
t(i ? a : void 0, i);
|
|
@@ -234,7 +234,7 @@ function Te({ items: e, order: r, onChange: t, isButton: n = !0, right: c = !1,
|
|
|
234
234
|
className: "d-flex justify-content-between align-items-center",
|
|
235
235
|
children: [
|
|
236
236
|
i,
|
|
237
|
-
r.field === a && /* @__PURE__ */ o(
|
|
237
|
+
r.field === a && /* @__PURE__ */ o(w, { icon: r.dir === "ASC" ? F : P })
|
|
238
238
|
]
|
|
239
239
|
},
|
|
240
240
|
a
|
|
@@ -244,46 +244,52 @@ function Te({ items: e, order: r, onChange: t, isButton: n = !0, right: c = !1,
|
|
|
244
244
|
] })
|
|
245
245
|
] });
|
|
246
246
|
}
|
|
247
|
-
const
|
|
247
|
+
const De = "#4696e5", Re = "rgba(70, 150, 229, 0.4)", Ie = "#f77f28", Ae = "rgba(247, 127, 40, 0.4)", Ee = "white", Fe = "#161b22", oe = (e) => {
|
|
248
248
|
var r;
|
|
249
249
|
return (r = document.querySelector("html")) == null ? void 0 : r.setAttribute("data-theme", e);
|
|
250
|
-
},
|
|
250
|
+
}, Pe = () => {
|
|
251
251
|
var e;
|
|
252
252
|
return ((e = document.querySelector("html")) == null ? void 0 : e.getAttribute("data-theme")) === "dark";
|
|
253
|
-
},
|
|
253
|
+
}, ce = (e = window.matchMedia.bind(window)) => e("(prefers-color-scheme: dark)").matches ? "dark" : "light", He = (e) => {
|
|
254
|
+
const [r, t] = p(() => e ?? ce());
|
|
255
|
+
return W(() => {
|
|
256
|
+
oe(r);
|
|
257
|
+
}, [r]), [r, t];
|
|
258
|
+
};
|
|
254
259
|
export {
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
260
|
+
pe as Checkbox,
|
|
261
|
+
re as DropdownBtn,
|
|
262
|
+
Ie as HIGHLIGHTED_COLOR,
|
|
263
|
+
Ae as HIGHLIGHTED_COLOR_ALPHA,
|
|
264
|
+
we as InputFormGroup,
|
|
265
|
+
Z as LabeledFormGroup,
|
|
266
|
+
De as MAIN_COLOR,
|
|
267
|
+
Re as MAIN_COLOR_ALPHA,
|
|
268
|
+
he as Message,
|
|
269
|
+
te as NavPillItem,
|
|
270
|
+
ke as NavPills,
|
|
271
|
+
Le as OrderingDropdown,
|
|
272
|
+
Fe as PRIMARY_DARK_COLOR,
|
|
273
|
+
Ee as PRIMARY_LIGHT_COLOR,
|
|
274
|
+
fe as Result,
|
|
275
|
+
ve as RowDropdownBtn,
|
|
276
|
+
ge as SearchField,
|
|
277
|
+
X as SimpleCard,
|
|
278
|
+
be as ToggleSwitch,
|
|
279
|
+
oe as changeThemeInMarkup,
|
|
280
|
+
ne as determineOrder,
|
|
276
281
|
O as determineOrderDir,
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
282
|
+
ce as getSystemPreferredTheme,
|
|
283
|
+
Pe as isDarkThemeEnabled,
|
|
284
|
+
Te as orderToString,
|
|
285
|
+
K as parseQueryString,
|
|
286
|
+
Se as sortList,
|
|
287
|
+
xe as stringToOrder,
|
|
288
|
+
Ne as stringifyQueryParams,
|
|
289
|
+
_e as useElementRef,
|
|
290
|
+
ye as useOrder,
|
|
291
|
+
Oe as useParsedQuery,
|
|
292
|
+
He as useTheme,
|
|
293
|
+
Ce as useTimeoutToggle,
|
|
294
|
+
ee as useToggle
|
|
289
295
|
};
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { HTMLProps } from 'react';
|
|
3
|
+
import { InputHTMLAttributes } from 'react';
|
|
4
|
+
import { LinkProps } from 'react-router';
|
|
5
|
+
import { PropsWithChildren } from 'react';
|
|
6
|
+
import { ReactNode } from 'react';
|
|
7
|
+
|
|
8
|
+
export declare type BaseInputProps = {
|
|
9
|
+
size?: Size;
|
|
10
|
+
feedback?: 'error';
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export declare const Button: FC<ButtonProps>;
|
|
14
|
+
|
|
15
|
+
export declare type ButtonProps = PropsWithChildren<{
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
className?: string;
|
|
18
|
+
variant?: 'primary' | 'secondary' | 'danger';
|
|
19
|
+
size?: Size;
|
|
20
|
+
inline?: boolean;
|
|
21
|
+
solid?: boolean;
|
|
22
|
+
} & (RegularButtonProps | LinkButtonProps_2)>;
|
|
23
|
+
|
|
24
|
+
export declare type Callback = () => unknown;
|
|
25
|
+
|
|
26
|
+
export declare const Card: FC<CardProps> & {
|
|
27
|
+
Body: FC<CardProps>;
|
|
28
|
+
Header: FC<CardProps>;
|
|
29
|
+
Footer: FC<CardProps>;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export declare type CardProps = HTMLProps<HTMLDivElement>;
|
|
33
|
+
|
|
34
|
+
export declare type CellProps = HTMLProps<HTMLTableCellElement> & {
|
|
35
|
+
/**
|
|
36
|
+
* The name of the column to be displayed in small resolutions when the table is responsive, where the cells collapse.
|
|
37
|
+
* It is ignored for non-responsive tables.
|
|
38
|
+
*/
|
|
39
|
+
columnName?: string;
|
|
40
|
+
/**
|
|
41
|
+
* Whether to use a th or td tag. If not provided, it is inferred based on the section, using td when inside tbody,
|
|
42
|
+
* and th when inside thead or tfoot
|
|
43
|
+
*/
|
|
44
|
+
type?: 'td' | 'th';
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export declare const CloseButton: FC<CloseButtonProps>;
|
|
48
|
+
|
|
49
|
+
export declare type CloseButtonProps = {
|
|
50
|
+
label?: string;
|
|
51
|
+
onClick?: HTMLProps<HTMLButtonElement>['onClick'];
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export declare const ELLIPSIS = "...";
|
|
55
|
+
|
|
56
|
+
declare type Ellipsis = typeof ELLIPSIS;
|
|
57
|
+
|
|
58
|
+
export declare const formatNumber: (number: number | string) => string;
|
|
59
|
+
|
|
60
|
+
export declare const Input: FC<InputProps>;
|
|
61
|
+
|
|
62
|
+
export declare type InputProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'size'> & BaseInputProps & {
|
|
63
|
+
borderless?: boolean;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export declare const keyForPage: (pageNumber: NumberOrEllipsis, index: number) => string;
|
|
67
|
+
|
|
68
|
+
export declare const Label: FC<LabelProps>;
|
|
69
|
+
|
|
70
|
+
export declare const LabelledInput: FC<LabelledInputProps>;
|
|
71
|
+
|
|
72
|
+
export declare type LabelledInputProps = Omit<InputProps, 'className' | 'id' | 'feedback'> & {
|
|
73
|
+
label: string;
|
|
74
|
+
inputClassName?: string;
|
|
75
|
+
error?: string;
|
|
76
|
+
/** Alternative to `required`. Causes the input to be required, without displaying an asterisk */
|
|
77
|
+
hiddenRequired?: boolean;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export declare const LabelledSelect: FC<LabelledSelectProps>;
|
|
81
|
+
|
|
82
|
+
export declare type LabelledSelectProps = Omit<SelectProps, 'className' | 'id'> & {
|
|
83
|
+
label: string;
|
|
84
|
+
selectClassName?: string;
|
|
85
|
+
/** Alternative to `required`. Causes the input to be required, without displaying an asterisk */
|
|
86
|
+
hiddenRequired?: boolean;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
export declare type LabelProps = HTMLProps<HTMLLabelElement> & {
|
|
90
|
+
required?: boolean;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
export declare const LinkButton: FC<LinkButtonProps>;
|
|
94
|
+
|
|
95
|
+
export declare type LinkButtonProps = Omit<HTMLProps<HTMLButtonElement>, 'size' | 'type'> & {
|
|
96
|
+
size?: Size;
|
|
97
|
+
type?: HTMLButtonElement['type'];
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
declare type LinkButtonProps_2 = LinkProps;
|
|
101
|
+
|
|
102
|
+
export declare const ModalDialog: FC<ModalDialogProps>;
|
|
103
|
+
|
|
104
|
+
export declare type ModalDialogProps = HTMLProps<HTMLDialogElement> & {
|
|
105
|
+
/** Whether the dialog is open or not */
|
|
106
|
+
open: boolean;
|
|
107
|
+
/** Invoked when the dialog is closed for any reason */
|
|
108
|
+
onClose: () => void;
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
declare type NoTitleProps = {
|
|
112
|
+
title?: never;
|
|
113
|
+
titleSize?: never;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
export declare type NumberOrEllipsis = number | Ellipsis;
|
|
117
|
+
|
|
118
|
+
export declare const pageIsEllipsis: (pageNumber: NumberOrEllipsis) => pageNumber is Ellipsis;
|
|
119
|
+
|
|
120
|
+
export declare const Paginator: FC<PaginatorProps>;
|
|
121
|
+
|
|
122
|
+
export declare type PaginatorProps = {
|
|
123
|
+
pagesCount: number;
|
|
124
|
+
currentPage: number;
|
|
125
|
+
} & ({
|
|
126
|
+
onPageChange: (currentPage: number) => void;
|
|
127
|
+
} | {
|
|
128
|
+
urlForPage: (pageNumber: number) => string;
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
export declare const prettifyPageNumber: (pageNumber: NumberOrEllipsis) => string;
|
|
132
|
+
|
|
133
|
+
export declare const progressivePagination: (currentPage: number, pageCount: number) => NumberOrEllipsis[];
|
|
134
|
+
|
|
135
|
+
declare type RegularButtonProps = Omit<HTMLProps<HTMLButtonElement>, 'size'>;
|
|
136
|
+
|
|
137
|
+
export declare const roundTen: (number: number) => number;
|
|
138
|
+
|
|
139
|
+
export declare const SearchInput: FC<SearchInputProps>;
|
|
140
|
+
|
|
141
|
+
export declare type SearchInputProps = Omit<InputProps, 'className' | 'onChange' | 'value'> & {
|
|
142
|
+
onChange: (searchTerm: string) => void;
|
|
143
|
+
containerClassName?: string;
|
|
144
|
+
inputClassName?: string;
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
export declare type SectionType = 'head' | 'body' | 'footer';
|
|
148
|
+
|
|
149
|
+
export declare const Select: FC<SelectProps>;
|
|
150
|
+
|
|
151
|
+
declare type SelectElementProps = Omit<HTMLProps<HTMLSelectElement>, 'size'>;
|
|
152
|
+
|
|
153
|
+
export declare type SelectProps = PropsWithChildren<SelectElementProps & BaseInputProps>;
|
|
154
|
+
|
|
155
|
+
export declare const SimpleCard: FC<SimpleCardProps>;
|
|
156
|
+
|
|
157
|
+
export declare type SimpleCardProps = Omit<CardProps, 'title' | 'size'> & {
|
|
158
|
+
bodyClassName?: string;
|
|
159
|
+
} & (TitleProps | NoTitleProps);
|
|
160
|
+
|
|
161
|
+
declare type Size = 'sm' | 'md' | 'lg';
|
|
162
|
+
|
|
163
|
+
export declare const Table: FC<TableProps> & {
|
|
164
|
+
Row: FC<HTMLProps<HTMLTableRowElement>>;
|
|
165
|
+
Cell: FC<CellProps>;
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
export declare type TableElementProps = PropsWithChildren & {
|
|
169
|
+
className?: string;
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
export declare type TableProps = HTMLProps<HTMLTableElement> & {
|
|
173
|
+
header: ReactNode;
|
|
174
|
+
footer?: ReactNode;
|
|
175
|
+
/**
|
|
176
|
+
* By default, the table rows will collapse under large resolutions, and the headers will be hidden.
|
|
177
|
+
* Set `responsive={false}` to avoid this behavior.
|
|
178
|
+
*/
|
|
179
|
+
responsive?: boolean;
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
declare type TitleProps = {
|
|
183
|
+
title: ReactNode;
|
|
184
|
+
titleSize?: Size;
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
export declare function useTimeout(defaultDelay: number,
|
|
188
|
+
/** Test seam. Defaults to global setTimeout */
|
|
189
|
+
setTimeout_?: typeof globalThis.setTimeout,
|
|
190
|
+
/** Test seam. Defaults to global clearTimeout */
|
|
191
|
+
clearTimeout_?: typeof clearTimeout): UseTimeoutResult;
|
|
192
|
+
|
|
193
|
+
export declare type UseTimeoutResult = {
|
|
194
|
+
/**
|
|
195
|
+
* Clears any in-progress timeout, and schedules a new callback.
|
|
196
|
+
* It optionally allows a delay to be provided, or falls back to the default delay otherwise.
|
|
197
|
+
*/
|
|
198
|
+
setTimeout: (callback: Callback, delay?: number) => void;
|
|
199
|
+
/** Clears any in-progress timeout */
|
|
200
|
+
clearCurrentTimeout: () => void;
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
export { }
|
package/dist/tailwind.js
ADDED
|
@@ -0,0 +1,494 @@
|
|
|
1
|
+
import { jsx as n, jsxs as c } from "react/jsx-runtime";
|
|
2
|
+
import a from "clsx";
|
|
3
|
+
import { createContext as C, useContext as m, useRef as S, useEffect as B, useId as L, useCallback as f, useMemo as v } from "react";
|
|
4
|
+
import { Link as R } from "react-router";
|
|
5
|
+
import { faClose as U, faSearch as A, faChevronLeft as T, faChevronRight as I } from "@fortawesome/free-solid-svg-icons";
|
|
6
|
+
import { FontAwesomeIcon as b } from "@fortawesome/react-fontawesome";
|
|
7
|
+
const p = C(void 0), h = C({ responsive: !0 }), D = ({ children: t, className: r }) => {
|
|
8
|
+
const { responsive: e } = m(h);
|
|
9
|
+
return /* @__PURE__ */ n(p.Provider, { value: { section: "head" }, children: /* @__PURE__ */ n(
|
|
10
|
+
"thead",
|
|
11
|
+
{
|
|
12
|
+
className: a(
|
|
13
|
+
{ "tw:hidden tw:lg:table-header-group": e },
|
|
14
|
+
r
|
|
15
|
+
),
|
|
16
|
+
children: t
|
|
17
|
+
}
|
|
18
|
+
) });
|
|
19
|
+
}, O = ({ children: t, className: r }) => {
|
|
20
|
+
const { responsive: e } = m(h);
|
|
21
|
+
return /* @__PURE__ */ n(p.Provider, { value: { section: "body" }, children: /* @__PURE__ */ n(
|
|
22
|
+
"tbody",
|
|
23
|
+
{
|
|
24
|
+
className: a(
|
|
25
|
+
{ "tw:lg:table-row-group tw:flex tw:flex-col tw:gap-y-3": e },
|
|
26
|
+
r
|
|
27
|
+
),
|
|
28
|
+
children: t
|
|
29
|
+
}
|
|
30
|
+
) });
|
|
31
|
+
}, W = ({ children: t, className: r }) => {
|
|
32
|
+
const { responsive: e } = m(h);
|
|
33
|
+
return /* @__PURE__ */ n(p.Provider, { value: { section: "footer" }, children: /* @__PURE__ */ n(
|
|
34
|
+
"tfoot",
|
|
35
|
+
{
|
|
36
|
+
className: a(
|
|
37
|
+
{ "tw:lg:table-row-group tw:flex tw:flex-col tw:gap-y-3 tw:mt-4": e },
|
|
38
|
+
r
|
|
39
|
+
),
|
|
40
|
+
children: t
|
|
41
|
+
}
|
|
42
|
+
) });
|
|
43
|
+
}, _ = ({ children: t, className: r, ...e }) => {
|
|
44
|
+
const o = m(p), d = (o == null ? void 0 : o.section) === "body", { responsive: l } = m(h);
|
|
45
|
+
return /* @__PURE__ */ n(
|
|
46
|
+
"tr",
|
|
47
|
+
{
|
|
48
|
+
className: a(
|
|
49
|
+
"tw:group",
|
|
50
|
+
{
|
|
51
|
+
"tw:lg:table-row tw:flex tw:flex-col": l,
|
|
52
|
+
"tw:lg:border-0 tw:border-y-2 tw:border-lm-border tw:dark:border-dm-border": l,
|
|
53
|
+
"tw:hover:bg-lm-primary tw:dark:hover:bg-dm-primary": d,
|
|
54
|
+
// Use a different hover bg color depending on the table being inside a card or not
|
|
55
|
+
"tw:group-[&]/card:hover:bg-lm-secondary tw:dark:group-[&]/card:hover:bg-dm-secondary": d
|
|
56
|
+
},
|
|
57
|
+
r
|
|
58
|
+
),
|
|
59
|
+
...e,
|
|
60
|
+
children: t
|
|
61
|
+
}
|
|
62
|
+
);
|
|
63
|
+
}, q = ({ children: t, className: r, columnName: e, type: o, ...d }) => {
|
|
64
|
+
const l = m(p), s = o ?? ((l == null ? void 0 : l.section) !== "body" ? "th" : "td"), { responsive: i } = m(h);
|
|
65
|
+
return /* @__PURE__ */ n(
|
|
66
|
+
s,
|
|
67
|
+
{
|
|
68
|
+
"data-column": i ? e : void 0,
|
|
69
|
+
className: a(
|
|
70
|
+
"tw:p-2 tw:border-lm-border tw:dark:border-dm-border",
|
|
71
|
+
{
|
|
72
|
+
"tw:border-b-1": !i,
|
|
73
|
+
"tw:block tw:lg:table-cell tw:not-last:border-b-1 tw:lg:border-b-1": i,
|
|
74
|
+
// For md and lower, display the content in data-column attribute as before
|
|
75
|
+
"tw:before:lg:hidden tw:before:content-[attr(data-column)] tw:before:font-bold tw:before:mr-1": i && s === "td"
|
|
76
|
+
},
|
|
77
|
+
r
|
|
78
|
+
),
|
|
79
|
+
...d,
|
|
80
|
+
children: t
|
|
81
|
+
}
|
|
82
|
+
);
|
|
83
|
+
}, G = ({ header: t, footer: r, children: e, responsive: o = !0, ...d }) => /* @__PURE__ */ n(h.Provider, { value: { responsive: o }, children: /* @__PURE__ */ c("table", { className: "tw:w-full", ...d, children: [
|
|
84
|
+
/* @__PURE__ */ n(D, { children: t }),
|
|
85
|
+
/* @__PURE__ */ n(O, { children: e }),
|
|
86
|
+
r && /* @__PURE__ */ n(W, { children: r })
|
|
87
|
+
] }) }), bt = Object.assign(G, { Row: _, Cell: q }), ht = ({
|
|
88
|
+
open: t,
|
|
89
|
+
children: r,
|
|
90
|
+
className: e,
|
|
91
|
+
...o
|
|
92
|
+
}) => {
|
|
93
|
+
const d = S(null);
|
|
94
|
+
return B(() => {
|
|
95
|
+
var w, N;
|
|
96
|
+
const l = document.body, s = l.style.overflow, i = l.style.paddingRight;
|
|
97
|
+
if (t) {
|
|
98
|
+
const $ = window.outerWidth - l.clientWidth, z = l.scrollHeight > l.clientHeight;
|
|
99
|
+
l.style.overflow = "hidden", z && (l.style.paddingRight = `${$}px`), (w = d.current) == null || w.showModal();
|
|
100
|
+
} else
|
|
101
|
+
(N = d.current) == null || N.close();
|
|
102
|
+
return () => {
|
|
103
|
+
l.style.overflow = s, l.style.paddingRight = i;
|
|
104
|
+
};
|
|
105
|
+
}, [t]), /* @__PURE__ */ n(
|
|
106
|
+
"dialog",
|
|
107
|
+
{
|
|
108
|
+
ref: d,
|
|
109
|
+
className: a("tw:bg-transparent tw:backdrop:bg-black/50", e),
|
|
110
|
+
...o,
|
|
111
|
+
children: t && r
|
|
112
|
+
}
|
|
113
|
+
);
|
|
114
|
+
}, ut = ({
|
|
115
|
+
children: t,
|
|
116
|
+
className: r,
|
|
117
|
+
disabled: e,
|
|
118
|
+
variant: o = "primary",
|
|
119
|
+
size: d = "md",
|
|
120
|
+
inline: l = !1,
|
|
121
|
+
solid: s = !1,
|
|
122
|
+
...i
|
|
123
|
+
}) => {
|
|
124
|
+
const w = "to" in i ? R : "button";
|
|
125
|
+
return (
|
|
126
|
+
// @ts-expect-error We are explicitly checking for the `to` prop before using Link
|
|
127
|
+
/* @__PURE__ */ n(
|
|
128
|
+
w,
|
|
129
|
+
{
|
|
130
|
+
className: a(
|
|
131
|
+
{
|
|
132
|
+
"tw:inline-flex": l,
|
|
133
|
+
"tw:flex": !l
|
|
134
|
+
},
|
|
135
|
+
"tw:gap-2 tw:items-center tw:justify-center",
|
|
136
|
+
"tw:border tw:rounded-md tw:no-underline",
|
|
137
|
+
"tw:transition-colors",
|
|
138
|
+
{
|
|
139
|
+
"tw:focus-ring": o !== "danger",
|
|
140
|
+
"tw:focus-ring-danger": o === "danger"
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"tw:px-1.5 tw:py-1 tw:text-sm": d === "sm",
|
|
144
|
+
"tw:px-3 tw:py-1.5": d === "md",
|
|
145
|
+
"tw:px-4 tw:py-2 tw:text-lg": d === "lg"
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
"tw:border-brand tw:text-brand": o === "primary",
|
|
149
|
+
"tw:border-zinc-500": o === "secondary",
|
|
150
|
+
"tw:text-zinc-500": o === "secondary" && !s,
|
|
151
|
+
"tw:border-danger": o === "danger",
|
|
152
|
+
"tw:text-danger": o === "danger" && !s
|
|
153
|
+
},
|
|
154
|
+
s && {
|
|
155
|
+
"tw:text-white": !0,
|
|
156
|
+
"tw:bg-brand": o === "primary",
|
|
157
|
+
"tw:highlight:bg-brand-dark tw:highlight:border-brand-dark": o === "primary",
|
|
158
|
+
"tw:bg-zinc-500": o === "secondary",
|
|
159
|
+
"tw:highlight:bg-zinc-600 tw:highlight:border-zinc-600": o === "secondary",
|
|
160
|
+
"tw:bg-danger": o === "danger",
|
|
161
|
+
"tw:highlight:bg-danger-dark tw:highlight:border-danger-dark": o === "danger"
|
|
162
|
+
},
|
|
163
|
+
!e && {
|
|
164
|
+
"tw:highlight:text-white": !s,
|
|
165
|
+
"tw:highlight:bg-brand": o === "primary",
|
|
166
|
+
"tw:highlight:bg-zinc-500": o === "secondary",
|
|
167
|
+
"tw:highlight:bg-danger": o === "danger"
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
"tw:pointer-events-none tw:opacity-65": e
|
|
171
|
+
},
|
|
172
|
+
r
|
|
173
|
+
),
|
|
174
|
+
disabled: e,
|
|
175
|
+
...i,
|
|
176
|
+
children: t
|
|
177
|
+
}
|
|
178
|
+
)
|
|
179
|
+
);
|
|
180
|
+
}, pt = ({ onClick: t, label: r = "Close" }) => /* @__PURE__ */ n(
|
|
181
|
+
"button",
|
|
182
|
+
{
|
|
183
|
+
onClick: t,
|
|
184
|
+
className: a(
|
|
185
|
+
"tw:opacity-50 tw:highlight:opacity-80 tw:transition-opacity",
|
|
186
|
+
"tw:rounded-md tw:focus-ring"
|
|
187
|
+
),
|
|
188
|
+
"aria-label": r,
|
|
189
|
+
children: /* @__PURE__ */ n(b, { icon: U, size: "xl" })
|
|
190
|
+
}
|
|
191
|
+
), F = ({
|
|
192
|
+
borderless: t = !1,
|
|
193
|
+
size: r = "md",
|
|
194
|
+
feedback: e,
|
|
195
|
+
className: o,
|
|
196
|
+
disabled: d,
|
|
197
|
+
readOnly: l,
|
|
198
|
+
...s
|
|
199
|
+
}) => {
|
|
200
|
+
const i = !d && !l;
|
|
201
|
+
return /* @__PURE__ */ n(
|
|
202
|
+
"input",
|
|
203
|
+
{
|
|
204
|
+
className: a(
|
|
205
|
+
"tw:w-full",
|
|
206
|
+
{
|
|
207
|
+
"tw:focus-ring": !e,
|
|
208
|
+
"tw:focus-ring-danger": e === "error"
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
"tw:px-2 tw:py-1 tw:text-sm": r === "sm",
|
|
212
|
+
"tw:px-3 tw:py-1.5": r === "md",
|
|
213
|
+
"tw:px-4 tw:py-2 tw:text-xl": r === "lg"
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
"tw:rounded-md tw:border": !t,
|
|
217
|
+
"tw:border-lm-input-border tw:dark:border-dm-input-border": !t && !e,
|
|
218
|
+
"tw:border-danger": !t && e === "error",
|
|
219
|
+
"tw:bg-lm-disabled-input tw:dark:bg-dm-disabled-input": !i,
|
|
220
|
+
"tw:bg-lm-primary tw:dark:bg-dm-primary": i,
|
|
221
|
+
// Use different background color when rendered inside a card
|
|
222
|
+
"tw:group-[&]/card:bg-lm-input tw:group-[&]/card:dark:bg-dm-input": i
|
|
223
|
+
},
|
|
224
|
+
o
|
|
225
|
+
),
|
|
226
|
+
disabled: d,
|
|
227
|
+
readOnly: l,
|
|
228
|
+
...s
|
|
229
|
+
}
|
|
230
|
+
);
|
|
231
|
+
}, E = ({ required: t, children: r, ...e }) => /* @__PURE__ */ c("label", { ...e, children: [
|
|
232
|
+
r,
|
|
233
|
+
t && /* @__PURE__ */ n("span", { className: "tw:text-danger tw:ml-1", "data-testid": "required-indicator", children: "*" })
|
|
234
|
+
] }), ft = ({ label: t, inputClassName: r, required: e, hiddenRequired: o, error: d, ...l }) => {
|
|
235
|
+
const s = L();
|
|
236
|
+
return /* @__PURE__ */ c("div", { className: "tw:flex tw:flex-col tw:gap-1", children: [
|
|
237
|
+
/* @__PURE__ */ n(E, { htmlFor: s, required: e, children: t }),
|
|
238
|
+
/* @__PURE__ */ n(
|
|
239
|
+
F,
|
|
240
|
+
{
|
|
241
|
+
id: s,
|
|
242
|
+
className: r,
|
|
243
|
+
required: e || o,
|
|
244
|
+
feedback: d ? "error" : void 0,
|
|
245
|
+
...l
|
|
246
|
+
}
|
|
247
|
+
),
|
|
248
|
+
d && /* @__PURE__ */ n("span", { className: "tw:text-danger", children: d })
|
|
249
|
+
] });
|
|
250
|
+
}, J = String.raw`data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/></svg>`, K = ({
|
|
251
|
+
className: t,
|
|
252
|
+
size: r = "md",
|
|
253
|
+
feedback: e,
|
|
254
|
+
style: o = {},
|
|
255
|
+
disabled: d,
|
|
256
|
+
...l
|
|
257
|
+
}) => /* @__PURE__ */ n(
|
|
258
|
+
"select",
|
|
259
|
+
{
|
|
260
|
+
className: a(
|
|
261
|
+
"tw:w-full tw:appearance-none tw:pr-9 tw:bg-no-repeat",
|
|
262
|
+
{
|
|
263
|
+
"tw:focus-ring": !e,
|
|
264
|
+
"tw:focus-ring-danger": e === "error"
|
|
265
|
+
},
|
|
266
|
+
"tw:rounded-md tw:border",
|
|
267
|
+
{
|
|
268
|
+
"tw:border-lm-input-border tw:dark:border-dm-input-border": !e,
|
|
269
|
+
"tw:border-danger": e === "error"
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
"tw:pl-2 tw:py-1 tw:text-sm": r === "sm",
|
|
273
|
+
"tw:pl-3 tw:py-1.5": r === "md",
|
|
274
|
+
"tw:pl-4 tw:py-2 tw:text-xl": r === "lg",
|
|
275
|
+
"tw:bg-lm-disabled-input tw:dark:bg-dm-disabled-input": d,
|
|
276
|
+
// Apply different background color when rendered inside a card
|
|
277
|
+
"tw:bg-lm-primary tw:dark:bg-dm-primary tw:group-[&]/card:bg-lm-input tw:group-[&]/card:dark:bg-dm-input": !d
|
|
278
|
+
},
|
|
279
|
+
t
|
|
280
|
+
),
|
|
281
|
+
style: {
|
|
282
|
+
...o,
|
|
283
|
+
backgroundImage: `url("${J}")`,
|
|
284
|
+
backgroundSize: "16px 12px",
|
|
285
|
+
backgroundPosition: "right 0.75rem center"
|
|
286
|
+
},
|
|
287
|
+
disabled: d,
|
|
288
|
+
...l
|
|
289
|
+
}
|
|
290
|
+
), yt = ({ selectClassName: t, label: r, required: e, hiddenRequired: o, ...d }) => {
|
|
291
|
+
const l = L();
|
|
292
|
+
return /* @__PURE__ */ c("div", { className: "tw:flex tw:flex-col tw:gap-1", children: [
|
|
293
|
+
/* @__PURE__ */ n(E, { htmlFor: l, required: e, children: r }),
|
|
294
|
+
/* @__PURE__ */ n(K, { id: l, className: t, required: e || o, ...d })
|
|
295
|
+
] });
|
|
296
|
+
};
|
|
297
|
+
function Q(t, r = globalThis.setTimeout.bind(globalThis), e = globalThis.clearTimeout.bind(globalThis)) {
|
|
298
|
+
const o = S(null), d = f(() => {
|
|
299
|
+
o.current && e(o.current);
|
|
300
|
+
}, [e]), l = f((s, i) => {
|
|
301
|
+
d(), o.current = r(() => {
|
|
302
|
+
s(), o.current = null;
|
|
303
|
+
}, i ?? t);
|
|
304
|
+
}, [d, t, r]);
|
|
305
|
+
return B(() => d, [d]), v(
|
|
306
|
+
() => ({ setTimeout: l, clearCurrentTimeout: d }),
|
|
307
|
+
[d, l]
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
const xt = ({
|
|
311
|
+
onChange: t,
|
|
312
|
+
containerClassName: r,
|
|
313
|
+
inputClassName: e,
|
|
314
|
+
// Inputs have a default 'md' size. Search inputs are usually 'lg' as they are rendered at the top of sections
|
|
315
|
+
size: o = "lg",
|
|
316
|
+
...d
|
|
317
|
+
}) => {
|
|
318
|
+
const { setTimeout: l, clearCurrentTimeout: s } = Q(500), i = f((w) => {
|
|
319
|
+
w ? l(() => t(w)) : (s(), t(w));
|
|
320
|
+
}, [s, t, l]);
|
|
321
|
+
return /* @__PURE__ */ c("div", { className: a("tw:group tw:relative tw:focus-within:z-10", r), children: [
|
|
322
|
+
/* @__PURE__ */ n(
|
|
323
|
+
b,
|
|
324
|
+
{
|
|
325
|
+
icon: A,
|
|
326
|
+
className: a(
|
|
327
|
+
"tw:absolute tw:top-[50%] tw:translate-y-[-50%] tw:transition-colors",
|
|
328
|
+
"tw:text-placeholder tw:group-focus-within:text-lm-text tw:dark:group-focus-within:text-dm-text",
|
|
329
|
+
{
|
|
330
|
+
"tw:left-3": o !== "sm",
|
|
331
|
+
"tw:scale-85 tw:left-2": o === "sm"
|
|
332
|
+
}
|
|
333
|
+
)
|
|
334
|
+
}
|
|
335
|
+
),
|
|
336
|
+
/* @__PURE__ */ n(
|
|
337
|
+
F,
|
|
338
|
+
{
|
|
339
|
+
type: "search",
|
|
340
|
+
className: a(
|
|
341
|
+
{
|
|
342
|
+
"tw:pl-9": o !== "sm",
|
|
343
|
+
"tw:pl-7": o === "sm"
|
|
344
|
+
},
|
|
345
|
+
e
|
|
346
|
+
),
|
|
347
|
+
placeholder: "Search...",
|
|
348
|
+
onChange: (w) => i(w.target.value),
|
|
349
|
+
size: o,
|
|
350
|
+
...d
|
|
351
|
+
}
|
|
352
|
+
)
|
|
353
|
+
] });
|
|
354
|
+
}, V = new Intl.NumberFormat("en-US"), X = (t) => V.format(Number(t)), P = 10, kt = (t) => Math.ceil(t / P) * P, g = 2, y = "...", Y = (t, r) => Array.from({ length: r - t }, (e, o) => t + o), Z = (t, r) => {
|
|
355
|
+
const e = Y(
|
|
356
|
+
Math.max(g, t - g),
|
|
357
|
+
Math.min(r - 1, t + g) + 1
|
|
358
|
+
);
|
|
359
|
+
return t - g > g && e.unshift(y), t + g < r - 1 && e.push(y), e.unshift(1), e.push(r), e;
|
|
360
|
+
}, u = (t) => t === y, tt = (t) => u(t) ? t : X(t), rt = (t, r) => u(t) ? `${t}_${r}` : `${t}`, vt = ({ className: t, disabled: r, size: e = "md", ...o }) => /* @__PURE__ */ n(
|
|
361
|
+
"button",
|
|
362
|
+
{
|
|
363
|
+
className: a(
|
|
364
|
+
"tw:inline-flex tw:rounded-md tw:focus-ring",
|
|
365
|
+
"tw:text-brand tw:highlight:text-brand-dark tw:highlight:underline",
|
|
366
|
+
{
|
|
367
|
+
"tw:px-1.5 tw:py-1 tw:text-sm": e === "sm",
|
|
368
|
+
"tw:px-3 tw:py-1.5": e === "md",
|
|
369
|
+
"tw:px-4 tw:py-2 tw:text-lg": e === "lg",
|
|
370
|
+
"tw:pointer-events-none tw:opacity-65": r
|
|
371
|
+
},
|
|
372
|
+
t
|
|
373
|
+
),
|
|
374
|
+
disabled: r,
|
|
375
|
+
...o
|
|
376
|
+
}
|
|
377
|
+
), M = [
|
|
378
|
+
"tw:border tw:border-r-0 tw:last:border-r tw:border-lm-border tw:dark:border-dm-border",
|
|
379
|
+
"tw:rounded-none tw:first:rounded-l tw:last:rounded-r"
|
|
380
|
+
], j = (t = !1) => a(
|
|
381
|
+
M,
|
|
382
|
+
"tw:px-3 py-2 tw:cursor-pointer tw:no-underline",
|
|
383
|
+
"tw:focus-ring tw:focus-visible:z-1",
|
|
384
|
+
{
|
|
385
|
+
"tw:highlight:bg-lm-secondary tw:dark:highlight:bg-dm-secondary tw:text-brand": !t,
|
|
386
|
+
"tw:bg-lm-brand tw:dark:bg-dm-brand tw:text-white": t
|
|
387
|
+
}
|
|
388
|
+
), k = ({ children: t }) => /* @__PURE__ */ n("span", { "aria-hidden": !0, className: a(M, "tw:px-3 py-2 tw:text-gray-400"), children: t }), H = () => /* @__PURE__ */ n(k, { children: y });
|
|
389
|
+
function et({ children: t, active: r, isEllipsis: e, href: o, ...d }) {
|
|
390
|
+
const l = v(() => j(r), [r]);
|
|
391
|
+
return e ? /* @__PURE__ */ n(H, {}) : /* @__PURE__ */ n(R, { className: l, to: o, ...d, children: t });
|
|
392
|
+
}
|
|
393
|
+
function ot({ children: t, active: r, isEllipsis: e, ...o }) {
|
|
394
|
+
const d = v(() => j(r), [r]);
|
|
395
|
+
return e ? /* @__PURE__ */ n(H, {}) : /* @__PURE__ */ n("button", { type: "button", className: d, ...o, children: t });
|
|
396
|
+
}
|
|
397
|
+
const Nt = ({ currentPage: t, pagesCount: r, ...e }) => {
|
|
398
|
+
const o = "urlForPage" in e, d = o ? et : ot, l = f(
|
|
399
|
+
(s) => o ? { href: u(s) ? void 0 : e.urlForPage(s) } : { onClick: () => !u(s) && e.onPageChange(s) },
|
|
400
|
+
[o, e]
|
|
401
|
+
);
|
|
402
|
+
return r < 2 ? null : /* @__PURE__ */ c("div", { className: "tw:select-none tw:flex", "data-testid": "paginator", children: [
|
|
403
|
+
t === 1 ? /* @__PURE__ */ n(k, { children: /* @__PURE__ */ n(b, { size: "xs", icon: T }) }) : /* @__PURE__ */ n(d, { ...l(Math.max(1, t - 1)), "aria-label": "Previous", children: /* @__PURE__ */ n(b, { size: "xs", icon: T }) }),
|
|
404
|
+
Z(t, r).map((s, i) => /* @__PURE__ */ n(
|
|
405
|
+
d,
|
|
406
|
+
{
|
|
407
|
+
active: s === t,
|
|
408
|
+
isEllipsis: u(s),
|
|
409
|
+
...l(s),
|
|
410
|
+
children: tt(s)
|
|
411
|
+
},
|
|
412
|
+
rt(s, i)
|
|
413
|
+
)),
|
|
414
|
+
t === r ? /* @__PURE__ */ n(k, { children: /* @__PURE__ */ n(b, { size: "xs", icon: I }) }) : /* @__PURE__ */ n(d, { ...l(Math.min(r, t + 1)), "aria-label": "Next", children: /* @__PURE__ */ n(b, { size: "xs", icon: I }) })
|
|
415
|
+
] });
|
|
416
|
+
}, nt = ({ className: t, ...r }) => /* @__PURE__ */ n(
|
|
417
|
+
"div",
|
|
418
|
+
{
|
|
419
|
+
className: a(
|
|
420
|
+
"tw:px-4 tw:py-3 tw:rounded-t-md",
|
|
421
|
+
"tw:bg-lm-primary tw:dark:bg-dm-primary tw:border-b tw:border-lm-border tw:dark:border-dm-border",
|
|
422
|
+
t
|
|
423
|
+
),
|
|
424
|
+
...r
|
|
425
|
+
}
|
|
426
|
+
), dt = ({ className: t, ...r }) => /* @__PURE__ */ n(
|
|
427
|
+
"div",
|
|
428
|
+
{
|
|
429
|
+
className: a(
|
|
430
|
+
"tw:p-4 tw:bg-lm-primary tw:dark:bg-dm-primary tw:first:rounded-t-md",
|
|
431
|
+
"tw:first:rounded-t-md tw:last:rounded-b-md",
|
|
432
|
+
t
|
|
433
|
+
),
|
|
434
|
+
...r
|
|
435
|
+
}
|
|
436
|
+
), lt = ({ className: t, ...r }) => /* @__PURE__ */ n(
|
|
437
|
+
"div",
|
|
438
|
+
{
|
|
439
|
+
className: a(
|
|
440
|
+
"tw:px-4 tw:py-3 tw:rounded-b-md",
|
|
441
|
+
"tw:bg-lm-primary tw:dark:bg-dm-primary tw:border-t tw:border-lm-border tw:dark:border-dm-border",
|
|
442
|
+
t
|
|
443
|
+
),
|
|
444
|
+
...r
|
|
445
|
+
}
|
|
446
|
+
), st = ({ className: t, ...r }) => /* @__PURE__ */ n(
|
|
447
|
+
"div",
|
|
448
|
+
{
|
|
449
|
+
className: a(
|
|
450
|
+
"tw:group/card tw:rounded-md tw:shadow-md",
|
|
451
|
+
"tw:border tw:border-lm-border tw:dark:border-dm-border tw:bg-lm-primary tw:dark:bg-dm-primary",
|
|
452
|
+
t
|
|
453
|
+
),
|
|
454
|
+
...r
|
|
455
|
+
}
|
|
456
|
+
), x = Object.assign(st, { Body: dt, Header: nt, Footer: lt }), Tt = ({ bodyClassName: t, children: r, ...e }) => {
|
|
457
|
+
const { title: o, titleSize: d = "md", ...l } = "title" in e ? e : {
|
|
458
|
+
...e,
|
|
459
|
+
title: void 0,
|
|
460
|
+
titleSize: void 0
|
|
461
|
+
};
|
|
462
|
+
return /* @__PURE__ */ c(x, { ...l, children: [
|
|
463
|
+
o && /* @__PURE__ */ c(x.Header, { children: [
|
|
464
|
+
d === "lg" && /* @__PURE__ */ n("h4", { children: o }),
|
|
465
|
+
d === "md" && /* @__PURE__ */ n("h5", { children: o }),
|
|
466
|
+
d === "sm" && /* @__PURE__ */ n("h6", { children: o })
|
|
467
|
+
] }),
|
|
468
|
+
/* @__PURE__ */ n(x.Body, { className: t, children: r })
|
|
469
|
+
] });
|
|
470
|
+
};
|
|
471
|
+
export {
|
|
472
|
+
ut as Button,
|
|
473
|
+
x as Card,
|
|
474
|
+
pt as CloseButton,
|
|
475
|
+
y as ELLIPSIS,
|
|
476
|
+
F as Input,
|
|
477
|
+
E as Label,
|
|
478
|
+
ft as LabelledInput,
|
|
479
|
+
yt as LabelledSelect,
|
|
480
|
+
vt as LinkButton,
|
|
481
|
+
ht as ModalDialog,
|
|
482
|
+
Nt as Paginator,
|
|
483
|
+
xt as SearchInput,
|
|
484
|
+
K as Select,
|
|
485
|
+
Tt as SimpleCard,
|
|
486
|
+
bt as Table,
|
|
487
|
+
X as formatNumber,
|
|
488
|
+
rt as keyForPage,
|
|
489
|
+
u as pageIsEllipsis,
|
|
490
|
+
tt as prettifyPageNumber,
|
|
491
|
+
Z as progressivePagination,
|
|
492
|
+
kt as roundTen,
|
|
493
|
+
Q as useTimeout
|
|
494
|
+
};
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Override `dark:` variant, which applies based on `prefers-color-scheme` by default, and make it apply based on the
|
|
3
|
+
* presence of `data-theme="dark"` attribute instead.
|
|
4
|
+
*/
|
|
5
|
+
@custom-variant dark (&:where([data-theme="dark"], [data-theme="dark"] *));
|
|
6
|
+
|
|
7
|
+
@theme static inline {
|
|
8
|
+
/* Light mode */
|
|
9
|
+
/*--color-lm-main: #2078CF;*/ /*Properly accessible with white background*/
|
|
10
|
+
--color-lm-main: #4696e5; /* TODO Rename to "brand" */
|
|
11
|
+
--color-lm-main-dark: #1f69c0;
|
|
12
|
+
--color-lm-primary: #ffffff;
|
|
13
|
+
--color-lm-primary-alfa: rgb(var(--tw-color-lm-primary) / .5);
|
|
14
|
+
--color-lm-secondary: #f5f6fe;
|
|
15
|
+
--color-lm-text: #232323;
|
|
16
|
+
--color-lm-border: rgb(0 0 0 / .125);
|
|
17
|
+
--color-lm-table-border: #dee2e6;
|
|
18
|
+
--color-lm-active: #eeeeee;
|
|
19
|
+
--color-lm-brand: var(--tw-color-lm-main); /* TODO Rename to "main" */
|
|
20
|
+
--color-lm-input: var(--tw-color-lm-primary);
|
|
21
|
+
--color-lm-disabled-input: var(--tw-color-lm-secondary);
|
|
22
|
+
--color-lm-input-text: #495057;
|
|
23
|
+
--color-lm-input-border: rgb(0 0 0 / .19);
|
|
24
|
+
--color-lm-table-highlight: rgb(0 0 0 / .075);
|
|
25
|
+
|
|
26
|
+
/* Dark mode */
|
|
27
|
+
--color-dm-main: #4696e5; /* TODO Rename to "brand" */
|
|
28
|
+
--color-dm-main-dark: #1f69c0;
|
|
29
|
+
--color-dm-primary: #161b22;
|
|
30
|
+
--color-dm-primary-alfa: rgb(var(--tw-color-dm-primary) / .8);
|
|
31
|
+
--color-dm-secondary: #0f131a;
|
|
32
|
+
--color-dm-text: rgb(201 209 217);
|
|
33
|
+
--color-dm-border: rgb(255 255 255 / .15);
|
|
34
|
+
--color-dm-table-border: #393d43;
|
|
35
|
+
--color-dm-active: var(--tw-color-dm-secondary);
|
|
36
|
+
--color-dm-brand: #0b2d4e; /* TODO Rename to "main" */
|
|
37
|
+
--color-dm-input: rgb(17.9928571429 22.0821428571 27.8071428571);
|
|
38
|
+
--color-dm-disabled-input: rgb(26.0071428571 31.9178571429 40.1928571429);
|
|
39
|
+
--color-dm-input-text: var(--tw-color-dm-text);
|
|
40
|
+
--color-dm-input-border: var(--tw-color-dm-border);
|
|
41
|
+
--color-dm-table-highlight: var(--tw-color-dm-border);
|
|
42
|
+
|
|
43
|
+
/* TODO Remove these two colors */
|
|
44
|
+
--color-brand: #4696e5;
|
|
45
|
+
--color-brand-dark: #1f69c0;
|
|
46
|
+
|
|
47
|
+
/* General color palette */
|
|
48
|
+
--color-danger: #dc3545;
|
|
49
|
+
--color-danger-dark: #bb2d3b;
|
|
50
|
+
--color-warning: #ffc107;
|
|
51
|
+
--color-warning-dark: #ffca2c;
|
|
52
|
+
--color-placeholder: #6c757d;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@layer base {
|
|
56
|
+
html:not([data-theme='dark']) {
|
|
57
|
+
--primary-color: var(--tw-color-lm-primary);
|
|
58
|
+
--primary-color-alfa: var(--tw-color-lm-primary-alfa);
|
|
59
|
+
--secondary-color: var(--tw-color-lm-secondary);
|
|
60
|
+
--text-color: var(--tw-color-lm-text);
|
|
61
|
+
--border-color: var(--tw-color-lm-border);
|
|
62
|
+
--active-color: var(--tw-color-lm-active);
|
|
63
|
+
--brand-color: var(--tw-color-lm-brand);
|
|
64
|
+
--input-color: var(--tw-color-lm-input);
|
|
65
|
+
--input-disabled-color: var(--tw-color-lm-disabled-input);
|
|
66
|
+
--input-text-color: var(--tw-color-lm-input-text);
|
|
67
|
+
--input-border-color: var(--tw-color-lm-input-border);
|
|
68
|
+
--table-border-color: var(--tw-color-lm-table-border);
|
|
69
|
+
--table-highlight-color: var(--tw-color-lm-table-highlight);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
html[data-theme='dark'] {
|
|
73
|
+
--primary-color: var(--tw-color-dm-primary);
|
|
74
|
+
--primary-color-alfa: var(--tw-color-dm-primary-alfa);
|
|
75
|
+
--secondary-color: var(--tw-color-dm-secondary);
|
|
76
|
+
--text-color: var(--tw-color-dm-text);
|
|
77
|
+
--border-color: var(--tw-color-dm-border);
|
|
78
|
+
--active-color: var(--tw-color-dm-active);
|
|
79
|
+
--brand-color: var(--tw-color-dm-brand);
|
|
80
|
+
--input-color: var(--tw-color-dm-input);
|
|
81
|
+
--input-disabled-color: var(--tw-color-dm-disabled-input);
|
|
82
|
+
--input-text-color: var(--tw-color-dm-input-text);
|
|
83
|
+
--input-border-color: var(--tw-color-dm-input-border);
|
|
84
|
+
--table-border-color: var(--tw-color-dm-table-border);
|
|
85
|
+
--table-highlight-color: var(--tw-color-dm-table-highlight);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
@layer base {
|
|
90
|
+
:root {
|
|
91
|
+
--header-height: 56px;
|
|
92
|
+
@apply tw:scheme-normal tw:dark:scheme-dark tw:scroll-auto;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
html, body {
|
|
96
|
+
@apply tw:h-full tw:bg-lm-secondary tw:dark:bg-dm-secondary tw:text-lm-text tw:dark:text-dm-text;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
a {
|
|
100
|
+
/* Set these styles as plain CSS instead of @apply to avoid higher specificity */
|
|
101
|
+
/* TODO Use `main` color, not `brand` color */
|
|
102
|
+
color: var(--tw-color-brand);
|
|
103
|
+
border-radius: var(--tw-radius-xs);
|
|
104
|
+
|
|
105
|
+
@apply tw:focus-visible:outline-3 tw:focus-visible:outline-brand/50 tw:focus-visible:outline-offset-3 tw:focus-visible:z-1;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
h1 {
|
|
109
|
+
@apply tw:text-[2.5rem]/[1.2] tw:m-0 tw:font-medium;
|
|
110
|
+
}
|
|
111
|
+
h2 {
|
|
112
|
+
@apply tw:text-[2rem]/[1.2] tw:m-0 tw:font-medium;
|
|
113
|
+
}
|
|
114
|
+
h3 {
|
|
115
|
+
@apply tw:text-[1.75rem]/[1.2] tw:m-0 tw:font-medium;
|
|
116
|
+
}
|
|
117
|
+
h4 {
|
|
118
|
+
@apply tw:text-2xl/[1.2] tw:m-0 tw:font-medium;
|
|
119
|
+
}
|
|
120
|
+
h5 {
|
|
121
|
+
@apply tw:text-xl/[1.2] tw:m-0 tw:font-medium;
|
|
122
|
+
}
|
|
123
|
+
h6 {
|
|
124
|
+
@apply tw:text-base/[1.2] tw:m-0 tw:font-medium;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
hr {
|
|
128
|
+
@apply tw:my-3
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
p {
|
|
132
|
+
@apply tw:m-0;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
@utility focus-ring-base {
|
|
137
|
+
@apply tw:outline-none tw:focus-visible:ring-3 tw:focus-visible:z-1 tw:transition-[box-shadow];
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
@utility focus-ring {
|
|
141
|
+
@apply tw:focus-ring-base tw:focus-visible:ring-brand/50;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
@utility focus-ring-danger {
|
|
145
|
+
@apply tw:focus-ring-base tw:focus-visible:ring-danger/50;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
@custom-variant highlight {
|
|
149
|
+
&:hover,
|
|
150
|
+
&:focus {
|
|
151
|
+
@slot;
|
|
152
|
+
}
|
|
153
|
+
}
|
package/package.json
CHANGED
|
@@ -7,19 +7,30 @@
|
|
|
7
7
|
"type": "module",
|
|
8
8
|
"main": "./dist/index.js",
|
|
9
9
|
"types": "./dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"types": "./dist/index.d.ts"
|
|
14
|
+
},
|
|
15
|
+
"./tailwind": {
|
|
16
|
+
"import": "./dist/tailwind.js",
|
|
17
|
+
"types": "./dist/tailwind.d.ts"
|
|
18
|
+
},
|
|
19
|
+
"./tailwind.preset.css": {
|
|
20
|
+
"style": "./dist/tailwind.preset.css",
|
|
21
|
+
"default": "./dist/tailwind.preset.css"
|
|
22
|
+
},
|
|
23
|
+
"./package.json": "./package.json"
|
|
24
|
+
},
|
|
10
25
|
"files": [
|
|
11
26
|
"dist"
|
|
12
27
|
],
|
|
13
28
|
"scripts": {
|
|
14
|
-
"build": "vite build && cp ./src/base.scss ./dist/base.scss",
|
|
29
|
+
"build": "vite build && cp ./src/base.scss ./dist/base.scss && cp ./src/tailwind/tailwind.preset.css ./dist/tailwind.preset.css",
|
|
15
30
|
"test": "vitest run",
|
|
16
31
|
"test:ci": "npm run test -- --coverage",
|
|
17
|
-
"lint": "
|
|
18
|
-
"lint:
|
|
19
|
-
"lint:js": "eslint dev src test",
|
|
20
|
-
"lint:fix": "npm run lint:css:fix && npm run lint:js:fix",
|
|
21
|
-
"lint:css:fix": "npm run lint:css -- --fix",
|
|
22
|
-
"lint:js:fix": "npm run lint:js -- --fix",
|
|
32
|
+
"lint": "eslint dev src test",
|
|
33
|
+
"lint:fix": "npm run lint:js -- --fix",
|
|
23
34
|
"types": "tsc",
|
|
24
35
|
"dev": "vite serve --host=0.0.0.0 --port 3001"
|
|
25
36
|
},
|
|
@@ -33,37 +44,42 @@
|
|
|
33
44
|
"react": "^18.3 || ^19.0",
|
|
34
45
|
"react-dom": "^18.3 || ^19.0",
|
|
35
46
|
"react-router": "^7.0.2",
|
|
36
|
-
"reactstrap": "^9.2.0"
|
|
47
|
+
"reactstrap": "^9.2.0",
|
|
48
|
+
"tailwindcss": "^4.0.1"
|
|
49
|
+
},
|
|
50
|
+
"peerDependenciesMeta": {
|
|
51
|
+
"tailwindcss": {
|
|
52
|
+
"optional": true
|
|
53
|
+
}
|
|
37
54
|
},
|
|
38
55
|
"devDependencies": {
|
|
39
56
|
"@shlinkio/eslint-config-js-coding-standard": "~3.4.0",
|
|
40
|
-
"@
|
|
41
|
-
"@
|
|
57
|
+
"@stylistic/eslint-plugin": "^4.2.0",
|
|
58
|
+
"@tailwindcss/vite": "^4.0.16",
|
|
42
59
|
"@testing-library/jest-dom": "^6.6.3",
|
|
43
60
|
"@testing-library/react": "^16.2.0",
|
|
44
61
|
"@testing-library/user-event": "^14.6.1",
|
|
45
62
|
"@total-typescript/shoehorn": "^0.1.2",
|
|
46
|
-
"@types/react": "^19.0.
|
|
63
|
+
"@types/react": "^19.0.12",
|
|
47
64
|
"@types/react-dom": "^19.0.4",
|
|
48
65
|
"@vitejs/plugin-react": "^4.3.4",
|
|
49
|
-
"@vitest/coverage-v8": "^3.0.
|
|
50
|
-
"axe-core": "^4.10.
|
|
66
|
+
"@vitest/coverage-v8": "^3.0.9",
|
|
67
|
+
"axe-core": "^4.10.3",
|
|
51
68
|
"bootstrap": "5.2.3",
|
|
52
|
-
"eslint": "^9.
|
|
69
|
+
"eslint": "^9.23.0",
|
|
53
70
|
"eslint-plugin-jsx-a11y": "^6.10.2",
|
|
54
71
|
"eslint-plugin-react": "^7.37.4",
|
|
55
|
-
"eslint-plugin-react-compiler": "^19.0.0-beta-
|
|
72
|
+
"eslint-plugin-react-compiler": "^19.0.0-beta-714736e-20250131",
|
|
56
73
|
"eslint-plugin-react-hooks": "^5.2.0",
|
|
57
74
|
"eslint-plugin-simple-import-sort": "^12.1.1",
|
|
58
75
|
"history": "^5.3.0",
|
|
59
76
|
"jsdom": "^26.0.0",
|
|
60
77
|
"resize-observer-polyfill": "^1.5.1",
|
|
61
|
-
"sass": "^1.
|
|
62
|
-
"
|
|
63
|
-
"typescript": "^
|
|
64
|
-
"
|
|
65
|
-
"vite": "^
|
|
66
|
-
"vite-plugin-dts": "^4.5.1",
|
|
78
|
+
"sass": "^1.86.0",
|
|
79
|
+
"typescript": "^5.8.2",
|
|
80
|
+
"typescript-eslint": "^8.27.0",
|
|
81
|
+
"vite": "^6.2.2",
|
|
82
|
+
"vite-plugin-dts": "^4.5.3",
|
|
67
83
|
"vitest": "^3.0.2"
|
|
68
84
|
},
|
|
69
85
|
"browserslist": [
|
|
@@ -72,5 +88,5 @@
|
|
|
72
88
|
"not ie <= 11",
|
|
73
89
|
"not op_mini all"
|
|
74
90
|
],
|
|
75
|
-
"version": "0.
|
|
91
|
+
"version": "0.8.1"
|
|
76
92
|
}
|