@jerco/ui 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/index.js ADDED
@@ -0,0 +1,1693 @@
1
+ // src/provider.tsx
2
+ import { createContext, useContext, useEffect, useMemo } from "react";
3
+ import { jsx } from "react/jsx-runtime";
4
+ var DesignSystemContext = createContext({
5
+ theme: "base-light",
6
+ density: "comfortable"
7
+ });
8
+ function DesignSystemProvider({
9
+ children,
10
+ theme = "base-light",
11
+ density = "comfortable",
12
+ target
13
+ }) {
14
+ useEffect(() => {
15
+ const element = target ?? document.documentElement;
16
+ const previousTheme = element.dataset.theme;
17
+ const previousDensity = element.dataset.density;
18
+ element.setAttribute("data-theme", theme);
19
+ element.setAttribute("data-density", density);
20
+ return () => {
21
+ if (previousTheme === void 0) element.removeAttribute("data-theme");
22
+ else element.setAttribute("data-theme", previousTheme);
23
+ if (previousDensity === void 0) element.removeAttribute("data-density");
24
+ else element.setAttribute("data-density", previousDensity);
25
+ };
26
+ }, [density, target, theme]);
27
+ const value = useMemo(() => ({ theme, density }), [density, theme]);
28
+ return /* @__PURE__ */ jsx(DesignSystemContext.Provider, { value, children });
29
+ }
30
+ function useDesignSystem() {
31
+ return useContext(DesignSystemContext);
32
+ }
33
+
34
+ // src/adapters/data-table-state.ts
35
+ function parameterName(prefix, name) {
36
+ return prefix ? `${prefix}.${name}` : name;
37
+ }
38
+ function positiveInteger(value, fallback) {
39
+ const parsed = Number.parseInt(value ?? "", 10);
40
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
41
+ }
42
+ function parseDataTableUrlState(search, fallback, options = {}) {
43
+ const params = new URLSearchParams(search.startsWith("?") ? search.slice(1) : search);
44
+ const query = params.get(parameterName(options.prefix, "q")) ?? fallback.query;
45
+ const pageSize = positiveInteger(
46
+ params.get(parameterName(options.prefix, "pageSize")),
47
+ fallback.pagination.pageSize
48
+ );
49
+ const page = positiveInteger(
50
+ params.get(parameterName(options.prefix, "page")),
51
+ fallback.pagination.pageIndex + 1
52
+ );
53
+ const sortingValue = params.get(parameterName(options.prefix, "sort"));
54
+ const sorting = sortingValue ? sortingValue.split(",").map((entry) => entry.trim()).filter(Boolean).map((entry) => {
55
+ const separator = entry.lastIndexOf(":");
56
+ const id = separator >= 0 ? entry.slice(0, separator) : entry;
57
+ const direction = separator >= 0 ? entry.slice(separator + 1) : "asc";
58
+ return { id, desc: direction === "desc" };
59
+ }).filter((entry) => entry.id) : fallback.sorting;
60
+ const filterPrefix = parameterName(options.prefix, "filter.");
61
+ const filters = { ...fallback.filters };
62
+ for (const [key, value] of params) {
63
+ if (key.startsWith(filterPrefix)) filters[key.slice(filterPrefix.length)] = value;
64
+ }
65
+ return {
66
+ query,
67
+ sorting,
68
+ filters,
69
+ pagination: { pageIndex: page - 1, pageSize }
70
+ };
71
+ }
72
+ function serializeDataTableUrlState(state, currentSearch = "", options = {}) {
73
+ const params = new URLSearchParams(
74
+ currentSearch.startsWith("?") ? currentSearch.slice(1) : currentSearch
75
+ );
76
+ const names = {
77
+ query: parameterName(options.prefix, "q"),
78
+ page: parameterName(options.prefix, "page"),
79
+ pageSize: parameterName(options.prefix, "pageSize"),
80
+ sorting: parameterName(options.prefix, "sort"),
81
+ filter: parameterName(options.prefix, "filter.")
82
+ };
83
+ for (const key of [...params.keys()]) {
84
+ if (key === names.query || key === names.page || key === names.pageSize || key === names.sorting || key.startsWith(names.filter)) {
85
+ params.delete(key);
86
+ }
87
+ }
88
+ if (state.query) params.set(names.query, state.query);
89
+ params.set(names.page, String(state.pagination.pageIndex + 1));
90
+ params.set(names.pageSize, String(state.pagination.pageSize));
91
+ if (state.sorting.length) {
92
+ params.set(
93
+ names.sorting,
94
+ state.sorting.map((entry) => `${entry.id}:${entry.desc ? "desc" : "asc"}`).join(",")
95
+ );
96
+ }
97
+ for (const [id, value] of Object.entries(state.filters).sort(
98
+ ([left], [right]) => left.localeCompare(right)
99
+ )) {
100
+ if (value && value !== "all") params.set(`${names.filter}${id}`, value);
101
+ }
102
+ const serialized = params.toString();
103
+ return serialized ? `?${serialized}` : "";
104
+ }
105
+ function createDataTableUrlStateAdapter(port, options = {}) {
106
+ return {
107
+ read: (fallback) => parseDataTableUrlState(port.getSearch(), fallback, options),
108
+ write: (state, mode = "push") => port.writeSearch(serializeDataTableUrlState(state, port.getSearch(), options), mode),
109
+ subscribe: (listener, fallback) => port.subscribe(() => listener(parseDataTableUrlState(port.getSearch(), fallback, options)))
110
+ };
111
+ }
112
+ function createBrowserDataTableUrlStateAdapter(options = {}) {
113
+ if (typeof window === "undefined") {
114
+ throw new Error(
115
+ "The browser URL adapter requires a window. Use createDataTableUrlStateAdapter for SSR or tests."
116
+ );
117
+ }
118
+ return createDataTableUrlStateAdapter(
119
+ {
120
+ getSearch: () => window.location.search,
121
+ writeSearch: (search, mode) => {
122
+ const url = `${window.location.pathname}${search}${window.location.hash}`;
123
+ window.history[mode === "replace" ? "replaceState" : "pushState"]({}, "", url);
124
+ },
125
+ subscribe: (listener) => {
126
+ window.addEventListener("popstate", listener);
127
+ return () => window.removeEventListener("popstate", listener);
128
+ }
129
+ },
130
+ options
131
+ );
132
+ }
133
+ function createDataTableRequestManager(loader) {
134
+ let sequence = 0;
135
+ let active;
136
+ return {
137
+ async run(state) {
138
+ active?.controller.abort();
139
+ const requestId = ++sequence;
140
+ const controller = new AbortController();
141
+ active = { requestId, controller };
142
+ try {
143
+ const value = await loader(state, { requestId, signal: controller.signal });
144
+ if (controller.signal.aborted) return { status: "aborted", requestId };
145
+ if (active?.requestId !== requestId) return { status: "stale", requestId };
146
+ active = void 0;
147
+ return { status: "applied", requestId, value };
148
+ } catch (error) {
149
+ if (controller.signal.aborted || error instanceof DOMException && error.name === "AbortError") {
150
+ return { status: "aborted", requestId };
151
+ }
152
+ if (active?.requestId !== requestId) return { status: "stale", requestId };
153
+ active = void 0;
154
+ throw error;
155
+ }
156
+ },
157
+ cancel() {
158
+ active?.controller.abort();
159
+ active = void 0;
160
+ },
161
+ getActiveRequestId: () => active?.requestId
162
+ };
163
+ }
164
+
165
+ // src/adapters/navigation-state.ts
166
+ function createBrowserBooleanStateAdapter(key, options = {}) {
167
+ const storage = options.storage ?? (typeof window !== "undefined" ? window.localStorage : void 0);
168
+ const eventSource = options.eventSource ?? (typeof window !== "undefined" ? {
169
+ addEventListener: (type, listener) => window.addEventListener(type, listener),
170
+ removeEventListener: (type, listener) => window.removeEventListener(type, listener)
171
+ } : void 0);
172
+ if (!storage) throw new Error("A storage implementation is required outside the browser.");
173
+ return {
174
+ read: () => {
175
+ const value = storage.getItem(key);
176
+ return value === null ? void 0 : value === "true";
177
+ },
178
+ write: (value) => storage.setItem(key, String(value)),
179
+ ...eventSource ? {
180
+ subscribe: (listener) => {
181
+ const onStorage = (event) => {
182
+ if (event.key !== key) return;
183
+ listener(event.newValue === null ? void 0 : event.newValue === "true");
184
+ };
185
+ eventSource.addEventListener("storage", onStorage);
186
+ return () => eventSource.removeEventListener("storage", onStorage);
187
+ }
188
+ } : {}
189
+ };
190
+ }
191
+ function normalizePath(path) {
192
+ const withoutQuery = path.split(/[?#]/, 1)[0] ?? "/";
193
+ if (withoutQuery === "/") return "/";
194
+ return withoutQuery.replace(/\/+$/, "");
195
+ }
196
+ function matchNavigationPath(currentPath, targetPath, end = false) {
197
+ if (!targetPath.startsWith("/")) return false;
198
+ const current = normalizePath(currentPath);
199
+ const target = normalizePath(targetPath);
200
+ if (target === "/" || end) return current === target;
201
+ return current === target || current.startsWith(`${target}/`);
202
+ }
203
+
204
+ // src/components/badge.tsx
205
+ import { cn } from "@jerco/utils";
206
+ import { cva } from "class-variance-authority";
207
+ import { jsx as jsx2 } from "react/jsx-runtime";
208
+ var badgeVariants = cva("j-badge", {
209
+ variants: {
210
+ variant: {
211
+ neutral: "j-badge--neutral",
212
+ success: "j-badge--success",
213
+ warning: "j-badge--warning",
214
+ danger: "j-badge--danger",
215
+ info: "j-badge--info"
216
+ }
217
+ },
218
+ defaultVariants: { variant: "neutral" }
219
+ });
220
+ function Badge({ className, variant, ...props }) {
221
+ return /* @__PURE__ */ jsx2("span", { className: cn(badgeVariants({ variant }), className), ...props });
222
+ }
223
+
224
+ // src/components/alert-dialog.tsx
225
+ import { cn as cn2 } from "@jerco/utils";
226
+ import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog";
227
+ import { forwardRef } from "react";
228
+ import { jsx as jsx3, jsxs } from "react/jsx-runtime";
229
+ var AlertDialog = AlertDialogPrimitive.Root;
230
+ var AlertDialogTrigger = AlertDialogPrimitive.Trigger;
231
+ var AlertDialogCancel = AlertDialogPrimitive.Cancel;
232
+ var AlertDialogAction = AlertDialogPrimitive.Action;
233
+ var AlertDialogContent = forwardRef(function AlertDialogContent2({ className, ...props }, ref) {
234
+ return /* @__PURE__ */ jsxs(AlertDialogPrimitive.Portal, { children: [
235
+ /* @__PURE__ */ jsx3(AlertDialogPrimitive.Overlay, { className: "j-dialog-overlay" }),
236
+ /* @__PURE__ */ jsx3(
237
+ AlertDialogPrimitive.Content,
238
+ {
239
+ ref,
240
+ className: cn2("j-dialog-content", className),
241
+ ...props
242
+ }
243
+ )
244
+ ] });
245
+ });
246
+ var AlertDialogTitle = forwardRef(function AlertDialogTitle2({ className, ...props }, ref) {
247
+ return /* @__PURE__ */ jsx3(AlertDialogPrimitive.Title, { ref, className: cn2("j-dialog-title", className), ...props });
248
+ });
249
+ var AlertDialogDescription = forwardRef(function AlertDialogDescription2({ className, ...props }, ref) {
250
+ return /* @__PURE__ */ jsx3(
251
+ AlertDialogPrimitive.Description,
252
+ {
253
+ ref,
254
+ className: cn2("j-dialog-description", className),
255
+ ...props
256
+ }
257
+ );
258
+ });
259
+ function AlertDialogHeader({ children }) {
260
+ return /* @__PURE__ */ jsx3("div", { className: "j-dialog-header", children });
261
+ }
262
+ function AlertDialogFooter({ children }) {
263
+ return /* @__PURE__ */ jsx3("div", { className: "j-dialog-footer", children });
264
+ }
265
+
266
+ // src/components/brand-logo.tsx
267
+ import { cn as cn3 } from "@jerco/utils";
268
+ import { jsx as jsx4 } from "react/jsx-runtime";
269
+ function BrandLogo({ asset, name = "Product", className }) {
270
+ if (asset) return /* @__PURE__ */ jsx4("span", { className: cn3("j-brand-logo", className), children: asset });
271
+ return /* @__PURE__ */ jsx4(
272
+ "span",
273
+ {
274
+ className: cn3("j-brand-logo j-brand-logo--placeholder", className),
275
+ "aria-label": `${name} placeholder logo`,
276
+ children: name.slice(0, 1).toUpperCase()
277
+ }
278
+ );
279
+ }
280
+
281
+ // src/components/button.tsx
282
+ import { LoaderCircle } from "@jerco/icons";
283
+ import { cn as cn4 } from "@jerco/utils";
284
+ import { Slot } from "@radix-ui/react-slot";
285
+ import { cva as cva2 } from "class-variance-authority";
286
+ import { forwardRef as forwardRef2 } from "react";
287
+ import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
288
+ var buttonVariants = cva2("j-button", {
289
+ variants: {
290
+ variant: {
291
+ primary: "j-button--primary",
292
+ secondary: "j-button--secondary",
293
+ outline: "j-button--outline",
294
+ ghost: "j-button--ghost",
295
+ destructive: "j-button--destructive"
296
+ },
297
+ size: {
298
+ sm: "j-button--sm",
299
+ md: "j-button--md",
300
+ lg: "j-button--lg",
301
+ icon: "j-button--icon"
302
+ }
303
+ },
304
+ defaultVariants: { variant: "primary", size: "md" }
305
+ });
306
+ var Button = forwardRef2(function Button2({ className, variant, size, asChild = false, loading = false, disabled, children, ...props }, ref) {
307
+ const Component = asChild ? Slot : "button";
308
+ return /* @__PURE__ */ jsxs2(
309
+ Component,
310
+ {
311
+ ref,
312
+ className: cn4(buttonVariants({ variant, size }), className),
313
+ disabled: asChild ? void 0 : disabled || loading,
314
+ "aria-disabled": disabled || loading || void 0,
315
+ "aria-busy": loading || void 0,
316
+ ...props,
317
+ children: [
318
+ loading ? /* @__PURE__ */ jsx5(LoaderCircle, { className: "j-spinner j-icon", "aria-hidden": "true" }) : null,
319
+ children
320
+ ]
321
+ }
322
+ );
323
+ });
324
+ var IconButton = forwardRef2(function IconButton2({ label, children, ...props }, ref) {
325
+ return /* @__PURE__ */ jsx5(Button, { ref, size: "icon", "aria-label": label, ...props, children });
326
+ });
327
+
328
+ // src/components/card.tsx
329
+ import { cn as cn5 } from "@jerco/utils";
330
+ import { jsx as jsx6 } from "react/jsx-runtime";
331
+ function Card({ className, ...props }) {
332
+ return /* @__PURE__ */ jsx6("div", { className: cn5("j-card", className), ...props });
333
+ }
334
+ function CardHeader({ className, ...props }) {
335
+ return /* @__PURE__ */ jsx6("div", { className: cn5("j-card-header", className), ...props });
336
+ }
337
+ function CardTitle({ className, ...props }) {
338
+ return /* @__PURE__ */ jsx6("h3", { className: cn5("j-card-title", className), ...props });
339
+ }
340
+ function CardDescription({ className, ...props }) {
341
+ return /* @__PURE__ */ jsx6("p", { className: cn5("j-card-description", className), ...props });
342
+ }
343
+ function CardContent({ className, ...props }) {
344
+ return /* @__PURE__ */ jsx6("div", { className: cn5("j-card-content", className), ...props });
345
+ }
346
+ function CardFooter({ className, ...props }) {
347
+ return /* @__PURE__ */ jsx6("div", { className: cn5("j-card-footer", className), ...props });
348
+ }
349
+
350
+ // src/components/checkbox.tsx
351
+ import { Check } from "@jerco/icons";
352
+ import { cn as cn6 } from "@jerco/utils";
353
+ import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
354
+ import { forwardRef as forwardRef3 } from "react";
355
+ import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
356
+ var Checkbox = forwardRef3(function Checkbox2({ className, ...props }, ref) {
357
+ return /* @__PURE__ */ jsx7(CheckboxPrimitive.Root, { ref, className: cn6("j-checkbox", className), ...props, children: /* @__PURE__ */ jsx7(CheckboxPrimitive.Indicator, { className: "j-checkbox-indicator", children: /* @__PURE__ */ jsx7(Check, { "aria-hidden": "true" }) }) });
358
+ });
359
+ function CheckboxField({ label, description, id, ...props }) {
360
+ return /* @__PURE__ */ jsxs3("div", { className: "j-choice-field", children: [
361
+ /* @__PURE__ */ jsx7(Checkbox, { id, ...props }),
362
+ /* @__PURE__ */ jsxs3("div", { children: [
363
+ /* @__PURE__ */ jsx7("label", { className: "j-choice-label", htmlFor: id, children: label }),
364
+ description ? /* @__PURE__ */ jsx7("div", { className: "j-choice-description", children: description }) : null
365
+ ] })
366
+ ] });
367
+ }
368
+
369
+ // src/components/data-table.tsx
370
+ import { ChevronDown as ChevronDown2, ChevronLeft, ChevronRight as ChevronRight2, ChevronUp, Columns3, Search } from "@jerco/icons";
371
+ import { cn as cn11 } from "@jerco/utils";
372
+ import {
373
+ flexRender,
374
+ getCoreRowModel,
375
+ getPaginationRowModel,
376
+ getSortedRowModel,
377
+ useReactTable
378
+ } from "@tanstack/react-table";
379
+ import { useVirtualizer } from "@tanstack/react-virtual";
380
+ import { useMemo as useMemo2, useRef, useState } from "react";
381
+
382
+ // src/components/dropdown-menu.tsx
383
+ import { Check as Check2, ChevronRight } from "@jerco/icons";
384
+ import { cn as cn7 } from "@jerco/utils";
385
+ import * as DropdownPrimitive from "@radix-ui/react-dropdown-menu";
386
+ import { forwardRef as forwardRef4 } from "react";
387
+ import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
388
+ var DropdownMenu = DropdownPrimitive.Root;
389
+ var DropdownMenuTrigger = DropdownPrimitive.Trigger;
390
+ var DropdownMenuGroup = DropdownPrimitive.Group;
391
+ var DropdownMenuPortal = DropdownPrimitive.Portal;
392
+ var DropdownMenuSub = DropdownPrimitive.Sub;
393
+ var DropdownMenuRadioGroup = DropdownPrimitive.RadioGroup;
394
+ var DropdownMenuContent = forwardRef4(function DropdownMenuContent2({ className, sideOffset = 6, ...props }, ref) {
395
+ return /* @__PURE__ */ jsx8(DropdownPrimitive.Portal, { children: /* @__PURE__ */ jsx8(
396
+ DropdownPrimitive.Content,
397
+ {
398
+ ref,
399
+ sideOffset,
400
+ className: cn7("j-dropdown-content", className),
401
+ ...props
402
+ }
403
+ ) });
404
+ });
405
+ var DropdownMenuItem = forwardRef4(function DropdownMenuItem2({ className, inset, ...props }, ref) {
406
+ return /* @__PURE__ */ jsx8(
407
+ DropdownPrimitive.Item,
408
+ {
409
+ ref,
410
+ className: cn7("j-dropdown-item", inset && "j-dropdown-item--inset", className),
411
+ ...props
412
+ }
413
+ );
414
+ });
415
+ var DropdownMenuCheckboxItem = forwardRef4(function DropdownMenuCheckboxItem2({ className, children, ...props }, ref) {
416
+ return /* @__PURE__ */ jsxs4(
417
+ DropdownPrimitive.CheckboxItem,
418
+ {
419
+ ref,
420
+ className: cn7("j-dropdown-item j-dropdown-check-item", className),
421
+ ...props,
422
+ children: [
423
+ /* @__PURE__ */ jsx8("span", { className: "j-dropdown-indicator", children: /* @__PURE__ */ jsx8(DropdownPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx8(Check2, { "aria-hidden": "true" }) }) }),
424
+ children
425
+ ]
426
+ }
427
+ );
428
+ });
429
+ var DropdownMenuRadioItem = forwardRef4(function DropdownMenuRadioItem2({ className, children, ...props }, ref) {
430
+ return /* @__PURE__ */ jsxs4(
431
+ DropdownPrimitive.RadioItem,
432
+ {
433
+ ref,
434
+ className: cn7("j-dropdown-item j-dropdown-check-item", className),
435
+ ...props,
436
+ children: [
437
+ /* @__PURE__ */ jsx8("span", { className: "j-dropdown-indicator", children: /* @__PURE__ */ jsx8(DropdownPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx8("span", { className: "j-dropdown-dot" }) }) }),
438
+ children
439
+ ]
440
+ }
441
+ );
442
+ });
443
+ var DropdownMenuLabel = forwardRef4(function DropdownMenuLabel2({ className, ...props }, ref) {
444
+ return /* @__PURE__ */ jsx8(DropdownPrimitive.Label, { ref, className: cn7("j-dropdown-label", className), ...props });
445
+ });
446
+ var DropdownMenuSeparator = forwardRef4(function DropdownMenuSeparator2({ className, ...props }, ref) {
447
+ return /* @__PURE__ */ jsx8(
448
+ DropdownPrimitive.Separator,
449
+ {
450
+ ref,
451
+ className: cn7("j-dropdown-separator", className),
452
+ ...props
453
+ }
454
+ );
455
+ });
456
+ var DropdownMenuSubTrigger = forwardRef4(function DropdownMenuSubTrigger2({ className, children, ...props }, ref) {
457
+ return /* @__PURE__ */ jsxs4(DropdownPrimitive.SubTrigger, { ref, className: cn7("j-dropdown-item", className), ...props, children: [
458
+ children,
459
+ /* @__PURE__ */ jsx8(ChevronRight, { className: "j-dropdown-chevron", "aria-hidden": "true" })
460
+ ] });
461
+ });
462
+ var DropdownMenuSubContent = forwardRef4(function DropdownMenuSubContent2({ className, ...props }, ref) {
463
+ return /* @__PURE__ */ jsx8(
464
+ DropdownPrimitive.SubContent,
465
+ {
466
+ ref,
467
+ className: cn7("j-dropdown-content", className),
468
+ ...props
469
+ }
470
+ );
471
+ });
472
+
473
+ // src/components/input.tsx
474
+ import { cn as cn8 } from "@jerco/utils";
475
+ import {
476
+ forwardRef as forwardRef5
477
+ } from "react";
478
+ import { jsx as jsx9 } from "react/jsx-runtime";
479
+ var Input = forwardRef5(function Input2({ className, invalid, ...props }, ref) {
480
+ return /* @__PURE__ */ jsx9(
481
+ "input",
482
+ {
483
+ ref,
484
+ className: cn8("j-input", className),
485
+ "aria-invalid": invalid || void 0,
486
+ ...props
487
+ }
488
+ );
489
+ });
490
+ var Textarea = forwardRef5(function Textarea2({ className, invalid, ...props }, ref) {
491
+ return /* @__PURE__ */ jsx9(
492
+ "textarea",
493
+ {
494
+ ref,
495
+ className: cn8("j-input j-textarea", className),
496
+ "aria-invalid": invalid || void 0,
497
+ ...props
498
+ }
499
+ );
500
+ });
501
+ var Label2 = forwardRef5(
502
+ function Label3({ className, ...props }, ref) {
503
+ return /* @__PURE__ */ jsx9("label", { ref, className: cn8("j-label", className), ...props });
504
+ }
505
+ );
506
+ function Separator2({ className }) {
507
+ return /* @__PURE__ */ jsx9("div", { className: cn8("j-separator", className), role: "separator" });
508
+ }
509
+
510
+ // src/components/select.tsx
511
+ import { Check as Check3, ChevronDown } from "@jerco/icons";
512
+ import { cn as cn9 } from "@jerco/utils";
513
+ import * as SelectPrimitive from "@radix-ui/react-select";
514
+ import { forwardRef as forwardRef6 } from "react";
515
+ import { jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
516
+ function Select({
517
+ options,
518
+ label,
519
+ placeholder = "Select an option",
520
+ ...props
521
+ }) {
522
+ return /* @__PURE__ */ jsxs5(SelectPrimitive.Root, { ...props, children: [
523
+ /* @__PURE__ */ jsxs5(SelectPrimitive.Trigger, { className: "j-select", "aria-label": label, children: [
524
+ /* @__PURE__ */ jsx10(SelectPrimitive.Value, { placeholder }),
525
+ /* @__PURE__ */ jsx10(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx10(ChevronDown, { className: "j-icon", "aria-hidden": "true" }) })
526
+ ] }),
527
+ /* @__PURE__ */ jsx10(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsx10(SelectPrimitive.Content, { className: "j-select-content", position: "popper", sideOffset: 6, children: /* @__PURE__ */ jsx10(SelectPrimitive.Viewport, { children: options.map((option) => /* @__PURE__ */ jsxs5(
528
+ SelectPrimitive.Item,
529
+ {
530
+ className: "j-select-item",
531
+ value: option.value,
532
+ ...option.disabled === void 0 ? {} : { disabled: option.disabled },
533
+ children: [
534
+ /* @__PURE__ */ jsx10(SelectPrimitive.ItemText, { children: option.label }),
535
+ /* @__PURE__ */ jsx10(SelectPrimitive.ItemIndicator, { className: "j-select-check", children: /* @__PURE__ */ jsx10(Check3, { className: "j-icon", "aria-hidden": "true" }) })
536
+ ]
537
+ },
538
+ option.value
539
+ )) }) }) })
540
+ ] });
541
+ }
542
+ var SelectGroup = SelectPrimitive.Group;
543
+ var SelectValue = SelectPrimitive.Value;
544
+ var SelectLabel = forwardRef6(function SelectLabel2({ className, ...props }, ref) {
545
+ return /* @__PURE__ */ jsx10(SelectPrimitive.Label, { ref, className: cn9("j-select-label", className), ...props });
546
+ });
547
+ function NativeSelect({
548
+ label,
549
+ children,
550
+ className,
551
+ ...props
552
+ }) {
553
+ return /* @__PURE__ */ jsx10("select", { className: cn9("j-select j-native-select", className), "aria-label": label, ...props, children });
554
+ }
555
+
556
+ // src/components/skeleton.tsx
557
+ import { cn as cn10 } from "@jerco/utils";
558
+ import { jsx as jsx11 } from "react/jsx-runtime";
559
+ function Skeleton({ className, ...props }) {
560
+ return /* @__PURE__ */ jsx11("div", { className: cn10("j-skeleton", className), "aria-hidden": "true", ...props });
561
+ }
562
+
563
+ // src/components/data-table.tsx
564
+ import { Fragment, jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
565
+ function resolveUpdate(updater, current) {
566
+ return typeof updater === "function" ? updater(current) : updater;
567
+ }
568
+ function DataTable({
569
+ data,
570
+ columns,
571
+ getRowId,
572
+ getSearchText,
573
+ searchPlaceholder = "Search",
574
+ filters = [],
575
+ pageSize = 10,
576
+ paginate = true,
577
+ server,
578
+ virtualization,
579
+ loading = false,
580
+ emptyState = "No results found.",
581
+ bulkActions,
582
+ className
583
+ }) {
584
+ const [localQuery, setLocalQuery] = useState("");
585
+ const [localFilterValues, setLocalFilterValues] = useState({});
586
+ const [localSorting, setLocalSorting] = useState([]);
587
+ const [localPagination, setLocalPagination] = useState({
588
+ pageIndex: 0,
589
+ pageSize
590
+ });
591
+ const [columnVisibility, setColumnVisibility] = useState({});
592
+ const [rowSelection, setRowSelection] = useState({});
593
+ const scrollRef = useRef(null);
594
+ const query = server?.state.query ?? localQuery;
595
+ const filterValues = server?.state.filters ?? localFilterValues;
596
+ const sorting = server?.state.sorting ?? localSorting;
597
+ const pagination = server?.state.pagination ?? localPagination;
598
+ const updateServerState = (next) => {
599
+ if (!server) return;
600
+ server.onStateChange({ ...server.state, ...next });
601
+ };
602
+ const updatePagination = (updater) => {
603
+ const next = resolveUpdate(updater, pagination);
604
+ if (server) updateServerState({ pagination: next });
605
+ else setLocalPagination(next);
606
+ };
607
+ const updateSorting = (updater) => {
608
+ const next = resolveUpdate(updater, sorting);
609
+ const nextPagination = { ...pagination, pageIndex: 0 };
610
+ if (server) updateServerState({ sorting: next, pagination: nextPagination });
611
+ else {
612
+ setLocalSorting(next);
613
+ setLocalPagination(nextPagination);
614
+ }
615
+ };
616
+ const updateQuery = (next) => {
617
+ const nextPagination = { ...pagination, pageIndex: 0 };
618
+ if (server) updateServerState({ query: next, pagination: nextPagination });
619
+ else {
620
+ setLocalQuery(next);
621
+ setLocalPagination(nextPagination);
622
+ }
623
+ };
624
+ const updateFilter = (id, value) => {
625
+ const nextFilters = { ...filterValues, [id]: value };
626
+ const nextPagination = { ...pagination, pageIndex: 0 };
627
+ if (server) updateServerState({ filters: nextFilters, pagination: nextPagination });
628
+ else {
629
+ setLocalFilterValues(nextFilters);
630
+ setLocalPagination(nextPagination);
631
+ }
632
+ };
633
+ const filteredData = useMemo2(() => {
634
+ if (server) return data;
635
+ const normalized = query.trim().toLocaleLowerCase();
636
+ return data.filter((row) => {
637
+ const matchesQuery = !normalized || (getSearchText?.(row) ?? Object.values(row).join(" ")).toLocaleLowerCase().includes(normalized);
638
+ const matchesFilters = filters.every((filter) => {
639
+ const value = filterValues[filter.id];
640
+ return !value || value === "all" || filter.getValue(row) === value;
641
+ });
642
+ return matchesQuery && matchesFilters;
643
+ });
644
+ }, [data, filterValues, filters, getSearchText, query, server]);
645
+ const selectionColumn = useMemo2(
646
+ () => ({
647
+ id: "select",
648
+ size: 44,
649
+ enableSorting: false,
650
+ enableHiding: false,
651
+ header: ({ table: table2 }) => /* @__PURE__ */ jsx12(
652
+ Checkbox,
653
+ {
654
+ "aria-label": "Select all visible rows",
655
+ checked: table2.getIsAllPageRowsSelected() || (table2.getIsSomePageRowsSelected() ? "indeterminate" : false),
656
+ onCheckedChange: (checked) => table2.toggleAllPageRowsSelected(Boolean(checked))
657
+ }
658
+ ),
659
+ cell: ({ row }) => /* @__PURE__ */ jsx12(
660
+ Checkbox,
661
+ {
662
+ "aria-label": `Select row ${row.index + 1}`,
663
+ checked: row.getIsSelected(),
664
+ onCheckedChange: (checked) => row.toggleSelected(Boolean(checked))
665
+ }
666
+ )
667
+ }),
668
+ []
669
+ );
670
+ const table = useReactTable({
671
+ data: filteredData,
672
+ columns: [selectionColumn, ...columns],
673
+ ...getRowId ? { getRowId } : {},
674
+ state: { sorting, columnVisibility, rowSelection, pagination },
675
+ onSortingChange: updateSorting,
676
+ onColumnVisibilityChange: setColumnVisibility,
677
+ onRowSelectionChange: setRowSelection,
678
+ onPaginationChange: updatePagination,
679
+ getCoreRowModel: getCoreRowModel(),
680
+ ...server ? {
681
+ manualPagination: true,
682
+ manualSorting: true,
683
+ manualFiltering: true,
684
+ pageCount: server.pageCount,
685
+ rowCount: server.rowCount
686
+ } : {
687
+ getSortedRowModel: getSortedRowModel(),
688
+ ...paginate ? { getPaginationRowModel: getPaginationRowModel() } : {}
689
+ },
690
+ columnResizeMode: "onChange",
691
+ enableRowSelection: true
692
+ });
693
+ const selectedRows = table.getSelectedRowModel().rows;
694
+ const visibleColumnCount = table.getVisibleLeafColumns().length;
695
+ const rows = table.getRowModel().rows;
696
+ const rowVirtualizer = useVirtualizer({
697
+ count: virtualization ? rows.length : 0,
698
+ getScrollElement: () => scrollRef.current,
699
+ estimateSize: () => virtualization?.estimateRowHeight ?? 48,
700
+ overscan: virtualization?.overscan ?? 6
701
+ });
702
+ const virtualRows = virtualization ? rowVirtualizer.getVirtualItems() : [];
703
+ const paddingTop = virtualRows.length ? virtualRows[0].start : 0;
704
+ const paddingBottom = virtualRows.length ? rowVirtualizer.getTotalSize() - virtualRows[virtualRows.length - 1].end : 0;
705
+ const renderRow = (row) => /* @__PURE__ */ jsx12("tr", { "data-selected": row.getIsSelected() || void 0, children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsx12("td", { children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, cell.id)) }, row.id);
706
+ return /* @__PURE__ */ jsxs6("section", { className: cn11("j-data-table", className), "aria-busy": loading || void 0, children: [
707
+ /* @__PURE__ */ jsxs6("div", { className: "j-data-table-toolbar", children: [
708
+ /* @__PURE__ */ jsxs6("div", { className: "j-data-table-search", children: [
709
+ /* @__PURE__ */ jsx12(Search, { "aria-hidden": "true" }),
710
+ /* @__PURE__ */ jsx12(
711
+ Input,
712
+ {
713
+ "aria-label": searchPlaceholder,
714
+ placeholder: searchPlaceholder,
715
+ value: query,
716
+ onChange: (event) => updateQuery(event.target.value)
717
+ }
718
+ )
719
+ ] }),
720
+ filters.map((filter) => /* @__PURE__ */ jsxs6(
721
+ NativeSelect,
722
+ {
723
+ label: filter.label,
724
+ value: filterValues[filter.id] ?? "all",
725
+ onChange: (event) => updateFilter(filter.id, event.target.value),
726
+ children: [
727
+ /* @__PURE__ */ jsxs6("option", { value: "all", children: [
728
+ "All ",
729
+ filter.label.toLocaleLowerCase()
730
+ ] }),
731
+ filter.options.map((option) => /* @__PURE__ */ jsx12("option", { value: option.value, children: option.label }, option.value))
732
+ ]
733
+ },
734
+ filter.id
735
+ )),
736
+ /* @__PURE__ */ jsxs6(DropdownMenu, { children: [
737
+ /* @__PURE__ */ jsx12(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs6(Button, { variant: "outline", children: [
738
+ /* @__PURE__ */ jsx12(Columns3, { "aria-hidden": "true" }),
739
+ " Columns"
740
+ ] }) }),
741
+ /* @__PURE__ */ jsxs6(DropdownMenuContent, { align: "end", children: [
742
+ /* @__PURE__ */ jsx12(DropdownMenuLabel, { children: "Visible columns" }),
743
+ /* @__PURE__ */ jsx12(DropdownMenuSeparator, {}),
744
+ table.getAllLeafColumns().filter((column) => column.getCanHide()).map((column) => /* @__PURE__ */ jsx12(
745
+ DropdownMenuCheckboxItem,
746
+ {
747
+ checked: column.getIsVisible(),
748
+ onCheckedChange: (value) => column.toggleVisibility(Boolean(value)),
749
+ children: column.id
750
+ },
751
+ column.id
752
+ ))
753
+ ] })
754
+ ] })
755
+ ] }),
756
+ selectedRows.length > 0 ? /* @__PURE__ */ jsxs6("div", { className: "j-data-table-selection", role: "status", children: [
757
+ /* @__PURE__ */ jsxs6("span", { children: [
758
+ selectedRows.length,
759
+ " selected"
760
+ ] }),
761
+ bulkActions?.(selectedRows)
762
+ ] }) : null,
763
+ /* @__PURE__ */ jsx12(
764
+ "div",
765
+ {
766
+ ref: scrollRef,
767
+ className: cn11("j-data-table-scroll", virtualization && "j-data-table-scroll--virtual"),
768
+ style: virtualization ? { maxHeight: virtualization.height ?? 480 } : void 0,
769
+ children: /* @__PURE__ */ jsxs6("table", { "aria-rowcount": server?.rowCount, children: [
770
+ /* @__PURE__ */ jsx12("thead", { children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsx12("tr", { children: headerGroup.headers.map((header) => {
771
+ const sorted = header.column.getIsSorted();
772
+ return /* @__PURE__ */ jsxs6(
773
+ "th",
774
+ {
775
+ style: { width: header.getSize() },
776
+ scope: "col",
777
+ "aria-sort": sorted === "asc" ? "ascending" : sorted === "desc" ? "descending" : void 0,
778
+ children: [
779
+ header.isPlaceholder ? null : header.column.getCanSort() ? /* @__PURE__ */ jsxs6(
780
+ "button",
781
+ {
782
+ className: "j-data-table-sort",
783
+ onClick: header.column.getToggleSortingHandler(),
784
+ children: [
785
+ flexRender(header.column.columnDef.header, header.getContext()),
786
+ sorted === "asc" ? /* @__PURE__ */ jsx12(ChevronUp, { "aria-hidden": "true" }) : sorted === "desc" ? /* @__PURE__ */ jsx12(ChevronDown2, { "aria-hidden": "true" }) : null
787
+ ]
788
+ }
789
+ ) : flexRender(header.column.columnDef.header, header.getContext()),
790
+ header.column.getCanResize() ? /* @__PURE__ */ jsx12(
791
+ "div",
792
+ {
793
+ className: "j-data-table-resizer",
794
+ onMouseDown: header.getResizeHandler(),
795
+ onTouchStart: header.getResizeHandler()
796
+ }
797
+ ) : null
798
+ ]
799
+ },
800
+ header.id
801
+ );
802
+ }) }, headerGroup.id)) }),
803
+ /* @__PURE__ */ jsx12("tbody", { children: loading ? Array.from({ length: Math.min(pageSize, 5) }, (_, index) => /* @__PURE__ */ jsx12("tr", { children: /* @__PURE__ */ jsx12("td", { colSpan: visibleColumnCount, children: /* @__PURE__ */ jsx12(Skeleton, { className: "j-data-table-skeleton" }) }) }, index)) : rows.length ? /* @__PURE__ */ jsxs6(Fragment, { children: [
804
+ virtualization && paddingTop > 0 ? /* @__PURE__ */ jsx12("tr", { "aria-hidden": "true", children: /* @__PURE__ */ jsx12("td", { colSpan: visibleColumnCount, style: { height: paddingTop, padding: 0 } }) }) : null,
805
+ virtualization ? virtualRows.map((virtualRow) => rows[virtualRow.index]).map(renderRow) : rows.map(renderRow),
806
+ virtualization && paddingBottom > 0 ? /* @__PURE__ */ jsx12("tr", { "aria-hidden": "true", children: /* @__PURE__ */ jsx12(
807
+ "td",
808
+ {
809
+ colSpan: visibleColumnCount,
810
+ style: { height: paddingBottom, padding: 0 }
811
+ }
812
+ ) }) : null
813
+ ] }) : /* @__PURE__ */ jsx12("tr", { children: /* @__PURE__ */ jsx12("td", { className: "j-data-table-empty", colSpan: visibleColumnCount, children: emptyState }) }) })
814
+ ] })
815
+ }
816
+ ),
817
+ /* @__PURE__ */ jsxs6("div", { className: "j-data-table-footer", children: [
818
+ /* @__PURE__ */ jsx12("span", { children: server ? `${data.length} of ${server.rowCount} rows` : `${filteredData.length} rows` }),
819
+ paginate || server ? /* @__PURE__ */ jsxs6(Fragment, { children: [
820
+ /* @__PURE__ */ jsxs6("span", { children: [
821
+ "Page ",
822
+ pagination.pageIndex + 1,
823
+ " of ",
824
+ Math.max(table.getPageCount(), 1)
825
+ ] }),
826
+ /* @__PURE__ */ jsxs6("div", { className: "j-data-table-pagination", children: [
827
+ /* @__PURE__ */ jsx12(
828
+ IconButton,
829
+ {
830
+ label: "Previous page",
831
+ variant: "outline",
832
+ disabled: !table.getCanPreviousPage(),
833
+ onClick: () => table.previousPage(),
834
+ children: /* @__PURE__ */ jsx12(ChevronLeft, { "aria-hidden": "true" })
835
+ }
836
+ ),
837
+ /* @__PURE__ */ jsx12(
838
+ IconButton,
839
+ {
840
+ label: "Next page",
841
+ variant: "outline",
842
+ disabled: !table.getCanNextPage(),
843
+ onClick: () => table.nextPage(),
844
+ children: /* @__PURE__ */ jsx12(ChevronRight2, { "aria-hidden": "true" })
845
+ }
846
+ )
847
+ ] })
848
+ ] }) : null
849
+ ] })
850
+ ] });
851
+ }
852
+
853
+ // src/components/device-card.tsx
854
+ import { Router } from "@jerco/icons";
855
+ import { cn as cn13 } from "@jerco/utils";
856
+
857
+ // src/components/status-indicator.tsx
858
+ import { AlertCircle, CheckCircle2, Circle, TriangleAlert, XCircle } from "@jerco/icons";
859
+ import { cn as cn12 } from "@jerco/utils";
860
+ import { jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
861
+ var statusMeta = {
862
+ online: { defaultLabel: "Online", icon: CheckCircle2 },
863
+ healthy: { defaultLabel: "Healthy", icon: CheckCircle2 },
864
+ degraded: { defaultLabel: "Degraded", icon: TriangleAlert },
865
+ warning: { defaultLabel: "Warning", icon: TriangleAlert },
866
+ offline: { defaultLabel: "Offline", icon: XCircle },
867
+ error: { defaultLabel: "Error", icon: AlertCircle },
868
+ unknown: { defaultLabel: "Unknown", icon: Circle }
869
+ };
870
+ function StatusIndicator({
871
+ status,
872
+ label,
873
+ showIcon = true,
874
+ className
875
+ }) {
876
+ const meta = statusMeta[status];
877
+ const Icon2 = meta.icon;
878
+ const visibleLabel = label ?? meta.defaultLabel;
879
+ return /* @__PURE__ */ jsxs7(
880
+ "span",
881
+ {
882
+ className: cn12("j-status", `j-status--${status}`, className),
883
+ role: "status",
884
+ "aria-label": visibleLabel,
885
+ children: [
886
+ showIcon ? /* @__PURE__ */ jsx13(Icon2, { className: "j-status-icon", "aria-hidden": "true" }) : /* @__PURE__ */ jsx13("span", { className: "j-status-dot", "aria-hidden": "true" }),
887
+ /* @__PURE__ */ jsx13("span", { children: visibleLabel })
888
+ ]
889
+ }
890
+ );
891
+ }
892
+
893
+ // src/components/device-card.tsx
894
+ import { Fragment as Fragment2, jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
895
+ function DeviceCard({
896
+ name,
897
+ type,
898
+ status,
899
+ address,
900
+ latency,
901
+ description,
902
+ icon: Icon2 = Router,
903
+ actions,
904
+ loading = false,
905
+ className
906
+ }) {
907
+ return /* @__PURE__ */ jsx14(Card, { className: cn13("j-device-card", className), "aria-busy": loading || void 0, children: loading ? /* @__PURE__ */ jsxs8(Fragment2, { children: [
908
+ /* @__PURE__ */ jsx14(Skeleton, { className: "j-device-card-icon" }),
909
+ /* @__PURE__ */ jsx14(Skeleton, { className: "j-device-card-line" }),
910
+ /* @__PURE__ */ jsx14(Skeleton, { className: "j-device-card-line j-device-card-line--short" }),
911
+ /* @__PURE__ */ jsxs8("span", { className: "j-sr-only", children: [
912
+ "Loading ",
913
+ name
914
+ ] })
915
+ ] }) : /* @__PURE__ */ jsxs8(Fragment2, { children: [
916
+ /* @__PURE__ */ jsxs8("div", { className: "j-device-card-header", children: [
917
+ /* @__PURE__ */ jsx14("div", { className: "j-device-card-icon", children: /* @__PURE__ */ jsx14(Icon2, { "aria-hidden": "true" }) }),
918
+ /* @__PURE__ */ jsxs8("div", { children: [
919
+ /* @__PURE__ */ jsx14("h3", { children: name }),
920
+ /* @__PURE__ */ jsx14("p", { children: type })
921
+ ] }),
922
+ actions ? /* @__PURE__ */ jsx14("div", { className: "j-device-card-actions", children: actions }) : null
923
+ ] }),
924
+ /* @__PURE__ */ jsxs8("div", { className: "j-device-card-status", children: [
925
+ /* @__PURE__ */ jsx14(StatusIndicator, { status }),
926
+ latency ? /* @__PURE__ */ jsx14("span", { children: latency }) : null
927
+ ] }),
928
+ address ? /* @__PURE__ */ jsx14("code", { className: "j-device-card-address", children: address }) : null,
929
+ description ? /* @__PURE__ */ jsx14("p", { className: "j-device-card-description", children: description }) : null
930
+ ] }) });
931
+ }
932
+
933
+ // src/components/dialog.tsx
934
+ import { X } from "@jerco/icons";
935
+ import { cn as cn14 } from "@jerco/utils";
936
+ import * as DialogPrimitive from "@radix-ui/react-dialog";
937
+ import { forwardRef as forwardRef7 } from "react";
938
+ import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
939
+ var Dialog = DialogPrimitive.Root;
940
+ var DialogTrigger = DialogPrimitive.Trigger;
941
+ var DialogClose = DialogPrimitive.Close;
942
+ var DialogContent = forwardRef7(function DialogContent2({ className, children, ...props }, ref) {
943
+ return /* @__PURE__ */ jsxs9(DialogPrimitive.Portal, { children: [
944
+ /* @__PURE__ */ jsx15(DialogPrimitive.Overlay, { className: "j-dialog-overlay" }),
945
+ /* @__PURE__ */ jsxs9(DialogPrimitive.Content, { ref, className: cn14("j-dialog-content", className), ...props, children: [
946
+ children,
947
+ /* @__PURE__ */ jsx15(DialogPrimitive.Close, { asChild: true, children: /* @__PURE__ */ jsx15(IconButton, { className: "j-dialog-close", variant: "ghost", label: "Close dialog", children: /* @__PURE__ */ jsx15(X, { className: "j-icon", "aria-hidden": "true" }) }) })
948
+ ] })
949
+ ] });
950
+ });
951
+ var DialogTitle = forwardRef7(function DialogTitle2({ className, ...props }, ref) {
952
+ return /* @__PURE__ */ jsx15(DialogPrimitive.Title, { ref, className: cn14("j-dialog-title", className), ...props });
953
+ });
954
+ var DialogDescription = forwardRef7(function DialogDescription2({ className, ...props }, ref) {
955
+ return /* @__PURE__ */ jsx15(
956
+ DialogPrimitive.Description,
957
+ {
958
+ ref,
959
+ className: cn14("j-dialog-description", className),
960
+ ...props
961
+ }
962
+ );
963
+ });
964
+ function DialogHeader({ children }) {
965
+ return /* @__PURE__ */ jsx15("div", { className: "j-dialog-header", children });
966
+ }
967
+ function DialogFooter({ children }) {
968
+ return /* @__PURE__ */ jsx15("div", { className: "j-dialog-footer", children });
969
+ }
970
+
971
+ // src/components/layout.tsx
972
+ import { ChevronDown as ChevronDown3, Menu, PanelLeftClose, PanelLeftOpen, X as X2 } from "@jerco/icons";
973
+ import { cn as cn15 } from "@jerco/utils";
974
+ import {
975
+ createContext as createContext2,
976
+ Fragment as Fragment3,
977
+ useCallback,
978
+ useContext as useContext2,
979
+ useEffect as useEffect2,
980
+ useId,
981
+ useMemo as useMemo3,
982
+ useState as useState2
983
+ } from "react";
984
+ import { Fragment as Fragment4, jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
985
+ var AppShellContext = createContext2(null);
986
+ function AppShell({
987
+ className,
988
+ defaultMobileOpen = false,
989
+ defaultSidebarCollapsed = false,
990
+ sidebarCollapsed: controlledSidebarCollapsed,
991
+ onSidebarCollapsedChange,
992
+ sidebarPersistence,
993
+ ...props
994
+ }) {
995
+ const navigationId = useId();
996
+ const [mobileOpen, setMobileOpen] = useState2(defaultMobileOpen);
997
+ const [internalSidebarCollapsed, setInternalSidebarCollapsed] = useState2(
998
+ () => sidebarPersistence?.read() ?? defaultSidebarCollapsed
999
+ );
1000
+ const sidebarCollapsed = controlledSidebarCollapsed ?? internalSidebarCollapsed;
1001
+ const setSidebarCollapsed = useCallback(
1002
+ (collapsed) => {
1003
+ if (controlledSidebarCollapsed === void 0) setInternalSidebarCollapsed(collapsed);
1004
+ sidebarPersistence?.write(collapsed);
1005
+ onSidebarCollapsedChange?.(collapsed);
1006
+ },
1007
+ [controlledSidebarCollapsed, onSidebarCollapsedChange, sidebarPersistence]
1008
+ );
1009
+ useEffect2(() => {
1010
+ if (!mobileOpen) return;
1011
+ const close = (event) => {
1012
+ if (event.key === "Escape") setMobileOpen(false);
1013
+ };
1014
+ window.addEventListener("keydown", close);
1015
+ return () => window.removeEventListener("keydown", close);
1016
+ }, [mobileOpen]);
1017
+ useEffect2(() => {
1018
+ if (!sidebarPersistence?.subscribe) return;
1019
+ return sidebarPersistence.subscribe((collapsed) => {
1020
+ if (collapsed !== void 0 && controlledSidebarCollapsed === void 0) {
1021
+ setInternalSidebarCollapsed(collapsed);
1022
+ }
1023
+ });
1024
+ }, [controlledSidebarCollapsed, sidebarPersistence]);
1025
+ const value = useMemo3(
1026
+ () => ({ navigationId, mobileOpen, setMobileOpen, sidebarCollapsed, setSidebarCollapsed }),
1027
+ [mobileOpen, navigationId, setSidebarCollapsed, sidebarCollapsed]
1028
+ );
1029
+ return /* @__PURE__ */ jsx16(AppShellContext.Provider, { value, children: /* @__PURE__ */ jsx16(
1030
+ "div",
1031
+ {
1032
+ className: cn15(
1033
+ "j-app-shell",
1034
+ mobileOpen && "j-app-shell--nav-open",
1035
+ sidebarCollapsed && "j-app-shell--collapsed",
1036
+ className
1037
+ ),
1038
+ ...props
1039
+ }
1040
+ ) });
1041
+ }
1042
+ function Sidebar({ className, children, ...props }) {
1043
+ const shell = useContext2(AppShellContext);
1044
+ return /* @__PURE__ */ jsxs10(Fragment4, { children: [
1045
+ /* @__PURE__ */ jsx16(
1046
+ "button",
1047
+ {
1048
+ className: "j-sidebar-overlay",
1049
+ "aria-label": "Close navigation",
1050
+ tabIndex: shell?.mobileOpen ? 0 : -1,
1051
+ onClick: () => shell?.setMobileOpen(false)
1052
+ }
1053
+ ),
1054
+ /* @__PURE__ */ jsxs10(
1055
+ "aside",
1056
+ {
1057
+ id: shell?.navigationId,
1058
+ className: cn15("j-sidebar", className),
1059
+ "aria-label": props["aria-label"] ?? "Primary navigation",
1060
+ ...props,
1061
+ children: [
1062
+ /* @__PURE__ */ jsxs10("div", { className: "j-sidebar-mobile-header", children: [
1063
+ /* @__PURE__ */ jsx16("span", { children: "Navigation" }),
1064
+ /* @__PURE__ */ jsx16(
1065
+ IconButton,
1066
+ {
1067
+ label: "Close navigation",
1068
+ variant: "ghost",
1069
+ onClick: () => shell?.setMobileOpen(false),
1070
+ children: /* @__PURE__ */ jsx16(X2, { "aria-hidden": "true" })
1071
+ }
1072
+ )
1073
+ ] }),
1074
+ children
1075
+ ]
1076
+ }
1077
+ )
1078
+ ] });
1079
+ }
1080
+ function AppShellMenuButton({
1081
+ className,
1082
+ label = "Open navigation",
1083
+ ...props
1084
+ }) {
1085
+ const shell = useContext2(AppShellContext);
1086
+ if (!shell) throw new Error("AppShellMenuButton must be used inside AppShell");
1087
+ return /* @__PURE__ */ jsx16(
1088
+ IconButton,
1089
+ {
1090
+ className: cn15("j-app-shell-menu", className),
1091
+ label,
1092
+ variant: "ghost",
1093
+ "aria-controls": shell.navigationId,
1094
+ "aria-expanded": shell.mobileOpen,
1095
+ onClick: () => shell.setMobileOpen(!shell.mobileOpen),
1096
+ ...props,
1097
+ children: /* @__PURE__ */ jsx16(Menu, { "aria-hidden": "true" })
1098
+ }
1099
+ );
1100
+ }
1101
+ function AppShellCollapseButton({
1102
+ className,
1103
+ ...props
1104
+ }) {
1105
+ const shell = useContext2(AppShellContext);
1106
+ if (!shell) throw new Error("AppShellCollapseButton must be used inside AppShell");
1107
+ const label = shell.sidebarCollapsed ? "Expand navigation" : "Collapse navigation";
1108
+ const Icon2 = shell.sidebarCollapsed ? PanelLeftOpen : PanelLeftClose;
1109
+ return /* @__PURE__ */ jsx16(
1110
+ IconButton,
1111
+ {
1112
+ className: cn15("j-app-shell-collapse", className),
1113
+ label,
1114
+ variant: "ghost",
1115
+ "aria-pressed": shell.sidebarCollapsed,
1116
+ onClick: () => shell.setSidebarCollapsed(!shell.sidebarCollapsed),
1117
+ ...props,
1118
+ children: /* @__PURE__ */ jsx16(Icon2, { "aria-hidden": "true" })
1119
+ }
1120
+ );
1121
+ }
1122
+ function Header({ className, ...props }) {
1123
+ return /* @__PURE__ */ jsx16("header", { className: cn15("j-header", className), ...props });
1124
+ }
1125
+ function MainContent({ className, ...props }) {
1126
+ return /* @__PURE__ */ jsx16("main", { className: cn15("j-main-content", className), ...props });
1127
+ }
1128
+ function itemIsActive(item, currentPath, isPathActive) {
1129
+ if (item.active !== void 0) return item.active;
1130
+ if (!currentPath || !item.href) return false;
1131
+ return isPathActive ? isPathActive(currentPath, item.href, item) : matchNavigationPath(currentPath, item.href, item.matchEnd);
1132
+ }
1133
+ function branchIsActive(item, currentPath, isPathActive) {
1134
+ return itemIsActive(item, currentPath, isPathActive) || Boolean(item.items?.some((child) => branchIsActive(child, currentPath, isPathActive)));
1135
+ }
1136
+ function collectExpanded(items, currentPath, isPathActive, result = /* @__PURE__ */ new Set(), includeDefaults = true) {
1137
+ for (const item of items) {
1138
+ const id = item.id ?? `${item.href ?? "group"}-${item.label}`;
1139
+ if (includeDefaults && item.defaultExpanded || item.items?.some((child) => branchIsActive(child, currentPath, isPathActive))) {
1140
+ result.add(id);
1141
+ }
1142
+ if (item.items) collectExpanded(item.items, currentPath, isPathActive, result, includeDefaults);
1143
+ }
1144
+ return result;
1145
+ }
1146
+ function NavigationBranch({
1147
+ items,
1148
+ level,
1149
+ expanded,
1150
+ toggle,
1151
+ shell,
1152
+ currentPath,
1153
+ isPathActive,
1154
+ onNavigate,
1155
+ renderLink
1156
+ }) {
1157
+ return /* @__PURE__ */ jsx16(
1158
+ "div",
1159
+ {
1160
+ className: cn15("j-app-navigation-list", level > 0 && "j-app-navigation-sublist"),
1161
+ role: level > 0 ? "group" : void 0,
1162
+ children: items.map((navigationItem) => {
1163
+ const {
1164
+ id: providedId,
1165
+ label,
1166
+ icon: Icon2,
1167
+ badge,
1168
+ active,
1169
+ items: nestedItems,
1170
+ defaultExpanded,
1171
+ matchEnd,
1172
+ className,
1173
+ onClick,
1174
+ ...item
1175
+ } = navigationItem;
1176
+ const id = providedId ?? `${item.href ?? "group"}-${label}`;
1177
+ if (nestedItems?.length) {
1178
+ const open = expanded.has(id);
1179
+ const nestedActive = branchIsActive(navigationItem, currentPath, isPathActive);
1180
+ return /* @__PURE__ */ jsxs10(
1181
+ "div",
1182
+ {
1183
+ className: "j-app-navigation-group",
1184
+ "data-active": nestedActive || void 0,
1185
+ children: [
1186
+ /* @__PURE__ */ jsxs10(
1187
+ "button",
1188
+ {
1189
+ type: "button",
1190
+ className: cn15("j-app-navigation-link j-app-navigation-group-trigger", className),
1191
+ "aria-expanded": open,
1192
+ "aria-controls": `${id}-children`,
1193
+ "data-default-expanded": defaultExpanded || void 0,
1194
+ title: shell?.sidebarCollapsed ? label : void 0,
1195
+ onClick: () => toggle(id),
1196
+ children: [
1197
+ Icon2 ? /* @__PURE__ */ jsx16(Icon2, { "aria-hidden": "true" }) : null,
1198
+ /* @__PURE__ */ jsx16("span", { children: label }),
1199
+ badge ? /* @__PURE__ */ jsx16("span", { className: "j-app-navigation-badge", children: badge }) : null,
1200
+ /* @__PURE__ */ jsx16(ChevronDown3, { className: "j-app-navigation-chevron", "aria-hidden": "true" })
1201
+ ]
1202
+ }
1203
+ ),
1204
+ open ? /* @__PURE__ */ jsx16("div", { id: `${id}-children`, children: /* @__PURE__ */ jsx16(
1205
+ NavigationBranch,
1206
+ {
1207
+ items: nestedItems,
1208
+ level: level + 1,
1209
+ expanded,
1210
+ toggle,
1211
+ shell,
1212
+ currentPath,
1213
+ isPathActive,
1214
+ onNavigate,
1215
+ renderLink
1216
+ }
1217
+ ) }) : null
1218
+ ]
1219
+ },
1220
+ id
1221
+ );
1222
+ }
1223
+ const resolvedActive = active ?? (currentPath && item.href ? isPathActive ? isPathActive(currentPath, item.href, navigationItem) : matchNavigationPath(currentPath, item.href, matchEnd) : false);
1224
+ const linkClassName = cn15("j-app-navigation-link", className);
1225
+ const children = /* @__PURE__ */ jsxs10(Fragment4, { children: [
1226
+ Icon2 ? /* @__PURE__ */ jsx16(Icon2, { "aria-hidden": "true" }) : null,
1227
+ /* @__PURE__ */ jsx16("span", { children: label }),
1228
+ badge ? /* @__PURE__ */ jsx16("span", { className: "j-app-navigation-badge", children: badge }) : null
1229
+ ] });
1230
+ const handleClick = (event) => {
1231
+ onClick?.(event);
1232
+ onNavigate?.(navigationItem, event);
1233
+ if (!event.defaultPrevented) shell?.setMobileOpen(false);
1234
+ };
1235
+ return renderLink ? /* @__PURE__ */ jsx16(Fragment3, { children: renderLink({
1236
+ item: navigationItem,
1237
+ active: resolvedActive,
1238
+ className: linkClassName,
1239
+ children,
1240
+ onClick: handleClick
1241
+ }) }, id) : /* @__PURE__ */ jsx16(
1242
+ "a",
1243
+ {
1244
+ className: linkClassName,
1245
+ "aria-current": resolvedActive ? "page" : void 0,
1246
+ title: shell?.sidebarCollapsed ? label : void 0,
1247
+ onClick: handleClick,
1248
+ ...item,
1249
+ children
1250
+ },
1251
+ id
1252
+ );
1253
+ })
1254
+ }
1255
+ );
1256
+ }
1257
+ function AppNavigation({
1258
+ items,
1259
+ label = "Primary navigation",
1260
+ footer,
1261
+ currentPath,
1262
+ isPathActive,
1263
+ onNavigate,
1264
+ renderLink,
1265
+ className,
1266
+ ...props
1267
+ }) {
1268
+ const shell = useContext2(AppShellContext);
1269
+ const [expanded, setExpanded] = useState2(() => collectExpanded(items, currentPath, isPathActive));
1270
+ const visibleExpanded = useMemo3(
1271
+ () => /* @__PURE__ */ new Set([
1272
+ ...expanded,
1273
+ ...collectExpanded(items, currentPath, isPathActive, /* @__PURE__ */ new Set(), false)
1274
+ ]),
1275
+ [currentPath, expanded, isPathActive, items]
1276
+ );
1277
+ const toggle = (id) => setExpanded((current) => {
1278
+ const next = new Set(current);
1279
+ if (next.has(id)) next.delete(id);
1280
+ else next.add(id);
1281
+ return next;
1282
+ });
1283
+ return /* @__PURE__ */ jsxs10("nav", { className: cn15("j-app-navigation", className), "aria-label": label, ...props, children: [
1284
+ /* @__PURE__ */ jsx16(
1285
+ NavigationBranch,
1286
+ {
1287
+ items,
1288
+ level: 0,
1289
+ expanded: visibleExpanded,
1290
+ toggle,
1291
+ shell,
1292
+ currentPath,
1293
+ isPathActive,
1294
+ onNavigate,
1295
+ renderLink
1296
+ }
1297
+ ),
1298
+ footer ? /* @__PURE__ */ jsx16("div", { className: "j-app-navigation-footer", children: footer }) : null
1299
+ ] });
1300
+ }
1301
+ function PageHeader({
1302
+ title,
1303
+ description,
1304
+ eyebrow,
1305
+ actions,
1306
+ className,
1307
+ ...props
1308
+ }) {
1309
+ return /* @__PURE__ */ jsxs10("div", { className: cn15("j-page-header", className), ...props, children: [
1310
+ /* @__PURE__ */ jsxs10("div", { children: [
1311
+ eyebrow ? /* @__PURE__ */ jsx16("div", { className: "j-page-eyebrow", children: eyebrow }) : null,
1312
+ /* @__PURE__ */ jsx16("h1", { className: "j-page-title", children: title }),
1313
+ description ? /* @__PURE__ */ jsx16("p", { className: "j-page-description", children: description }) : null
1314
+ ] }),
1315
+ actions ? /* @__PURE__ */ jsx16("div", { className: "j-page-actions", children: actions }) : null
1316
+ ] });
1317
+ }
1318
+
1319
+ // src/components/metric-card.tsx
1320
+ import { cn as cn16 } from "@jerco/utils";
1321
+ import { Fragment as Fragment5, jsx as jsx17, jsxs as jsxs11 } from "react/jsx-runtime";
1322
+ function MetricCard({
1323
+ label,
1324
+ value,
1325
+ description,
1326
+ trend,
1327
+ status,
1328
+ icon: Icon2,
1329
+ loading = false,
1330
+ className
1331
+ }) {
1332
+ return /* @__PURE__ */ jsxs11(Card, { className: cn16("j-metric-card", className), "aria-busy": loading || void 0, children: [
1333
+ /* @__PURE__ */ jsxs11("div", { className: "j-metric-card-header", children: [
1334
+ /* @__PURE__ */ jsx17("span", { className: "j-metric-label", children: label }),
1335
+ Icon2 ? /* @__PURE__ */ jsx17(Icon2, { className: "j-metric-icon", "aria-hidden": "true" }) : null
1336
+ ] }),
1337
+ loading ? /* @__PURE__ */ jsxs11(Fragment5, { children: [
1338
+ /* @__PURE__ */ jsx17(Skeleton, { className: "j-metric-skeleton-value" }),
1339
+ /* @__PURE__ */ jsx17(Skeleton, { className: "j-metric-skeleton-text" }),
1340
+ /* @__PURE__ */ jsxs11("span", { className: "j-sr-only", children: [
1341
+ "Loading ",
1342
+ label
1343
+ ] })
1344
+ ] }) : /* @__PURE__ */ jsxs11(Fragment5, { children: [
1345
+ /* @__PURE__ */ jsx17("div", { className: "j-metric-value", children: value }),
1346
+ /* @__PURE__ */ jsxs11("div", { className: "j-metric-meta", children: [
1347
+ trend ? /* @__PURE__ */ jsx17("span", { className: "j-metric-trend", children: trend }) : null,
1348
+ status ? /* @__PURE__ */ jsx17(StatusIndicator, { status }) : null
1349
+ ] }),
1350
+ description ? /* @__PURE__ */ jsx17("p", { className: "j-metric-description", children: description }) : null
1351
+ ] })
1352
+ ] });
1353
+ }
1354
+
1355
+ // src/components/operational-state.tsx
1356
+ import { AlertCircle as AlertCircle2, Info, RefreshCw } from "@jerco/icons";
1357
+ import { cn as cn17 } from "@jerco/utils";
1358
+ import { jsx as jsx18, jsxs as jsxs12 } from "react/jsx-runtime";
1359
+ function EmptyState({
1360
+ icon: Icon2 = Info,
1361
+ title,
1362
+ description,
1363
+ action,
1364
+ compact = false,
1365
+ className
1366
+ }) {
1367
+ return /* @__PURE__ */ jsxs12(
1368
+ "div",
1369
+ {
1370
+ className: cn17("j-operational-state", compact && "j-operational-state--compact", className),
1371
+ children: [
1372
+ /* @__PURE__ */ jsx18(Icon2, { className: "j-operational-state-icon", "aria-hidden": "true" }),
1373
+ /* @__PURE__ */ jsx18("h3", { children: title }),
1374
+ /* @__PURE__ */ jsx18("p", { children: description }),
1375
+ action ? /* @__PURE__ */ jsx18("div", { className: "j-operational-state-action", children: action }) : null
1376
+ ]
1377
+ }
1378
+ );
1379
+ }
1380
+ function ErrorState({
1381
+ icon: Icon2 = AlertCircle2,
1382
+ title,
1383
+ description,
1384
+ action,
1385
+ onRetry,
1386
+ retryLabel = "Try again",
1387
+ compact = false,
1388
+ className
1389
+ }) {
1390
+ const resolvedAction = action ?? (onRetry ? /* @__PURE__ */ jsxs12(Button, { variant: "outline", onClick: onRetry, children: [
1391
+ /* @__PURE__ */ jsx18(RefreshCw, { "aria-hidden": "true" }),
1392
+ " ",
1393
+ retryLabel
1394
+ ] }) : null);
1395
+ return /* @__PURE__ */ jsxs12(
1396
+ "div",
1397
+ {
1398
+ className: cn17(
1399
+ "j-operational-state j-operational-state--error",
1400
+ compact && "j-operational-state--compact",
1401
+ className
1402
+ ),
1403
+ role: "alert",
1404
+ children: [
1405
+ /* @__PURE__ */ jsx18(Icon2, { className: "j-operational-state-icon", "aria-hidden": "true" }),
1406
+ /* @__PURE__ */ jsx18("h3", { children: title }),
1407
+ /* @__PURE__ */ jsx18("p", { children: description }),
1408
+ resolvedAction ? /* @__PURE__ */ jsx18("div", { className: "j-operational-state-action", children: resolvedAction }) : null
1409
+ ]
1410
+ }
1411
+ );
1412
+ }
1413
+
1414
+ // src/components/radio-group.tsx
1415
+ import { cn as cn18 } from "@jerco/utils";
1416
+ import * as RadioGroupPrimitive from "@radix-ui/react-radio-group";
1417
+ import { forwardRef as forwardRef8 } from "react";
1418
+ import { jsx as jsx19, jsxs as jsxs13 } from "react/jsx-runtime";
1419
+ var RadioGroup2 = forwardRef8(function RadioGroup3({ className, ...props }, ref) {
1420
+ return /* @__PURE__ */ jsx19(RadioGroupPrimitive.Root, { ref, className: cn18("j-radio-group", className), ...props });
1421
+ });
1422
+ var RadioGroupItem = forwardRef8(function RadioGroupItem2({ className, ...props }, ref) {
1423
+ return /* @__PURE__ */ jsx19(RadioGroupPrimitive.Item, { ref, className: cn18("j-radio", className), ...props, children: /* @__PURE__ */ jsx19(RadioGroupPrimitive.Indicator, { className: "j-radio-indicator" }) });
1424
+ });
1425
+ function RadioField({
1426
+ id,
1427
+ label,
1428
+ description,
1429
+ value
1430
+ }) {
1431
+ return /* @__PURE__ */ jsxs13("div", { className: "j-choice-field", children: [
1432
+ /* @__PURE__ */ jsx19(RadioGroupItem, { id, value }),
1433
+ /* @__PURE__ */ jsxs13("div", { children: [
1434
+ /* @__PURE__ */ jsx19("label", { className: "j-choice-label", htmlFor: id, children: label }),
1435
+ description ? /* @__PURE__ */ jsx19("div", { className: "j-choice-description", children: description }) : null
1436
+ ] })
1437
+ ] });
1438
+ }
1439
+
1440
+ // src/components/service-health.tsx
1441
+ import { Activity } from "@jerco/icons";
1442
+ import { cn as cn19 } from "@jerco/utils";
1443
+ import { jsx as jsx20, jsxs as jsxs14 } from "react/jsx-runtime";
1444
+ function ServiceHealth({
1445
+ name,
1446
+ status,
1447
+ endpoint,
1448
+ latency,
1449
+ description,
1450
+ meta,
1451
+ className
1452
+ }) {
1453
+ return /* @__PURE__ */ jsxs14("article", { className: cn19("j-service-health", className), children: [
1454
+ /* @__PURE__ */ jsx20("div", { className: "j-service-health-icon", children: /* @__PURE__ */ jsx20(Activity, { "aria-hidden": "true" }) }),
1455
+ /* @__PURE__ */ jsxs14("div", { className: "j-service-health-main", children: [
1456
+ /* @__PURE__ */ jsxs14("div", { className: "j-service-health-title", children: [
1457
+ /* @__PURE__ */ jsx20("h3", { children: name }),
1458
+ /* @__PURE__ */ jsx20(StatusIndicator, { status })
1459
+ ] }),
1460
+ endpoint ? /* @__PURE__ */ jsx20("code", { children: endpoint }) : null,
1461
+ description ? /* @__PURE__ */ jsx20("p", { children: description }) : null
1462
+ ] }),
1463
+ /* @__PURE__ */ jsxs14("div", { className: "j-service-health-meta", children: [
1464
+ latency ? /* @__PURE__ */ jsx20("strong", { children: latency }) : null,
1465
+ meta
1466
+ ] })
1467
+ ] });
1468
+ }
1469
+
1470
+ // src/components/spinner.tsx
1471
+ import { LoaderCircle as LoaderCircle2 } from "@jerco/icons";
1472
+ import { cn as cn20 } from "@jerco/utils";
1473
+ import { jsx as jsx21, jsxs as jsxs15 } from "react/jsx-runtime";
1474
+ function Spinner({ label = "Loading", className }) {
1475
+ return /* @__PURE__ */ jsxs15("span", { className: cn20("j-spinner-wrap", className), role: "status", children: [
1476
+ /* @__PURE__ */ jsx21(LoaderCircle2, { className: "j-spinner", "aria-hidden": "true" }),
1477
+ /* @__PURE__ */ jsx21("span", { className: "j-sr-only", children: label })
1478
+ ] });
1479
+ }
1480
+
1481
+ // src/components/switch.tsx
1482
+ import { cn as cn21 } from "@jerco/utils";
1483
+ import * as SwitchPrimitive from "@radix-ui/react-switch";
1484
+ import { forwardRef as forwardRef9 } from "react";
1485
+ import { jsx as jsx22, jsxs as jsxs16 } from "react/jsx-runtime";
1486
+ var Switch = forwardRef9(function Switch2({ className, ...props }, ref) {
1487
+ return /* @__PURE__ */ jsx22(SwitchPrimitive.Root, { ref, className: cn21("j-switch", className), ...props, children: /* @__PURE__ */ jsx22(SwitchPrimitive.Thumb, { className: "j-switch-thumb" }) });
1488
+ });
1489
+ function SwitchField({
1490
+ id,
1491
+ label,
1492
+ description,
1493
+ ...props
1494
+ }) {
1495
+ return /* @__PURE__ */ jsxs16("div", { className: "j-switch-field", children: [
1496
+ /* @__PURE__ */ jsxs16("div", { children: [
1497
+ /* @__PURE__ */ jsx22("label", { className: "j-choice-label", htmlFor: id, children: label }),
1498
+ description ? /* @__PURE__ */ jsx22("div", { className: "j-choice-description", children: description }) : null
1499
+ ] }),
1500
+ /* @__PURE__ */ jsx22(Switch, { id, ...props })
1501
+ ] });
1502
+ }
1503
+
1504
+ // src/components/tabs.tsx
1505
+ import { cn as cn22 } from "@jerco/utils";
1506
+ import * as TabsPrimitive from "@radix-ui/react-tabs";
1507
+ import { forwardRef as forwardRef10 } from "react";
1508
+ import { jsx as jsx23 } from "react/jsx-runtime";
1509
+ var Tabs = TabsPrimitive.Root;
1510
+ var TabsList = forwardRef10(function TabsList2({ className, ...props }, ref) {
1511
+ return /* @__PURE__ */ jsx23(TabsPrimitive.List, { ref, className: cn22("j-tabs-list", className), ...props });
1512
+ });
1513
+ var TabsTrigger = forwardRef10(function TabsTrigger2({ className, ...props }, ref) {
1514
+ return /* @__PURE__ */ jsx23(TabsPrimitive.Trigger, { ref, className: cn22("j-tabs-trigger", className), ...props });
1515
+ });
1516
+ var TabsContent = forwardRef10(function TabsContent2({ className, ...props }, ref) {
1517
+ return /* @__PURE__ */ jsx23(TabsPrimitive.Content, { ref, className: cn22("j-tabs-content", className), ...props });
1518
+ });
1519
+
1520
+ // src/components/toast.tsx
1521
+ import { X as X3 } from "@jerco/icons";
1522
+ import { cn as cn23 } from "@jerco/utils";
1523
+ import * as ToastPrimitive from "@radix-ui/react-toast";
1524
+ import { forwardRef as forwardRef11 } from "react";
1525
+ import { jsx as jsx24 } from "react/jsx-runtime";
1526
+ var ToastProvider = ToastPrimitive.Provider;
1527
+ var Toast = forwardRef11(function Toast2({ className, tone = "neutral", ...props }, ref) {
1528
+ return /* @__PURE__ */ jsx24(
1529
+ ToastPrimitive.Root,
1530
+ {
1531
+ ref,
1532
+ className: cn23("j-toast", `j-toast--${tone}`, className),
1533
+ ...props
1534
+ }
1535
+ );
1536
+ });
1537
+ var ToastTitle = forwardRef11(function ToastTitle2({ className, ...props }, ref) {
1538
+ return /* @__PURE__ */ jsx24(ToastPrimitive.Title, { ref, className: cn23("j-toast-title", className), ...props });
1539
+ });
1540
+ var ToastDescription = forwardRef11(function ToastDescription2({ className, ...props }, ref) {
1541
+ return /* @__PURE__ */ jsx24(
1542
+ ToastPrimitive.Description,
1543
+ {
1544
+ ref,
1545
+ className: cn23("j-toast-description", className),
1546
+ ...props
1547
+ }
1548
+ );
1549
+ });
1550
+ var ToastAction = ToastPrimitive.Action;
1551
+ var ToastClose = forwardRef11(function ToastClose2({ className, children, ...props }, ref) {
1552
+ return /* @__PURE__ */ jsx24(
1553
+ ToastPrimitive.Close,
1554
+ {
1555
+ ref,
1556
+ className: cn23("j-toast-close", className),
1557
+ "aria-label": "Dismiss notification",
1558
+ ...props,
1559
+ children: children ?? /* @__PURE__ */ jsx24(X3, { "aria-hidden": "true" })
1560
+ }
1561
+ );
1562
+ });
1563
+ var ToastViewport = forwardRef11(function ToastViewport2({ className, ...props }, ref) {
1564
+ return /* @__PURE__ */ jsx24(ToastPrimitive.Viewport, { ref, className: cn23("j-toast-viewport", className), ...props });
1565
+ });
1566
+
1567
+ // src/components/tooltip.tsx
1568
+ import { cn as cn24 } from "@jerco/utils";
1569
+ import * as TooltipPrimitive from "@radix-ui/react-tooltip";
1570
+ import { forwardRef as forwardRef12 } from "react";
1571
+ import { jsx as jsx25, jsxs as jsxs17 } from "react/jsx-runtime";
1572
+ var TooltipProvider = TooltipPrimitive.Provider;
1573
+ var Tooltip = TooltipPrimitive.Root;
1574
+ var TooltipTrigger = TooltipPrimitive.Trigger;
1575
+ var TooltipContent = forwardRef12(function TooltipContent2({ className, sideOffset = 6, ...props }, ref) {
1576
+ return /* @__PURE__ */ jsx25(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsx25(
1577
+ TooltipPrimitive.Content,
1578
+ {
1579
+ ref,
1580
+ className: cn24("j-tooltip", className),
1581
+ sideOffset,
1582
+ ...props
1583
+ }
1584
+ ) });
1585
+ });
1586
+ function SimpleTooltip({ content, children }) {
1587
+ return /* @__PURE__ */ jsx25(TooltipProvider, { children: /* @__PURE__ */ jsxs17(Tooltip, { children: [
1588
+ /* @__PURE__ */ jsx25(TooltipTrigger, { asChild: true, children }),
1589
+ /* @__PURE__ */ jsx25(TooltipContent, { children: content })
1590
+ ] }) });
1591
+ }
1592
+ export {
1593
+ AlertDialog,
1594
+ AlertDialogAction,
1595
+ AlertDialogCancel,
1596
+ AlertDialogContent,
1597
+ AlertDialogDescription,
1598
+ AlertDialogFooter,
1599
+ AlertDialogHeader,
1600
+ AlertDialogTitle,
1601
+ AlertDialogTrigger,
1602
+ AppNavigation,
1603
+ AppShell,
1604
+ AppShellCollapseButton,
1605
+ AppShellMenuButton,
1606
+ Badge,
1607
+ BrandLogo,
1608
+ Button,
1609
+ Card,
1610
+ CardContent,
1611
+ CardDescription,
1612
+ CardFooter,
1613
+ CardHeader,
1614
+ CardTitle,
1615
+ Checkbox,
1616
+ CheckboxField,
1617
+ DataTable,
1618
+ DesignSystemProvider,
1619
+ DeviceCard,
1620
+ Dialog,
1621
+ DialogClose,
1622
+ DialogContent,
1623
+ DialogDescription,
1624
+ DialogFooter,
1625
+ DialogHeader,
1626
+ DialogTitle,
1627
+ DialogTrigger,
1628
+ DropdownMenu,
1629
+ DropdownMenuCheckboxItem,
1630
+ DropdownMenuContent,
1631
+ DropdownMenuGroup,
1632
+ DropdownMenuItem,
1633
+ DropdownMenuLabel,
1634
+ DropdownMenuPortal,
1635
+ DropdownMenuRadioGroup,
1636
+ DropdownMenuRadioItem,
1637
+ DropdownMenuSeparator,
1638
+ DropdownMenuSub,
1639
+ DropdownMenuSubContent,
1640
+ DropdownMenuSubTrigger,
1641
+ DropdownMenuTrigger,
1642
+ EmptyState,
1643
+ ErrorState,
1644
+ Header,
1645
+ IconButton,
1646
+ Input,
1647
+ Label2 as Label,
1648
+ MainContent,
1649
+ MetricCard,
1650
+ NativeSelect,
1651
+ PageHeader,
1652
+ RadioField,
1653
+ RadioGroup2 as RadioGroup,
1654
+ RadioGroupItem,
1655
+ Select,
1656
+ SelectGroup,
1657
+ SelectLabel,
1658
+ SelectValue,
1659
+ Separator2 as Separator,
1660
+ ServiceHealth,
1661
+ Sidebar,
1662
+ SimpleTooltip,
1663
+ Skeleton,
1664
+ Spinner,
1665
+ StatusIndicator,
1666
+ Switch,
1667
+ SwitchField,
1668
+ Tabs,
1669
+ TabsContent,
1670
+ TabsList,
1671
+ TabsTrigger,
1672
+ Textarea,
1673
+ Toast,
1674
+ ToastAction,
1675
+ ToastClose,
1676
+ ToastDescription,
1677
+ ToastProvider,
1678
+ ToastTitle,
1679
+ ToastViewport,
1680
+ Tooltip,
1681
+ TooltipContent,
1682
+ TooltipProvider,
1683
+ TooltipTrigger,
1684
+ buttonVariants,
1685
+ createBrowserBooleanStateAdapter,
1686
+ createBrowserDataTableUrlStateAdapter,
1687
+ createDataTableRequestManager,
1688
+ createDataTableUrlStateAdapter,
1689
+ matchNavigationPath,
1690
+ parseDataTableUrlState,
1691
+ serializeDataTableUrlState,
1692
+ useDesignSystem
1693
+ };