@xex/ui 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-3M3PAPT3.js → chunk-DBZZKHSF.js} +2 -2
- package/dist/font-picker.js +12 -12
- package/dist/index.d.ts +1 -1
- package/dist/index.js +54 -54
- package/package.json +13 -4
|
@@ -29,10 +29,10 @@ import clsx2 from "clsx";
|
|
|
29
29
|
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
30
30
|
var variants = {
|
|
31
31
|
primary: "bg-brand-600 hover:bg-brand-700 text-white shadow-sm",
|
|
32
|
-
secondary: "bg-
|
|
32
|
+
secondary: "bg-surface border border-gray-300 text-gray-700 hover:bg-gray-50 shadow-sm",
|
|
33
33
|
ghost: "bg-transparent text-gray-600 hover:bg-gray-100",
|
|
34
34
|
danger: "bg-red-600 hover:bg-red-700 text-white shadow-sm",
|
|
35
|
-
outline: "border border-brand-500 text-
|
|
35
|
+
outline: "border border-brand-500 text-accent hover:bg-accent-soft bg-transparent"
|
|
36
36
|
};
|
|
37
37
|
var sizes2 = {
|
|
38
38
|
xs: "px-2 py-1 text-xs rounded-md gap-1",
|
package/dist/font-picker.js
CHANGED
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
Button,
|
|
3
3
|
LoadingDots,
|
|
4
4
|
useTheme
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-DBZZKHSF.js";
|
|
6
6
|
|
|
7
7
|
// src/font-picker/FontPicker.tsx
|
|
8
8
|
import { useEffect as useEffect2, useId, useLayoutEffect, useMemo, useRef, useState as useState2 } from "react";
|
|
@@ -193,16 +193,16 @@ function FontPicker() {
|
|
|
193
193
|
openList();
|
|
194
194
|
}
|
|
195
195
|
},
|
|
196
|
-
className: "flex w-full cursor-default items-center justify-between rounded-lg border border-gray-300 bg-
|
|
196
|
+
className: "flex w-full cursor-default items-center justify-between rounded-lg border border-gray-300 bg-surface px-3 py-2 text-left text-sm text-gray-900 focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400",
|
|
197
197
|
children: [
|
|
198
198
|
/* @__PURE__ */ jsx("span", { className: "truncate", style: { fontFamily: fontStack(font) }, children: font.family }),
|
|
199
|
-
/* @__PURE__ */ jsx(ChevronUpDownIcon, { className: "h-5 w-5 shrink-0 text-gray-
|
|
199
|
+
/* @__PURE__ */ jsx(ChevronUpDownIcon, { className: "h-5 w-5 shrink-0 text-gray-500" })
|
|
200
200
|
]
|
|
201
201
|
}
|
|
202
202
|
),
|
|
203
|
-
open && /* @__PURE__ */ jsxs("div", { className: "absolute left-0 right-0 z-40 mt-1 rounded-xl border border-gray-200 bg-
|
|
203
|
+
open && /* @__PURE__ */ jsxs("div", { className: "absolute left-0 right-0 z-40 mt-1 rounded-xl border border-gray-200 bg-surface p-2 shadow-xl", children: [
|
|
204
204
|
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
205
|
-
/* @__PURE__ */ jsx(MagnifyingGlassIcon, { className: "pointer-events-none absolute left-2.5 top-1/2 h-4 w-4 -translate-y-1/2 text-gray-
|
|
205
|
+
/* @__PURE__ */ jsx(MagnifyingGlassIcon, { className: "pointer-events-none absolute left-2.5 top-1/2 h-4 w-4 -translate-y-1/2 text-gray-500" }),
|
|
206
206
|
/* @__PURE__ */ jsx(
|
|
207
207
|
"input",
|
|
208
208
|
{
|
|
@@ -217,7 +217,7 @@ function FontPicker() {
|
|
|
217
217
|
"aria-label": "Search fonts",
|
|
218
218
|
"aria-activedescendant": matches[active] ? optId(active) : void 0,
|
|
219
219
|
placeholder: "Search Google Fonts\u2026",
|
|
220
|
-
className: "w-full rounded-lg border border-gray-300 bg-
|
|
220
|
+
className: "w-full rounded-lg border border-gray-300 bg-surface py-1.5 pl-8 pr-2 text-sm text-gray-900 placeholder:text-gray-400 focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400"
|
|
221
221
|
}
|
|
222
222
|
)
|
|
223
223
|
] }),
|
|
@@ -239,7 +239,7 @@ function FontPicker() {
|
|
|
239
239
|
"Loading fonts ",
|
|
240
240
|
/* @__PURE__ */ jsx(LoadingDots, {})
|
|
241
241
|
] }),
|
|
242
|
-
catalog.status === "error" && /* @__PURE__ */ jsxs("li", { className: "px-3 py-2 text-sm text-
|
|
242
|
+
catalog.status === "error" && /* @__PURE__ */ jsxs("li", { className: "px-3 py-2 text-sm text-danger-ink", children: [
|
|
243
243
|
"Couldn\u2019t load the font list.",
|
|
244
244
|
" ",
|
|
245
245
|
/* @__PURE__ */ jsx("button", { type: "button", className: "font-medium underline", onClick: catalog.retry, children: "Retry" })
|
|
@@ -254,19 +254,19 @@ function FontPicker() {
|
|
|
254
254
|
className: clsx(
|
|
255
255
|
"flex w-full cursor-default items-center justify-between rounded-md px-3 py-1.5 text-left text-sm text-gray-800",
|
|
256
256
|
i === active && "bg-gray-100 ring-2 ring-inset ring-brand-300",
|
|
257
|
-
f.family === font.family && "bg-
|
|
257
|
+
f.family === font.family && "bg-accent-soft font-medium"
|
|
258
258
|
),
|
|
259
259
|
children: [
|
|
260
260
|
/* @__PURE__ */ jsx("span", { style: { fontFamily: fontStack(f) }, children: f.family }),
|
|
261
|
-
/* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2 text-xs text-gray-
|
|
261
|
+
/* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2 text-xs text-gray-500", children: [
|
|
262
262
|
f.category,
|
|
263
|
-
f.family === font.family && /* @__PURE__ */ jsx(CheckIcon, { className: "h-4 w-4 text-
|
|
263
|
+
f.family === font.family && /* @__PURE__ */ jsx(CheckIcon, { className: "h-4 w-4 text-accent" })
|
|
264
264
|
] })
|
|
265
265
|
]
|
|
266
266
|
}
|
|
267
267
|
) }, f.family)),
|
|
268
268
|
catalog.status === "ready" && matches.length === 0 && /* @__PURE__ */ jsx("li", { className: "px-3 py-2 text-sm text-gray-500", children: "No fonts match." }),
|
|
269
|
-
visible < matches.length && /* @__PURE__ */ jsxs("li", { className: "px-3 py-2 text-xs text-gray-
|
|
269
|
+
visible < matches.length && /* @__PURE__ */ jsxs("li", { className: "px-3 py-2 text-xs text-gray-500", children: [
|
|
270
270
|
"Showing ",
|
|
271
271
|
visible,
|
|
272
272
|
" of ",
|
|
@@ -282,7 +282,7 @@ function FontPicker() {
|
|
|
282
282
|
/* @__PURE__ */ jsxs("p", { className: "text-sm text-gray-500", children: [
|
|
283
283
|
"Selected: ",
|
|
284
284
|
/* @__PURE__ */ jsx("span", { className: "font-semibold text-gray-900", children: font.family }),
|
|
285
|
-
font.stack ? "" : /* @__PURE__ */ jsxs("span", { className: "text-gray-
|
|
285
|
+
font.stack ? "" : /* @__PURE__ */ jsxs("span", { className: "text-gray-500", children: [
|
|
286
286
|
" \xB7 ",
|
|
287
287
|
font.category
|
|
288
288
|
] })
|
package/dist/index.d.ts
CHANGED
|
@@ -137,7 +137,7 @@ interface DataTableColumn<T> {
|
|
|
137
137
|
sortable?: boolean;
|
|
138
138
|
/** Adds a multi-select dropdown listing this column's distinct values (OR within a column, AND across columns). Default: false. */
|
|
139
139
|
filter?: boolean;
|
|
140
|
-
/** Placeholder for that dropdown, e.g. "All roles". */
|
|
140
|
+
/** Placeholder for that dropdown, e.g. "All roles". Defaults to "Any <header>". */
|
|
141
141
|
filterLabel?: string;
|
|
142
142
|
align?: 'left' | 'right';
|
|
143
143
|
/** Default width as a relative weight (a column with 2 starts twice as wide as one with 1). Default: 1. */
|
package/dist/index.js
CHANGED
|
@@ -4,18 +4,18 @@ import {
|
|
|
4
4
|
Spinner,
|
|
5
5
|
ThemeProvider,
|
|
6
6
|
useTheme
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-DBZZKHSF.js";
|
|
8
8
|
|
|
9
9
|
// src/components/Badge.tsx
|
|
10
10
|
import clsx from "clsx";
|
|
11
11
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
12
12
|
var variants = {
|
|
13
|
-
default: { pill: "bg-
|
|
14
|
-
success: { pill: "bg-
|
|
15
|
-
warning: { pill: "bg-
|
|
16
|
-
danger: { pill: "bg-
|
|
17
|
-
info: { pill: "bg-
|
|
18
|
-
purple: { pill: "bg-purple-
|
|
13
|
+
default: { pill: "bg-accent-softer text-accent", dot: "bg-brand-500" },
|
|
14
|
+
success: { pill: "bg-success-soft text-success-ink", dot: "bg-success" },
|
|
15
|
+
warning: { pill: "bg-warning-soft text-warning-ink", dot: "bg-warning" },
|
|
16
|
+
danger: { pill: "bg-danger-soft text-danger-ink", dot: "bg-danger" },
|
|
17
|
+
info: { pill: "bg-info-soft text-info-ink", dot: "bg-info" },
|
|
18
|
+
purple: { pill: "bg-purple-soft text-purple-ink", dot: "bg-purple" },
|
|
19
19
|
gray: { pill: "bg-gray-100 text-gray-700", dot: "bg-gray-500" }
|
|
20
20
|
};
|
|
21
21
|
function Badge({ variant = "default", dot = false, className, children }) {
|
|
@@ -128,7 +128,7 @@ function Modal({ open, onClose, title, footer, size = "md", ariaLabel, children
|
|
|
128
128
|
"aria-label": title ? void 0 : ariaLabel,
|
|
129
129
|
tabIndex: -1,
|
|
130
130
|
onKeyDown: trapTab,
|
|
131
|
-
className: clsx2("relative flex max-h-[90vh] w-full flex-col rounded-2xl bg-
|
|
131
|
+
className: clsx2("relative flex max-h-[90vh] w-full flex-col rounded-2xl bg-surface shadow-2xl focus:outline-none", sizes[size]),
|
|
132
132
|
children: [
|
|
133
133
|
title && /* @__PURE__ */ jsxs2("div", { className: "flex items-center justify-between border-b border-gray-100 px-6 py-4", children: [
|
|
134
134
|
/* @__PURE__ */ jsx2("h2", { id: titleId, className: "text-lg font-semibold text-gray-900", children: title }),
|
|
@@ -138,7 +138,7 @@ function Modal({ open, onClose, title, footer, size = "md", ariaLabel, children
|
|
|
138
138
|
type: "button",
|
|
139
139
|
onClick: onClose,
|
|
140
140
|
"aria-label": "Close",
|
|
141
|
-
className: "rounded-lg p-1 text-gray-
|
|
141
|
+
className: "rounded-lg p-1 text-gray-500 hover:bg-gray-100 hover:text-gray-600 focus:outline-none focus-visible:ring-2 focus-visible:ring-brand-400",
|
|
142
142
|
children: /* @__PURE__ */ jsx2(XMarkIcon, { className: "h-5 w-5" })
|
|
143
143
|
}
|
|
144
144
|
)
|
|
@@ -165,11 +165,11 @@ function ConfirmDialog({
|
|
|
165
165
|
onCancel
|
|
166
166
|
}) {
|
|
167
167
|
return /* @__PURE__ */ jsxs3(Modal, { open, onClose: onCancel, size: "lg", ariaLabel: title, children: [
|
|
168
|
-
/* @__PURE__ */ jsxs3("div", { role: "alert", className: "flex items-start gap-3 rounded-xl border border-
|
|
169
|
-
/* @__PURE__ */ jsx3(ExclamationTriangleIcon, { className: "mt-0.5 h-6 w-6 shrink-0 text-
|
|
168
|
+
/* @__PURE__ */ jsxs3("div", { role: "alert", className: "flex items-start gap-3 rounded-xl border border-danger-line bg-danger-soft p-4", children: [
|
|
169
|
+
/* @__PURE__ */ jsx3(ExclamationTriangleIcon, { className: "mt-0.5 h-6 w-6 shrink-0 text-danger-ink" }),
|
|
170
170
|
/* @__PURE__ */ jsxs3("div", { children: [
|
|
171
|
-
/* @__PURE__ */ jsx3("p", { className: "font-bold text-
|
|
172
|
-
/* @__PURE__ */ jsx3("p", { className: "mt-1 text-sm text-
|
|
171
|
+
/* @__PURE__ */ jsx3("p", { className: "font-bold text-danger-ink", children: title }),
|
|
172
|
+
/* @__PURE__ */ jsx3("p", { className: "mt-1 text-sm text-danger-ink", children: message })
|
|
173
173
|
] })
|
|
174
174
|
] }),
|
|
175
175
|
/* @__PURE__ */ jsxs3("div", { className: "mt-5 flex justify-end gap-2", children: [
|
|
@@ -197,10 +197,10 @@ function Select({ label, options, placeholder, error, hint, className, id, disab
|
|
|
197
197
|
disabled,
|
|
198
198
|
"aria-invalid": !!error || void 0,
|
|
199
199
|
className: clsx3(
|
|
200
|
-
"w-full appearance-none rounded-lg border bg-
|
|
200
|
+
"w-full appearance-none rounded-lg border bg-surface px-3 py-2 pr-9 text-sm text-gray-900",
|
|
201
201
|
"focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400",
|
|
202
202
|
"disabled:bg-gray-50 disabled:text-gray-400 disabled:cursor-not-allowed",
|
|
203
|
-
error ? "border-
|
|
203
|
+
error ? "border-danger" : "border-gray-300"
|
|
204
204
|
),
|
|
205
205
|
...rest,
|
|
206
206
|
children: [
|
|
@@ -209,9 +209,9 @@ function Select({ label, options, placeholder, error, hint, className, id, disab
|
|
|
209
209
|
]
|
|
210
210
|
}
|
|
211
211
|
),
|
|
212
|
-
/* @__PURE__ */ jsx4(ChevronDownIcon, { className: "pointer-events-none absolute right-3 top-1/2 h-5 w-5 -translate-y-1/2 text-gray-
|
|
212
|
+
/* @__PURE__ */ jsx4(ChevronDownIcon, { className: "pointer-events-none absolute right-3 top-1/2 h-5 w-5 -translate-y-1/2 text-gray-500" })
|
|
213
213
|
] }),
|
|
214
|
-
error ? /* @__PURE__ */ jsx4("p", { className: "mt-1 text-xs text-
|
|
214
|
+
error ? /* @__PURE__ */ jsx4("p", { className: "mt-1 text-xs text-danger-ink", children: error }) : hint ? /* @__PURE__ */ jsx4("p", { className: "mt-1 text-xs text-gray-500", children: hint }) : null
|
|
215
215
|
] });
|
|
216
216
|
}
|
|
217
217
|
|
|
@@ -225,24 +225,24 @@ function Input({ label, error, hint, icon, className, id, ...rest }) {
|
|
|
225
225
|
return /* @__PURE__ */ jsxs5("div", { className, children: [
|
|
226
226
|
label && /* @__PURE__ */ jsx5("label", { htmlFor: inputId, className: "mb-1 block text-sm font-medium text-gray-700", children: label }),
|
|
227
227
|
/* @__PURE__ */ jsxs5("div", { className: "relative", children: [
|
|
228
|
-
icon && /* @__PURE__ */ jsx5("span", { className: "pointer-events-none absolute left-3 top-1/2 flex -translate-y-1/2 items-center text-gray-
|
|
228
|
+
icon && /* @__PURE__ */ jsx5("span", { className: "pointer-events-none absolute left-3 top-1/2 flex -translate-y-1/2 items-center text-gray-500 [&>svg]:h-5 [&>svg]:w-5", children: icon }),
|
|
229
229
|
/* @__PURE__ */ jsx5(
|
|
230
230
|
"input",
|
|
231
231
|
{
|
|
232
232
|
id: inputId,
|
|
233
233
|
"aria-invalid": !!error || void 0,
|
|
234
234
|
className: clsx4(
|
|
235
|
-
"w-full rounded-lg border bg-
|
|
235
|
+
"w-full rounded-lg border bg-surface px-3 py-2 text-sm text-gray-900 placeholder:text-gray-400",
|
|
236
236
|
"focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400",
|
|
237
237
|
"disabled:cursor-not-allowed disabled:bg-gray-50 disabled:text-gray-400",
|
|
238
238
|
icon && "pl-9",
|
|
239
|
-
error ? "border-
|
|
239
|
+
error ? "border-danger" : "border-gray-300"
|
|
240
240
|
),
|
|
241
241
|
...rest
|
|
242
242
|
}
|
|
243
243
|
)
|
|
244
244
|
] }),
|
|
245
|
-
error ? /* @__PURE__ */ jsx5("p", { className: "mt-1 text-xs text-
|
|
245
|
+
error ? /* @__PURE__ */ jsx5("p", { className: "mt-1 text-xs text-danger-ink", children: error }) : hint ? /* @__PURE__ */ jsx5("p", { className: "mt-1 text-xs text-gray-500", children: hint }) : null
|
|
246
246
|
] });
|
|
247
247
|
}
|
|
248
248
|
|
|
@@ -256,7 +256,7 @@ var sizes2 = {
|
|
|
256
256
|
lg: "h-12 w-12 text-base",
|
|
257
257
|
xl: "h-14 w-14 text-lg"
|
|
258
258
|
};
|
|
259
|
-
var AVATAR_COLORS = ["#
|
|
259
|
+
var AVATAR_COLORS = ["#4f46e5", "#0369a1", "#047857", "#b45309", "#dc2626", "#7c3aed", "#db2777", "#0f766e"];
|
|
260
260
|
function initialsOf(name) {
|
|
261
261
|
const parts = name.trim().split(/\s+/).filter(Boolean);
|
|
262
262
|
if (parts.length === 0) return "?";
|
|
@@ -320,7 +320,7 @@ function PaginationBar({
|
|
|
320
320
|
/* @__PURE__ */ jsx7("div", { children: totalPages > 1 && /* @__PURE__ */ jsxs6("nav", { "aria-label": placement ? `Pagination, ${placement} table` : "Pagination", className: "flex items-center gap-1", children: [
|
|
321
321
|
/* @__PURE__ */ jsx7("button", { type: "button", className: navBtn, disabled: page <= 1, onClick: () => onPageChange(page - 1), children: "\xAB Prev" }),
|
|
322
322
|
pageWindow(page, totalPages).map(
|
|
323
|
-
(p, i) => p === null ? /* @__PURE__ */ jsx7("span", { className: "px-1 text-gray-
|
|
323
|
+
(p, i) => p === null ? /* @__PURE__ */ jsx7("span", { className: "px-1 text-gray-500", children: "\u2026" }, `gap-${i}`) : /* @__PURE__ */ jsx7(
|
|
324
324
|
"button",
|
|
325
325
|
{
|
|
326
326
|
type: "button",
|
|
@@ -349,7 +349,7 @@ function PaginationBar({
|
|
|
349
349
|
{
|
|
350
350
|
value: pageSize,
|
|
351
351
|
onChange: (e) => onPageSizeChange(Number(e.target.value)),
|
|
352
|
-
className: "rounded-md border border-gray-300 bg-
|
|
352
|
+
className: "rounded-md border border-gray-300 bg-surface px-1.5 py-1 text-sm text-gray-700 focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400",
|
|
353
353
|
children: pageSizeOptions.map((n) => /* @__PURE__ */ jsx7("option", { value: n, children: n }, n))
|
|
354
354
|
}
|
|
355
355
|
)
|
|
@@ -390,7 +390,7 @@ function SegmentedControl({ options, value, onChange, label, className }) {
|
|
|
390
390
|
onClick: () => onChange(o.value),
|
|
391
391
|
className: clsx7(
|
|
392
392
|
"rounded-md px-2.5 py-1 text-xs font-medium transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-brand-400",
|
|
393
|
-
selected ? "bg-
|
|
393
|
+
selected ? "bg-surface text-gray-900 shadow-sm" : "text-gray-600 hover:text-gray-900"
|
|
394
394
|
),
|
|
395
395
|
children: o.label
|
|
396
396
|
},
|
|
@@ -457,12 +457,12 @@ function MultiSelect({ options, value, onChange, label, className }) {
|
|
|
457
457
|
"aria-label": labels.length ? `${label}: ${labels.join(", ")}` : label,
|
|
458
458
|
onClick: () => setOpen((o) => !o),
|
|
459
459
|
className: clsx8(
|
|
460
|
-
"flex w-full items-center justify-between gap-2 rounded-lg border bg-
|
|
460
|
+
"flex w-full items-center justify-between gap-2 rounded-lg border bg-surface px-3 py-2 text-left text-sm focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400",
|
|
461
461
|
value.length ? "border-brand-500 text-gray-900" : "border-gray-300 text-gray-500"
|
|
462
462
|
),
|
|
463
463
|
children: [
|
|
464
464
|
/* @__PURE__ */ jsx9("span", { className: "truncate", children: summary }),
|
|
465
|
-
/* @__PURE__ */ jsx9(ChevronDownIcon2, { className: "h-5 w-5 shrink-0 text-gray-
|
|
465
|
+
/* @__PURE__ */ jsx9(ChevronDownIcon2, { className: "h-5 w-5 shrink-0 text-gray-500" })
|
|
466
466
|
]
|
|
467
467
|
}
|
|
468
468
|
),
|
|
@@ -475,19 +475,19 @@ function MultiSelect({ options, value, onChange, label, className }) {
|
|
|
475
475
|
onMouseDown: (e) => {
|
|
476
476
|
if (!(e.target instanceof HTMLInputElement)) e.preventDefault();
|
|
477
477
|
},
|
|
478
|
-
className: "absolute left-0 z-20 mt-1 max-h-64 min-w-full overflow-y-auto rounded-xl border border-gray-200 bg-
|
|
478
|
+
className: "absolute left-0 z-20 mt-1 max-h-64 min-w-full overflow-y-auto rounded-xl border border-gray-200 bg-surface p-1 shadow-xl",
|
|
479
479
|
children: [
|
|
480
480
|
options.map((o) => /* @__PURE__ */ jsxs7("label", { className: "flex cursor-default items-center gap-2 rounded-md px-2.5 py-1.5 text-sm text-gray-800 hover:bg-gray-50", children: [
|
|
481
481
|
/* @__PURE__ */ jsx9("input", { type: "checkbox", className: "h-4 w-4 rounded", checked: value.includes(o.value), onChange: () => toggle(o.value) }),
|
|
482
482
|
/* @__PURE__ */ jsx9("span", { className: "flex-1 whitespace-nowrap", children: o.label }),
|
|
483
|
-
o.count !== void 0 && /* @__PURE__ */ jsx9("span", { className: "text-xs tabular-nums text-gray-
|
|
483
|
+
o.count !== void 0 && /* @__PURE__ */ jsx9("span", { className: "text-xs tabular-nums text-gray-500", children: o.count })
|
|
484
484
|
] }, o.value)),
|
|
485
485
|
value.length > 0 && /* @__PURE__ */ jsx9(
|
|
486
486
|
"button",
|
|
487
487
|
{
|
|
488
488
|
type: "button",
|
|
489
489
|
onClick: () => onChange([]),
|
|
490
|
-
className: "mt-1 w-full rounded-md border-t border-gray-100 px-2.5 py-1.5 text-left text-xs font-medium text-
|
|
490
|
+
className: "mt-1 w-full rounded-md border-t border-gray-100 px-2.5 py-1.5 text-left text-xs font-medium text-accent hover:bg-gray-50 focus:outline-none focus-visible:ring-2 focus-visible:ring-brand-400",
|
|
491
491
|
children: "Clear selection"
|
|
492
492
|
}
|
|
493
493
|
)
|
|
@@ -700,7 +700,7 @@ function DataTable({
|
|
|
700
700
|
MultiSelect,
|
|
701
701
|
{
|
|
702
702
|
className: "w-full sm:w-44",
|
|
703
|
-
label: c.filterLabel ?? `
|
|
703
|
+
label: c.filterLabel ?? `Any ${c.header.toLowerCase()}`,
|
|
704
704
|
value: filters[c.id] ?? [],
|
|
705
705
|
onChange: (v) => {
|
|
706
706
|
setFilters((f) => ({ ...f, [c.id]: v }));
|
|
@@ -776,7 +776,7 @@ function DataTable({
|
|
|
776
776
|
),
|
|
777
777
|
children: [
|
|
778
778
|
/* @__PURE__ */ jsx10("span", { className: "truncate", children: c.header }),
|
|
779
|
-
/* @__PURE__ */ jsx10(Icon, { className: clsx9("h-4 w-4 shrink-0", sorted ? "text-
|
|
779
|
+
/* @__PURE__ */ jsx10(Icon, { className: clsx9("h-4 w-4 shrink-0", sorted ? "text-accent" : "text-gray-500"), "aria-hidden": "true" })
|
|
780
780
|
]
|
|
781
781
|
}
|
|
782
782
|
) : /* @__PURE__ */ jsx10("span", { className: "block truncate", children: c.header }),
|
|
@@ -822,7 +822,7 @@ function DataTable({
|
|
|
822
822
|
pageRows.length === 0 && /* @__PURE__ */ jsx10("tr", { className: "border-t border-gray-100", children: /* @__PURE__ */ jsxs8("td", { colSpan: columns.length, className: "px-4 py-10 text-center text-sm text-gray-500", children: [
|
|
823
823
|
emptyMessage,
|
|
824
824
|
" ",
|
|
825
|
-
filterActive && /* @__PURE__ */ jsx10("button", { type: "button", onClick: clearAll, className: "font-medium text-
|
|
825
|
+
filterActive && /* @__PURE__ */ jsx10("button", { type: "button", onClick: clearAll, className: "font-medium text-accent underline", children: "Clear filters" })
|
|
826
826
|
] }) })
|
|
827
827
|
] })
|
|
828
828
|
]
|
|
@@ -837,15 +837,15 @@ import clsx10 from "clsx";
|
|
|
837
837
|
import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
838
838
|
var fills = {
|
|
839
839
|
brand: "bg-brand-600",
|
|
840
|
-
success: "bg-
|
|
841
|
-
warning: "bg-
|
|
842
|
-
danger: "bg-
|
|
840
|
+
success: "bg-success",
|
|
841
|
+
warning: "bg-warning",
|
|
842
|
+
danger: "bg-danger"
|
|
843
843
|
};
|
|
844
844
|
var strokes = {
|
|
845
|
-
brand: "text-
|
|
846
|
-
success: "text-
|
|
847
|
-
warning: "text-
|
|
848
|
-
danger: "text-
|
|
845
|
+
brand: "text-accent",
|
|
846
|
+
success: "text-success",
|
|
847
|
+
warning: "text-warning",
|
|
848
|
+
danger: "text-danger"
|
|
849
849
|
};
|
|
850
850
|
var heights = { sm: "h-1", md: "h-2", lg: "h-3" };
|
|
851
851
|
function ProgressBar({ value, label, showLabel = false, tone = "brand", size = "md", className }) {
|
|
@@ -943,7 +943,7 @@ function LoadingOverlay({ loading, label = "Loading\u2026", children, className
|
|
|
943
943
|
return /* @__PURE__ */ jsxs10("div", { className: className ? `relative ${className}` : "relative", "aria-busy": loading || void 0, children: [
|
|
944
944
|
/* @__PURE__ */ jsx13("div", { inert: loading || void 0, children }),
|
|
945
945
|
loading && /* @__PURE__ */ jsxs10("div", { className: "xex-overlay absolute inset-0 z-10 flex items-center justify-center gap-3 rounded-[inherit] backdrop-blur-[1px]", children: [
|
|
946
|
-
/* @__PURE__ */ jsx13(Spinner, { size: "lg", label, className: "text-
|
|
946
|
+
/* @__PURE__ */ jsx13(Spinner, { size: "lg", label, className: "text-accent" }),
|
|
947
947
|
/* @__PURE__ */ jsx13("span", { className: "text-sm font-medium text-gray-700", "aria-hidden": "true", children: label })
|
|
948
948
|
] })
|
|
949
949
|
] });
|
|
@@ -962,12 +962,12 @@ var defaults = {
|
|
|
962
962
|
function FetchStatus({ state, messages, onRetry }) {
|
|
963
963
|
const text = messages?.[state] ?? defaults[state];
|
|
964
964
|
return /* @__PURE__ */ jsxs11("p", { role: "status", "aria-live": "polite", className: "flex items-center gap-2 text-sm", children: [
|
|
965
|
-
state === "idle" && /* @__PURE__ */ jsx14(CloudIcon, { className: "h-5 w-5 text-gray-
|
|
966
|
-
state === "loading" && /* @__PURE__ */ jsx14(Spinner, { size: "md", decorative: true, className: "text-
|
|
967
|
-
state === "success" && /* @__PURE__ */ jsx14(CheckCircleIcon, { className: "h-5 w-5 text-
|
|
968
|
-
state === "error" && /* @__PURE__ */ jsx14(ExclamationCircleIcon, { className: "h-5 w-5 text-
|
|
969
|
-
/* @__PURE__ */ jsx14("span", { className: state === "error" ? "text-
|
|
970
|
-
state === "loading" && /* @__PURE__ */ jsx14(LoadingDots, { className: "text-gray-
|
|
965
|
+
state === "idle" && /* @__PURE__ */ jsx14(CloudIcon, { className: "h-5 w-5 text-gray-500" }),
|
|
966
|
+
state === "loading" && /* @__PURE__ */ jsx14(Spinner, { size: "md", decorative: true, className: "text-accent" }),
|
|
967
|
+
state === "success" && /* @__PURE__ */ jsx14(CheckCircleIcon, { className: "h-5 w-5 text-success" }),
|
|
968
|
+
state === "error" && /* @__PURE__ */ jsx14(ExclamationCircleIcon, { className: "h-5 w-5 text-danger" }),
|
|
969
|
+
/* @__PURE__ */ jsx14("span", { className: state === "error" ? "text-danger-ink" : state === "idle" ? "text-gray-500" : "text-gray-700", children: text }),
|
|
970
|
+
state === "loading" && /* @__PURE__ */ jsx14(LoadingDots, { className: "text-gray-500" }),
|
|
971
971
|
state === "error" && onRetry && /* @__PURE__ */ jsx14(Button, { size: "xs", variant: "outline", onClick: onRetry, children: "Retry" })
|
|
972
972
|
] });
|
|
973
973
|
}
|
|
@@ -1064,7 +1064,7 @@ function Tabs({
|
|
|
1064
1064
|
"inline-flex shrink-0 items-center justify-center whitespace-nowrap font-medium transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-brand-400 disabled:cursor-not-allowed disabled:opacity-50",
|
|
1065
1065
|
sizes3[size],
|
|
1066
1066
|
fullWidth && "flex-1",
|
|
1067
|
-
variant === "underline" ? clsx12("rounded-t-lg", isSelected ? "text-
|
|
1067
|
+
variant === "underline" ? clsx12("rounded-t-lg", isSelected ? "text-accent" : "text-gray-500 hover:text-gray-800") : clsx12("rounded-full", isSelected ? "bg-brand-600 text-white" : "text-gray-600 hover:bg-gray-100")
|
|
1068
1068
|
),
|
|
1069
1069
|
children: [
|
|
1070
1070
|
item.icon,
|
|
@@ -1074,7 +1074,7 @@ function Tabs({
|
|
|
1074
1074
|
{
|
|
1075
1075
|
className: clsx12(
|
|
1076
1076
|
"rounded-full px-1.5 py-px text-[11px] font-semibold tabular-nums",
|
|
1077
|
-
isSelected ? variant === "pills" ? "bg-white/25 text-white" : "bg-
|
|
1077
|
+
isSelected ? variant === "pills" ? "bg-white/25 text-white" : "bg-accent-softer text-accent" : "bg-gray-100 text-gray-600"
|
|
1078
1078
|
),
|
|
1079
1079
|
children: item.badge
|
|
1080
1080
|
}
|
|
@@ -1107,7 +1107,7 @@ function Tabs({
|
|
|
1107
1107
|
import { Bars3Icon } from "@heroicons/react/24/outline";
|
|
1108
1108
|
import { jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1109
1109
|
function Header({ title, subtitle, actions, onMenu }) {
|
|
1110
|
-
return /* @__PURE__ */ jsxs13("header", { className: "sticky top-0 z-30 flex flex-wrap items-center justify-between gap-3 border-b border-gray-200 bg-
|
|
1110
|
+
return /* @__PURE__ */ jsxs13("header", { className: "sticky top-0 z-30 flex flex-wrap items-center justify-between gap-3 border-b border-gray-200 bg-surface px-4 py-4 sm:px-6", children: [
|
|
1111
1111
|
/* @__PURE__ */ jsxs13("div", { className: "flex min-w-0 items-center gap-3", children: [
|
|
1112
1112
|
onMenu && /* @__PURE__ */ jsx16(
|
|
1113
1113
|
"button",
|
|
@@ -1279,7 +1279,7 @@ function PageGuide({ sections }) {
|
|
|
1279
1279
|
},
|
|
1280
1280
|
className: clsx13(
|
|
1281
1281
|
"block py-1.5 pl-3 pr-2 text-sm transition-colors",
|
|
1282
|
-
i === active ? "font-medium text-
|
|
1282
|
+
i === active ? "font-medium text-accent" : "text-gray-500 hover:text-gray-900"
|
|
1283
1283
|
),
|
|
1284
1284
|
children: s.label
|
|
1285
1285
|
}
|
|
@@ -1330,7 +1330,7 @@ function Sidebar({ items, active, onSelect, open, onClose }) {
|
|
|
1330
1330
|
"aria-label": "Main navigation",
|
|
1331
1331
|
onKeyDown: open ? trapTab : void 0,
|
|
1332
1332
|
className: clsx14(
|
|
1333
|
-
"fixed inset-y-0 left-0 z-50 flex w-64 flex-col border-r border-gray-200 bg-
|
|
1333
|
+
"fixed inset-y-0 left-0 z-50 flex w-64 flex-col border-r border-gray-200 bg-surface duration-200",
|
|
1334
1334
|
"lg:sticky lg:top-0 lg:z-auto lg:h-screen lg:w-60 lg:shrink-0 lg:translate-x-0",
|
|
1335
1335
|
// Closed on small screens: invisible = out of the tab order. It switches off only after
|
|
1336
1336
|
// the slide-out finishes, but switches on immediately so focus can move in on open.
|
|
@@ -1342,7 +1342,7 @@ function Sidebar({ items, active, onSelect, open, onClose }) {
|
|
|
1342
1342
|
/* @__PURE__ */ jsx19("span", { className: "flex h-8 w-8 items-center justify-center rounded-lg bg-brand-600 text-sm font-bold text-white", children: "X" }),
|
|
1343
1343
|
/* @__PURE__ */ jsx19("span", { className: "text-lg font-bold tracking-tight text-gray-900", children: "XeX" })
|
|
1344
1344
|
] }),
|
|
1345
|
-
/* @__PURE__ */ jsx19("button", { type: "button", onClick: onClose, "aria-label": "Close navigation", className: "rounded-lg p-1 text-gray-
|
|
1345
|
+
/* @__PURE__ */ jsx19("button", { type: "button", onClick: onClose, "aria-label": "Close navigation", className: "rounded-lg p-1 text-gray-500 hover:bg-gray-100 lg:hidden", children: /* @__PURE__ */ jsx19(XMarkIcon3, { className: "h-5 w-5" }) })
|
|
1346
1346
|
] }),
|
|
1347
1347
|
/* @__PURE__ */ jsx19("nav", { className: "flex-1 space-y-1 overflow-y-auto px-3 pb-4 pt-2", children: items.map(({ id, label, icon: Icon }) => /* @__PURE__ */ jsxs16(
|
|
1348
1348
|
"a",
|
|
@@ -1411,7 +1411,7 @@ function ThemeSwitcher({ showLabels = false }) {
|
|
|
1411
1411
|
type: "button",
|
|
1412
1412
|
onClick: toggleMode,
|
|
1413
1413
|
"aria-label": `Switch to ${mode === "dark" ? "light" : "dark"} mode`,
|
|
1414
|
-
className: "flex items-center gap-1.5 rounded-lg border border-gray-300 bg-
|
|
1414
|
+
className: "flex items-center gap-1.5 rounded-lg border border-gray-300 bg-surface px-2.5 py-1.5 text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus-visible:ring-2 focus-visible:ring-brand-400",
|
|
1415
1415
|
children: [
|
|
1416
1416
|
mode === "dark" ? /* @__PURE__ */ jsx20(SunIcon, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx20(MoonIcon, { className: "h-4 w-4" }),
|
|
1417
1417
|
mode === "dark" ? "Light" : "Dark"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xex/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "XeX design system: React components, app shell and theme provider.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
@@ -46,11 +46,13 @@
|
|
|
46
46
|
"scripts": {
|
|
47
47
|
"build": "tsup",
|
|
48
48
|
"clean": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"",
|
|
49
|
-
"typecheck": "tsc --noEmit"
|
|
49
|
+
"typecheck": "tsc --noEmit",
|
|
50
|
+
"test": "vitest run",
|
|
51
|
+
"test:watch": "vitest"
|
|
50
52
|
},
|
|
51
53
|
"dependencies": {
|
|
52
54
|
"@heroicons/react": "^2.2.0",
|
|
53
|
-
"@xex/tokens": "^0.
|
|
55
|
+
"@xex/tokens": "^0.2.0",
|
|
54
56
|
"clsx": "^2.1.1"
|
|
55
57
|
},
|
|
56
58
|
"peerDependencies": {
|
|
@@ -58,9 +60,16 @@
|
|
|
58
60
|
"react-dom": "^19.0.0"
|
|
59
61
|
},
|
|
60
62
|
"devDependencies": {
|
|
63
|
+
"@testing-library/jest-dom": "^7.0.1",
|
|
64
|
+
"@testing-library/react": "^16.3.3",
|
|
65
|
+
"@testing-library/user-event": "^14.6.8",
|
|
61
66
|
"@types/react": "^19.0.0",
|
|
62
67
|
"@types/react-dom": "^19.0.0",
|
|
68
|
+
"axe-core": "^4.14.0",
|
|
69
|
+
"jsdom": "^30.1.2",
|
|
63
70
|
"tsup": "^8.3.5",
|
|
64
|
-
"typescript": "^5.7.2"
|
|
71
|
+
"typescript": "^5.7.2",
|
|
72
|
+
"vitest": "^3.2.7",
|
|
73
|
+
"vitest-axe": "^0.1.0"
|
|
65
74
|
}
|
|
66
75
|
}
|