@mirror-physics/fractal-ui 0.2.0-next.5 → 0.2.0-next.50
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.cjs +1316 -246
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +1345 -105
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +273 -20
- package/dist/index.d.ts +273 -20
- package/dist/index.js +1273 -240
- package/dist/index.js.map +1 -1
- package/dist/lattice-FAYE5KWW.svg +3 -0
- package/dist/tokens.css +5 -3
- package/package.json +7 -1
package/dist/index.cjs
CHANGED
|
@@ -32,39 +32,76 @@ var index_exports = {};
|
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
Alert: () => Alert,
|
|
34
34
|
AlertDescription: () => AlertDescription,
|
|
35
|
+
AlertGhost: () => AlertGhost,
|
|
35
36
|
AlertTitle: () => AlertTitle,
|
|
37
|
+
Breadcrumbs: () => Breadcrumbs,
|
|
36
38
|
Button: () => Button,
|
|
39
|
+
ButtonGhost: () => ButtonGhost,
|
|
37
40
|
Card: () => Card,
|
|
38
41
|
CardContent: () => CardContent,
|
|
39
42
|
CardDescription: () => CardDescription,
|
|
40
43
|
CardFooter: () => CardFooter,
|
|
44
|
+
CardGhost: () => CardGhost,
|
|
41
45
|
CardHeader: () => CardHeader,
|
|
42
46
|
CardTitle: () => CardTitle,
|
|
47
|
+
Checkbox: () => Checkbox,
|
|
48
|
+
CheckboxGhost: () => CheckboxGhost,
|
|
43
49
|
Chip: () => Chip,
|
|
50
|
+
ChipGhost: () => ChipGhost,
|
|
51
|
+
CodeBlock: () => CodeBlock,
|
|
52
|
+
ContentSwitcher: () => ContentSwitcher,
|
|
53
|
+
ContentSwitcherGhost: () => ContentSwitcherGhost,
|
|
54
|
+
ConversationGhost: () => ConversationGhost,
|
|
44
55
|
DataTable: () => DataTable,
|
|
56
|
+
DataTableGhost: () => DataTableGhost,
|
|
45
57
|
Disclosure: () => Disclosure,
|
|
58
|
+
DisclosureGhost: () => DisclosureGhost,
|
|
46
59
|
Dropdown: () => Dropdown,
|
|
60
|
+
DropdownGhost: () => DropdownGhost,
|
|
47
61
|
FeatureCard: () => FeatureCard,
|
|
62
|
+
FileDropzone: () => FileDropzone,
|
|
63
|
+
FileDropzoneGhost: () => FileDropzoneGhost,
|
|
48
64
|
FolderCard: () => FolderCard,
|
|
65
|
+
Ghost: () => Ghost,
|
|
66
|
+
GhostLine: () => GhostLine,
|
|
49
67
|
Input: () => Input,
|
|
68
|
+
InputGhost: () => InputGhost,
|
|
50
69
|
Label: () => Label,
|
|
70
|
+
LabelGhost: () => LabelGhost,
|
|
71
|
+
LatticeLoader: () => LatticeLoader,
|
|
51
72
|
Link: () => Link,
|
|
73
|
+
LinkGhost: () => LinkGhost,
|
|
52
74
|
Modal: () => Modal,
|
|
53
|
-
|
|
75
|
+
ModalGhost: () => ModalGhost,
|
|
76
|
+
NumberInput: () => NumberInput,
|
|
77
|
+
Pagination: () => Pagination,
|
|
78
|
+
PaginationGhost: () => PaginationGhost,
|
|
79
|
+
PasswordInput: () => PasswordInput,
|
|
54
80
|
PromptCard: () => PromptCard,
|
|
81
|
+
PromptCardGhost: () => PromptCardGhost,
|
|
55
82
|
PromptGrid: () => PromptGrid,
|
|
56
83
|
SidePanel: () => SidePanel,
|
|
84
|
+
SidePanelGhost: () => SidePanelGhost,
|
|
57
85
|
Sidebar: () => Sidebar,
|
|
86
|
+
SidebarAccountMenu: () => SidebarAccountMenu,
|
|
58
87
|
SidebarBrand: () => SidebarBrand,
|
|
59
88
|
SidebarFooter: () => SidebarFooter,
|
|
89
|
+
SidebarGhost: () => SidebarGhost,
|
|
60
90
|
SidebarHeader: () => SidebarHeader,
|
|
61
91
|
SidebarNav: () => SidebarNav,
|
|
62
92
|
SidebarNavItem: () => SidebarNavItem,
|
|
63
93
|
SidebarSection: () => SidebarSection,
|
|
64
94
|
SortableTable: () => SortableTable,
|
|
95
|
+
SortableTableGhost: () => SortableTableGhost,
|
|
65
96
|
Tabs: () => Tabs,
|
|
97
|
+
TabsGhost: () => TabsGhost,
|
|
98
|
+
TextButton: () => TextButton,
|
|
99
|
+
TextButtonGhost: () => TextButtonGhost,
|
|
66
100
|
Textarea: () => Textarea,
|
|
101
|
+
TextareaGhost: () => TextareaGhost,
|
|
67
102
|
Toggle: () => Toggle,
|
|
103
|
+
ToggleGhost: () => ToggleGhost,
|
|
104
|
+
UILoader: () => UILoader,
|
|
68
105
|
cn: () => cn,
|
|
69
106
|
useEscapeDismiss: () => useEscapeDismiss
|
|
70
107
|
});
|
|
@@ -122,7 +159,7 @@ var colorPalette = {
|
|
|
122
159
|
var sizeConfig = {
|
|
123
160
|
xs: { height: "28px", padding: "4px 8px", iconOnly: "28px", fontSize: "0.75rem" },
|
|
124
161
|
sm: { height: "32px", padding: "6px 12px", iconOnly: "32px", fontSize: "0.75rem" },
|
|
125
|
-
md: { height: "
|
|
162
|
+
md: { height: "40px", padding: "8px 16px", iconOnly: "40px", fontSize: "0.875rem" },
|
|
126
163
|
lg: { height: "44px", padding: "10px 20px", iconOnly: "44px", fontSize: "1rem" },
|
|
127
164
|
xl: { height: "56px", padding: "14px 28px", iconOnly: "56px", fontSize: "1rem" }
|
|
128
165
|
};
|
|
@@ -237,44 +274,251 @@ var Button = React.forwardRef(
|
|
|
237
274
|
);
|
|
238
275
|
Button.displayName = "Button";
|
|
239
276
|
|
|
240
|
-
// src/components/
|
|
241
|
-
var
|
|
277
|
+
// src/components/CodeBlock/CodeBlock.tsx
|
|
278
|
+
var import_react = require("react");
|
|
279
|
+
var import_react_codemirror = __toESM(require("@uiw/react-codemirror"), 1);
|
|
280
|
+
var import_language = require("@codemirror/language");
|
|
281
|
+
var import_lang_json = require("@codemirror/lang-json");
|
|
282
|
+
var import_view = require("@codemirror/view");
|
|
283
|
+
var import_highlight = require("@lezer/highlight");
|
|
242
284
|
var import_fractal_icons = require("@mirror-physics/fractal-icons");
|
|
243
285
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
286
|
+
var codeTheme = import_view.EditorView.theme({
|
|
287
|
+
"&": {
|
|
288
|
+
backgroundColor: "transparent",
|
|
289
|
+
color: "var(--fg-primary)",
|
|
290
|
+
fontSize: "0.75rem"
|
|
291
|
+
},
|
|
292
|
+
"&.cm-focused": { outline: "none" },
|
|
293
|
+
".cm-scroller": {
|
|
294
|
+
fontFamily: "var(--font-mono)",
|
|
295
|
+
lineHeight: "1.55",
|
|
296
|
+
overscrollBehavior: "contain"
|
|
297
|
+
},
|
|
298
|
+
".cm-content": { padding: "10px 0" },
|
|
299
|
+
".cm-line": { padding: "0 12px" },
|
|
300
|
+
".cm-cursor, .cm-dropCursor": { borderLeftColor: "var(--fg-primary)" },
|
|
301
|
+
".cm-gutters": {
|
|
302
|
+
backgroundColor: "var(--bg-canvas)",
|
|
303
|
+
borderRight: "1px solid var(--border-subtle)",
|
|
304
|
+
color: "var(--fg-tertiary)"
|
|
305
|
+
},
|
|
306
|
+
".cm-lineNumbers .cm-gutterElement": { padding: "0 10px 0 12px" },
|
|
307
|
+
".cm-foldGutter .cm-gutterElement": { padding: "0 8px 0 2px" },
|
|
308
|
+
".cm-activeLine, .cm-activeLineGutter": { backgroundColor: "var(--bg-surface-1)" },
|
|
309
|
+
".cm-selectionBackground, &.cm-focused .cm-selectionBackground, ::selection": {
|
|
310
|
+
backgroundColor: "var(--accent-surface-stroke) !important"
|
|
311
|
+
},
|
|
312
|
+
".cm-searchMatch": {
|
|
313
|
+
backgroundColor: "var(--warning-surface)",
|
|
314
|
+
outline: "1px solid var(--warning-surface-stroke)"
|
|
315
|
+
},
|
|
316
|
+
".cm-searchMatch.cm-searchMatch-selected": { backgroundColor: "var(--warning-subtle)" },
|
|
317
|
+
".cm-panels": { backgroundColor: "var(--bg-surface-1)", color: "var(--fg-primary)" },
|
|
318
|
+
".cm-tooltip": {
|
|
319
|
+
borderColor: "var(--border-subtle)",
|
|
320
|
+
backgroundColor: "var(--bg-canvas)",
|
|
321
|
+
color: "var(--fg-primary)"
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
var fractalHighlightStyle = import_language.HighlightStyle.define([
|
|
325
|
+
{ tag: import_highlight.tags.comment, color: "var(--fg-tertiary)", fontStyle: "italic" },
|
|
326
|
+
{ tag: [import_highlight.tags.keyword, import_highlight.tags.controlKeyword, import_highlight.tags.operatorKeyword], color: "var(--purple-default)" },
|
|
327
|
+
{ tag: [import_highlight.tags.string, import_highlight.tags.special(import_highlight.tags.string)], color: "var(--purple-default)" },
|
|
328
|
+
{ tag: [import_highlight.tags.number, import_highlight.tags.bool, import_highlight.tags.null], color: "var(--orange-default)" },
|
|
329
|
+
{ tag: [import_highlight.tags.function(import_highlight.tags.variableName), import_highlight.tags.labelName], color: "var(--accent-default)" },
|
|
330
|
+
{ tag: [import_highlight.tags.typeName, import_highlight.tags.className, import_highlight.tags.namespace], color: "var(--pink-default)" },
|
|
331
|
+
{ tag: [import_highlight.tags.propertyName, import_highlight.tags.attributeName], color: "var(--success-default)" },
|
|
332
|
+
{ tag: [import_highlight.tags.operator, import_highlight.tags.punctuation], color: "var(--fg-secondary)" },
|
|
333
|
+
{ tag: import_highlight.tags.bracket, color: "var(--accent-default)" },
|
|
334
|
+
{ tag: [import_highlight.tags.heading, import_highlight.tags.strong], color: "var(--fg-primary)", fontWeight: "600" },
|
|
335
|
+
{ tag: import_highlight.tags.emphasis, fontStyle: "italic" },
|
|
336
|
+
{ tag: import_highlight.tags.link, color: "var(--accent-default)", textDecoration: "underline" },
|
|
337
|
+
{ tag: import_highlight.tags.invalid, color: "var(--error-default)", textDecoration: "underline wavy" }
|
|
338
|
+
]);
|
|
339
|
+
var jsonSupport = (0, import_lang_json.json)();
|
|
340
|
+
var JSON_LANGUAGE_NAMES = /* @__PURE__ */ new Set(["json", "jsonl", "ndjson", "geojson"]);
|
|
341
|
+
function resolveLanguage(language, fileName) {
|
|
342
|
+
const normalized = language?.trim().toLowerCase();
|
|
343
|
+
const extension = fileName?.split(/[?#]/, 1)[0].split(".").pop()?.toLowerCase();
|
|
344
|
+
if (normalized && JSON_LANGUAGE_NAMES.has(normalized) || extension && JSON_LANGUAGE_NAMES.has(extension)) {
|
|
345
|
+
return { label: normalized === "jsonl" || extension === "jsonl" ? "JSONL" : "JSON", support: jsonSupport };
|
|
346
|
+
}
|
|
347
|
+
if (normalized && !["text", "txt", "plaintext", "plain"].includes(normalized)) {
|
|
348
|
+
return { label: language?.trim(), support: null };
|
|
349
|
+
}
|
|
350
|
+
return { support: null };
|
|
351
|
+
}
|
|
352
|
+
function CodeBlock({
|
|
353
|
+
value,
|
|
354
|
+
language,
|
|
355
|
+
fileName,
|
|
356
|
+
label,
|
|
357
|
+
editable = false,
|
|
358
|
+
onChange,
|
|
359
|
+
lineNumbers = true,
|
|
360
|
+
wrap = true,
|
|
361
|
+
copyable = true,
|
|
362
|
+
ariaLabel,
|
|
363
|
+
height,
|
|
364
|
+
minHeight,
|
|
365
|
+
maxHeight = "28rem",
|
|
366
|
+
placeholder,
|
|
367
|
+
autoFocus,
|
|
368
|
+
className,
|
|
369
|
+
...props
|
|
370
|
+
}) {
|
|
371
|
+
const resolvedLanguage = (0, import_react.useMemo)(() => resolveLanguage(language, fileName), [fileName, language]);
|
|
372
|
+
const [copyStatus, setCopyStatus] = (0, import_react.useState)("idle");
|
|
373
|
+
const copyResetTimer = (0, import_react.useRef)(null);
|
|
374
|
+
(0, import_react.useEffect)(() => () => {
|
|
375
|
+
if (copyResetTimer.current) clearTimeout(copyResetTimer.current);
|
|
376
|
+
}, []);
|
|
377
|
+
const extensions = (0, import_react.useMemo)(() => [
|
|
378
|
+
codeTheme,
|
|
379
|
+
(0, import_language.syntaxHighlighting)(fractalHighlightStyle),
|
|
380
|
+
...resolvedLanguage.support ? [resolvedLanguage.support] : [],
|
|
381
|
+
...lineNumbers ? [(0, import_language.foldGutter)(), (0, import_view.lineNumbers)()] : [],
|
|
382
|
+
...wrap ? [import_view.EditorView.lineWrapping] : []
|
|
383
|
+
], [lineNumbers, resolvedLanguage.support, wrap]);
|
|
384
|
+
const languageLabel = resolvedLanguage.label;
|
|
385
|
+
const toolbarLabel = label ?? fileName ?? languageLabel;
|
|
386
|
+
const surfaceLabel = ariaLabel ?? (fileName ? `${fileName} ${editable ? "editor" : "viewer"}` : `Code ${editable ? "editor" : "viewer"}`);
|
|
387
|
+
const copyCode = async () => {
|
|
388
|
+
try {
|
|
389
|
+
await navigator.clipboard.writeText(value);
|
|
390
|
+
setCopyStatus("copied");
|
|
391
|
+
} catch {
|
|
392
|
+
setCopyStatus("error");
|
|
393
|
+
}
|
|
394
|
+
if (copyResetTimer.current) clearTimeout(copyResetTimer.current);
|
|
395
|
+
copyResetTimer.current = setTimeout(() => setCopyStatus("idle"), 1800);
|
|
396
|
+
};
|
|
397
|
+
const showToolbar = toolbarLabel !== void 0 || copyable || editable;
|
|
398
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
399
|
+
"div",
|
|
400
|
+
{
|
|
401
|
+
className: cn(
|
|
402
|
+
"fractal-code-block",
|
|
403
|
+
editable && "fractal-code-block--editable",
|
|
404
|
+
!lineNumbers && "fractal-code-block--no-line-numbers",
|
|
405
|
+
className
|
|
406
|
+
),
|
|
407
|
+
...props,
|
|
408
|
+
children: [
|
|
409
|
+
showToolbar && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "fractal-code-block__toolbar", children: [
|
|
410
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "fractal-code-block__identity", children: [
|
|
411
|
+
toolbarLabel !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "fractal-code-block__label", title: typeof toolbarLabel === "string" ? toolbarLabel : void 0, children: toolbarLabel }),
|
|
412
|
+
fileName && languageLabel && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "fractal-code-block__language", children: languageLabel }),
|
|
413
|
+
editable && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "fractal-code-block__mode", children: "Editing" })
|
|
414
|
+
] }),
|
|
415
|
+
copyable && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
416
|
+
"button",
|
|
417
|
+
{
|
|
418
|
+
type: "button",
|
|
419
|
+
className: "fractal-code-block__copy",
|
|
420
|
+
"aria-label": copyStatus === "copied" ? "Code copied" : "Copy code",
|
|
421
|
+
onClick: () => void copyCode(),
|
|
422
|
+
children: [
|
|
423
|
+
copyStatus === "copied" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_fractal_icons.Check, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_fractal_icons.Copy, { size: 14 }),
|
|
424
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: copyStatus === "copied" ? "Copied" : copyStatus === "error" ? "Copy failed" : "Copy" })
|
|
425
|
+
]
|
|
426
|
+
}
|
|
427
|
+
)
|
|
428
|
+
] }),
|
|
429
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "fractal-code-block__surface", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
430
|
+
import_react_codemirror.default,
|
|
431
|
+
{
|
|
432
|
+
"aria-label": surfaceLabel,
|
|
433
|
+
value,
|
|
434
|
+
editable,
|
|
435
|
+
readOnly: !editable,
|
|
436
|
+
onChange,
|
|
437
|
+
extensions,
|
|
438
|
+
theme: "none",
|
|
439
|
+
basicSetup: {
|
|
440
|
+
lineNumbers: false,
|
|
441
|
+
foldGutter: false,
|
|
442
|
+
drawSelection: editable,
|
|
443
|
+
highlightActiveLine: editable,
|
|
444
|
+
highlightActiveLineGutter: editable,
|
|
445
|
+
highlightSelectionMatches: editable,
|
|
446
|
+
autocompletion: editable,
|
|
447
|
+
history: editable
|
|
448
|
+
},
|
|
449
|
+
indentWithTab: editable,
|
|
450
|
+
height,
|
|
451
|
+
minHeight,
|
|
452
|
+
maxHeight,
|
|
453
|
+
placeholder,
|
|
454
|
+
autoFocus
|
|
455
|
+
}
|
|
456
|
+
) }),
|
|
457
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "fractal-code-block__status", "aria-live": "polite", children: copyStatus === "copied" ? "Code copied to clipboard." : copyStatus === "error" ? "Code could not be copied." : "" })
|
|
458
|
+
]
|
|
459
|
+
}
|
|
460
|
+
);
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// src/components/Breadcrumbs/Breadcrumbs.tsx
|
|
464
|
+
var import_fractal_icons2 = require("@mirror-physics/fractal-icons");
|
|
465
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
466
|
+
function Breadcrumbs({
|
|
467
|
+
items,
|
|
468
|
+
ariaLabel = "Breadcrumbs",
|
|
469
|
+
separator = /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_fractal_icons2.ChevronRight, { "aria-hidden": "true", size: 14 }),
|
|
470
|
+
className,
|
|
471
|
+
...props
|
|
472
|
+
}) {
|
|
473
|
+
if (items.length === 0) return null;
|
|
474
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("nav", { "aria-label": ariaLabel, className: cn("fractal-breadcrumbs", className), ...props, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ol", { className: "fractal-breadcrumbs__list", children: items.map((item, index) => {
|
|
475
|
+
const isCurrent = index === items.length - 1;
|
|
476
|
+
const content = isCurrent ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { "aria-current": "page", className: "fractal-breadcrumbs__current", children: item.label }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("a", { className: "fractal-breadcrumbs__link", href: item.href ?? "#", onClick: item.onClick, children: item.label });
|
|
477
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { className: "fractal-breadcrumbs__item", children: [
|
|
478
|
+
index > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { "aria-hidden": "true", className: "fractal-breadcrumbs__separator", children: separator }),
|
|
479
|
+
content
|
|
480
|
+
] }, index);
|
|
481
|
+
}) }) });
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
// src/components/Card/Card.tsx
|
|
485
|
+
var React2 = __toESM(require("react"), 1);
|
|
486
|
+
var import_fractal_icons3 = require("@mirror-physics/fractal-icons");
|
|
487
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
244
488
|
var Card = React2.forwardRef(
|
|
245
|
-
({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
489
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { ref, className: cn("fractal-card", className), ...props })
|
|
246
490
|
);
|
|
247
491
|
Card.displayName = "Card";
|
|
248
492
|
var CardHeader = React2.forwardRef(
|
|
249
|
-
({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
493
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { ref, className: cn("fractal-card-header", className), ...props })
|
|
250
494
|
);
|
|
251
495
|
CardHeader.displayName = "CardHeader";
|
|
252
496
|
var CardTitle = React2.forwardRef(
|
|
253
|
-
({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
497
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h3", { ref, className: cn("fractal-card-title", className), ...props })
|
|
254
498
|
);
|
|
255
499
|
CardTitle.displayName = "CardTitle";
|
|
256
500
|
var CardDescription = React2.forwardRef(
|
|
257
|
-
({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
501
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { ref, className: cn("fractal-card-description", className), ...props })
|
|
258
502
|
);
|
|
259
503
|
CardDescription.displayName = "CardDescription";
|
|
260
504
|
var CardContent = React2.forwardRef(
|
|
261
|
-
({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
505
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { ref, className: cn("fractal-card-content", className), ...props })
|
|
262
506
|
);
|
|
263
507
|
CardContent.displayName = "CardContent";
|
|
264
508
|
var CardFooter = React2.forwardRef(
|
|
265
|
-
({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
509
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { ref, className: cn("fractal-card-footer", className), ...props })
|
|
266
510
|
);
|
|
267
511
|
CardFooter.displayName = "CardFooter";
|
|
268
512
|
var FeatureCard = React2.forwardRef(
|
|
269
|
-
({ icon, title, description, className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
270
|
-
icon && /* @__PURE__ */ (0,
|
|
271
|
-
/* @__PURE__ */ (0,
|
|
272
|
-
/* @__PURE__ */ (0,
|
|
513
|
+
({ icon, title, description, className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { ref, className: cn("fractal-feature-card", className), ...props, children: [
|
|
514
|
+
icon && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "fractal-feature-card__icon", children: icon }),
|
|
515
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h3", { className: "fractal-feature-card__title", children: title }),
|
|
516
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "fractal-feature-card__description", children: description })
|
|
273
517
|
] })
|
|
274
518
|
);
|
|
275
519
|
FeatureCard.displayName = "FeatureCard";
|
|
276
520
|
var FolderCard = React2.forwardRef(
|
|
277
|
-
({ name, sessionCount, selected, className, onClick, ...props }, ref) => /* @__PURE__ */ (0,
|
|
521
|
+
({ name, sessionCount, selected, className, onClick, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
278
522
|
"div",
|
|
279
523
|
{
|
|
280
524
|
ref,
|
|
@@ -290,11 +534,11 @@ var FolderCard = React2.forwardRef(
|
|
|
290
534
|
className: cn("fractal-folder-card", selected && "fractal-folder-card--selected", className),
|
|
291
535
|
...props,
|
|
292
536
|
children: [
|
|
293
|
-
/* @__PURE__ */ (0,
|
|
294
|
-
/* @__PURE__ */ (0,
|
|
295
|
-
/* @__PURE__ */ (0,
|
|
537
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "fractal-folder-card__header", children: [
|
|
538
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_fractal_icons3.Folder, { size: 16, className: "fractal-folder-card__icon", "aria-hidden": true }),
|
|
539
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "fractal-folder-card__name", children: name })
|
|
296
540
|
] }),
|
|
297
|
-
sessionCount !== void 0 && /* @__PURE__ */ (0,
|
|
541
|
+
sessionCount !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "fractal-folder-card__footer", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "fractal-folder-card__sessions", children: [
|
|
298
542
|
sessionCount,
|
|
299
543
|
" ",
|
|
300
544
|
sessionCount === 1 ? "session" : "sessions"
|
|
@@ -307,7 +551,7 @@ FolderCard.displayName = "FolderCard";
|
|
|
307
551
|
|
|
308
552
|
// src/components/PromptCard/PromptCard.tsx
|
|
309
553
|
var React3 = __toESM(require("react"), 1);
|
|
310
|
-
var
|
|
554
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
311
555
|
var titleToPrompt = (title) => typeof title === "string" || typeof title === "number" ? String(title) : "";
|
|
312
556
|
var PromptCard = React3.forwardRef(
|
|
313
557
|
({
|
|
@@ -328,7 +572,7 @@ var PromptCard = React3.forwardRef(
|
|
|
328
572
|
onPromptSelect?.(prompt ?? titleToPrompt(title));
|
|
329
573
|
}
|
|
330
574
|
};
|
|
331
|
-
return /* @__PURE__ */ (0,
|
|
575
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
332
576
|
"button",
|
|
333
577
|
{
|
|
334
578
|
ref,
|
|
@@ -343,8 +587,8 @@ var PromptCard = React3.forwardRef(
|
|
|
343
587
|
onClick: handleClick,
|
|
344
588
|
...props,
|
|
345
589
|
children: [
|
|
346
|
-
icon && /* @__PURE__ */ (0,
|
|
347
|
-
/* @__PURE__ */ (0,
|
|
590
|
+
icon && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "fractal-prompt-card__icon", "aria-hidden": "true", children: icon }),
|
|
591
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "fractal-prompt-card__title", children: title })
|
|
348
592
|
]
|
|
349
593
|
}
|
|
350
594
|
);
|
|
@@ -352,7 +596,7 @@ var PromptCard = React3.forwardRef(
|
|
|
352
596
|
);
|
|
353
597
|
PromptCard.displayName = "PromptCard";
|
|
354
598
|
var PromptGrid = React3.forwardRef(
|
|
355
|
-
({ compact, padded, className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
599
|
+
({ compact, padded, className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
356
600
|
"div",
|
|
357
601
|
{
|
|
358
602
|
ref,
|
|
@@ -370,9 +614,9 @@ PromptGrid.displayName = "PromptGrid";
|
|
|
370
614
|
|
|
371
615
|
// src/components/Input/Input.tsx
|
|
372
616
|
var React4 = __toESM(require("react"), 1);
|
|
373
|
-
var
|
|
617
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
374
618
|
var Input = React4.forwardRef(
|
|
375
|
-
({ className, type, ...props }, ref) => /* @__PURE__ */ (0,
|
|
619
|
+
({ className, type, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
376
620
|
"input",
|
|
377
621
|
{
|
|
378
622
|
type,
|
|
@@ -384,11 +628,141 @@ var Input = React4.forwardRef(
|
|
|
384
628
|
);
|
|
385
629
|
Input.displayName = "Input";
|
|
386
630
|
|
|
387
|
-
// src/components/
|
|
631
|
+
// src/components/NumberInput/NumberInput.tsx
|
|
388
632
|
var React5 = __toESM(require("react"), 1);
|
|
389
|
-
var
|
|
390
|
-
var
|
|
391
|
-
|
|
633
|
+
var import_fractal_icons4 = require("@mirror-physics/fractal-icons");
|
|
634
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
635
|
+
function NumberInput({
|
|
636
|
+
unit,
|
|
637
|
+
className,
|
|
638
|
+
value,
|
|
639
|
+
defaultValue,
|
|
640
|
+
disabled,
|
|
641
|
+
readOnly,
|
|
642
|
+
min,
|
|
643
|
+
max,
|
|
644
|
+
...props
|
|
645
|
+
}) {
|
|
646
|
+
const inputRef = React5.useRef(null);
|
|
647
|
+
const numericValue = Number(value ?? defaultValue);
|
|
648
|
+
const characterCount = Math.max(String(value ?? defaultValue ?? "").length, 1);
|
|
649
|
+
const controlLabel = typeof props["aria-label"] === "string" ? props["aria-label"] : "value";
|
|
650
|
+
const decrementDisabled = disabled || readOnly || Number.isFinite(numericValue) && min !== void 0 && numericValue <= Number(min);
|
|
651
|
+
const incrementDisabled = disabled || readOnly || Number.isFinite(numericValue) && max !== void 0 && numericValue >= Number(max);
|
|
652
|
+
const changeByStep = (direction) => {
|
|
653
|
+
const input = inputRef.current;
|
|
654
|
+
if (!input) return;
|
|
655
|
+
if (direction === -1) input.stepDown();
|
|
656
|
+
else input.stepUp();
|
|
657
|
+
input.dispatchEvent(new Event("input", { bubbles: true }));
|
|
658
|
+
input.focus();
|
|
659
|
+
};
|
|
660
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: cn("fractal-number-input", unit && "fractal-number-input--with-unit", className), children: [
|
|
661
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
662
|
+
Input,
|
|
663
|
+
{
|
|
664
|
+
ref: inputRef,
|
|
665
|
+
type: "number",
|
|
666
|
+
value,
|
|
667
|
+
defaultValue,
|
|
668
|
+
disabled,
|
|
669
|
+
readOnly,
|
|
670
|
+
min,
|
|
671
|
+
max,
|
|
672
|
+
...props
|
|
673
|
+
}
|
|
674
|
+
),
|
|
675
|
+
unit && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
676
|
+
"span",
|
|
677
|
+
{
|
|
678
|
+
className: "fractal-number-input-unit",
|
|
679
|
+
style: { left: `calc(var(--space-3, 12px) + ${characterCount}ch)` },
|
|
680
|
+
"aria-hidden": "true",
|
|
681
|
+
children: unit
|
|
682
|
+
}
|
|
683
|
+
),
|
|
684
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "fractal-number-input-controls", children: [
|
|
685
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
686
|
+
"button",
|
|
687
|
+
{
|
|
688
|
+
type: "button",
|
|
689
|
+
className: "fractal-number-input-step",
|
|
690
|
+
"aria-label": `Decrease ${controlLabel}`,
|
|
691
|
+
disabled: decrementDisabled,
|
|
692
|
+
onClick: () => changeByStep(-1),
|
|
693
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_fractal_icons4.Minus, { "aria-hidden": "true", size: 16 })
|
|
694
|
+
}
|
|
695
|
+
),
|
|
696
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
697
|
+
"button",
|
|
698
|
+
{
|
|
699
|
+
type: "button",
|
|
700
|
+
className: "fractal-number-input-step",
|
|
701
|
+
"aria-label": `Increase ${controlLabel}`,
|
|
702
|
+
disabled: incrementDisabled,
|
|
703
|
+
onClick: () => changeByStep(1),
|
|
704
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_fractal_icons4.Plus, { "aria-hidden": "true", size: 16 })
|
|
705
|
+
}
|
|
706
|
+
)
|
|
707
|
+
] })
|
|
708
|
+
] });
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
// src/components/PasswordInput/PasswordInput.tsx
|
|
712
|
+
var React6 = __toESM(require("react"), 1);
|
|
713
|
+
var import_fractal_icons5 = require("@mirror-physics/fractal-icons");
|
|
714
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
715
|
+
var PasswordInput = React6.forwardRef(
|
|
716
|
+
({
|
|
717
|
+
className,
|
|
718
|
+
disabled,
|
|
719
|
+
showPasswordLabel = "Show password",
|
|
720
|
+
hidePasswordLabel = "Hide password",
|
|
721
|
+
...props
|
|
722
|
+
}, ref) => {
|
|
723
|
+
const [passwordVisible, setPasswordVisible] = React6.useState(false);
|
|
724
|
+
const toggleLabel = passwordVisible ? hidePasswordLabel : showPasswordLabel;
|
|
725
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
726
|
+
"div",
|
|
727
|
+
{
|
|
728
|
+
className: cn("fractal-password-input", className),
|
|
729
|
+
"data-password-visible": passwordVisible ? "" : void 0,
|
|
730
|
+
children: [
|
|
731
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
732
|
+
Input,
|
|
733
|
+
{
|
|
734
|
+
...props,
|
|
735
|
+
ref,
|
|
736
|
+
className: "fractal-password-input-field",
|
|
737
|
+
disabled,
|
|
738
|
+
type: passwordVisible ? "text" : "password"
|
|
739
|
+
}
|
|
740
|
+
),
|
|
741
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
742
|
+
"button",
|
|
743
|
+
{
|
|
744
|
+
type: "button",
|
|
745
|
+
className: "fractal-password-input-toggle",
|
|
746
|
+
"aria-label": toggleLabel,
|
|
747
|
+
"aria-pressed": passwordVisible,
|
|
748
|
+
disabled,
|
|
749
|
+
title: toggleLabel,
|
|
750
|
+
onClick: () => setPasswordVisible((visible) => !visible),
|
|
751
|
+
children: passwordVisible ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_fractal_icons5.EyeSlash, { "aria-hidden": "true", size: 18 }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_fractal_icons5.Eye, { "aria-hidden": "true", size: 18 })
|
|
752
|
+
}
|
|
753
|
+
)
|
|
754
|
+
]
|
|
755
|
+
}
|
|
756
|
+
);
|
|
757
|
+
}
|
|
758
|
+
);
|
|
759
|
+
PasswordInput.displayName = "PasswordInput";
|
|
760
|
+
|
|
761
|
+
// src/components/Label/Label.tsx
|
|
762
|
+
var React7 = __toESM(require("react"), 1);
|
|
763
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
764
|
+
var Label = React7.forwardRef(
|
|
765
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
392
766
|
"label",
|
|
393
767
|
{
|
|
394
768
|
ref,
|
|
@@ -400,44 +774,48 @@ var Label = React5.forwardRef(
|
|
|
400
774
|
Label.displayName = "Label";
|
|
401
775
|
|
|
402
776
|
// src/components/Alert/Alert.tsx
|
|
403
|
-
var
|
|
404
|
-
var
|
|
777
|
+
var React8 = __toESM(require("react"), 1);
|
|
778
|
+
var import_fractal_icons6 = require("@mirror-physics/fractal-icons");
|
|
779
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
405
780
|
var defaultIcons = {
|
|
406
|
-
default:
|
|
407
|
-
info:
|
|
408
|
-
success:
|
|
409
|
-
warning:
|
|
410
|
-
error:
|
|
781
|
+
default: import_fractal_icons6.CircleInfo,
|
|
782
|
+
info: import_fractal_icons6.CircleInfo,
|
|
783
|
+
success: import_fractal_icons6.CircleCheck,
|
|
784
|
+
warning: import_fractal_icons6.Warning,
|
|
785
|
+
error: import_fractal_icons6.CircleClose
|
|
411
786
|
};
|
|
412
|
-
var Alert =
|
|
413
|
-
({ className, variant = "default", icon, children, ...props }, ref) =>
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
787
|
+
var Alert = React8.forwardRef(
|
|
788
|
+
({ className, variant = "default", icon, children, ...props }, ref) => {
|
|
789
|
+
const DefaultIcon = defaultIcons[variant];
|
|
790
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
791
|
+
"div",
|
|
792
|
+
{
|
|
793
|
+
ref,
|
|
794
|
+
role: "alert",
|
|
795
|
+
className: cn("fractal-alert", `fractal-alert--${variant}`, className),
|
|
796
|
+
...props,
|
|
797
|
+
children: [
|
|
798
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "fractal-alert-icon", "aria-hidden": true, children: icon ?? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(DefaultIcon, { size: 18 }) }),
|
|
799
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "fractal-alert-content", children })
|
|
800
|
+
]
|
|
801
|
+
}
|
|
802
|
+
);
|
|
803
|
+
}
|
|
426
804
|
);
|
|
427
805
|
Alert.displayName = "Alert";
|
|
428
|
-
var AlertTitle =
|
|
429
|
-
({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
806
|
+
var AlertTitle = React8.forwardRef(
|
|
807
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h5", { ref, className: cn("fractal-alert-title", className), ...props })
|
|
430
808
|
);
|
|
431
809
|
AlertTitle.displayName = "AlertTitle";
|
|
432
|
-
var AlertDescription =
|
|
433
|
-
({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
810
|
+
var AlertDescription = React8.forwardRef(
|
|
811
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { ref, className: cn("fractal-alert-description", className), ...props })
|
|
434
812
|
);
|
|
435
813
|
AlertDescription.displayName = "AlertDescription";
|
|
436
814
|
|
|
437
815
|
// src/components/Toggle/Toggle.tsx
|
|
438
|
-
var
|
|
816
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
439
817
|
function Toggle({ checked, onChange, label, className }) {
|
|
440
|
-
return /* @__PURE__ */ (0,
|
|
818
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
441
819
|
"button",
|
|
442
820
|
{
|
|
443
821
|
type: "button",
|
|
@@ -446,8 +824,8 @@ function Toggle({ checked, onChange, label, className }) {
|
|
|
446
824
|
className: cn("fractal-toggle", className),
|
|
447
825
|
onClick: () => onChange(!checked),
|
|
448
826
|
children: [
|
|
449
|
-
/* @__PURE__ */ (0,
|
|
450
|
-
label && /* @__PURE__ */ (0,
|
|
827
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: cn("fractal-toggle-track", checked && "fractal-toggle-track--checked"), children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: cn("fractal-toggle-thumb", checked && "fractal-toggle-thumb--checked") }) }),
|
|
828
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "fractal-toggle-label", children: label })
|
|
451
829
|
]
|
|
452
830
|
}
|
|
453
831
|
);
|
|
@@ -457,7 +835,7 @@ function Toggle({ checked, onChange, label, className }) {
|
|
|
457
835
|
var import_react_dom = require("react-dom");
|
|
458
836
|
|
|
459
837
|
// src/hooks/useEscapeDismiss.ts
|
|
460
|
-
var
|
|
838
|
+
var import_react2 = require("react");
|
|
461
839
|
var nextId = 0;
|
|
462
840
|
var stack = [];
|
|
463
841
|
function insertSorted(entry) {
|
|
@@ -490,9 +868,9 @@ function ensureGlobalListener() {
|
|
|
490
868
|
);
|
|
491
869
|
}
|
|
492
870
|
function useEscapeDismiss(priority, handler, enabled = true) {
|
|
493
|
-
const handlerRef = (0,
|
|
871
|
+
const handlerRef = (0, import_react2.useRef)(handler);
|
|
494
872
|
handlerRef.current = handler;
|
|
495
|
-
(0,
|
|
873
|
+
(0, import_react2.useEffect)(() => {
|
|
496
874
|
if (!enabled) return;
|
|
497
875
|
ensureGlobalListener();
|
|
498
876
|
const id = nextId++;
|
|
@@ -506,27 +884,84 @@ function useEscapeDismiss(priority, handler, enabled = true) {
|
|
|
506
884
|
}, [priority, enabled]);
|
|
507
885
|
}
|
|
508
886
|
|
|
887
|
+
// src/components/UILoader/UILoader.tsx
|
|
888
|
+
var import_react3 = require("react");
|
|
889
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
890
|
+
var LEFT = "M0 53C0 51 1.6 49.5 3.6 49.5h16.5c1 0 1.9.4 2.5 1L42.1 69.6c.7.7 1.1 1.6 1.1 2.5v16.2c0 2-1.6 3.5-3.6 3.5H23.1c-1 0-1.9-.4-2.5-1L1.1 71.7C.4 71 0 70.1 0 69.2V53Z";
|
|
891
|
+
var CENTER = "M0 3.5C0 1.6 1.6 0 3.6 0h16.5c1 0 1.9.4 2.5 1L92.5 69.6c.7.7 1 1.6 1 2.5v16.2c0 2-1.6 3.5-3.6 3.5H73.4c-1 0-1.9-.4-2.5-1L1.1 22.2C.4 21.6 0 20.7 0 19.7V3.5Z";
|
|
892
|
+
var RIGHT = "M50.4 3.5C50.4 1.6 52 0 54 0h16.5c1 0 1.9.4 2.5 1l69.8 68.6c.7.7 1.1 1.6 1.1 2.5v16.2c0 2-1.6 3.5-3.6 3.5h-16.5c-1 0-1.9-.4-2.5-1L51.4 22.2c-.7-.6-1-1.5-1-2.5V3.5Z";
|
|
893
|
+
function UILoader({ size = 48, tone = "neutral", className, style, label = "Loading", ariaHidden = false }) {
|
|
894
|
+
const rawId = (0, import_react3.useId)().replace(/[^a-zA-Z0-9_-]/g, "");
|
|
895
|
+
const clipId = `fractal-ui-loader-clip-${rawId}`;
|
|
896
|
+
const gradientId = `fractal-ui-loader-gradient-${rawId}`;
|
|
897
|
+
const height = typeof size === "number" ? `${size}px` : size;
|
|
898
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
899
|
+
"span",
|
|
900
|
+
{
|
|
901
|
+
"aria-hidden": ariaHidden || void 0,
|
|
902
|
+
"aria-label": ariaHidden ? void 0 : label,
|
|
903
|
+
className: cn("fractal-ui-loader", `fractal-ui-loader--${tone}`, className),
|
|
904
|
+
role: ariaHidden ? void 0 : "status",
|
|
905
|
+
style,
|
|
906
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("svg", { "aria-hidden": "true", fill: "none", viewBox: "0 0 144 92", style: { height, width: "auto" }, children: [
|
|
907
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("defs", { children: [
|
|
908
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("linearGradient", { id: gradientId, x1: "59", x2: "94.3", y1: "0", y2: "89.1", gradientUnits: "userSpaceOnUse", children: [
|
|
909
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("stop", { className: "fractal-ui-loader__stop-start", offset: "0" }),
|
|
910
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("stop", { className: "fractal-ui-loader__stop-end", offset: "1" })
|
|
911
|
+
] }),
|
|
912
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("linearGradient", { id: `${gradientId}-shine`, x1: "0", x2: "1", y1: "0", y2: "0", children: [
|
|
913
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("stop", { offset: "0.4", stopColor: "white", stopOpacity: "0" }),
|
|
914
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("stop", { offset: "0.5", stopColor: "white", stopOpacity: "0.62" }),
|
|
915
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("stop", { offset: "0.6", stopColor: "white", stopOpacity: "0" })
|
|
916
|
+
] }),
|
|
917
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("clipPath", { id: clipId, children: [
|
|
918
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: LEFT }),
|
|
919
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: CENTER }),
|
|
920
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: RIGHT })
|
|
921
|
+
] })
|
|
922
|
+
] }),
|
|
923
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: CENTER, fill: `url(#${gradientId})` }),
|
|
924
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: RIGHT, fill: `url(#${gradientId})` }),
|
|
925
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: LEFT, fill: `url(#${gradientId})` }),
|
|
926
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("g", { clipPath: `url(#${clipId})`, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("g", { className: "fractal-ui-loader__shine-axis", transform: "translate(72 46) rotate(68.4)", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("rect", { className: "fractal-ui-loader__shine", x: "-160", y: "-100", width: "320", height: "200", fill: `url(#${gradientId}-shine)` }) }) })
|
|
927
|
+
] })
|
|
928
|
+
}
|
|
929
|
+
);
|
|
930
|
+
}
|
|
931
|
+
|
|
509
932
|
// src/components/Modal/Modal.tsx
|
|
510
|
-
var
|
|
511
|
-
var CloseIcon = () => /* @__PURE__ */ (0,
|
|
512
|
-
function Modal({ open, onClose, title, children, danger, warn, footer, noClose, size = "sm", className }) {
|
|
513
|
-
useEscapeDismiss(80, onClose, open && !noClose);
|
|
933
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
934
|
+
var CloseIcon = () => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M12 4L4 12M4 4L12 12", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) });
|
|
935
|
+
function Modal({ open, onClose, title, children, danger, warn, footer, noClose, closeDisabled = false, size = "sm", loading = false, loadingLabel = "Loading", scrollable = false, className }) {
|
|
936
|
+
useEscapeDismiss(80, onClose, open && !noClose && !closeDisabled);
|
|
514
937
|
if (!open) return null;
|
|
515
938
|
const sizeClass = `fractal-modal-panel--${size}`;
|
|
516
939
|
const accentClass = danger ? "fractal-modal-panel--danger" : warn ? "fractal-modal-panel--warn" : "";
|
|
517
940
|
return (0, import_react_dom.createPortal)(
|
|
518
|
-
/* @__PURE__ */ (0,
|
|
941
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "fractal-modal-overlay", onClick: noClose || closeDisabled ? void 0 : onClose, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
519
942
|
"div",
|
|
520
943
|
{
|
|
521
|
-
className: cn("fractal-modal-panel", sizeClass, accentClass, className),
|
|
944
|
+
className: cn("fractal-modal-panel", sizeClass, accentClass, scrollable && "fractal-modal-panel--scrollable", className),
|
|
522
945
|
onClick: (e) => e.stopPropagation(),
|
|
523
946
|
children: [
|
|
524
|
-
/* @__PURE__ */ (0,
|
|
525
|
-
/* @__PURE__ */ (0,
|
|
526
|
-
!noClose && /* @__PURE__ */ (0,
|
|
947
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "fractal-modal-title-row", children: [
|
|
948
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("h3", { className: cn("fractal-modal-title", danger && "fractal-modal-title--danger", warn && "fractal-modal-title--warn"), children: title }),
|
|
949
|
+
!noClose && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", onClick: onClose, title: "Close", disabled: closeDisabled, className: "fractal-modal-close", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CloseIcon, {}) })
|
|
527
950
|
] }),
|
|
528
|
-
/* @__PURE__ */ (0,
|
|
529
|
-
|
|
951
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
952
|
+
"div",
|
|
953
|
+
{
|
|
954
|
+
"aria-busy": loading || void 0,
|
|
955
|
+
className: cn(
|
|
956
|
+
"fractal-modal-body",
|
|
957
|
+
size === "lg" && "fractal-modal-body--lg",
|
|
958
|
+
loading && "fractal-modal-body--loading",
|
|
959
|
+
scrollable && "fractal-modal-body--scrollable"
|
|
960
|
+
),
|
|
961
|
+
children: loading ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(UILoader, { label: loadingLabel }) : children
|
|
962
|
+
}
|
|
963
|
+
),
|
|
964
|
+
footer && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: cn("fractal-modal-footer", scrollable && "fractal-modal-footer--divided"), children: footer })
|
|
530
965
|
]
|
|
531
966
|
}
|
|
532
967
|
) }),
|
|
@@ -535,17 +970,17 @@ function Modal({ open, onClose, title, children, danger, warn, footer, noClose,
|
|
|
535
970
|
}
|
|
536
971
|
|
|
537
972
|
// src/components/DataTable/DataTable.tsx
|
|
538
|
-
var
|
|
973
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
539
974
|
function DataTable({ columns, data, emptyMessage, header, size = "md", className }) {
|
|
540
|
-
return /* @__PURE__ */ (0,
|
|
541
|
-
header && /* @__PURE__ */ (0,
|
|
542
|
-
data.length === 0 ? /* @__PURE__ */ (0,
|
|
543
|
-
/* @__PURE__ */ (0,
|
|
544
|
-
/* @__PURE__ */ (0,
|
|
975
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: cn("fractal-datatable", `fractal-datatable--${size}`, className), children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "fractal-datatable-surface", children: [
|
|
976
|
+
header && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "fractal-datatable-header", children: header }),
|
|
977
|
+
data.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "fractal-datatable-empty", children: emptyMessage || "No data" }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("table", { className: "fractal-datatable-table", children: [
|
|
978
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("tr", { className: "fractal-datatable-thead-row", children: columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("th", { className: "fractal-datatable-th", style: { width: col.width }, children: col.header }, col.key)) }) }),
|
|
979
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("tbody", { children: data.map((row, rowIndex) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
545
980
|
"tr",
|
|
546
981
|
{
|
|
547
982
|
className: "fractal-datatable-row",
|
|
548
|
-
children: columns.map((col) => /* @__PURE__ */ (0,
|
|
983
|
+
children: columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("td", { className: "fractal-datatable-td", style: { width: col.width }, children: col.render(row, rowIndex) }, col.key))
|
|
549
984
|
},
|
|
550
985
|
rowIndex
|
|
551
986
|
)) })
|
|
@@ -554,9 +989,9 @@ function DataTable({ columns, data, emptyMessage, header, size = "md", className
|
|
|
554
989
|
}
|
|
555
990
|
|
|
556
991
|
// src/components/Dropdown/Dropdown.tsx
|
|
557
|
-
var
|
|
558
|
-
var
|
|
559
|
-
var
|
|
992
|
+
var React9 = __toESM(require("react"), 1);
|
|
993
|
+
var import_fractal_icons7 = require("@mirror-physics/fractal-icons");
|
|
994
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
560
995
|
var MARGIN = 4;
|
|
561
996
|
function Dropdown({
|
|
562
997
|
items,
|
|
@@ -567,18 +1002,20 @@ function Dropdown({
|
|
|
567
1002
|
align = "left",
|
|
568
1003
|
triggerContent,
|
|
569
1004
|
label,
|
|
1005
|
+
iconOnly = false,
|
|
570
1006
|
noChevron = false,
|
|
571
1007
|
size = "md",
|
|
572
1008
|
triggerVariant = "outline",
|
|
573
1009
|
className,
|
|
574
1010
|
triggerClassName,
|
|
575
1011
|
panelClassName,
|
|
576
|
-
closeOnSelect = true
|
|
1012
|
+
closeOnSelect = true,
|
|
1013
|
+
disabled = false
|
|
577
1014
|
}) {
|
|
578
|
-
const [open, setOpen] =
|
|
579
|
-
const triggerRef =
|
|
580
|
-
const panelRef =
|
|
581
|
-
const [panelStyle, setPanelStyle] =
|
|
1015
|
+
const [open, setOpen] = React9.useState(false);
|
|
1016
|
+
const triggerRef = React9.useRef(null);
|
|
1017
|
+
const panelRef = React9.useRef(null);
|
|
1018
|
+
const [panelStyle, setPanelStyle] = React9.useState({});
|
|
582
1019
|
const visibleItems = items.filter(
|
|
583
1020
|
(item) => item.icon != null || item.description != null && (typeof item.description === "string" ? item.description !== "" : true)
|
|
584
1021
|
);
|
|
@@ -586,8 +1023,8 @@ function Dropdown({
|
|
|
586
1023
|
const selectableItems = visibleItems.filter((i) => i.kind !== "header");
|
|
587
1024
|
const selected = items.find((i) => i.value === selectedValue && i.kind !== "header") ?? selectableItems[0] ?? visibleItems[0];
|
|
588
1025
|
const isUp = direction === "up";
|
|
589
|
-
const ChevronIcon = isUp ?
|
|
590
|
-
|
|
1026
|
+
const ChevronIcon = isUp ? import_fractal_icons7.ChevronUp : import_fractal_icons7.ChevronDown;
|
|
1027
|
+
React9.useLayoutEffect(() => {
|
|
591
1028
|
if (!open || !triggerRef.current || !panelRef.current) return;
|
|
592
1029
|
const triggerRect = triggerRef.current.getBoundingClientRect();
|
|
593
1030
|
const panelRect = panelRef.current.getBoundingClientRect();
|
|
@@ -621,7 +1058,7 @@ function Dropdown({
|
|
|
621
1058
|
}
|
|
622
1059
|
setPanelStyle({ top, left, right });
|
|
623
1060
|
}, [open, isUp, align]);
|
|
624
|
-
|
|
1061
|
+
React9.useEffect(() => {
|
|
625
1062
|
if (!open) return;
|
|
626
1063
|
const handleClickOutside = (e) => {
|
|
627
1064
|
const target = e.target;
|
|
@@ -631,12 +1068,13 @@ function Dropdown({
|
|
|
631
1068
|
document.addEventListener("mousedown", handleClickOutside);
|
|
632
1069
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
633
1070
|
}, [open]);
|
|
634
|
-
return /* @__PURE__ */ (0,
|
|
635
|
-
/* @__PURE__ */ (0,
|
|
1071
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: cn("fractal-dropdown", className), children: [
|
|
1072
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
636
1073
|
"button",
|
|
637
1074
|
{
|
|
638
1075
|
ref: triggerRef,
|
|
639
1076
|
type: "button",
|
|
1077
|
+
disabled,
|
|
640
1078
|
"aria-haspopup": "listbox",
|
|
641
1079
|
"aria-expanded": open,
|
|
642
1080
|
"aria-label": triggerLabel,
|
|
@@ -645,18 +1083,19 @@ function Dropdown({
|
|
|
645
1083
|
"fractal-dropdown-trigger",
|
|
646
1084
|
`fractal-dropdown-trigger--${size}`,
|
|
647
1085
|
`fractal-dropdown-trigger--${triggerVariant}`,
|
|
1086
|
+
iconOnly && "fractal-dropdown-trigger--icon-only",
|
|
648
1087
|
triggerClassName
|
|
649
1088
|
),
|
|
650
1089
|
children: [
|
|
651
|
-
triggerContent != null ? triggerContent : /* @__PURE__ */ (0,
|
|
652
|
-
selected.icon != null && /* @__PURE__ */ (0,
|
|
653
|
-
selected.description != null && (typeof selected.description !== "string" || selected.description !== "") && /* @__PURE__ */ (0,
|
|
1090
|
+
triggerContent != null ? triggerContent : /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
|
|
1091
|
+
selected.icon != null && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "fractal-dropdown-icon fractal-dropdown-icon--trigger", children: selected.icon }),
|
|
1092
|
+
selected.description != null && (typeof selected.description !== "string" || selected.description !== "") && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "fractal-dropdown-selected-text", children: selected.description })
|
|
654
1093
|
] }),
|
|
655
|
-
!noChevron && /* @__PURE__ */ (0,
|
|
1094
|
+
!noChevron && !iconOnly && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "fractal-dropdown-chevron", "aria-hidden": true, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ChevronIcon, { size: size === "sm" ? 14 : 16 }) })
|
|
656
1095
|
]
|
|
657
1096
|
}
|
|
658
1097
|
),
|
|
659
|
-
open && /* @__PURE__ */ (0,
|
|
1098
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
660
1099
|
"div",
|
|
661
1100
|
{
|
|
662
1101
|
ref: panelRef,
|
|
@@ -665,21 +1104,21 @@ function Dropdown({
|
|
|
665
1104
|
className: cn("fractal-dropdown-panel", `fractal-dropdown-panel--${size}`, panelClassName),
|
|
666
1105
|
style: panelStyle,
|
|
667
1106
|
children: [
|
|
668
|
-
label != null && /* @__PURE__ */ (0,
|
|
1107
|
+
label != null && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "fractal-dropdown-label", children: label }),
|
|
669
1108
|
visibleItems.map((item, index) => {
|
|
670
|
-
const topDivider = item.border === "top" ? /* @__PURE__ */ (0,
|
|
671
|
-
const bottomDivider = item.border === "bottom" ? /* @__PURE__ */ (0,
|
|
1109
|
+
const topDivider = item.border === "top" ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "fractal-dropdown-separator" }) : null;
|
|
1110
|
+
const bottomDivider = item.border === "bottom" ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "fractal-dropdown-separator" }) : null;
|
|
672
1111
|
if (item.kind === "header") {
|
|
673
|
-
return /* @__PURE__ */ (0,
|
|
1112
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(React9.Fragment, { children: [
|
|
674
1113
|
topDivider,
|
|
675
|
-
/* @__PURE__ */ (0,
|
|
1114
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { role: "presentation", className: "fractal-dropdown-label", children: item.description }),
|
|
676
1115
|
bottomDivider
|
|
677
1116
|
] }, `header-${index}`);
|
|
678
1117
|
}
|
|
679
1118
|
const isSelected = item.value === selectedValue;
|
|
680
|
-
return /* @__PURE__ */ (0,
|
|
1119
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(React9.Fragment, { children: [
|
|
681
1120
|
topDivider,
|
|
682
|
-
/* @__PURE__ */ (0,
|
|
1121
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
683
1122
|
"button",
|
|
684
1123
|
{
|
|
685
1124
|
type: "button",
|
|
@@ -691,9 +1130,9 @@ function Dropdown({
|
|
|
691
1130
|
},
|
|
692
1131
|
className: "fractal-dropdown-option",
|
|
693
1132
|
children: [
|
|
694
|
-
item.icon != null && /* @__PURE__ */ (0,
|
|
695
|
-
item.description != null && (typeof item.description !== "string" || item.description !== "") && /* @__PURE__ */ (0,
|
|
696
|
-
item.trailing != null && /* @__PURE__ */ (0,
|
|
1133
|
+
item.icon != null && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "fractal-dropdown-icon", children: item.icon }),
|
|
1134
|
+
item.description != null && (typeof item.description !== "string" || item.description !== "") && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "fractal-dropdown-option-text", children: item.description }),
|
|
1135
|
+
item.trailing != null && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "fractal-dropdown-trailing", children: item.trailing })
|
|
697
1136
|
]
|
|
698
1137
|
}
|
|
699
1138
|
),
|
|
@@ -707,10 +1146,10 @@ function Dropdown({
|
|
|
707
1146
|
}
|
|
708
1147
|
|
|
709
1148
|
// src/components/Link/Link.tsx
|
|
710
|
-
var
|
|
711
|
-
var
|
|
712
|
-
var Link =
|
|
713
|
-
({ className, theme = "default", size = "md", ...props }, ref) => /* @__PURE__ */ (0,
|
|
1149
|
+
var React10 = __toESM(require("react"), 1);
|
|
1150
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
1151
|
+
var Link = React10.forwardRef(
|
|
1152
|
+
({ className, theme = "default", size = "md", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
714
1153
|
"a",
|
|
715
1154
|
{
|
|
716
1155
|
ref,
|
|
@@ -722,10 +1161,10 @@ var Link = React8.forwardRef(
|
|
|
722
1161
|
Link.displayName = "Link";
|
|
723
1162
|
|
|
724
1163
|
// src/components/Chip/Chip.tsx
|
|
725
|
-
var
|
|
726
|
-
var
|
|
727
|
-
var Chip =
|
|
728
|
-
({ className, tone = "neutral", ...props }, ref) => /* @__PURE__ */ (0,
|
|
1164
|
+
var React11 = __toESM(require("react"), 1);
|
|
1165
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
1166
|
+
var Chip = React11.forwardRef(
|
|
1167
|
+
({ className, tone = "neutral", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
729
1168
|
"span",
|
|
730
1169
|
{
|
|
731
1170
|
ref,
|
|
@@ -736,36 +1175,86 @@ var Chip = React9.forwardRef(
|
|
|
736
1175
|
);
|
|
737
1176
|
Chip.displayName = "Chip";
|
|
738
1177
|
|
|
1178
|
+
// src/components/Checkbox/Checkbox.tsx
|
|
1179
|
+
var import_fractal_icons8 = require("@mirror-physics/fractal-icons");
|
|
1180
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
1181
|
+
function Checkbox({
|
|
1182
|
+
checked,
|
|
1183
|
+
indeterminate = false,
|
|
1184
|
+
onCheckedChange,
|
|
1185
|
+
className,
|
|
1186
|
+
disabled,
|
|
1187
|
+
onClick,
|
|
1188
|
+
onKeyDown,
|
|
1189
|
+
...props
|
|
1190
|
+
}) {
|
|
1191
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
1192
|
+
"button",
|
|
1193
|
+
{
|
|
1194
|
+
...props,
|
|
1195
|
+
className: cn(
|
|
1196
|
+
"fractal-checkbox",
|
|
1197
|
+
(checked || indeterminate) && "fractal-checkbox--checked",
|
|
1198
|
+
indeterminate && "fractal-checkbox--indeterminate",
|
|
1199
|
+
className
|
|
1200
|
+
),
|
|
1201
|
+
type: "button",
|
|
1202
|
+
role: "checkbox",
|
|
1203
|
+
"aria-checked": indeterminate ? "mixed" : checked,
|
|
1204
|
+
disabled,
|
|
1205
|
+
onClick: (event) => {
|
|
1206
|
+
onClick?.(event);
|
|
1207
|
+
if (!event.defaultPrevented) onCheckedChange(indeterminate || !checked);
|
|
1208
|
+
},
|
|
1209
|
+
onKeyDown: (event) => {
|
|
1210
|
+
onKeyDown?.(event);
|
|
1211
|
+
if (event.key === " " || event.key === "Enter") event.stopPropagation();
|
|
1212
|
+
},
|
|
1213
|
+
children: indeterminate ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: "fractal-checkbox__indeterminate-icon", "aria-hidden": "true", children: [
|
|
1214
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_fractal_icons8.Checkbox, { size: 18 }),
|
|
1215
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_fractal_icons8.Minus, { className: "fractal-checkbox__indeterminate-mark", size: 12 })
|
|
1216
|
+
] }) : checked ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_fractal_icons8.CheckboxChecked, { "aria-hidden": "true", size: 18 }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_fractal_icons8.Checkbox, { "aria-hidden": "true", size: 18 })
|
|
1217
|
+
}
|
|
1218
|
+
);
|
|
1219
|
+
}
|
|
1220
|
+
|
|
739
1221
|
// src/components/SortableTable/SortableTable.tsx
|
|
740
|
-
var
|
|
741
|
-
var
|
|
742
|
-
var
|
|
1222
|
+
var import_react4 = require("react");
|
|
1223
|
+
var import_fractal_icons9 = require("@mirror-physics/fractal-icons");
|
|
1224
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
743
1225
|
function SortableTable({
|
|
744
1226
|
columns,
|
|
745
1227
|
data,
|
|
746
1228
|
emptyMessage,
|
|
747
1229
|
header,
|
|
748
1230
|
size = "md",
|
|
1231
|
+
embedded = false,
|
|
749
1232
|
className,
|
|
1233
|
+
defaultSort,
|
|
750
1234
|
defaultSortKey = void 0,
|
|
751
1235
|
defaultSortDirection = null,
|
|
752
1236
|
sortKey: controlledKey,
|
|
753
1237
|
sortDirection: controlledDirection,
|
|
754
1238
|
onSortChange,
|
|
755
1239
|
highlightRow,
|
|
756
|
-
onRowClick
|
|
1240
|
+
onRowClick,
|
|
1241
|
+
rowAction
|
|
757
1242
|
}) {
|
|
758
|
-
const [internalKey, setInternalKey] = (0,
|
|
759
|
-
const [internalDirection, setInternalDirection] = (0,
|
|
1243
|
+
const [internalKey, setInternalKey] = (0, import_react4.useState)(defaultSortKey ?? null);
|
|
1244
|
+
const [internalDirection, setInternalDirection] = (0, import_react4.useState)(defaultSortDirection);
|
|
760
1245
|
const isControlled = controlledKey !== void 0 && controlledDirection !== void 0;
|
|
761
1246
|
const activeKey = isControlled ? controlledKey : internalKey;
|
|
762
1247
|
const activeDirection = isControlled ? controlledDirection : internalDirection;
|
|
763
|
-
const
|
|
764
|
-
|
|
765
|
-
|
|
1248
|
+
const baselineKey = defaultSort?.key ?? null;
|
|
1249
|
+
const baselineDirection = defaultSort?.direction ?? null;
|
|
1250
|
+
const effectiveKey = activeKey && activeDirection ? activeKey : baselineKey;
|
|
1251
|
+
const effectiveDirection = activeKey && activeDirection ? activeDirection : baselineDirection;
|
|
1252
|
+
const sorted = (0, import_react4.useMemo)(() => {
|
|
1253
|
+
if (!effectiveKey || !effectiveDirection) return data;
|
|
1254
|
+
const col = columns.find((c) => c.key === effectiveKey);
|
|
766
1255
|
if (!col) return data;
|
|
767
1256
|
const accessor = col.sortAccessor ?? ((row) => {
|
|
768
|
-
const value = row[
|
|
1257
|
+
const value = row[effectiveKey];
|
|
769
1258
|
return typeof value === "string" || typeof value === "number" ? value : null;
|
|
770
1259
|
});
|
|
771
1260
|
const copy = [...data];
|
|
@@ -776,26 +1265,28 @@ function SortableTable({
|
|
|
776
1265
|
if (av == null) return 1;
|
|
777
1266
|
if (bv == null) return -1;
|
|
778
1267
|
if (typeof av === "number" && typeof bv === "number") {
|
|
779
|
-
return
|
|
1268
|
+
return effectiveDirection === "asc" ? av - bv : bv - av;
|
|
780
1269
|
}
|
|
781
1270
|
const as = String(av).toLowerCase();
|
|
782
1271
|
const bs = String(bv).toLowerCase();
|
|
783
|
-
if (as < bs) return
|
|
784
|
-
if (as > bs) return
|
|
1272
|
+
if (as < bs) return effectiveDirection === "asc" ? -1 : 1;
|
|
1273
|
+
if (as > bs) return effectiveDirection === "asc" ? 1 : -1;
|
|
785
1274
|
return 0;
|
|
786
1275
|
});
|
|
787
1276
|
return copy;
|
|
788
|
-
}, [data, columns,
|
|
1277
|
+
}, [data, columns, effectiveKey, effectiveDirection]);
|
|
789
1278
|
const handleSortClick = (key) => {
|
|
790
1279
|
let nextDirection;
|
|
791
|
-
if (activeKey
|
|
1280
|
+
if (!activeKey || !activeDirection) {
|
|
1281
|
+
nextDirection = baselineKey === key && baselineDirection ? baselineDirection : "asc";
|
|
1282
|
+
} else if (activeKey !== key) {
|
|
792
1283
|
nextDirection = "asc";
|
|
1284
|
+
} else if (baselineKey === key && baselineDirection) {
|
|
1285
|
+
nextDirection = activeDirection === baselineDirection ? baselineDirection === "asc" ? "desc" : "asc" : null;
|
|
793
1286
|
} else if (activeDirection === "asc") {
|
|
794
1287
|
nextDirection = "desc";
|
|
795
|
-
} else if (activeDirection === "desc") {
|
|
796
|
-
nextDirection = null;
|
|
797
1288
|
} else {
|
|
798
|
-
nextDirection =
|
|
1289
|
+
nextDirection = null;
|
|
799
1290
|
}
|
|
800
1291
|
const nextKey = nextDirection === null ? null : key;
|
|
801
1292
|
if (isControlled) {
|
|
@@ -806,13 +1297,13 @@ function SortableTable({
|
|
|
806
1297
|
onSortChange?.(nextKey, nextDirection);
|
|
807
1298
|
}
|
|
808
1299
|
};
|
|
809
|
-
return /* @__PURE__ */ (0,
|
|
810
|
-
header && /* @__PURE__ */ (0,
|
|
811
|
-
sorted.length === 0 ? /* @__PURE__ */ (0,
|
|
812
|
-
/* @__PURE__ */ (0,
|
|
1300
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: cn("fractal-sortable-table", `fractal-sortable-table--${size}`, embedded && "fractal-sortable-table--embedded", className), children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "fractal-sortable-table-surface", children: [
|
|
1301
|
+
header && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "fractal-sortable-table-header", children: header }),
|
|
1302
|
+
sorted.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "fractal-sortable-table-empty", children: emptyMessage || "No data" }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("table", { className: "fractal-sortable-table-table", children: [
|
|
1303
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("tr", { className: "fractal-sortable-table-thead-row", children: columns.map((col) => {
|
|
813
1304
|
const isActive = activeKey === col.key && activeDirection !== null;
|
|
814
1305
|
if (!col.sortable) {
|
|
815
|
-
return /* @__PURE__ */ (0,
|
|
1306
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
816
1307
|
"th",
|
|
817
1308
|
{
|
|
818
1309
|
className: "fractal-sortable-table-th",
|
|
@@ -822,12 +1313,12 @@ function SortableTable({
|
|
|
822
1313
|
col.key
|
|
823
1314
|
);
|
|
824
1315
|
}
|
|
825
|
-
return /* @__PURE__ */ (0,
|
|
1316
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
826
1317
|
"th",
|
|
827
1318
|
{
|
|
828
1319
|
className: "fractal-sortable-table-th fractal-sortable-table-th--sortable",
|
|
829
1320
|
style: { width: col.width },
|
|
830
|
-
children: /* @__PURE__ */ (0,
|
|
1321
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
831
1322
|
"button",
|
|
832
1323
|
{
|
|
833
1324
|
type: "button",
|
|
@@ -838,8 +1329,8 @@ function SortableTable({
|
|
|
838
1329
|
onClick: () => handleSortClick(col.key),
|
|
839
1330
|
"aria-sort": isActive ? activeDirection === "asc" ? "ascending" : "descending" : "none",
|
|
840
1331
|
children: [
|
|
841
|
-
/* @__PURE__ */ (0,
|
|
842
|
-
/* @__PURE__ */ (0,
|
|
1332
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { children: col.header }),
|
|
1333
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "fractal-sortable-table-sort-icon", "aria-hidden": "true", children: isActive && activeDirection === "asc" ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_fractal_icons9.ArrowUp, { size: 14 }) : isActive && activeDirection === "desc" ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_fractal_icons9.ArrowDown, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_fractal_icons9.ArrowsUpDown, { size: 14 }) })
|
|
843
1334
|
]
|
|
844
1335
|
}
|
|
845
1336
|
)
|
|
@@ -847,9 +1338,13 @@ function SortableTable({
|
|
|
847
1338
|
col.key
|
|
848
1339
|
);
|
|
849
1340
|
}) }) }),
|
|
850
|
-
/* @__PURE__ */ (0,
|
|
1341
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("tbody", { children: sorted.map((row, rowIndex) => {
|
|
851
1342
|
const highlighted = highlightRow?.(row, rowIndex) ?? false;
|
|
852
|
-
|
|
1343
|
+
const action = rowAction ? {
|
|
1344
|
+
label: rowAction.label(row, rowIndex),
|
|
1345
|
+
icon: rowAction.icon(row, rowIndex)
|
|
1346
|
+
} : null;
|
|
1347
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
853
1348
|
"tr",
|
|
854
1349
|
{
|
|
855
1350
|
className: cn(
|
|
@@ -864,14 +1359,21 @@ function SortableTable({
|
|
|
864
1359
|
onRowClick(row, rowIndex);
|
|
865
1360
|
}
|
|
866
1361
|
} : void 0,
|
|
1362
|
+
"aria-label": action?.label,
|
|
867
1363
|
role: onRowClick ? "button" : void 0,
|
|
868
1364
|
tabIndex: onRowClick ? 0 : void 0,
|
|
869
|
-
children: columns.map((col) => /* @__PURE__ */ (0,
|
|
1365
|
+
children: columns.map((col, columnIndex) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
870
1366
|
"td",
|
|
871
1367
|
{
|
|
872
|
-
className:
|
|
1368
|
+
className: cn(
|
|
1369
|
+
"fractal-sortable-table-td",
|
|
1370
|
+
action && columnIndex === columns.length - 1 && "fractal-sortable-table-td--row-action"
|
|
1371
|
+
),
|
|
873
1372
|
style: { width: col.width, textAlign: col.align ?? "left" },
|
|
874
|
-
children:
|
|
1373
|
+
children: [
|
|
1374
|
+
col.render(row, rowIndex),
|
|
1375
|
+
action && columnIndex === columns.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "fractal-sortable-table-row-action", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "fractal-sortable-table-row-action__icon", children: action.icon }) })
|
|
1376
|
+
]
|
|
875
1377
|
},
|
|
876
1378
|
col.key
|
|
877
1379
|
))
|
|
@@ -884,23 +1386,40 @@ function SortableTable({
|
|
|
884
1386
|
}
|
|
885
1387
|
|
|
886
1388
|
// src/components/Tabs/Tabs.tsx
|
|
887
|
-
var
|
|
888
|
-
var
|
|
1389
|
+
var import_react5 = require("react");
|
|
1390
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
889
1391
|
function Tabs({
|
|
890
1392
|
items,
|
|
891
1393
|
defaultValue,
|
|
892
1394
|
value: controlledValue,
|
|
893
1395
|
onValueChange,
|
|
894
1396
|
className,
|
|
895
|
-
ariaLabel
|
|
1397
|
+
ariaLabel,
|
|
1398
|
+
divider = false,
|
|
1399
|
+
variant = "line"
|
|
896
1400
|
}) {
|
|
897
|
-
const reactId = (0,
|
|
898
|
-
const [internalValue, setInternalValue] = (0,
|
|
1401
|
+
const reactId = (0, import_react5.useId)();
|
|
1402
|
+
const [internalValue, setInternalValue] = (0, import_react5.useState)(
|
|
899
1403
|
defaultValue ?? items.find((i) => !i.disabled)?.id ?? items[0]?.id ?? ""
|
|
900
1404
|
);
|
|
901
1405
|
const isControlled = controlledValue !== void 0;
|
|
902
1406
|
const activeId = isControlled ? controlledValue : internalValue;
|
|
903
|
-
const
|
|
1407
|
+
const tabListRef = (0, import_react5.useRef)(null);
|
|
1408
|
+
const tabRefs = (0, import_react5.useRef)({});
|
|
1409
|
+
const [indicator, setIndicator] = (0, import_react5.useState)(null);
|
|
1410
|
+
(0, import_react5.useLayoutEffect)(() => {
|
|
1411
|
+
const updateIndicator = () => {
|
|
1412
|
+
const activeTab = tabRefs.current[activeId];
|
|
1413
|
+
if (!activeTab) return;
|
|
1414
|
+
setIndicator({ offset: activeTab.offsetLeft, width: activeTab.offsetWidth });
|
|
1415
|
+
};
|
|
1416
|
+
updateIndicator();
|
|
1417
|
+
const list = tabListRef.current;
|
|
1418
|
+
if (!list || typeof ResizeObserver === "undefined") return;
|
|
1419
|
+
const observer = new ResizeObserver(updateIndicator);
|
|
1420
|
+
observer.observe(list);
|
|
1421
|
+
return () => observer.disconnect();
|
|
1422
|
+
}, [activeId, items.length]);
|
|
904
1423
|
const selectTab = (id) => {
|
|
905
1424
|
if (isControlled) {
|
|
906
1425
|
onValueChange?.(id);
|
|
@@ -910,6 +1429,10 @@ function Tabs({
|
|
|
910
1429
|
}
|
|
911
1430
|
};
|
|
912
1431
|
const focusable = items.filter((i) => !i.disabled);
|
|
1432
|
+
const indicatorStyle = indicator ? {
|
|
1433
|
+
"--fractal-tabs-indicator-offset": `${indicator.offset}px`,
|
|
1434
|
+
"--fractal-tabs-indicator-width": `${indicator.width}px`
|
|
1435
|
+
} : void 0;
|
|
913
1436
|
const onKeyDown = (event) => {
|
|
914
1437
|
const currentIndex = focusable.findIndex((i) => i.id === activeId);
|
|
915
1438
|
if (currentIndex === -1) return;
|
|
@@ -935,41 +1458,52 @@ function Tabs({
|
|
|
935
1458
|
selectTab(nextId2);
|
|
936
1459
|
requestAnimationFrame(() => tabRefs.current[nextId2]?.focus());
|
|
937
1460
|
};
|
|
938
|
-
return /* @__PURE__ */ (0,
|
|
939
|
-
/* @__PURE__ */ (0,
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
"
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
id
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
1461
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: cn("fractal-tabs", `fractal-tabs--${variant}`, divider && "fractal-tabs--divider", className), children: [
|
|
1462
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
1463
|
+
"div",
|
|
1464
|
+
{
|
|
1465
|
+
ref: tabListRef,
|
|
1466
|
+
role: "tablist",
|
|
1467
|
+
"aria-label": ariaLabel,
|
|
1468
|
+
className: "fractal-tabs-list",
|
|
1469
|
+
"data-indicator-ready": indicator ? "true" : void 0,
|
|
1470
|
+
style: indicatorStyle,
|
|
1471
|
+
children: items.map((item) => {
|
|
1472
|
+
const isActive = item.id === activeId;
|
|
1473
|
+
const tabId = `${reactId}-tab-${item.id}`;
|
|
1474
|
+
const panelId = `${reactId}-panel-${item.id}`;
|
|
1475
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
1476
|
+
"button",
|
|
1477
|
+
{
|
|
1478
|
+
ref: (el) => {
|
|
1479
|
+
tabRefs.current[item.id] = el;
|
|
1480
|
+
},
|
|
1481
|
+
id: tabId,
|
|
1482
|
+
role: "tab",
|
|
1483
|
+
type: "button",
|
|
1484
|
+
"aria-selected": isActive,
|
|
1485
|
+
"aria-controls": panelId,
|
|
1486
|
+
tabIndex: isActive ? 0 : -1,
|
|
1487
|
+
disabled: item.disabled,
|
|
1488
|
+
className: cn(
|
|
1489
|
+
"fractal-tabs-trigger",
|
|
1490
|
+
isActive && "fractal-tabs-trigger--active",
|
|
1491
|
+
item.disabled && "fractal-tabs-trigger--disabled"
|
|
1492
|
+
),
|
|
1493
|
+
onClick: () => !item.disabled && selectTab(item.id),
|
|
1494
|
+
onKeyDown,
|
|
1495
|
+
children: item.label
|
|
1496
|
+
},
|
|
1497
|
+
item.id
|
|
1498
|
+
);
|
|
1499
|
+
})
|
|
1500
|
+
}
|
|
1501
|
+
),
|
|
968
1502
|
items.map((item) => {
|
|
969
1503
|
const tabId = `${reactId}-tab-${item.id}`;
|
|
970
1504
|
const panelId = `${reactId}-panel-${item.id}`;
|
|
971
1505
|
const isActive = item.id === activeId;
|
|
972
|
-
return /* @__PURE__ */ (0,
|
|
1506
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
973
1507
|
"div",
|
|
974
1508
|
{
|
|
975
1509
|
id: panelId,
|
|
@@ -985,10 +1519,112 @@ function Tabs({
|
|
|
985
1519
|
] });
|
|
986
1520
|
}
|
|
987
1521
|
|
|
1522
|
+
// src/components/ContentSwitcher/ContentSwitcher.tsx
|
|
1523
|
+
var React12 = __toESM(require("react"), 1);
|
|
1524
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
1525
|
+
function ContentSwitcher({ items, value, onValueChange, ariaLabel, fullWidth = false, className }) {
|
|
1526
|
+
const switcherRef = React12.useRef(null);
|
|
1527
|
+
const buttonRefs = React12.useRef([]);
|
|
1528
|
+
const indicatorMotionReadyRef = React12.useRef(false);
|
|
1529
|
+
const activeIndex = items.findIndex((item) => item.value === value);
|
|
1530
|
+
React12.useLayoutEffect(() => {
|
|
1531
|
+
const switcher = switcherRef.current;
|
|
1532
|
+
const activeButton = buttonRefs.current[activeIndex];
|
|
1533
|
+
let motionFrame = 0;
|
|
1534
|
+
if (!switcher || !activeButton) {
|
|
1535
|
+
switcher?.removeAttribute("data-indicator-ready");
|
|
1536
|
+
switcher?.removeAttribute("data-indicator-animate");
|
|
1537
|
+
indicatorMotionReadyRef.current = false;
|
|
1538
|
+
return;
|
|
1539
|
+
}
|
|
1540
|
+
const updateIndicator = () => {
|
|
1541
|
+
const switcherRect = switcher.getBoundingClientRect();
|
|
1542
|
+
const activeButtonRect = activeButton.getBoundingClientRect();
|
|
1543
|
+
switcher.style.setProperty("--fractal-content-switcher-indicator-x", `${activeButtonRect.left - switcherRect.left - switcher.clientLeft}px`);
|
|
1544
|
+
switcher.style.setProperty("--fractal-content-switcher-indicator-y", `${activeButtonRect.top - switcherRect.top - switcher.clientTop}px`);
|
|
1545
|
+
switcher.style.setProperty("--fractal-content-switcher-indicator-width", `${activeButtonRect.width}px`);
|
|
1546
|
+
switcher.style.setProperty("--fractal-content-switcher-indicator-height", `${activeButtonRect.height}px`);
|
|
1547
|
+
switcher.setAttribute("data-indicator-ready", "true");
|
|
1548
|
+
if (!indicatorMotionReadyRef.current && motionFrame === 0) {
|
|
1549
|
+
motionFrame = window.requestAnimationFrame(() => {
|
|
1550
|
+
indicatorMotionReadyRef.current = true;
|
|
1551
|
+
switcher.setAttribute("data-indicator-animate", "true");
|
|
1552
|
+
motionFrame = 0;
|
|
1553
|
+
});
|
|
1554
|
+
}
|
|
1555
|
+
};
|
|
1556
|
+
updateIndicator();
|
|
1557
|
+
if (typeof ResizeObserver === "undefined") {
|
|
1558
|
+
return () => {
|
|
1559
|
+
if (motionFrame !== 0) window.cancelAnimationFrame(motionFrame);
|
|
1560
|
+
};
|
|
1561
|
+
}
|
|
1562
|
+
const resizeObserver = new ResizeObserver(updateIndicator);
|
|
1563
|
+
resizeObserver.observe(switcher);
|
|
1564
|
+
buttonRefs.current.forEach((button) => {
|
|
1565
|
+
if (button) resizeObserver.observe(button);
|
|
1566
|
+
});
|
|
1567
|
+
return () => {
|
|
1568
|
+
resizeObserver.disconnect();
|
|
1569
|
+
if (motionFrame !== 0) window.cancelAnimationFrame(motionFrame);
|
|
1570
|
+
};
|
|
1571
|
+
}, [activeIndex, items.length]);
|
|
1572
|
+
const moveFocus = (index, direction) => {
|
|
1573
|
+
let nextIndex = index;
|
|
1574
|
+
do {
|
|
1575
|
+
nextIndex = (nextIndex + direction + items.length) % items.length;
|
|
1576
|
+
} while (items[nextIndex]?.disabled && nextIndex !== index);
|
|
1577
|
+
if (!items[nextIndex]?.disabled) {
|
|
1578
|
+
buttonRefs.current[nextIndex]?.focus();
|
|
1579
|
+
onValueChange(items[nextIndex].value);
|
|
1580
|
+
}
|
|
1581
|
+
};
|
|
1582
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
1583
|
+
"div",
|
|
1584
|
+
{
|
|
1585
|
+
className: cn("fractal-content-switcher", fullWidth && "fractal-content-switcher--full-width", className),
|
|
1586
|
+
role: "group",
|
|
1587
|
+
"aria-label": ariaLabel,
|
|
1588
|
+
ref: switcherRef,
|
|
1589
|
+
children: [
|
|
1590
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "fractal-content-switcher__indicator", "aria-hidden": true }),
|
|
1591
|
+
items.map((item, index) => {
|
|
1592
|
+
const active = item.value === value;
|
|
1593
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
1594
|
+
"button",
|
|
1595
|
+
{
|
|
1596
|
+
className: cn("fractal-content-switcher__item", active && "fractal-content-switcher__item--active"),
|
|
1597
|
+
type: "button",
|
|
1598
|
+
"aria-pressed": active,
|
|
1599
|
+
disabled: item.disabled,
|
|
1600
|
+
onClick: () => onValueChange(item.value),
|
|
1601
|
+
onKeyDown: (event) => {
|
|
1602
|
+
if (event.key === "ArrowRight") {
|
|
1603
|
+
event.preventDefault();
|
|
1604
|
+
moveFocus(index, 1);
|
|
1605
|
+
}
|
|
1606
|
+
if (event.key === "ArrowLeft") {
|
|
1607
|
+
event.preventDefault();
|
|
1608
|
+
moveFocus(index, -1);
|
|
1609
|
+
}
|
|
1610
|
+
},
|
|
1611
|
+
ref: (element) => {
|
|
1612
|
+
buttonRefs.current[index] = element;
|
|
1613
|
+
},
|
|
1614
|
+
children: item.label
|
|
1615
|
+
},
|
|
1616
|
+
item.value
|
|
1617
|
+
);
|
|
1618
|
+
})
|
|
1619
|
+
]
|
|
1620
|
+
}
|
|
1621
|
+
);
|
|
1622
|
+
}
|
|
1623
|
+
|
|
988
1624
|
// src/components/Disclosure/Disclosure.tsx
|
|
989
|
-
var
|
|
990
|
-
var
|
|
991
|
-
var
|
|
1625
|
+
var import_react6 = require("react");
|
|
1626
|
+
var import_fractal_icons10 = require("@mirror-physics/fractal-icons");
|
|
1627
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
992
1628
|
function Disclosure({
|
|
993
1629
|
title,
|
|
994
1630
|
meta,
|
|
@@ -996,16 +1632,18 @@ function Disclosure({
|
|
|
996
1632
|
defaultOpen = false,
|
|
997
1633
|
open: controlledOpen,
|
|
998
1634
|
onOpenChange,
|
|
1635
|
+
disabled = false,
|
|
999
1636
|
className,
|
|
1000
1637
|
variant = "card"
|
|
1001
1638
|
}) {
|
|
1002
|
-
const reactId = (0,
|
|
1639
|
+
const reactId = (0, import_react6.useId)();
|
|
1003
1640
|
const headerId = `${reactId}-header`;
|
|
1004
1641
|
const panelId = `${reactId}-panel`;
|
|
1005
|
-
const [internalOpen, setInternalOpen] = (0,
|
|
1642
|
+
const [internalOpen, setInternalOpen] = (0, import_react6.useState)(defaultOpen);
|
|
1006
1643
|
const isControlled = controlledOpen !== void 0;
|
|
1007
1644
|
const isOpen = isControlled ? controlledOpen : internalOpen;
|
|
1008
1645
|
const toggle = () => {
|
|
1646
|
+
if (disabled) return;
|
|
1009
1647
|
const next = !isOpen;
|
|
1010
1648
|
if (isControlled) {
|
|
1011
1649
|
onOpenChange?.(next);
|
|
@@ -1014,17 +1652,18 @@ function Disclosure({
|
|
|
1014
1652
|
onOpenChange?.(next);
|
|
1015
1653
|
}
|
|
1016
1654
|
};
|
|
1017
|
-
return /* @__PURE__ */ (0,
|
|
1655
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
1018
1656
|
"div",
|
|
1019
1657
|
{
|
|
1020
1658
|
className: cn(
|
|
1021
1659
|
"fractal-disclosure",
|
|
1022
1660
|
variant === "card" && "fractal-disclosure--card",
|
|
1023
1661
|
isOpen && "fractal-disclosure--open",
|
|
1662
|
+
disabled && "fractal-disclosure--disabled",
|
|
1024
1663
|
className
|
|
1025
1664
|
),
|
|
1026
1665
|
children: [
|
|
1027
|
-
/* @__PURE__ */ (0,
|
|
1666
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
1028
1667
|
"button",
|
|
1029
1668
|
{
|
|
1030
1669
|
type: "button",
|
|
@@ -1032,15 +1671,16 @@ function Disclosure({
|
|
|
1032
1671
|
className: "fractal-disclosure-trigger",
|
|
1033
1672
|
"aria-expanded": isOpen,
|
|
1034
1673
|
"aria-controls": panelId,
|
|
1674
|
+
disabled,
|
|
1035
1675
|
onClick: toggle,
|
|
1036
1676
|
children: [
|
|
1037
|
-
/* @__PURE__ */ (0,
|
|
1038
|
-
/* @__PURE__ */ (0,
|
|
1039
|
-
meta && /* @__PURE__ */ (0,
|
|
1677
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "fractal-disclosure-icon", "aria-hidden": "true", children: isOpen ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_fractal_icons10.ChevronDown, { size: 16 }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_fractal_icons10.ChevronRight, { size: 16 }) }),
|
|
1678
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "fractal-disclosure-title", children: title }),
|
|
1679
|
+
meta && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "fractal-disclosure-meta", children: meta })
|
|
1040
1680
|
]
|
|
1041
1681
|
}
|
|
1042
1682
|
),
|
|
1043
|
-
/* @__PURE__ */ (0,
|
|
1683
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
1044
1684
|
"div",
|
|
1045
1685
|
{
|
|
1046
1686
|
id: panelId,
|
|
@@ -1048,7 +1688,7 @@ function Disclosure({
|
|
|
1048
1688
|
"aria-labelledby": headerId,
|
|
1049
1689
|
className: "fractal-disclosure-panel",
|
|
1050
1690
|
hidden: !isOpen,
|
|
1051
|
-
children: /* @__PURE__ */ (0,
|
|
1691
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "fractal-disclosure-panel-inner", children })
|
|
1052
1692
|
}
|
|
1053
1693
|
)
|
|
1054
1694
|
]
|
|
@@ -1056,39 +1696,260 @@ function Disclosure({
|
|
|
1056
1696
|
);
|
|
1057
1697
|
}
|
|
1058
1698
|
|
|
1699
|
+
// src/components/LatticeLoader/LatticeLoader.tsx
|
|
1700
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
1701
|
+
var LATTICE_COUNT = 160;
|
|
1702
|
+
var WAVE_PERIOD = 80;
|
|
1703
|
+
function LatticeLoader({ className, label = "Loading", ...props }) {
|
|
1704
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
1705
|
+
"span",
|
|
1706
|
+
{
|
|
1707
|
+
"aria-label": label,
|
|
1708
|
+
className: cn("fractal-lattice-loader", className),
|
|
1709
|
+
role: "progressbar",
|
|
1710
|
+
...props,
|
|
1711
|
+
children: Array.from({ length: LATTICE_COUNT }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
1712
|
+
"span",
|
|
1713
|
+
{
|
|
1714
|
+
"aria-hidden": "true",
|
|
1715
|
+
className: "fractal-lattice-loader__cell",
|
|
1716
|
+
style: { "--fractal-lattice-index": index % WAVE_PERIOD }
|
|
1717
|
+
},
|
|
1718
|
+
index
|
|
1719
|
+
))
|
|
1720
|
+
}
|
|
1721
|
+
);
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1724
|
+
// src/components/Ghost/Ghost.tsx
|
|
1725
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
1726
|
+
var toCssLength = (value) => typeof value === "number" ? `${value}px` : value;
|
|
1727
|
+
function Ghost({ className, width, height, radius, style, ...props }) {
|
|
1728
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
1729
|
+
"div",
|
|
1730
|
+
{
|
|
1731
|
+
"aria-hidden": "true",
|
|
1732
|
+
className: cn("fractal-ghost", className),
|
|
1733
|
+
style: {
|
|
1734
|
+
width: toCssLength(width),
|
|
1735
|
+
height: toCssLength(height),
|
|
1736
|
+
borderRadius: toCssLength(radius),
|
|
1737
|
+
...style
|
|
1738
|
+
},
|
|
1739
|
+
...props
|
|
1740
|
+
}
|
|
1741
|
+
);
|
|
1742
|
+
}
|
|
1743
|
+
function GhostLine({ className, size = "md", width = "100%", ...props }) {
|
|
1744
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Ghost, { className: cn("fractal-ghost-line", `fractal-ghost-line--${size}`, className), width, ...props });
|
|
1745
|
+
}
|
|
1746
|
+
function ButtonGhost({ className, size = "md", iconOnly = false, width, ...props }) {
|
|
1747
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Ghost, { className: cn("fractal-ghost-button", `fractal-ghost-button--${size}`, iconOnly && "fractal-ghost-button--icon-only", className), width, ...props });
|
|
1748
|
+
}
|
|
1749
|
+
function CardGhost({ className, lines = 3, showHeader = true, ...props }) {
|
|
1750
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { "aria-hidden": "true", className: cn("fractal-ghost-card", className), ...props, children: [
|
|
1751
|
+
showHeader && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(GhostLine, { width: "38%" }),
|
|
1752
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "fractal-ghost-stack", children: Array.from({ length: lines }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(GhostLine, { width: index === lines - 1 ? "62%" : "100%" }, index)) })
|
|
1753
|
+
] });
|
|
1754
|
+
}
|
|
1755
|
+
function DataTableGhost({
|
|
1756
|
+
className,
|
|
1757
|
+
showHeader = true,
|
|
1758
|
+
headers,
|
|
1759
|
+
columns = 4,
|
|
1760
|
+
rows = 5,
|
|
1761
|
+
columnWidths,
|
|
1762
|
+
size = "md",
|
|
1763
|
+
...props
|
|
1764
|
+
}) {
|
|
1765
|
+
const cells = Array.from({ length: columns }, (_, index) => index);
|
|
1766
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { "aria-busy": "true", "aria-label": "Loading table", className: cn("fractal-ghost-table", `fractal-ghost-table--${size}`, className), role: "status", ...props, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("table", { className: "fractal-ghost-table__table", children: [
|
|
1767
|
+
(showHeader || headers) && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("tr", { className: "fractal-ghost-table__head-row", children: cells.map((index) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("th", { style: { width: columnWidths?.[index] }, children: headers?.[index] ?? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(GhostLine, { size: "sm", width: index === columns - 1 ? "62%" : "76%" }) }, index)) }) }),
|
|
1768
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("tbody", { children: Array.from({ length: rows }, (_, rowIndex) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("tr", { className: "fractal-ghost-table__row", children: cells.map((columnIndex) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("td", { style: { width: columnWidths?.[columnIndex] }, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(GhostLine, { width: `${[72, 54, 82, 63, 46][(rowIndex + columnIndex) % 5]}%` }) }, columnIndex)) }, rowIndex)) })
|
|
1769
|
+
] }) });
|
|
1770
|
+
}
|
|
1771
|
+
function InputGhost({ className, labelWidth = "26%", ...props }) {
|
|
1772
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(FormFieldGhost, { className, labelWidth, ...props });
|
|
1773
|
+
}
|
|
1774
|
+
function TextareaGhost({ className, labelWidth = "26%", ...props }) {
|
|
1775
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(FormFieldGhost, { className, labelWidth, multiline: true, ...props });
|
|
1776
|
+
}
|
|
1777
|
+
function LabelGhost({ className, width = "26%", ...props }) {
|
|
1778
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(GhostLine, { className: cn("fractal-ghost-label", className), size: "sm", width, ...props });
|
|
1779
|
+
}
|
|
1780
|
+
function FormFieldGhost({ className, labelWidth = "26%", multiline = false, ...props }) {
|
|
1781
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { "aria-hidden": "true", className: cn("fractal-ghost-field", className), ...props, children: [
|
|
1782
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(LabelGhost, { width: labelWidth }),
|
|
1783
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Ghost, { className: cn("fractal-ghost-field__control", multiline && "fractal-ghost-field__control--multiline") })
|
|
1784
|
+
] });
|
|
1785
|
+
}
|
|
1786
|
+
function AlertGhost({ className, ...props }) {
|
|
1787
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { "aria-hidden": "true", className: cn("fractal-ghost-alert", className), ...props, children: [
|
|
1788
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(GhostLine, { width: "30%" }),
|
|
1789
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(GhostLine, { size: "sm", width: "78%" })
|
|
1790
|
+
] });
|
|
1791
|
+
}
|
|
1792
|
+
function CheckboxGhost({ className, ...props }) {
|
|
1793
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { "aria-hidden": "true", className: cn("fractal-ghost-choice", className), ...props, children: [
|
|
1794
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Ghost, { className: "fractal-ghost-choice__control" }),
|
|
1795
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(GhostLine, { width: "42%" })
|
|
1796
|
+
] });
|
|
1797
|
+
}
|
|
1798
|
+
var ToggleGhost = CheckboxGhost;
|
|
1799
|
+
function ChipGhost({ className, width = 74, ...props }) {
|
|
1800
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Ghost, { className: cn("fractal-ghost-chip", className), height: 24, width, ...props });
|
|
1801
|
+
}
|
|
1802
|
+
function LinkGhost({ className, width = 96, ...props }) {
|
|
1803
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(GhostLine, { className: cn("fractal-ghost-link", className), size: "sm", width, ...props });
|
|
1804
|
+
}
|
|
1805
|
+
var TextButtonGhost = LinkGhost;
|
|
1806
|
+
function DropdownGhost({ className, ...props }) {
|
|
1807
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { "aria-hidden": "true", className: cn("fractal-ghost-dropdown", className), ...props, children: [
|
|
1808
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(GhostLine, { width: "38%" }),
|
|
1809
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Ghost, { className: "fractal-ghost-dropdown__chevron" })
|
|
1810
|
+
] });
|
|
1811
|
+
}
|
|
1812
|
+
function ContentSwitcherGhost({ className, options = 3, ...props }) {
|
|
1813
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { "aria-hidden": "true", className: cn("fractal-ghost-switcher", className), ...props, children: Array.from({ length: options }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Ghost, {}, index)) });
|
|
1814
|
+
}
|
|
1815
|
+
var TabsGhost = ContentSwitcherGhost;
|
|
1816
|
+
function DisclosureGhost({ className, ...props }) {
|
|
1817
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { "aria-hidden": "true", className: cn("fractal-ghost-disclosure", className), ...props, children: [
|
|
1818
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Ghost, { className: "fractal-ghost-disclosure__icon" }),
|
|
1819
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(GhostLine, { width: "42%" })
|
|
1820
|
+
] });
|
|
1821
|
+
}
|
|
1822
|
+
function PaginationGhost({ className, pages = 5, ...props }) {
|
|
1823
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { "aria-hidden": "true", className: cn("fractal-ghost-pagination", className), ...props, children: Array.from({ length: pages }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Ghost, {}, index)) });
|
|
1824
|
+
}
|
|
1825
|
+
function FileDropzoneGhost({ className, ...props }) {
|
|
1826
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { "aria-hidden": "true", className: cn("fractal-ghost-dropzone", className), ...props, children: [
|
|
1827
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Ghost, { className: "fractal-ghost-dropzone__icon" }),
|
|
1828
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(GhostLine, { width: "26%" }),
|
|
1829
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(GhostLine, { size: "sm", width: "46%" })
|
|
1830
|
+
] });
|
|
1831
|
+
}
|
|
1832
|
+
function PromptCardGhost({ className, ...props }) {
|
|
1833
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(CardGhost, { className: cn("fractal-ghost-prompt-card", className), lines: 4, ...props });
|
|
1834
|
+
}
|
|
1835
|
+
function ConversationGhost({
|
|
1836
|
+
className,
|
|
1837
|
+
"aria-label": ariaLabel = "Loading conversation",
|
|
1838
|
+
...props
|
|
1839
|
+
}) {
|
|
1840
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
1841
|
+
"div",
|
|
1842
|
+
{
|
|
1843
|
+
"aria-busy": "true",
|
|
1844
|
+
"aria-label": ariaLabel,
|
|
1845
|
+
className: cn("fractal-ghost-conversation", className),
|
|
1846
|
+
role: "status",
|
|
1847
|
+
...props,
|
|
1848
|
+
children: [
|
|
1849
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { "aria-hidden": "true", className: "fractal-ghost-conversation__message fractal-ghost-conversation__message--user", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "fractal-ghost-conversation__bubble", children: [
|
|
1850
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(GhostLine, { width: "100%" }),
|
|
1851
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(GhostLine, { width: "86%" }),
|
|
1852
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(GhostLine, { width: "64%" })
|
|
1853
|
+
] }) }),
|
|
1854
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { "aria-hidden": "true", className: "fractal-ghost-conversation__message fractal-ghost-conversation__message--assistant", children: [
|
|
1855
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(GhostLine, { width: "92%" }),
|
|
1856
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(GhostLine, { width: "78%" }),
|
|
1857
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(GhostLine, { width: "58%" })
|
|
1858
|
+
] })
|
|
1859
|
+
]
|
|
1860
|
+
}
|
|
1861
|
+
);
|
|
1862
|
+
}
|
|
1863
|
+
function SortableTableGhost(props) {
|
|
1864
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(DataTableGhost, { ...props });
|
|
1865
|
+
}
|
|
1866
|
+
function SidebarGhost({ className, items = 6, ...props }) {
|
|
1867
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("aside", { "aria-hidden": "true", className: cn("fractal-ghost-sidebar", className), ...props, children: [
|
|
1868
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Ghost, { className: "fractal-ghost-sidebar__brand" }),
|
|
1869
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "fractal-ghost-sidebar__items", children: Array.from({ length: items }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "fractal-ghost-sidebar__item", children: [
|
|
1870
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Ghost, {}),
|
|
1871
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(GhostLine, { width: `${[54, 68, 44, 61][index % 4]}%` })
|
|
1872
|
+
] }, index)) })
|
|
1873
|
+
] });
|
|
1874
|
+
}
|
|
1875
|
+
function ModalGhost({ className, title, lines = 3, ...props }) {
|
|
1876
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SurfaceGhost, { className: cn("fractal-ghost-modal", className), title, lines, ...props });
|
|
1877
|
+
}
|
|
1878
|
+
function SidePanelGhost({ className, title, lines = 5, ...props }) {
|
|
1879
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SurfaceGhost, { className: cn("fractal-ghost-side-panel", className), title, lines, ...props });
|
|
1880
|
+
}
|
|
1881
|
+
function SurfaceGhost({ className, title, lines = 3, ...props }) {
|
|
1882
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { "aria-hidden": "true", className: cn("fractal-ghost-surface", className), ...props, children: [
|
|
1883
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "fractal-ghost-surface__header", children: [
|
|
1884
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(GhostLine, { width: "42%" }),
|
|
1885
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Ghost, { className: "fractal-ghost-surface__close" })
|
|
1886
|
+
] }),
|
|
1887
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "fractal-ghost-surface__title", children: title }),
|
|
1888
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "fractal-ghost-stack", children: Array.from({ length: lines }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(GhostLine, { width: index === lines - 1 ? "64%" : "100%" }, index)) })
|
|
1889
|
+
] });
|
|
1890
|
+
}
|
|
1891
|
+
|
|
1059
1892
|
// src/components/Sidebar/Sidebar.tsx
|
|
1060
|
-
var
|
|
1061
|
-
var
|
|
1062
|
-
var Sidebar =
|
|
1063
|
-
({ className, width, style, ...props }, ref) => /* @__PURE__ */ (0,
|
|
1893
|
+
var React13 = __toESM(require("react"), 1);
|
|
1894
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
1895
|
+
var Sidebar = React13.forwardRef(
|
|
1896
|
+
({ className, width, compact = false, style, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
1064
1897
|
"aside",
|
|
1065
1898
|
{
|
|
1066
1899
|
ref,
|
|
1067
1900
|
className: cn("fractal-sidebar", className),
|
|
1901
|
+
"data-compact": compact || void 0,
|
|
1068
1902
|
style: { ...style, ...width ? { "--fractal-sidebar-width": width } : {} },
|
|
1069
1903
|
...props
|
|
1070
1904
|
}
|
|
1071
1905
|
)
|
|
1072
1906
|
);
|
|
1073
1907
|
Sidebar.displayName = "Sidebar";
|
|
1074
|
-
var SidebarHeader =
|
|
1075
|
-
({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
1908
|
+
var SidebarHeader = React13.forwardRef(
|
|
1909
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { ref, className: cn("fractal-sidebar__header", className), ...props })
|
|
1076
1910
|
);
|
|
1077
1911
|
SidebarHeader.displayName = "SidebarHeader";
|
|
1078
|
-
var SidebarBrand =
|
|
1079
|
-
({ className, type = "button", ...props }, ref) => /* @__PURE__ */ (0,
|
|
1912
|
+
var SidebarBrand = React13.forwardRef(
|
|
1913
|
+
({ className, type = "button", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { ref, type, className: cn("fractal-sidebar__brand", className), ...props })
|
|
1080
1914
|
);
|
|
1081
1915
|
SidebarBrand.displayName = "SidebarBrand";
|
|
1082
|
-
|
|
1083
|
-
|
|
1916
|
+
function SidebarAccountMenu({
|
|
1917
|
+
name,
|
|
1918
|
+
items,
|
|
1919
|
+
onSelect,
|
|
1920
|
+
triggerLabel = "Account menu",
|
|
1921
|
+
icon,
|
|
1922
|
+
className
|
|
1923
|
+
}) {
|
|
1924
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
1925
|
+
Dropdown,
|
|
1926
|
+
{
|
|
1927
|
+
align: "left",
|
|
1928
|
+
className: cn("fractal-sidebar__account", className),
|
|
1929
|
+
items,
|
|
1930
|
+
onSelect,
|
|
1931
|
+
panelClassName: "fractal-sidebar__account-panel",
|
|
1932
|
+
selectedValue: "",
|
|
1933
|
+
triggerClassName: "fractal-sidebar__account-trigger",
|
|
1934
|
+
triggerContent: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
|
|
1935
|
+
icon && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "fractal-sidebar__account-icon", "aria-hidden": "true", children: icon }),
|
|
1936
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "fractal-sidebar__account-name", children: name })
|
|
1937
|
+
] }),
|
|
1938
|
+
triggerLabel,
|
|
1939
|
+
triggerVariant: "tertiary"
|
|
1940
|
+
}
|
|
1941
|
+
);
|
|
1942
|
+
}
|
|
1943
|
+
var SidebarNav = React13.forwardRef(
|
|
1944
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("nav", { ref, className: cn("fractal-sidebar__nav", className), ...props })
|
|
1084
1945
|
);
|
|
1085
1946
|
SidebarNav.displayName = "SidebarNav";
|
|
1086
|
-
var SidebarSection =
|
|
1087
|
-
({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
1947
|
+
var SidebarSection = React13.forwardRef(
|
|
1948
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { ref, className: cn("fractal-sidebar__section", className), ...props })
|
|
1088
1949
|
);
|
|
1089
1950
|
SidebarSection.displayName = "SidebarSection";
|
|
1090
|
-
var SidebarNavItem =
|
|
1091
|
-
({ active = false, icon, endAdornment, className, type = "button", children, ...props }, ref) => /* @__PURE__ */ (0,
|
|
1951
|
+
var SidebarNavItem = React13.forwardRef(
|
|
1952
|
+
({ active = false, icon, endAdornment, className, type = "button", children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
1092
1953
|
"button",
|
|
1093
1954
|
{
|
|
1094
1955
|
ref,
|
|
@@ -1098,42 +1959,28 @@ var SidebarNavItem = React10.forwardRef(
|
|
|
1098
1959
|
"aria-current": active ? "page" : void 0,
|
|
1099
1960
|
...props,
|
|
1100
1961
|
children: [
|
|
1101
|
-
icon && /* @__PURE__ */ (0,
|
|
1102
|
-
/* @__PURE__ */ (0,
|
|
1103
|
-
endAdornment && /* @__PURE__ */ (0,
|
|
1962
|
+
icon && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "fractal-sidebar__nav-item-icon", "aria-hidden": "true", children: icon }),
|
|
1963
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "fractal-sidebar__nav-item-label", children }),
|
|
1964
|
+
endAdornment && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "fractal-sidebar__nav-item-end", children: endAdornment })
|
|
1104
1965
|
]
|
|
1105
1966
|
}
|
|
1106
1967
|
)
|
|
1107
1968
|
);
|
|
1108
1969
|
SidebarNavItem.displayName = "SidebarNavItem";
|
|
1109
|
-
var SidebarFooter =
|
|
1110
|
-
({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
1970
|
+
var SidebarFooter = React13.forwardRef(
|
|
1971
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { ref, className: cn("fractal-sidebar__footer", className), ...props })
|
|
1111
1972
|
);
|
|
1112
1973
|
SidebarFooter.displayName = "SidebarFooter";
|
|
1113
1974
|
|
|
1114
|
-
// src/components/PageHeader/PageHeader.tsx
|
|
1115
|
-
var React11 = __toESM(require("react"), 1);
|
|
1116
|
-
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
1117
|
-
var PageHeader = React11.forwardRef(
|
|
1118
|
-
({ title, description, actions, className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { ref, className: cn("fractal-page-header", className), ...props, children: [
|
|
1119
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "fractal-page-header__content", children: [
|
|
1120
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("h1", { className: "fractal-page-header__title", children: title }),
|
|
1121
|
-
description && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "fractal-page-header__description", children: description })
|
|
1122
|
-
] }),
|
|
1123
|
-
actions && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "fractal-page-header__actions", children: actions })
|
|
1124
|
-
] })
|
|
1125
|
-
);
|
|
1126
|
-
PageHeader.displayName = "PageHeader";
|
|
1127
|
-
|
|
1128
1975
|
// src/components/SidePanel/SidePanel.tsx
|
|
1129
1976
|
var import_react_dom2 = require("react-dom");
|
|
1130
|
-
var
|
|
1131
|
-
var
|
|
1132
|
-
function SidePanel({ open, onClose, title, description, children, footer, size = "md", className }) {
|
|
1977
|
+
var import_fractal_icons11 = require("@mirror-physics/fractal-icons");
|
|
1978
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
1979
|
+
function SidePanel({ open, onClose, title, description, children, footer, size = "md", loading = false, loadingLabel = "Loading", className }) {
|
|
1133
1980
|
useEscapeDismiss(80, onClose, open);
|
|
1134
1981
|
if (!open) return null;
|
|
1135
1982
|
return (0, import_react_dom2.createPortal)(
|
|
1136
|
-
/* @__PURE__ */ (0,
|
|
1983
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "fractal-side-panel-overlay", onMouseDown: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
1137
1984
|
"aside",
|
|
1138
1985
|
{
|
|
1139
1986
|
className: cn("fractal-side-panel", `fractal-side-panel--${size}`, className),
|
|
@@ -1142,15 +1989,15 @@ function SidePanel({ open, onClose, title, description, children, footer, size =
|
|
|
1142
1989
|
role: "dialog",
|
|
1143
1990
|
onMouseDown: (event) => event.stopPropagation(),
|
|
1144
1991
|
children: [
|
|
1145
|
-
/* @__PURE__ */ (0,
|
|
1146
|
-
/* @__PURE__ */ (0,
|
|
1147
|
-
/* @__PURE__ */ (0,
|
|
1148
|
-
description && /* @__PURE__ */ (0,
|
|
1992
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("header", { className: "fractal-side-panel__header", children: [
|
|
1993
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "fractal-side-panel__heading", children: [
|
|
1994
|
+
typeof title === "string" ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("h2", { className: "fractal-side-panel__title", children: title }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "fractal-side-panel__title", children: title }),
|
|
1995
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { className: "fractal-side-panel__description", children: description })
|
|
1149
1996
|
] }),
|
|
1150
|
-
/* @__PURE__ */ (0,
|
|
1997
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("button", { type: "button", className: "fractal-side-panel__close", "aria-label": "Close panel", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_fractal_icons11.Close, { size: 18 }) })
|
|
1151
1998
|
] }),
|
|
1152
|
-
/* @__PURE__ */ (0,
|
|
1153
|
-
footer && /* @__PURE__ */ (0,
|
|
1999
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { "aria-busy": loading || void 0, className: cn("fractal-side-panel__body", loading && "fractal-side-panel__body--loading"), children: loading ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(UILoader, { label: loadingLabel }) : children }),
|
|
2000
|
+
footer && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("footer", { className: "fractal-side-panel__footer", children: footer })
|
|
1154
2001
|
]
|
|
1155
2002
|
}
|
|
1156
2003
|
) }),
|
|
@@ -1159,49 +2006,272 @@ function SidePanel({ open, onClose, title, description, children, footer, size =
|
|
|
1159
2006
|
}
|
|
1160
2007
|
|
|
1161
2008
|
// src/components/Textarea/Textarea.tsx
|
|
1162
|
-
var
|
|
1163
|
-
var
|
|
1164
|
-
var Textarea =
|
|
1165
|
-
({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
2009
|
+
var React14 = __toESM(require("react"), 1);
|
|
2010
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
2011
|
+
var Textarea = React14.forwardRef(
|
|
2012
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("textarea", { ref, className: cn("fractal-textarea", className), ...props })
|
|
1166
2013
|
);
|
|
1167
2014
|
Textarea.displayName = "Textarea";
|
|
2015
|
+
|
|
2016
|
+
// src/components/TextButton/TextButton.tsx
|
|
2017
|
+
var React15 = __toESM(require("react"), 1);
|
|
2018
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
2019
|
+
var TextButton = React15.forwardRef(
|
|
2020
|
+
({ className, icon, iconPosition = "start", size = "md", tone = "primary", children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
2021
|
+
"button",
|
|
2022
|
+
{
|
|
2023
|
+
ref,
|
|
2024
|
+
className: cn("fractal-text-button", `fractal-text-button--${size}`, `fractal-text-button--${tone}`, className),
|
|
2025
|
+
type: "button",
|
|
2026
|
+
...props,
|
|
2027
|
+
children: [
|
|
2028
|
+
icon && iconPosition === "start" && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "fractal-text-button__icon", "aria-hidden": "true", children: icon }),
|
|
2029
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { children }),
|
|
2030
|
+
icon && iconPosition === "end" && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "fractal-text-button__icon", "aria-hidden": "true", children: icon })
|
|
2031
|
+
]
|
|
2032
|
+
}
|
|
2033
|
+
)
|
|
2034
|
+
);
|
|
2035
|
+
TextButton.displayName = "TextButton";
|
|
2036
|
+
|
|
2037
|
+
// src/components/FileDropzone/FileDropzone.tsx
|
|
2038
|
+
var React16 = __toESM(require("react"), 1);
|
|
2039
|
+
var import_fractal_icons12 = require("@mirror-physics/fractal-icons");
|
|
2040
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
2041
|
+
function FileDropzone({
|
|
2042
|
+
files,
|
|
2043
|
+
onFilesChange,
|
|
2044
|
+
accept,
|
|
2045
|
+
multiple = true,
|
|
2046
|
+
disabled = false,
|
|
2047
|
+
title = "Drop files here or click to browse",
|
|
2048
|
+
description = "Files stay attached to this record.",
|
|
2049
|
+
className
|
|
2050
|
+
}) {
|
|
2051
|
+
const inputId = React16.useId();
|
|
2052
|
+
const inputRef = React16.useRef(null);
|
|
2053
|
+
const [isDragging, setIsDragging] = React16.useState(false);
|
|
2054
|
+
const addFiles = (nextFiles) => {
|
|
2055
|
+
if (disabled) return;
|
|
2056
|
+
const additions = Array.from(nextFiles);
|
|
2057
|
+
if (additions.length === 0) return;
|
|
2058
|
+
onFilesChange(multiple ? [...files, ...additions] : additions.slice(0, 1));
|
|
2059
|
+
};
|
|
2060
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: cn("fractal-file-dropzone", className), children: [
|
|
2061
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
2062
|
+
"input",
|
|
2063
|
+
{
|
|
2064
|
+
ref: inputRef,
|
|
2065
|
+
id: inputId,
|
|
2066
|
+
className: "fractal-file-dropzone__input",
|
|
2067
|
+
type: "file",
|
|
2068
|
+
accept,
|
|
2069
|
+
multiple,
|
|
2070
|
+
disabled,
|
|
2071
|
+
onChange: (event) => {
|
|
2072
|
+
if (event.target.files) addFiles(event.target.files);
|
|
2073
|
+
event.target.value = "";
|
|
2074
|
+
}
|
|
2075
|
+
}
|
|
2076
|
+
),
|
|
2077
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
2078
|
+
"button",
|
|
2079
|
+
{
|
|
2080
|
+
className: "fractal-file-dropzone__target",
|
|
2081
|
+
"data-dragging": isDragging || void 0,
|
|
2082
|
+
type: "button",
|
|
2083
|
+
disabled,
|
|
2084
|
+
onClick: () => inputRef.current?.click(),
|
|
2085
|
+
onDragEnter: (event) => {
|
|
2086
|
+
event.preventDefault();
|
|
2087
|
+
if (!disabled) setIsDragging(true);
|
|
2088
|
+
},
|
|
2089
|
+
onDragOver: (event) => event.preventDefault(),
|
|
2090
|
+
onDragLeave: (event) => {
|
|
2091
|
+
event.preventDefault();
|
|
2092
|
+
setIsDragging(false);
|
|
2093
|
+
},
|
|
2094
|
+
onDrop: (event) => {
|
|
2095
|
+
event.preventDefault();
|
|
2096
|
+
setIsDragging(false);
|
|
2097
|
+
addFiles(event.dataTransfer.files);
|
|
2098
|
+
},
|
|
2099
|
+
children: [
|
|
2100
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_fractal_icons12.FileArrowUp, { "aria-hidden": "true", size: 20 }),
|
|
2101
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("span", { className: "fractal-file-dropzone__copy", children: [
|
|
2102
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "fractal-file-dropzone__title", children: title }),
|
|
2103
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "fractal-file-dropzone__description", children: description })
|
|
2104
|
+
] })
|
|
2105
|
+
]
|
|
2106
|
+
}
|
|
2107
|
+
),
|
|
2108
|
+
files.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("ul", { className: "fractal-file-dropzone__files", "aria-label": "Attached files", children: files.map((file, index) => /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("li", { className: "fractal-file-dropzone__file", children: [
|
|
2109
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "fractal-file-dropzone__file-name", children: file.name }),
|
|
2110
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "fractal-file-dropzone__file-meta", children: formatFileSize(file.size) }),
|
|
2111
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
2112
|
+
"button",
|
|
2113
|
+
{
|
|
2114
|
+
className: "fractal-file-dropzone__remove",
|
|
2115
|
+
type: "button",
|
|
2116
|
+
"aria-label": `Remove ${file.name}`,
|
|
2117
|
+
disabled,
|
|
2118
|
+
onClick: () => onFilesChange(files.filter((_, fileIndex) => fileIndex !== index)),
|
|
2119
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_fractal_icons12.Close, { "aria-hidden": "true", size: 14 })
|
|
2120
|
+
}
|
|
2121
|
+
)
|
|
2122
|
+
] }, `${file.name}-${file.size}-${index}`)) })
|
|
2123
|
+
] });
|
|
2124
|
+
}
|
|
2125
|
+
function formatFileSize(bytes) {
|
|
2126
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
2127
|
+
if (bytes < 1024 * 1024) return `${Math.round(bytes / 1024)} KB`;
|
|
2128
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
2129
|
+
}
|
|
2130
|
+
|
|
2131
|
+
// src/components/Pagination/Pagination.tsx
|
|
2132
|
+
var import_fractal_icons13 = require("@mirror-physics/fractal-icons");
|
|
2133
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
2134
|
+
function Pagination({
|
|
2135
|
+
page,
|
|
2136
|
+
pageSize,
|
|
2137
|
+
totalItems,
|
|
2138
|
+
onPageChange,
|
|
2139
|
+
pageSizeOptions,
|
|
2140
|
+
onPageSizeChange,
|
|
2141
|
+
ariaLabel = "Pagination",
|
|
2142
|
+
className
|
|
2143
|
+
}) {
|
|
2144
|
+
const totalPages = Math.max(1, Math.ceil(totalItems / pageSize));
|
|
2145
|
+
const currentPage = Math.min(Math.max(page, 1), totalPages);
|
|
2146
|
+
const start = totalItems === 0 ? 0 : (currentPage - 1) * pageSize + 1;
|
|
2147
|
+
const end = Math.min(currentPage * pageSize, totalItems);
|
|
2148
|
+
const canChangePageSize = pageSizeOptions != null && pageSizeOptions.length > 0 && onPageSizeChange != null;
|
|
2149
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("nav", { className: cn("fractal-pagination", className), "aria-label": ariaLabel, children: [
|
|
2150
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "fractal-pagination__summary", children: totalItems === 0 ? "No results" : `${start}-${end} of ${totalItems}` }),
|
|
2151
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "fractal-pagination__controls", children: [
|
|
2152
|
+
canChangePageSize && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
2153
|
+
Dropdown,
|
|
2154
|
+
{
|
|
2155
|
+
align: "right",
|
|
2156
|
+
className: "fractal-pagination__page-size",
|
|
2157
|
+
direction: "up",
|
|
2158
|
+
items: pageSizeOptions.map((option) => ({
|
|
2159
|
+
value: String(option),
|
|
2160
|
+
description: `${option} per page`
|
|
2161
|
+
})),
|
|
2162
|
+
onSelect: (value) => onPageSizeChange(Number(value)),
|
|
2163
|
+
selectedValue: String(pageSize),
|
|
2164
|
+
size: "sm",
|
|
2165
|
+
triggerLabel: "Results per page",
|
|
2166
|
+
triggerVariant: "tertiary"
|
|
2167
|
+
}
|
|
2168
|
+
),
|
|
2169
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
2170
|
+
"button",
|
|
2171
|
+
{
|
|
2172
|
+
className: "fractal-pagination__button",
|
|
2173
|
+
type: "button",
|
|
2174
|
+
"aria-label": "Previous page",
|
|
2175
|
+
title: "Previous page",
|
|
2176
|
+
disabled: currentPage === 1 || totalItems === 0,
|
|
2177
|
+
onClick: () => onPageChange(currentPage - 1),
|
|
2178
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_fractal_icons13.ArrowLeft, { "aria-hidden": "true", size: 16 })
|
|
2179
|
+
}
|
|
2180
|
+
),
|
|
2181
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { className: "fractal-pagination__page", "aria-current": "page", children: [
|
|
2182
|
+
currentPage,
|
|
2183
|
+
" of ",
|
|
2184
|
+
totalPages
|
|
2185
|
+
] }),
|
|
2186
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
2187
|
+
"button",
|
|
2188
|
+
{
|
|
2189
|
+
className: "fractal-pagination__button",
|
|
2190
|
+
type: "button",
|
|
2191
|
+
"aria-label": "Next page",
|
|
2192
|
+
title: "Next page",
|
|
2193
|
+
disabled: currentPage === totalPages || totalItems === 0,
|
|
2194
|
+
onClick: () => onPageChange(currentPage + 1),
|
|
2195
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_fractal_icons13.ArrowRight, { "aria-hidden": "true", size: 16 })
|
|
2196
|
+
}
|
|
2197
|
+
)
|
|
2198
|
+
] })
|
|
2199
|
+
] });
|
|
2200
|
+
}
|
|
1168
2201
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1169
2202
|
0 && (module.exports = {
|
|
1170
2203
|
Alert,
|
|
1171
2204
|
AlertDescription,
|
|
2205
|
+
AlertGhost,
|
|
1172
2206
|
AlertTitle,
|
|
2207
|
+
Breadcrumbs,
|
|
1173
2208
|
Button,
|
|
2209
|
+
ButtonGhost,
|
|
1174
2210
|
Card,
|
|
1175
2211
|
CardContent,
|
|
1176
2212
|
CardDescription,
|
|
1177
2213
|
CardFooter,
|
|
2214
|
+
CardGhost,
|
|
1178
2215
|
CardHeader,
|
|
1179
2216
|
CardTitle,
|
|
2217
|
+
Checkbox,
|
|
2218
|
+
CheckboxGhost,
|
|
1180
2219
|
Chip,
|
|
2220
|
+
ChipGhost,
|
|
2221
|
+
CodeBlock,
|
|
2222
|
+
ContentSwitcher,
|
|
2223
|
+
ContentSwitcherGhost,
|
|
2224
|
+
ConversationGhost,
|
|
1181
2225
|
DataTable,
|
|
2226
|
+
DataTableGhost,
|
|
1182
2227
|
Disclosure,
|
|
2228
|
+
DisclosureGhost,
|
|
1183
2229
|
Dropdown,
|
|
2230
|
+
DropdownGhost,
|
|
1184
2231
|
FeatureCard,
|
|
2232
|
+
FileDropzone,
|
|
2233
|
+
FileDropzoneGhost,
|
|
1185
2234
|
FolderCard,
|
|
2235
|
+
Ghost,
|
|
2236
|
+
GhostLine,
|
|
1186
2237
|
Input,
|
|
2238
|
+
InputGhost,
|
|
1187
2239
|
Label,
|
|
2240
|
+
LabelGhost,
|
|
2241
|
+
LatticeLoader,
|
|
1188
2242
|
Link,
|
|
2243
|
+
LinkGhost,
|
|
1189
2244
|
Modal,
|
|
1190
|
-
|
|
2245
|
+
ModalGhost,
|
|
2246
|
+
NumberInput,
|
|
2247
|
+
Pagination,
|
|
2248
|
+
PaginationGhost,
|
|
2249
|
+
PasswordInput,
|
|
1191
2250
|
PromptCard,
|
|
2251
|
+
PromptCardGhost,
|
|
1192
2252
|
PromptGrid,
|
|
1193
2253
|
SidePanel,
|
|
2254
|
+
SidePanelGhost,
|
|
1194
2255
|
Sidebar,
|
|
2256
|
+
SidebarAccountMenu,
|
|
1195
2257
|
SidebarBrand,
|
|
1196
2258
|
SidebarFooter,
|
|
2259
|
+
SidebarGhost,
|
|
1197
2260
|
SidebarHeader,
|
|
1198
2261
|
SidebarNav,
|
|
1199
2262
|
SidebarNavItem,
|
|
1200
2263
|
SidebarSection,
|
|
1201
2264
|
SortableTable,
|
|
2265
|
+
SortableTableGhost,
|
|
1202
2266
|
Tabs,
|
|
2267
|
+
TabsGhost,
|
|
2268
|
+
TextButton,
|
|
2269
|
+
TextButtonGhost,
|
|
1203
2270
|
Textarea,
|
|
2271
|
+
TextareaGhost,
|
|
1204
2272
|
Toggle,
|
|
2273
|
+
ToggleGhost,
|
|
2274
|
+
UILoader,
|
|
1205
2275
|
cn,
|
|
1206
2276
|
useEscapeDismiss
|
|
1207
2277
|
});
|