@mirror-physics/fractal-ui 0.2.0-next.7 → 0.2.0-next.70
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 +1683 -288
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +1472 -88
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +318 -11
- package/dist/index.d.ts +318 -11
- package/dist/index.js +1647 -285
- 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,38 +32,77 @@ 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,
|
|
75
|
+
ModalGhost: () => ModalGhost,
|
|
76
|
+
NumberInput: () => NumberInput,
|
|
77
|
+
Pagination: () => Pagination,
|
|
78
|
+
PaginationGhost: () => PaginationGhost,
|
|
79
|
+
PasswordInput: () => PasswordInput,
|
|
53
80
|
PromptCard: () => PromptCard,
|
|
81
|
+
PromptCardGhost: () => PromptCardGhost,
|
|
54
82
|
PromptGrid: () => PromptGrid,
|
|
55
83
|
SidePanel: () => SidePanel,
|
|
84
|
+
SidePanelGhost: () => SidePanelGhost,
|
|
56
85
|
Sidebar: () => Sidebar,
|
|
86
|
+
SidebarAccountMenu: () => SidebarAccountMenu,
|
|
57
87
|
SidebarBrand: () => SidebarBrand,
|
|
58
88
|
SidebarFooter: () => SidebarFooter,
|
|
89
|
+
SidebarGhost: () => SidebarGhost,
|
|
59
90
|
SidebarHeader: () => SidebarHeader,
|
|
60
91
|
SidebarNav: () => SidebarNav,
|
|
61
92
|
SidebarNavItem: () => SidebarNavItem,
|
|
62
93
|
SidebarSection: () => SidebarSection,
|
|
63
94
|
SortableTable: () => SortableTable,
|
|
95
|
+
SortableTableGhost: () => SortableTableGhost,
|
|
96
|
+
TableSearch: () => TableSearch,
|
|
64
97
|
Tabs: () => Tabs,
|
|
98
|
+
TabsGhost: () => TabsGhost,
|
|
99
|
+
TextButton: () => TextButton,
|
|
100
|
+
TextButtonGhost: () => TextButtonGhost,
|
|
65
101
|
Textarea: () => Textarea,
|
|
102
|
+
TextareaGhost: () => TextareaGhost,
|
|
66
103
|
Toggle: () => Toggle,
|
|
104
|
+
ToggleGhost: () => ToggleGhost,
|
|
105
|
+
UILoader: () => UILoader,
|
|
67
106
|
cn: () => cn,
|
|
68
107
|
useEscapeDismiss: () => useEscapeDismiss
|
|
69
108
|
});
|
|
@@ -236,44 +275,409 @@ var Button = React.forwardRef(
|
|
|
236
275
|
);
|
|
237
276
|
Button.displayName = "Button";
|
|
238
277
|
|
|
239
|
-
// src/components/
|
|
240
|
-
var
|
|
278
|
+
// src/components/CodeBlock/CodeBlock.tsx
|
|
279
|
+
var import_react = require("react");
|
|
280
|
+
var import_react_codemirror = __toESM(require("@uiw/react-codemirror"), 1);
|
|
281
|
+
var import_language = require("@codemirror/language");
|
|
282
|
+
var import_lang_json = require("@codemirror/lang-json");
|
|
283
|
+
var import_view = require("@codemirror/view");
|
|
284
|
+
var import_highlight = require("@lezer/highlight");
|
|
241
285
|
var import_fractal_icons = require("@mirror-physics/fractal-icons");
|
|
242
286
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
287
|
+
var codeTheme = import_view.EditorView.theme({
|
|
288
|
+
"&": {
|
|
289
|
+
backgroundColor: "transparent",
|
|
290
|
+
color: "var(--fg-primary)",
|
|
291
|
+
fontSize: "0.75rem"
|
|
292
|
+
},
|
|
293
|
+
"&.cm-focused": { outline: "none" },
|
|
294
|
+
".cm-scroller": {
|
|
295
|
+
fontFamily: "var(--font-mono)",
|
|
296
|
+
lineHeight: "1.55",
|
|
297
|
+
overscrollBehavior: "none"
|
|
298
|
+
},
|
|
299
|
+
".cm-content": { padding: "10px 0" },
|
|
300
|
+
".cm-line": {
|
|
301
|
+
padding: "0 12px 0 calc(12px + var(--fractal-code-wrap-indent, 0ch))",
|
|
302
|
+
textIndent: "calc(0px - var(--fractal-code-wrap-indent, 0ch))"
|
|
303
|
+
},
|
|
304
|
+
".cm-cursor, .cm-dropCursor": { borderLeftColor: "var(--fg-primary)" },
|
|
305
|
+
".cm-gutters": {
|
|
306
|
+
backgroundColor: "var(--bg-canvas)",
|
|
307
|
+
borderRight: "1px solid var(--border-subtle)",
|
|
308
|
+
color: "var(--fg-tertiary)"
|
|
309
|
+
},
|
|
310
|
+
".cm-lineNumbers .cm-gutterElement": { padding: "0 10px 0 4px" },
|
|
311
|
+
".cm-foldGutter": { width: "14px" },
|
|
312
|
+
".cm-foldGutter .cm-gutterElement": {
|
|
313
|
+
position: "relative",
|
|
314
|
+
display: "block",
|
|
315
|
+
width: "14px",
|
|
316
|
+
padding: "0"
|
|
317
|
+
},
|
|
318
|
+
".cm-foldGutter .cm-gutterElement > span": {
|
|
319
|
+
position: "absolute",
|
|
320
|
+
top: "2px",
|
|
321
|
+
left: "0",
|
|
322
|
+
display: "inline-flex",
|
|
323
|
+
width: "14px",
|
|
324
|
+
height: "14px",
|
|
325
|
+
alignItems: "center",
|
|
326
|
+
justifyContent: "center",
|
|
327
|
+
padding: "0",
|
|
328
|
+
color: "var(--fg-tertiary)",
|
|
329
|
+
lineHeight: "14px",
|
|
330
|
+
transition: "color 120ms ease"
|
|
331
|
+
},
|
|
332
|
+
'.cm-foldGutter .cm-gutterElement > span[title="Fold line"]': { transform: "translateY(-3px)" },
|
|
333
|
+
".cm-foldGutter .cm-gutterElement > span:hover": { color: "var(--fg-secondary)" },
|
|
334
|
+
".fractal-code-block__escape": { color: "var(--fg-secondary)" },
|
|
335
|
+
".cm-activeLine, .cm-activeLineGutter": { backgroundColor: "var(--bg-surface-1)" },
|
|
336
|
+
".cm-selectionBackground, &.cm-focused .cm-selectionBackground, ::selection": {
|
|
337
|
+
backgroundColor: "var(--accent-surface-stroke) !important"
|
|
338
|
+
},
|
|
339
|
+
".cm-searchMatch": {
|
|
340
|
+
backgroundColor: "var(--warning-surface)",
|
|
341
|
+
outline: "1px solid var(--warning-surface-stroke)"
|
|
342
|
+
},
|
|
343
|
+
".cm-searchMatch.cm-searchMatch-selected": { backgroundColor: "var(--warning-subtle)" },
|
|
344
|
+
".cm-panels": { backgroundColor: "var(--bg-surface-1)", color: "var(--fg-primary)" },
|
|
345
|
+
".cm-tooltip": {
|
|
346
|
+
borderColor: "var(--border-subtle)",
|
|
347
|
+
backgroundColor: "var(--bg-canvas)",
|
|
348
|
+
color: "var(--fg-primary)"
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
var fractalHighlightStyle = import_language.HighlightStyle.define([
|
|
352
|
+
{ tag: import_highlight.tags.comment, color: "var(--fg-tertiary)", fontStyle: "italic" },
|
|
353
|
+
{ tag: [import_highlight.tags.keyword, import_highlight.tags.controlKeyword, import_highlight.tags.operatorKeyword], color: "var(--purple-default)" },
|
|
354
|
+
{ tag: [import_highlight.tags.string, import_highlight.tags.special(import_highlight.tags.string)], color: "var(--purple-default)" },
|
|
355
|
+
{ tag: [import_highlight.tags.number, import_highlight.tags.bool, import_highlight.tags.null], color: "var(--orange-default)" },
|
|
356
|
+
{ tag: [import_highlight.tags.function(import_highlight.tags.variableName), import_highlight.tags.labelName], color: "var(--accent-default)" },
|
|
357
|
+
{ tag: [import_highlight.tags.typeName, import_highlight.tags.className, import_highlight.tags.namespace], color: "var(--pink-default)" },
|
|
358
|
+
{ tag: [import_highlight.tags.propertyName, import_highlight.tags.attributeName], color: "var(--success-default)" },
|
|
359
|
+
{ tag: [import_highlight.tags.operator, import_highlight.tags.punctuation], color: "var(--fg-secondary)" },
|
|
360
|
+
{ tag: import_highlight.tags.bracket, color: "var(--accent-default)" },
|
|
361
|
+
{ tag: [import_highlight.tags.heading, import_highlight.tags.strong], color: "var(--fg-primary)", fontWeight: "600" },
|
|
362
|
+
{ tag: import_highlight.tags.emphasis, fontStyle: "italic" },
|
|
363
|
+
{ tag: import_highlight.tags.link, color: "var(--accent-default)", textDecoration: "underline" },
|
|
364
|
+
{ tag: import_highlight.tags.invalid, color: "var(--error-default)", textDecoration: "underline wavy" }
|
|
365
|
+
]);
|
|
366
|
+
var jsonSupport = (0, import_lang_json.json)();
|
|
367
|
+
var JSON_LANGUAGE_NAMES = /* @__PURE__ */ new Set(["json", "jsonl", "ndjson", "geojson"]);
|
|
368
|
+
var JSON_LINES_LANGUAGE_NAMES = /* @__PURE__ */ new Set(["jsonl", "ndjson"]);
|
|
369
|
+
var JSON_LINES_PRETTY_PRINT_THRESHOLD = 160;
|
|
370
|
+
var JSON_PROPERTY_PREFIX = /^(\s*"(?:\\.|[^"\\])*"\s*:\s*)/;
|
|
371
|
+
function countVisualColumns(value) {
|
|
372
|
+
let columns = 0;
|
|
373
|
+
for (const character of value) columns += character === " " ? 2 : 1;
|
|
374
|
+
return columns;
|
|
375
|
+
}
|
|
376
|
+
function getWrappedLineIndent(line) {
|
|
377
|
+
const leadingWhitespace = line.match(/^\s*/)?.[0] ?? "";
|
|
378
|
+
if (JSON_PROPERTY_PREFIX.test(line)) return Math.min(countVisualColumns(leadingWhitespace), 24);
|
|
379
|
+
return Math.min(countVisualColumns(leadingWhitespace) + 2, 12);
|
|
380
|
+
}
|
|
381
|
+
function buildWrappedLineIndentation(view) {
|
|
382
|
+
const decorations = [];
|
|
383
|
+
const decoratedLines = /* @__PURE__ */ new Set();
|
|
384
|
+
for (const visibleRange of view.visibleRanges) {
|
|
385
|
+
let position = visibleRange.from;
|
|
386
|
+
while (position <= visibleRange.to) {
|
|
387
|
+
const line = view.state.doc.lineAt(position);
|
|
388
|
+
if (!decoratedLines.has(line.from)) {
|
|
389
|
+
const indent = getWrappedLineIndent(line.text);
|
|
390
|
+
decorations.push(import_view.Decoration.line({
|
|
391
|
+
attributes: { style: `--fractal-code-wrap-indent: ${indent}ch` }
|
|
392
|
+
}).range(line.from));
|
|
393
|
+
decoratedLines.add(line.from);
|
|
394
|
+
}
|
|
395
|
+
if (line.to >= visibleRange.to) break;
|
|
396
|
+
position = line.to + 1;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
return import_view.Decoration.set(decorations, true);
|
|
400
|
+
}
|
|
401
|
+
var wrappedLineIndentation = import_view.ViewPlugin.fromClass(class {
|
|
402
|
+
constructor(view) {
|
|
403
|
+
this.decorations = buildWrappedLineIndentation(view);
|
|
404
|
+
}
|
|
405
|
+
update(update) {
|
|
406
|
+
this.decorations = buildWrappedLineIndentation(update.view);
|
|
407
|
+
}
|
|
408
|
+
}, {
|
|
409
|
+
decorations: (plugin) => plugin.decorations
|
|
410
|
+
});
|
|
411
|
+
var jsonEscapeMatcher = new import_view.MatchDecorator({
|
|
412
|
+
regexp: /\\(?:["\\/bfnrt]|u[0-9a-fA-F]{4})/g,
|
|
413
|
+
decoration: import_view.Decoration.mark({ class: "fractal-code-block__escape" })
|
|
414
|
+
});
|
|
415
|
+
var jsonEscapeHighlighting = import_view.ViewPlugin.fromClass(class {
|
|
416
|
+
constructor(view) {
|
|
417
|
+
this.decorations = jsonEscapeMatcher.createDeco(view);
|
|
418
|
+
}
|
|
419
|
+
update(update) {
|
|
420
|
+
this.decorations = jsonEscapeMatcher.updateDeco(update, this.decorations);
|
|
421
|
+
}
|
|
422
|
+
}, {
|
|
423
|
+
decorations: (plugin) => plugin.decorations
|
|
424
|
+
});
|
|
425
|
+
function formatJsonLinesForDisplay(value) {
|
|
426
|
+
return value.split(/\r?\n/).map((line) => {
|
|
427
|
+
const firstContentIndex = line.search(/\S/);
|
|
428
|
+
if (firstContentIndex < 0 || line.length - firstContentIndex <= JSON_LINES_PRETTY_PRINT_THRESHOLD) return line;
|
|
429
|
+
const indentation = line.slice(0, firstContentIndex);
|
|
430
|
+
try {
|
|
431
|
+
const parsed = JSON.parse(line.slice(firstContentIndex));
|
|
432
|
+
if (parsed === null || typeof parsed !== "object") return line;
|
|
433
|
+
return JSON.stringify(parsed, null, 2).split("\n").map((formattedLine) => `${indentation}${formattedLine}`).join("\n");
|
|
434
|
+
} catch {
|
|
435
|
+
return line;
|
|
436
|
+
}
|
|
437
|
+
}).join("\n");
|
|
438
|
+
}
|
|
439
|
+
function findJsonContainerEnd(document2, start) {
|
|
440
|
+
const openingCharacter = document2[start];
|
|
441
|
+
if (openingCharacter !== "{" && openingCharacter !== "[") return null;
|
|
442
|
+
const closingCharacters = [];
|
|
443
|
+
let isInsideString = false;
|
|
444
|
+
let isEscaped = false;
|
|
445
|
+
for (let index = start; index < document2.length; index += 1) {
|
|
446
|
+
const character = document2[index];
|
|
447
|
+
if (isInsideString) {
|
|
448
|
+
if (isEscaped) {
|
|
449
|
+
isEscaped = false;
|
|
450
|
+
} else if (character === "\\") {
|
|
451
|
+
isEscaped = true;
|
|
452
|
+
} else if (character === '"') {
|
|
453
|
+
isInsideString = false;
|
|
454
|
+
}
|
|
455
|
+
continue;
|
|
456
|
+
}
|
|
457
|
+
if (character === '"') {
|
|
458
|
+
isInsideString = true;
|
|
459
|
+
} else if (character === "{") {
|
|
460
|
+
closingCharacters.push("}");
|
|
461
|
+
} else if (character === "[") {
|
|
462
|
+
closingCharacters.push("]");
|
|
463
|
+
} else if (character === "}" || character === "]") {
|
|
464
|
+
if (closingCharacters.pop() !== character) return null;
|
|
465
|
+
if (closingCharacters.length === 0) return index;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
return null;
|
|
469
|
+
}
|
|
470
|
+
var jsonLinesFoldSupport = import_language.foldService.of((state, lineStart, lineEnd) => {
|
|
471
|
+
const line = state.doc.sliceString(lineStart, lineEnd);
|
|
472
|
+
const firstContentIndex = line.search(/\S/);
|
|
473
|
+
if (firstContentIndex < 0) return null;
|
|
474
|
+
const containerStart = lineStart + firstContentIndex;
|
|
475
|
+
const openingCharacter = line[firstContentIndex];
|
|
476
|
+
if (openingCharacter !== "{" && openingCharacter !== "[") return null;
|
|
477
|
+
const document2 = state.doc.toString();
|
|
478
|
+
const containerEnd = findJsonContainerEnd(document2, containerStart);
|
|
479
|
+
if (containerEnd === null || containerEnd - containerStart < 2) return null;
|
|
480
|
+
try {
|
|
481
|
+
const parsed = JSON.parse(document2.slice(containerStart, containerEnd + 1));
|
|
482
|
+
if (parsed === null || typeof parsed !== "object") return null;
|
|
483
|
+
} catch {
|
|
484
|
+
return null;
|
|
485
|
+
}
|
|
486
|
+
return {
|
|
487
|
+
from: containerStart + 1,
|
|
488
|
+
to: containerEnd
|
|
489
|
+
};
|
|
490
|
+
});
|
|
491
|
+
function resolveLanguage(language, fileName) {
|
|
492
|
+
const normalized = language?.trim().toLowerCase();
|
|
493
|
+
const extension = fileName?.split(/[?#]/, 1)[0].split(".").pop()?.toLowerCase();
|
|
494
|
+
if (normalized && JSON_LANGUAGE_NAMES.has(normalized) || extension && JSON_LANGUAGE_NAMES.has(extension)) {
|
|
495
|
+
const isJsonLines = Boolean(
|
|
496
|
+
normalized && JSON_LINES_LANGUAGE_NAMES.has(normalized) || extension && JSON_LINES_LANGUAGE_NAMES.has(extension)
|
|
497
|
+
);
|
|
498
|
+
return { label: isJsonLines ? "JSONL" : "JSON", support: jsonSupport, isJsonLines };
|
|
499
|
+
}
|
|
500
|
+
if (normalized && !["text", "txt", "plaintext", "plain"].includes(normalized)) {
|
|
501
|
+
return { label: language?.trim(), support: null, isJsonLines: false };
|
|
502
|
+
}
|
|
503
|
+
return { support: null, isJsonLines: false };
|
|
504
|
+
}
|
|
505
|
+
function CodeBlock({
|
|
506
|
+
value,
|
|
507
|
+
language,
|
|
508
|
+
fileName,
|
|
509
|
+
label,
|
|
510
|
+
editable = false,
|
|
511
|
+
onChange,
|
|
512
|
+
lineNumbers = true,
|
|
513
|
+
wrap = true,
|
|
514
|
+
copyable = true,
|
|
515
|
+
ariaLabel,
|
|
516
|
+
height,
|
|
517
|
+
minHeight,
|
|
518
|
+
maxHeight = "28rem",
|
|
519
|
+
placeholder,
|
|
520
|
+
autoFocus,
|
|
521
|
+
className,
|
|
522
|
+
...props
|
|
523
|
+
}) {
|
|
524
|
+
const resolvedLanguage = (0, import_react.useMemo)(() => resolveLanguage(language, fileName), [fileName, language]);
|
|
525
|
+
const displayValue = (0, import_react.useMemo)(
|
|
526
|
+
() => !editable && resolvedLanguage.isJsonLines ? formatJsonLinesForDisplay(value) : value,
|
|
527
|
+
[editable, resolvedLanguage.isJsonLines, value]
|
|
528
|
+
);
|
|
529
|
+
const [copyStatus, setCopyStatus] = (0, import_react.useState)("idle");
|
|
530
|
+
const copyResetTimer = (0, import_react.useRef)(null);
|
|
531
|
+
(0, import_react.useEffect)(() => () => {
|
|
532
|
+
if (copyResetTimer.current) clearTimeout(copyResetTimer.current);
|
|
533
|
+
}, []);
|
|
534
|
+
const extensions = (0, import_react.useMemo)(() => [
|
|
535
|
+
codeTheme,
|
|
536
|
+
(0, import_language.syntaxHighlighting)(fractalHighlightStyle),
|
|
537
|
+
...resolvedLanguage.support ? [resolvedLanguage.support] : [],
|
|
538
|
+
...resolvedLanguage.support ? [jsonEscapeHighlighting] : [],
|
|
539
|
+
...resolvedLanguage.isJsonLines ? [jsonLinesFoldSupport] : [],
|
|
540
|
+
...lineNumbers ? [(0, import_language.foldGutter)(), (0, import_view.lineNumbers)()] : [],
|
|
541
|
+
...wrap ? [import_view.EditorView.lineWrapping, wrappedLineIndentation] : []
|
|
542
|
+
], [lineNumbers, resolvedLanguage.isJsonLines, resolvedLanguage.support, wrap]);
|
|
543
|
+
const languageLabel = resolvedLanguage.label;
|
|
544
|
+
const toolbarLabel = label ?? fileName ?? languageLabel;
|
|
545
|
+
const surfaceLabel = ariaLabel ?? (fileName ? `${fileName} ${editable ? "editor" : "viewer"}` : `Code ${editable ? "editor" : "viewer"}`);
|
|
546
|
+
const copyCode = async () => {
|
|
547
|
+
try {
|
|
548
|
+
await navigator.clipboard.writeText(value);
|
|
549
|
+
setCopyStatus("copied");
|
|
550
|
+
} catch {
|
|
551
|
+
setCopyStatus("error");
|
|
552
|
+
}
|
|
553
|
+
if (copyResetTimer.current) clearTimeout(copyResetTimer.current);
|
|
554
|
+
copyResetTimer.current = setTimeout(() => setCopyStatus("idle"), 1800);
|
|
555
|
+
};
|
|
556
|
+
const showToolbar = toolbarLabel !== void 0 || copyable || editable;
|
|
557
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
558
|
+
"div",
|
|
559
|
+
{
|
|
560
|
+
className: cn(
|
|
561
|
+
"fractal-code-block",
|
|
562
|
+
editable && "fractal-code-block--editable",
|
|
563
|
+
!lineNumbers && "fractal-code-block--no-line-numbers",
|
|
564
|
+
className
|
|
565
|
+
),
|
|
566
|
+
...props,
|
|
567
|
+
children: [
|
|
568
|
+
showToolbar && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "fractal-code-block__toolbar", children: [
|
|
569
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "fractal-code-block__identity", children: [
|
|
570
|
+
toolbarLabel !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "fractal-code-block__label", title: typeof toolbarLabel === "string" ? toolbarLabel : void 0, children: toolbarLabel }),
|
|
571
|
+
fileName && languageLabel && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "fractal-code-block__language", children: languageLabel }),
|
|
572
|
+
editable && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "fractal-code-block__mode", children: "Editing" })
|
|
573
|
+
] }),
|
|
574
|
+
copyable && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
575
|
+
"button",
|
|
576
|
+
{
|
|
577
|
+
type: "button",
|
|
578
|
+
className: "fractal-code-block__copy",
|
|
579
|
+
"aria-label": copyStatus === "copied" ? "Code copied" : "Copy code",
|
|
580
|
+
onClick: () => void copyCode(),
|
|
581
|
+
children: [
|
|
582
|
+
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 }),
|
|
583
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: copyStatus === "copied" ? "Copied" : copyStatus === "error" ? "Copy failed" : "Copy" })
|
|
584
|
+
]
|
|
585
|
+
}
|
|
586
|
+
)
|
|
587
|
+
] }),
|
|
588
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "fractal-code-block__surface", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
589
|
+
import_react_codemirror.default,
|
|
590
|
+
{
|
|
591
|
+
"aria-label": surfaceLabel,
|
|
592
|
+
value: displayValue,
|
|
593
|
+
editable,
|
|
594
|
+
readOnly: !editable,
|
|
595
|
+
onChange,
|
|
596
|
+
extensions,
|
|
597
|
+
theme: "none",
|
|
598
|
+
basicSetup: {
|
|
599
|
+
lineNumbers: false,
|
|
600
|
+
foldGutter: false,
|
|
601
|
+
drawSelection: editable,
|
|
602
|
+
highlightActiveLine: editable,
|
|
603
|
+
highlightActiveLineGutter: editable,
|
|
604
|
+
highlightSelectionMatches: editable,
|
|
605
|
+
autocompletion: editable,
|
|
606
|
+
history: editable
|
|
607
|
+
},
|
|
608
|
+
indentWithTab: editable,
|
|
609
|
+
height,
|
|
610
|
+
minHeight,
|
|
611
|
+
maxHeight,
|
|
612
|
+
placeholder,
|
|
613
|
+
autoFocus
|
|
614
|
+
}
|
|
615
|
+
) }),
|
|
616
|
+
/* @__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." : "" })
|
|
617
|
+
]
|
|
618
|
+
}
|
|
619
|
+
);
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
// src/components/Breadcrumbs/Breadcrumbs.tsx
|
|
623
|
+
var import_fractal_icons2 = require("@mirror-physics/fractal-icons");
|
|
624
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
625
|
+
function Breadcrumbs({
|
|
626
|
+
items,
|
|
627
|
+
ariaLabel = "Breadcrumbs",
|
|
628
|
+
separator = /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_fractal_icons2.ChevronRight, { "aria-hidden": "true", size: 14 }),
|
|
629
|
+
className,
|
|
630
|
+
...props
|
|
631
|
+
}) {
|
|
632
|
+
if (items.length === 0) return null;
|
|
633
|
+
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) => {
|
|
634
|
+
const isCurrent = index === items.length - 1;
|
|
635
|
+
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 });
|
|
636
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { className: "fractal-breadcrumbs__item", children: [
|
|
637
|
+
index > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { "aria-hidden": "true", className: "fractal-breadcrumbs__separator", children: separator }),
|
|
638
|
+
content
|
|
639
|
+
] }, index);
|
|
640
|
+
}) }) });
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
// src/components/Card/Card.tsx
|
|
644
|
+
var React2 = __toESM(require("react"), 1);
|
|
645
|
+
var import_fractal_icons3 = require("@mirror-physics/fractal-icons");
|
|
646
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
243
647
|
var Card = React2.forwardRef(
|
|
244
|
-
({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
648
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { ref, className: cn("fractal-card", className), ...props })
|
|
245
649
|
);
|
|
246
650
|
Card.displayName = "Card";
|
|
247
651
|
var CardHeader = React2.forwardRef(
|
|
248
|
-
({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
652
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { ref, className: cn("fractal-card-header", className), ...props })
|
|
249
653
|
);
|
|
250
654
|
CardHeader.displayName = "CardHeader";
|
|
251
655
|
var CardTitle = React2.forwardRef(
|
|
252
|
-
({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
656
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h3", { ref, className: cn("fractal-card-title", className), ...props })
|
|
253
657
|
);
|
|
254
658
|
CardTitle.displayName = "CardTitle";
|
|
255
659
|
var CardDescription = React2.forwardRef(
|
|
256
|
-
({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
660
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { ref, className: cn("fractal-card-description", className), ...props })
|
|
257
661
|
);
|
|
258
662
|
CardDescription.displayName = "CardDescription";
|
|
259
663
|
var CardContent = React2.forwardRef(
|
|
260
|
-
({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
664
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { ref, className: cn("fractal-card-content", className), ...props })
|
|
261
665
|
);
|
|
262
666
|
CardContent.displayName = "CardContent";
|
|
263
667
|
var CardFooter = React2.forwardRef(
|
|
264
|
-
({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
668
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { ref, className: cn("fractal-card-footer", className), ...props })
|
|
265
669
|
);
|
|
266
670
|
CardFooter.displayName = "CardFooter";
|
|
267
671
|
var FeatureCard = React2.forwardRef(
|
|
268
|
-
({ icon, title, description, className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
269
|
-
icon && /* @__PURE__ */ (0,
|
|
270
|
-
/* @__PURE__ */ (0,
|
|
271
|
-
/* @__PURE__ */ (0,
|
|
672
|
+
({ icon, title, description, className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { ref, className: cn("fractal-feature-card", className), ...props, children: [
|
|
673
|
+
icon && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "fractal-feature-card__icon", children: icon }),
|
|
674
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h3", { className: "fractal-feature-card__title", children: title }),
|
|
675
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "fractal-feature-card__description", children: description })
|
|
272
676
|
] })
|
|
273
677
|
);
|
|
274
678
|
FeatureCard.displayName = "FeatureCard";
|
|
275
679
|
var FolderCard = React2.forwardRef(
|
|
276
|
-
({ name, sessionCount, selected, className, onClick, ...props }, ref) => /* @__PURE__ */ (0,
|
|
680
|
+
({ name, sessionCount, selected, className, onClick, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
277
681
|
"div",
|
|
278
682
|
{
|
|
279
683
|
ref,
|
|
@@ -289,11 +693,11 @@ var FolderCard = React2.forwardRef(
|
|
|
289
693
|
className: cn("fractal-folder-card", selected && "fractal-folder-card--selected", className),
|
|
290
694
|
...props,
|
|
291
695
|
children: [
|
|
292
|
-
/* @__PURE__ */ (0,
|
|
293
|
-
/* @__PURE__ */ (0,
|
|
294
|
-
/* @__PURE__ */ (0,
|
|
696
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "fractal-folder-card__header", children: [
|
|
697
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_fractal_icons3.Folder, { size: 16, className: "fractal-folder-card__icon", "aria-hidden": true }),
|
|
698
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "fractal-folder-card__name", children: name })
|
|
295
699
|
] }),
|
|
296
|
-
sessionCount !== void 0 && /* @__PURE__ */ (0,
|
|
700
|
+
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: [
|
|
297
701
|
sessionCount,
|
|
298
702
|
" ",
|
|
299
703
|
sessionCount === 1 ? "session" : "sessions"
|
|
@@ -306,7 +710,7 @@ FolderCard.displayName = "FolderCard";
|
|
|
306
710
|
|
|
307
711
|
// src/components/PromptCard/PromptCard.tsx
|
|
308
712
|
var React3 = __toESM(require("react"), 1);
|
|
309
|
-
var
|
|
713
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
310
714
|
var titleToPrompt = (title) => typeof title === "string" || typeof title === "number" ? String(title) : "";
|
|
311
715
|
var PromptCard = React3.forwardRef(
|
|
312
716
|
({
|
|
@@ -327,7 +731,7 @@ var PromptCard = React3.forwardRef(
|
|
|
327
731
|
onPromptSelect?.(prompt ?? titleToPrompt(title));
|
|
328
732
|
}
|
|
329
733
|
};
|
|
330
|
-
return /* @__PURE__ */ (0,
|
|
734
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
331
735
|
"button",
|
|
332
736
|
{
|
|
333
737
|
ref,
|
|
@@ -342,8 +746,8 @@ var PromptCard = React3.forwardRef(
|
|
|
342
746
|
onClick: handleClick,
|
|
343
747
|
...props,
|
|
344
748
|
children: [
|
|
345
|
-
icon && /* @__PURE__ */ (0,
|
|
346
|
-
/* @__PURE__ */ (0,
|
|
749
|
+
icon && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "fractal-prompt-card__icon", "aria-hidden": "true", children: icon }),
|
|
750
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "fractal-prompt-card__title", children: title })
|
|
347
751
|
]
|
|
348
752
|
}
|
|
349
753
|
);
|
|
@@ -351,7 +755,7 @@ var PromptCard = React3.forwardRef(
|
|
|
351
755
|
);
|
|
352
756
|
PromptCard.displayName = "PromptCard";
|
|
353
757
|
var PromptGrid = React3.forwardRef(
|
|
354
|
-
({ compact, padded, className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
758
|
+
({ compact, padded, className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
355
759
|
"div",
|
|
356
760
|
{
|
|
357
761
|
ref,
|
|
@@ -369,9 +773,9 @@ PromptGrid.displayName = "PromptGrid";
|
|
|
369
773
|
|
|
370
774
|
// src/components/Input/Input.tsx
|
|
371
775
|
var React4 = __toESM(require("react"), 1);
|
|
372
|
-
var
|
|
776
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
373
777
|
var Input = React4.forwardRef(
|
|
374
|
-
({ className, type, ...props }, ref) => /* @__PURE__ */ (0,
|
|
778
|
+
({ className, type, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
375
779
|
"input",
|
|
376
780
|
{
|
|
377
781
|
type,
|
|
@@ -383,11 +787,181 @@ var Input = React4.forwardRef(
|
|
|
383
787
|
);
|
|
384
788
|
Input.displayName = "Input";
|
|
385
789
|
|
|
386
|
-
// src/components/
|
|
790
|
+
// src/components/TableSearch/TableSearch.tsx
|
|
387
791
|
var React5 = __toESM(require("react"), 1);
|
|
388
|
-
var
|
|
389
|
-
var
|
|
390
|
-
|
|
792
|
+
var import_fractal_icons4 = require("@mirror-physics/fractal-icons");
|
|
793
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
794
|
+
var TableSearch = React5.forwardRef(
|
|
795
|
+
({
|
|
796
|
+
searchType = "text",
|
|
797
|
+
className,
|
|
798
|
+
inputClassName,
|
|
799
|
+
placeholder,
|
|
800
|
+
title,
|
|
801
|
+
...props
|
|
802
|
+
}, ref) => {
|
|
803
|
+
const isGlob = searchType === "glob";
|
|
804
|
+
const SearchIcon = isGlob ? import_fractal_icons4.MagnifyingGlassLines : import_fractal_icons4.MagnifyingGlass;
|
|
805
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
806
|
+
"div",
|
|
807
|
+
{
|
|
808
|
+
className: cn("fractal-table-search", className),
|
|
809
|
+
"data-search-type": searchType,
|
|
810
|
+
children: [
|
|
811
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SearchIcon, { className: "fractal-table-search__icon", size: 17, "aria-hidden": "true" }),
|
|
812
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
813
|
+
Input,
|
|
814
|
+
{
|
|
815
|
+
...props,
|
|
816
|
+
ref,
|
|
817
|
+
type: "search",
|
|
818
|
+
className: cn("fractal-table-search__input", inputClassName),
|
|
819
|
+
placeholder: placeholder ?? (isGlob ? "Glob search \u2014 use *, ?, or [a-z]" : "Search"),
|
|
820
|
+
title: title ?? (isGlob ? "Glob pattern: *, **, ?, [abc], [a-z], and [!abc]" : void 0)
|
|
821
|
+
}
|
|
822
|
+
)
|
|
823
|
+
]
|
|
824
|
+
}
|
|
825
|
+
);
|
|
826
|
+
}
|
|
827
|
+
);
|
|
828
|
+
TableSearch.displayName = "TableSearch";
|
|
829
|
+
|
|
830
|
+
// src/components/NumberInput/NumberInput.tsx
|
|
831
|
+
var React6 = __toESM(require("react"), 1);
|
|
832
|
+
var import_fractal_icons5 = require("@mirror-physics/fractal-icons");
|
|
833
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
834
|
+
function NumberInput({
|
|
835
|
+
unit,
|
|
836
|
+
className,
|
|
837
|
+
value,
|
|
838
|
+
defaultValue,
|
|
839
|
+
disabled,
|
|
840
|
+
readOnly,
|
|
841
|
+
min,
|
|
842
|
+
max,
|
|
843
|
+
...props
|
|
844
|
+
}) {
|
|
845
|
+
const inputRef = React6.useRef(null);
|
|
846
|
+
const numericValue = Number(value ?? defaultValue);
|
|
847
|
+
const characterCount = Math.max(String(value ?? defaultValue ?? "").length, 1);
|
|
848
|
+
const controlLabel = typeof props["aria-label"] === "string" ? props["aria-label"] : "value";
|
|
849
|
+
const decrementDisabled = disabled || readOnly || Number.isFinite(numericValue) && min !== void 0 && numericValue <= Number(min);
|
|
850
|
+
const incrementDisabled = disabled || readOnly || Number.isFinite(numericValue) && max !== void 0 && numericValue >= Number(max);
|
|
851
|
+
const changeByStep = (direction) => {
|
|
852
|
+
const input = inputRef.current;
|
|
853
|
+
if (!input) return;
|
|
854
|
+
if (direction === -1) input.stepDown();
|
|
855
|
+
else input.stepUp();
|
|
856
|
+
input.dispatchEvent(new Event("input", { bubbles: true }));
|
|
857
|
+
input.focus();
|
|
858
|
+
};
|
|
859
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: cn("fractal-number-input", unit && "fractal-number-input--with-unit", className), children: [
|
|
860
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
861
|
+
Input,
|
|
862
|
+
{
|
|
863
|
+
ref: inputRef,
|
|
864
|
+
type: "number",
|
|
865
|
+
value,
|
|
866
|
+
defaultValue,
|
|
867
|
+
disabled,
|
|
868
|
+
readOnly,
|
|
869
|
+
min,
|
|
870
|
+
max,
|
|
871
|
+
...props
|
|
872
|
+
}
|
|
873
|
+
),
|
|
874
|
+
unit && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
875
|
+
"span",
|
|
876
|
+
{
|
|
877
|
+
className: "fractal-number-input-unit",
|
|
878
|
+
style: { left: `calc(var(--space-3, 12px) + ${characterCount}ch)` },
|
|
879
|
+
"aria-hidden": "true",
|
|
880
|
+
children: unit
|
|
881
|
+
}
|
|
882
|
+
),
|
|
883
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "fractal-number-input-controls", children: [
|
|
884
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
885
|
+
"button",
|
|
886
|
+
{
|
|
887
|
+
type: "button",
|
|
888
|
+
className: "fractal-number-input-step",
|
|
889
|
+
"aria-label": `Decrease ${controlLabel}`,
|
|
890
|
+
disabled: decrementDisabled,
|
|
891
|
+
onClick: () => changeByStep(-1),
|
|
892
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_fractal_icons5.Minus, { "aria-hidden": "true", size: 16 })
|
|
893
|
+
}
|
|
894
|
+
),
|
|
895
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
896
|
+
"button",
|
|
897
|
+
{
|
|
898
|
+
type: "button",
|
|
899
|
+
className: "fractal-number-input-step",
|
|
900
|
+
"aria-label": `Increase ${controlLabel}`,
|
|
901
|
+
disabled: incrementDisabled,
|
|
902
|
+
onClick: () => changeByStep(1),
|
|
903
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_fractal_icons5.Plus, { "aria-hidden": "true", size: 16 })
|
|
904
|
+
}
|
|
905
|
+
)
|
|
906
|
+
] })
|
|
907
|
+
] });
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
// src/components/PasswordInput/PasswordInput.tsx
|
|
911
|
+
var React7 = __toESM(require("react"), 1);
|
|
912
|
+
var import_fractal_icons6 = require("@mirror-physics/fractal-icons");
|
|
913
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
914
|
+
var PasswordInput = React7.forwardRef(
|
|
915
|
+
({
|
|
916
|
+
className,
|
|
917
|
+
disabled,
|
|
918
|
+
showPasswordLabel = "Show password",
|
|
919
|
+
hidePasswordLabel = "Hide password",
|
|
920
|
+
...props
|
|
921
|
+
}, ref) => {
|
|
922
|
+
const [passwordVisible, setPasswordVisible] = React7.useState(false);
|
|
923
|
+
const toggleLabel = passwordVisible ? hidePasswordLabel : showPasswordLabel;
|
|
924
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
925
|
+
"div",
|
|
926
|
+
{
|
|
927
|
+
className: cn("fractal-password-input", className),
|
|
928
|
+
"data-password-visible": passwordVisible ? "" : void 0,
|
|
929
|
+
children: [
|
|
930
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
931
|
+
Input,
|
|
932
|
+
{
|
|
933
|
+
...props,
|
|
934
|
+
ref,
|
|
935
|
+
className: "fractal-password-input-field",
|
|
936
|
+
disabled,
|
|
937
|
+
type: passwordVisible ? "text" : "password"
|
|
938
|
+
}
|
|
939
|
+
),
|
|
940
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
941
|
+
"button",
|
|
942
|
+
{
|
|
943
|
+
type: "button",
|
|
944
|
+
className: "fractal-password-input-toggle",
|
|
945
|
+
"aria-label": toggleLabel,
|
|
946
|
+
"aria-pressed": passwordVisible,
|
|
947
|
+
disabled,
|
|
948
|
+
title: toggleLabel,
|
|
949
|
+
onClick: () => setPasswordVisible((visible) => !visible),
|
|
950
|
+
children: passwordVisible ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_fractal_icons6.EyeSlash, { "aria-hidden": "true", size: 18 }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_fractal_icons6.Eye, { "aria-hidden": "true", size: 18 })
|
|
951
|
+
}
|
|
952
|
+
)
|
|
953
|
+
]
|
|
954
|
+
}
|
|
955
|
+
);
|
|
956
|
+
}
|
|
957
|
+
);
|
|
958
|
+
PasswordInput.displayName = "PasswordInput";
|
|
959
|
+
|
|
960
|
+
// src/components/Label/Label.tsx
|
|
961
|
+
var React8 = __toESM(require("react"), 1);
|
|
962
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
963
|
+
var Label = React8.forwardRef(
|
|
964
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
391
965
|
"label",
|
|
392
966
|
{
|
|
393
967
|
ref,
|
|
@@ -399,44 +973,48 @@ var Label = React5.forwardRef(
|
|
|
399
973
|
Label.displayName = "Label";
|
|
400
974
|
|
|
401
975
|
// src/components/Alert/Alert.tsx
|
|
402
|
-
var
|
|
403
|
-
var
|
|
976
|
+
var React9 = __toESM(require("react"), 1);
|
|
977
|
+
var import_fractal_icons7 = require("@mirror-physics/fractal-icons");
|
|
978
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
404
979
|
var defaultIcons = {
|
|
405
|
-
default:
|
|
406
|
-
info:
|
|
407
|
-
success:
|
|
408
|
-
warning:
|
|
409
|
-
error:
|
|
980
|
+
default: import_fractal_icons7.CircleInfo,
|
|
981
|
+
info: import_fractal_icons7.CircleInfo,
|
|
982
|
+
success: import_fractal_icons7.CircleCheck,
|
|
983
|
+
warning: import_fractal_icons7.Warning,
|
|
984
|
+
error: import_fractal_icons7.CircleClose
|
|
410
985
|
};
|
|
411
|
-
var Alert =
|
|
412
|
-
({ className, variant = "default", icon, children, ...props }, ref) =>
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
986
|
+
var Alert = React9.forwardRef(
|
|
987
|
+
({ className, variant = "default", icon, children, ...props }, ref) => {
|
|
988
|
+
const DefaultIcon = defaultIcons[variant];
|
|
989
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
990
|
+
"div",
|
|
991
|
+
{
|
|
992
|
+
ref,
|
|
993
|
+
role: "alert",
|
|
994
|
+
className: cn("fractal-alert", `fractal-alert--${variant}`, className),
|
|
995
|
+
...props,
|
|
996
|
+
children: [
|
|
997
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "fractal-alert-icon", "aria-hidden": true, children: icon ?? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(DefaultIcon, { size: 18 }) }),
|
|
998
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "fractal-alert-content", children })
|
|
999
|
+
]
|
|
1000
|
+
}
|
|
1001
|
+
);
|
|
1002
|
+
}
|
|
425
1003
|
);
|
|
426
1004
|
Alert.displayName = "Alert";
|
|
427
|
-
var AlertTitle =
|
|
428
|
-
({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
1005
|
+
var AlertTitle = React9.forwardRef(
|
|
1006
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h5", { ref, className: cn("fractal-alert-title", className), ...props })
|
|
429
1007
|
);
|
|
430
1008
|
AlertTitle.displayName = "AlertTitle";
|
|
431
|
-
var AlertDescription =
|
|
432
|
-
({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
1009
|
+
var AlertDescription = React9.forwardRef(
|
|
1010
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { ref, className: cn("fractal-alert-description", className), ...props })
|
|
433
1011
|
);
|
|
434
1012
|
AlertDescription.displayName = "AlertDescription";
|
|
435
1013
|
|
|
436
1014
|
// src/components/Toggle/Toggle.tsx
|
|
437
|
-
var
|
|
1015
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
438
1016
|
function Toggle({ checked, onChange, label, className }) {
|
|
439
|
-
return /* @__PURE__ */ (0,
|
|
1017
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
440
1018
|
"button",
|
|
441
1019
|
{
|
|
442
1020
|
type: "button",
|
|
@@ -445,18 +1023,19 @@ function Toggle({ checked, onChange, label, className }) {
|
|
|
445
1023
|
className: cn("fractal-toggle", className),
|
|
446
1024
|
onClick: () => onChange(!checked),
|
|
447
1025
|
children: [
|
|
448
|
-
/* @__PURE__ */ (0,
|
|
449
|
-
label && /* @__PURE__ */ (0,
|
|
1026
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: cn("fractal-toggle-track", checked && "fractal-toggle-track--checked"), children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: cn("fractal-toggle-thumb", checked && "fractal-toggle-thumb--checked") }) }),
|
|
1027
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "fractal-toggle-label", children: label })
|
|
450
1028
|
]
|
|
451
1029
|
}
|
|
452
1030
|
);
|
|
453
1031
|
}
|
|
454
1032
|
|
|
455
1033
|
// src/components/Modal/Modal.tsx
|
|
1034
|
+
var React10 = __toESM(require("react"), 1);
|
|
456
1035
|
var import_react_dom = require("react-dom");
|
|
457
1036
|
|
|
458
1037
|
// src/hooks/useEscapeDismiss.ts
|
|
459
|
-
var
|
|
1038
|
+
var import_react2 = require("react");
|
|
460
1039
|
var nextId = 0;
|
|
461
1040
|
var stack = [];
|
|
462
1041
|
function insertSorted(entry) {
|
|
@@ -489,9 +1068,9 @@ function ensureGlobalListener() {
|
|
|
489
1068
|
);
|
|
490
1069
|
}
|
|
491
1070
|
function useEscapeDismiss(priority, handler, enabled = true) {
|
|
492
|
-
const handlerRef = (0,
|
|
1071
|
+
const handlerRef = (0, import_react2.useRef)(handler);
|
|
493
1072
|
handlerRef.current = handler;
|
|
494
|
-
(0,
|
|
1073
|
+
(0, import_react2.useEffect)(() => {
|
|
495
1074
|
if (!enabled) return;
|
|
496
1075
|
ensureGlobalListener();
|
|
497
1076
|
const id = nextId++;
|
|
@@ -505,27 +1084,99 @@ function useEscapeDismiss(priority, handler, enabled = true) {
|
|
|
505
1084
|
}, [priority, enabled]);
|
|
506
1085
|
}
|
|
507
1086
|
|
|
1087
|
+
// src/components/UILoader/UILoader.tsx
|
|
1088
|
+
var import_react3 = require("react");
|
|
1089
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
1090
|
+
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";
|
|
1091
|
+
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";
|
|
1092
|
+
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";
|
|
1093
|
+
function UILoader({ size = 48, tone = "neutral", className, style, label = "Loading", ariaHidden = false }) {
|
|
1094
|
+
const rawId = (0, import_react3.useId)().replace(/[^a-zA-Z0-9_-]/g, "");
|
|
1095
|
+
const clipId = `fractal-ui-loader-clip-${rawId}`;
|
|
1096
|
+
const gradientId = `fractal-ui-loader-gradient-${rawId}`;
|
|
1097
|
+
const height = typeof size === "number" ? `${size}px` : size;
|
|
1098
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1099
|
+
"span",
|
|
1100
|
+
{
|
|
1101
|
+
"aria-hidden": ariaHidden || void 0,
|
|
1102
|
+
"aria-label": ariaHidden ? void 0 : label,
|
|
1103
|
+
className: cn("fractal-ui-loader", `fractal-ui-loader--${tone}`, className),
|
|
1104
|
+
role: ariaHidden ? void 0 : "status",
|
|
1105
|
+
style,
|
|
1106
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("svg", { "aria-hidden": "true", fill: "none", viewBox: "0 0 144 92", style: { height, width: "auto" }, children: [
|
|
1107
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("defs", { children: [
|
|
1108
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("linearGradient", { id: gradientId, x1: "59", x2: "94.3", y1: "0", y2: "89.1", gradientUnits: "userSpaceOnUse", children: [
|
|
1109
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("stop", { className: "fractal-ui-loader__stop-start", offset: "0" }),
|
|
1110
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("stop", { className: "fractal-ui-loader__stop-end", offset: "1" })
|
|
1111
|
+
] }),
|
|
1112
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("linearGradient", { id: `${gradientId}-shine`, x1: "0", x2: "1", y1: "0", y2: "0", children: [
|
|
1113
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("stop", { offset: "0.4", stopColor: "white", stopOpacity: "0" }),
|
|
1114
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("stop", { offset: "0.5", stopColor: "white", stopOpacity: "0.62" }),
|
|
1115
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("stop", { offset: "0.6", stopColor: "white", stopOpacity: "0" })
|
|
1116
|
+
] }),
|
|
1117
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("clipPath", { id: clipId, children: [
|
|
1118
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: LEFT }),
|
|
1119
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: CENTER }),
|
|
1120
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: RIGHT })
|
|
1121
|
+
] })
|
|
1122
|
+
] }),
|
|
1123
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: CENTER, fill: `url(#${gradientId})` }),
|
|
1124
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: RIGHT, fill: `url(#${gradientId})` }),
|
|
1125
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: LEFT, fill: `url(#${gradientId})` }),
|
|
1126
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("g", { clipPath: `url(#${clipId})`, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("g", { className: "fractal-ui-loader__shine-axis", transform: "translate(72 46) rotate(68.4)", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("rect", { className: "fractal-ui-loader__shine", x: "-160", y: "-100", width: "320", height: "200", fill: `url(#${gradientId}-shine)` }) }) })
|
|
1127
|
+
] })
|
|
1128
|
+
}
|
|
1129
|
+
);
|
|
1130
|
+
}
|
|
1131
|
+
|
|
508
1132
|
// src/components/Modal/Modal.tsx
|
|
509
|
-
var
|
|
510
|
-
var CloseIcon = () => /* @__PURE__ */ (0,
|
|
511
|
-
function Modal({ open, onClose, title, children, danger, warn, footer, noClose, size = "sm", className }) {
|
|
512
|
-
|
|
1133
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
1134
|
+
var CloseIcon = () => /* @__PURE__ */ (0, import_jsx_runtime14.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_runtime14.jsx)("path", { d: "M12 4L4 12M4 4L12 12", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) });
|
|
1135
|
+
function Modal({ open, onClose, title, children, danger, warn, footer, noClose, closeDisabled = false, size = "sm", loading = false, loadingLabel = "Loading", scrollable = false, className }) {
|
|
1136
|
+
const [bodyScrolled, setBodyScrolled] = React10.useState(false);
|
|
1137
|
+
useEscapeDismiss(80, onClose, open && !noClose && !closeDisabled);
|
|
1138
|
+
React10.useEffect(() => {
|
|
1139
|
+
if (open) setBodyScrolled(false);
|
|
1140
|
+
}, [open]);
|
|
513
1141
|
if (!open) return null;
|
|
514
1142
|
const sizeClass = `fractal-modal-panel--${size}`;
|
|
515
1143
|
const accentClass = danger ? "fractal-modal-panel--danger" : warn ? "fractal-modal-panel--warn" : "";
|
|
516
1144
|
return (0, import_react_dom.createPortal)(
|
|
517
|
-
/* @__PURE__ */ (0,
|
|
1145
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "fractal-modal-overlay", onClick: noClose || closeDisabled ? void 0 : onClose, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
518
1146
|
"div",
|
|
519
1147
|
{
|
|
520
|
-
className: cn("fractal-modal-panel", sizeClass, accentClass, className),
|
|
1148
|
+
className: cn("fractal-modal-panel", sizeClass, accentClass, scrollable && "fractal-modal-panel--scrollable", className),
|
|
521
1149
|
onClick: (e) => e.stopPropagation(),
|
|
522
1150
|
children: [
|
|
523
|
-
/* @__PURE__ */ (0,
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
1151
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
1152
|
+
"div",
|
|
1153
|
+
{
|
|
1154
|
+
className: cn(
|
|
1155
|
+
"fractal-modal-title-row",
|
|
1156
|
+
scrollable && "fractal-modal-title-row--scrollable",
|
|
1157
|
+
scrollable && bodyScrolled && "fractal-modal-title-row--scrolled"
|
|
1158
|
+
),
|
|
1159
|
+
children: [
|
|
1160
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h3", { className: cn("fractal-modal-title", danger && "fractal-modal-title--danger", warn && "fractal-modal-title--warn"), children: title }),
|
|
1161
|
+
!noClose && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", onClick: onClose, title: "Close", disabled: closeDisabled, className: "fractal-modal-close", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(CloseIcon, {}) })
|
|
1162
|
+
]
|
|
1163
|
+
}
|
|
1164
|
+
),
|
|
1165
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1166
|
+
"div",
|
|
1167
|
+
{
|
|
1168
|
+
"aria-busy": loading || void 0,
|
|
1169
|
+
className: cn(
|
|
1170
|
+
"fractal-modal-body",
|
|
1171
|
+
size === "lg" && "fractal-modal-body--lg",
|
|
1172
|
+
loading && "fractal-modal-body--loading",
|
|
1173
|
+
scrollable && "fractal-modal-body--scrollable"
|
|
1174
|
+
),
|
|
1175
|
+
onScroll: scrollable ? (event) => setBodyScrolled(event.currentTarget.scrollTop > 0) : void 0,
|
|
1176
|
+
children: loading ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(UILoader, { label: loadingLabel }) : children
|
|
1177
|
+
}
|
|
1178
|
+
),
|
|
1179
|
+
footer && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: cn("fractal-modal-footer", scrollable && "fractal-modal-footer--divided"), children: footer })
|
|
529
1180
|
]
|
|
530
1181
|
}
|
|
531
1182
|
) }),
|
|
@@ -534,17 +1185,17 @@ function Modal({ open, onClose, title, children, danger, warn, footer, noClose,
|
|
|
534
1185
|
}
|
|
535
1186
|
|
|
536
1187
|
// src/components/DataTable/DataTable.tsx
|
|
537
|
-
var
|
|
1188
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
538
1189
|
function DataTable({ columns, data, emptyMessage, header, size = "md", className }) {
|
|
539
|
-
return /* @__PURE__ */ (0,
|
|
540
|
-
header && /* @__PURE__ */ (0,
|
|
541
|
-
data.length === 0 ? /* @__PURE__ */ (0,
|
|
542
|
-
/* @__PURE__ */ (0,
|
|
543
|
-
/* @__PURE__ */ (0,
|
|
1190
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: cn("fractal-datatable", `fractal-datatable--${size}`, className), children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "fractal-datatable-surface", children: [
|
|
1191
|
+
header && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "fractal-datatable-header", children: header }),
|
|
1192
|
+
data.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "fractal-datatable-empty", children: emptyMessage || "No data" }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("table", { className: "fractal-datatable-table", children: [
|
|
1193
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("tr", { className: "fractal-datatable-thead-row", children: columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("th", { className: "fractal-datatable-th", style: { width: col.width }, children: col.header }, col.key)) }) }),
|
|
1194
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("tbody", { children: data.map((row, rowIndex) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
544
1195
|
"tr",
|
|
545
1196
|
{
|
|
546
1197
|
className: "fractal-datatable-row",
|
|
547
|
-
children: columns.map((col) => /* @__PURE__ */ (0,
|
|
1198
|
+
children: columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("td", { className: "fractal-datatable-td", style: { width: col.width }, children: col.render(row, rowIndex) }, col.key))
|
|
548
1199
|
},
|
|
549
1200
|
rowIndex
|
|
550
1201
|
)) })
|
|
@@ -553,9 +1204,9 @@ function DataTable({ columns, data, emptyMessage, header, size = "md", className
|
|
|
553
1204
|
}
|
|
554
1205
|
|
|
555
1206
|
// src/components/Dropdown/Dropdown.tsx
|
|
556
|
-
var
|
|
557
|
-
var
|
|
558
|
-
var
|
|
1207
|
+
var React11 = __toESM(require("react"), 1);
|
|
1208
|
+
var import_fractal_icons8 = require("@mirror-physics/fractal-icons");
|
|
1209
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
559
1210
|
var MARGIN = 4;
|
|
560
1211
|
function Dropdown({
|
|
561
1212
|
items,
|
|
@@ -564,20 +1215,23 @@ function Dropdown({
|
|
|
564
1215
|
triggerLabel = "Options",
|
|
565
1216
|
direction = "down",
|
|
566
1217
|
align = "left",
|
|
1218
|
+
triggerOrientation = "horizontal",
|
|
567
1219
|
triggerContent,
|
|
568
1220
|
label,
|
|
1221
|
+
iconOnly = false,
|
|
569
1222
|
noChevron = false,
|
|
570
1223
|
size = "md",
|
|
571
1224
|
triggerVariant = "outline",
|
|
572
1225
|
className,
|
|
573
1226
|
triggerClassName,
|
|
574
1227
|
panelClassName,
|
|
575
|
-
closeOnSelect = true
|
|
1228
|
+
closeOnSelect = true,
|
|
1229
|
+
disabled = false
|
|
576
1230
|
}) {
|
|
577
|
-
const [open, setOpen] =
|
|
578
|
-
const triggerRef =
|
|
579
|
-
const panelRef =
|
|
580
|
-
const [panelStyle, setPanelStyle] =
|
|
1231
|
+
const [open, setOpen] = React11.useState(false);
|
|
1232
|
+
const triggerRef = React11.useRef(null);
|
|
1233
|
+
const panelRef = React11.useRef(null);
|
|
1234
|
+
const [panelStyle, setPanelStyle] = React11.useState({});
|
|
581
1235
|
const visibleItems = items.filter(
|
|
582
1236
|
(item) => item.icon != null || item.description != null && (typeof item.description === "string" ? item.description !== "" : true)
|
|
583
1237
|
);
|
|
@@ -585,42 +1239,60 @@ function Dropdown({
|
|
|
585
1239
|
const selectableItems = visibleItems.filter((i) => i.kind !== "header");
|
|
586
1240
|
const selected = items.find((i) => i.value === selectedValue && i.kind !== "header") ?? selectableItems[0] ?? visibleItems[0];
|
|
587
1241
|
const isUp = direction === "up";
|
|
588
|
-
const
|
|
589
|
-
|
|
1242
|
+
const isHorizontalDirection = direction === "left" || direction === "right";
|
|
1243
|
+
const ChevronIcon = direction === "up" ? import_fractal_icons8.ChevronUp : direction === "left" ? import_fractal_icons8.ChevronLeft : direction === "right" ? import_fractal_icons8.ChevronRight : import_fractal_icons8.ChevronDown;
|
|
1244
|
+
React11.useLayoutEffect(() => {
|
|
590
1245
|
if (!open || !triggerRef.current || !panelRef.current) return;
|
|
591
1246
|
const triggerRect = triggerRef.current.getBoundingClientRect();
|
|
592
1247
|
const panelRect = panelRef.current.getBoundingClientRect();
|
|
593
1248
|
const vw = window.innerWidth;
|
|
594
1249
|
const vh = window.innerHeight;
|
|
595
|
-
|
|
596
|
-
const spaceAbove = triggerRect.top - MARGIN;
|
|
597
|
-
let placeAbove = isUp;
|
|
598
|
-
if (placeAbove && panelRect.height > spaceAbove && spaceBelow > spaceAbove) {
|
|
599
|
-
placeAbove = false;
|
|
600
|
-
} else if (!placeAbove && panelRect.height > spaceBelow && spaceAbove > spaceBelow) {
|
|
601
|
-
placeAbove = true;
|
|
602
|
-
}
|
|
603
|
-
const top = placeAbove ? -(panelRect.height + MARGIN) : triggerRect.height + MARGIN;
|
|
1250
|
+
let top;
|
|
604
1251
|
let left;
|
|
605
1252
|
let right;
|
|
606
|
-
if (
|
|
607
|
-
|
|
608
|
-
const
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
1253
|
+
if (isHorizontalDirection) {
|
|
1254
|
+
const spaceRight = vw - triggerRect.right - MARGIN;
|
|
1255
|
+
const spaceLeft = triggerRect.left - MARGIN;
|
|
1256
|
+
let placeRight = direction === "right";
|
|
1257
|
+
if (placeRight && panelRect.width > spaceRight && spaceLeft > spaceRight) {
|
|
1258
|
+
placeRight = false;
|
|
1259
|
+
} else if (!placeRight && panelRect.width > spaceLeft && spaceRight > spaceLeft) {
|
|
1260
|
+
placeRight = true;
|
|
612
1261
|
}
|
|
1262
|
+
left = placeRight ? triggerRect.width + MARGIN : -(panelRect.width + MARGIN);
|
|
1263
|
+
top = 0;
|
|
1264
|
+
const panelBottom = triggerRect.top + panelRect.height;
|
|
1265
|
+
if (panelBottom > vh - MARGIN) top -= panelBottom - (vh - MARGIN);
|
|
1266
|
+
if (triggerRect.top + top < MARGIN) top += MARGIN - (triggerRect.top + top);
|
|
613
1267
|
} else {
|
|
614
|
-
|
|
615
|
-
const
|
|
616
|
-
|
|
617
|
-
|
|
1268
|
+
const spaceBelow = vh - triggerRect.bottom - MARGIN;
|
|
1269
|
+
const spaceAbove = triggerRect.top - MARGIN;
|
|
1270
|
+
let placeAbove = isUp;
|
|
1271
|
+
if (placeAbove && panelRect.height > spaceAbove && spaceBelow > spaceAbove) {
|
|
1272
|
+
placeAbove = false;
|
|
1273
|
+
} else if (!placeAbove && panelRect.height > spaceBelow && spaceAbove > spaceBelow) {
|
|
1274
|
+
placeAbove = true;
|
|
1275
|
+
}
|
|
1276
|
+
top = placeAbove ? -(panelRect.height + MARGIN) : triggerRect.height + MARGIN;
|
|
1277
|
+
if (align === "right") {
|
|
618
1278
|
right = 0;
|
|
1279
|
+
const panelLeft = triggerRect.right - panelRect.width;
|
|
1280
|
+
if (panelLeft < 0) {
|
|
1281
|
+
right = void 0;
|
|
1282
|
+
left = 0;
|
|
1283
|
+
}
|
|
1284
|
+
} else {
|
|
1285
|
+
left = 0;
|
|
1286
|
+
const panelRight = triggerRect.left + panelRect.width;
|
|
1287
|
+
if (panelRight > vw) {
|
|
1288
|
+
left = void 0;
|
|
1289
|
+
right = 0;
|
|
1290
|
+
}
|
|
619
1291
|
}
|
|
620
1292
|
}
|
|
621
1293
|
setPanelStyle({ top, left, right });
|
|
622
|
-
}, [open, isUp, align]);
|
|
623
|
-
|
|
1294
|
+
}, [open, direction, isHorizontalDirection, isUp, align]);
|
|
1295
|
+
React11.useEffect(() => {
|
|
624
1296
|
if (!open) return;
|
|
625
1297
|
const handleClickOutside = (e) => {
|
|
626
1298
|
const target = e.target;
|
|
@@ -630,12 +1302,13 @@ function Dropdown({
|
|
|
630
1302
|
document.addEventListener("mousedown", handleClickOutside);
|
|
631
1303
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
632
1304
|
}, [open]);
|
|
633
|
-
return /* @__PURE__ */ (0,
|
|
634
|
-
/* @__PURE__ */ (0,
|
|
1305
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: cn("fractal-dropdown", className), children: [
|
|
1306
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
635
1307
|
"button",
|
|
636
1308
|
{
|
|
637
1309
|
ref: triggerRef,
|
|
638
1310
|
type: "button",
|
|
1311
|
+
disabled,
|
|
639
1312
|
"aria-haspopup": "listbox",
|
|
640
1313
|
"aria-expanded": open,
|
|
641
1314
|
"aria-label": triggerLabel,
|
|
@@ -644,18 +1317,20 @@ function Dropdown({
|
|
|
644
1317
|
"fractal-dropdown-trigger",
|
|
645
1318
|
`fractal-dropdown-trigger--${size}`,
|
|
646
1319
|
`fractal-dropdown-trigger--${triggerVariant}`,
|
|
1320
|
+
`fractal-dropdown-trigger--${triggerOrientation}`,
|
|
1321
|
+
iconOnly && "fractal-dropdown-trigger--icon-only",
|
|
647
1322
|
triggerClassName
|
|
648
1323
|
),
|
|
649
1324
|
children: [
|
|
650
|
-
triggerContent != null ? triggerContent : /* @__PURE__ */ (0,
|
|
651
|
-
selected.icon != null && /* @__PURE__ */ (0,
|
|
652
|
-
selected.description != null && (typeof selected.description !== "string" || selected.description !== "") && /* @__PURE__ */ (0,
|
|
1325
|
+
triggerContent != null ? triggerContent : /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
1326
|
+
selected.icon != null && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "fractal-dropdown-icon fractal-dropdown-icon--trigger", children: selected.icon }),
|
|
1327
|
+
selected.description != null && (typeof selected.description !== "string" || selected.description !== "") && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "fractal-dropdown-selected-text", children: selected.description })
|
|
653
1328
|
] }),
|
|
654
|
-
!noChevron && /* @__PURE__ */ (0,
|
|
1329
|
+
!noChevron && !iconOnly && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "fractal-dropdown-chevron", "aria-hidden": true, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ChevronIcon, { size: size === "sm" ? 14 : 16 }) })
|
|
655
1330
|
]
|
|
656
1331
|
}
|
|
657
1332
|
),
|
|
658
|
-
open && /* @__PURE__ */ (0,
|
|
1333
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
659
1334
|
"div",
|
|
660
1335
|
{
|
|
661
1336
|
ref: panelRef,
|
|
@@ -664,21 +1339,21 @@ function Dropdown({
|
|
|
664
1339
|
className: cn("fractal-dropdown-panel", `fractal-dropdown-panel--${size}`, panelClassName),
|
|
665
1340
|
style: panelStyle,
|
|
666
1341
|
children: [
|
|
667
|
-
label != null && /* @__PURE__ */ (0,
|
|
1342
|
+
label != null && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "fractal-dropdown-label", children: label }),
|
|
668
1343
|
visibleItems.map((item, index) => {
|
|
669
|
-
const topDivider = item.border === "top" ? /* @__PURE__ */ (0,
|
|
670
|
-
const bottomDivider = item.border === "bottom" ? /* @__PURE__ */ (0,
|
|
1344
|
+
const topDivider = item.border === "top" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "fractal-dropdown-separator" }) : null;
|
|
1345
|
+
const bottomDivider = item.border === "bottom" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "fractal-dropdown-separator" }) : null;
|
|
671
1346
|
if (item.kind === "header") {
|
|
672
|
-
return /* @__PURE__ */ (0,
|
|
1347
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(React11.Fragment, { children: [
|
|
673
1348
|
topDivider,
|
|
674
|
-
/* @__PURE__ */ (0,
|
|
1349
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { role: "presentation", className: "fractal-dropdown-label", children: item.description }),
|
|
675
1350
|
bottomDivider
|
|
676
1351
|
] }, `header-${index}`);
|
|
677
1352
|
}
|
|
678
1353
|
const isSelected = item.value === selectedValue;
|
|
679
|
-
return /* @__PURE__ */ (0,
|
|
1354
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(React11.Fragment, { children: [
|
|
680
1355
|
topDivider,
|
|
681
|
-
/* @__PURE__ */ (0,
|
|
1356
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
682
1357
|
"button",
|
|
683
1358
|
{
|
|
684
1359
|
type: "button",
|
|
@@ -690,9 +1365,9 @@ function Dropdown({
|
|
|
690
1365
|
},
|
|
691
1366
|
className: "fractal-dropdown-option",
|
|
692
1367
|
children: [
|
|
693
|
-
item.icon != null && /* @__PURE__ */ (0,
|
|
694
|
-
item.description != null && (typeof item.description !== "string" || item.description !== "") && /* @__PURE__ */ (0,
|
|
695
|
-
item.trailing != null && /* @__PURE__ */ (0,
|
|
1368
|
+
item.icon != null && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "fractal-dropdown-icon", children: item.icon }),
|
|
1369
|
+
item.description != null && (typeof item.description !== "string" || item.description !== "") && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "fractal-dropdown-option-text", children: item.description }),
|
|
1370
|
+
item.trailing != null && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "fractal-dropdown-trailing", children: item.trailing })
|
|
696
1371
|
]
|
|
697
1372
|
}
|
|
698
1373
|
),
|
|
@@ -706,10 +1381,10 @@ function Dropdown({
|
|
|
706
1381
|
}
|
|
707
1382
|
|
|
708
1383
|
// src/components/Link/Link.tsx
|
|
709
|
-
var
|
|
710
|
-
var
|
|
711
|
-
var Link =
|
|
712
|
-
({ className, theme = "default", size = "md", ...props }, ref) => /* @__PURE__ */ (0,
|
|
1384
|
+
var React12 = __toESM(require("react"), 1);
|
|
1385
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
1386
|
+
var Link = React12.forwardRef(
|
|
1387
|
+
({ className, theme = "default", size = "md", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
713
1388
|
"a",
|
|
714
1389
|
{
|
|
715
1390
|
ref,
|
|
@@ -721,10 +1396,10 @@ var Link = React8.forwardRef(
|
|
|
721
1396
|
Link.displayName = "Link";
|
|
722
1397
|
|
|
723
1398
|
// src/components/Chip/Chip.tsx
|
|
724
|
-
var
|
|
725
|
-
var
|
|
726
|
-
var Chip =
|
|
727
|
-
({ className, tone = "neutral", ...props }, ref) => /* @__PURE__ */ (0,
|
|
1399
|
+
var React13 = __toESM(require("react"), 1);
|
|
1400
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
1401
|
+
var Chip = React13.forwardRef(
|
|
1402
|
+
({ className, tone = "neutral", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
728
1403
|
"span",
|
|
729
1404
|
{
|
|
730
1405
|
ref,
|
|
@@ -735,36 +1410,92 @@ var Chip = React9.forwardRef(
|
|
|
735
1410
|
);
|
|
736
1411
|
Chip.displayName = "Chip";
|
|
737
1412
|
|
|
1413
|
+
// src/components/Checkbox/Checkbox.tsx
|
|
1414
|
+
var import_fractal_icons9 = require("@mirror-physics/fractal-icons");
|
|
1415
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
1416
|
+
function Checkbox({
|
|
1417
|
+
checked,
|
|
1418
|
+
indeterminate = false,
|
|
1419
|
+
onCheckedChange,
|
|
1420
|
+
className,
|
|
1421
|
+
disabled,
|
|
1422
|
+
onClick,
|
|
1423
|
+
onKeyDown,
|
|
1424
|
+
...props
|
|
1425
|
+
}) {
|
|
1426
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1427
|
+
"button",
|
|
1428
|
+
{
|
|
1429
|
+
...props,
|
|
1430
|
+
className: cn(
|
|
1431
|
+
"fractal-checkbox",
|
|
1432
|
+
(checked || indeterminate) && "fractal-checkbox--checked",
|
|
1433
|
+
indeterminate && "fractal-checkbox--indeterminate",
|
|
1434
|
+
className
|
|
1435
|
+
),
|
|
1436
|
+
type: "button",
|
|
1437
|
+
role: "checkbox",
|
|
1438
|
+
"aria-checked": indeterminate ? "mixed" : checked,
|
|
1439
|
+
disabled,
|
|
1440
|
+
onClick: (event) => {
|
|
1441
|
+
onClick?.(event);
|
|
1442
|
+
if (!event.defaultPrevented) onCheckedChange(indeterminate || !checked);
|
|
1443
|
+
},
|
|
1444
|
+
onKeyDown: (event) => {
|
|
1445
|
+
onKeyDown?.(event);
|
|
1446
|
+
if (event.key === " " || event.key === "Enter") event.stopPropagation();
|
|
1447
|
+
},
|
|
1448
|
+
children: indeterminate ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { className: "fractal-checkbox__indeterminate-icon", "aria-hidden": "true", children: [
|
|
1449
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_fractal_icons9.Checkbox, { size: 18 }),
|
|
1450
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_fractal_icons9.Minus, { className: "fractal-checkbox__indeterminate-mark", size: 12 })
|
|
1451
|
+
] }) : checked ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_fractal_icons9.CheckboxChecked, { "aria-hidden": "true", size: 18 }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_fractal_icons9.Checkbox, { "aria-hidden": "true", size: 18 })
|
|
1452
|
+
}
|
|
1453
|
+
);
|
|
1454
|
+
}
|
|
1455
|
+
|
|
738
1456
|
// src/components/SortableTable/SortableTable.tsx
|
|
739
|
-
var
|
|
740
|
-
var
|
|
741
|
-
var
|
|
1457
|
+
var import_react4 = require("react");
|
|
1458
|
+
var import_fractal_icons10 = require("@mirror-physics/fractal-icons");
|
|
1459
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
742
1460
|
function SortableTable({
|
|
743
1461
|
columns,
|
|
744
1462
|
data,
|
|
1463
|
+
"aria-label": ariaLabel,
|
|
745
1464
|
emptyMessage,
|
|
746
1465
|
header,
|
|
747
1466
|
size = "md",
|
|
1467
|
+
embedded = false,
|
|
748
1468
|
className,
|
|
1469
|
+
defaultSort,
|
|
749
1470
|
defaultSortKey = void 0,
|
|
750
1471
|
defaultSortDirection = null,
|
|
751
1472
|
sortKey: controlledKey,
|
|
752
1473
|
sortDirection: controlledDirection,
|
|
753
1474
|
onSortChange,
|
|
1475
|
+
pagination,
|
|
754
1476
|
highlightRow,
|
|
755
|
-
|
|
1477
|
+
selection,
|
|
1478
|
+
isRowDisabled,
|
|
1479
|
+
isRowSelectionDisabled,
|
|
1480
|
+
onRowClick,
|
|
1481
|
+
onRowDoubleClick,
|
|
1482
|
+
rowAction
|
|
756
1483
|
}) {
|
|
757
|
-
const [internalKey, setInternalKey] = (0,
|
|
758
|
-
const [internalDirection, setInternalDirection] = (0,
|
|
1484
|
+
const [internalKey, setInternalKey] = (0, import_react4.useState)(defaultSortKey ?? null);
|
|
1485
|
+
const [internalDirection, setInternalDirection] = (0, import_react4.useState)(defaultSortDirection);
|
|
759
1486
|
const isControlled = controlledKey !== void 0 && controlledDirection !== void 0;
|
|
760
1487
|
const activeKey = isControlled ? controlledKey : internalKey;
|
|
761
1488
|
const activeDirection = isControlled ? controlledDirection : internalDirection;
|
|
762
|
-
const
|
|
763
|
-
|
|
764
|
-
|
|
1489
|
+
const baselineKey = defaultSort?.key ?? null;
|
|
1490
|
+
const baselineDirection = defaultSort?.direction ?? null;
|
|
1491
|
+
const effectiveKey = activeKey && activeDirection ? activeKey : baselineKey;
|
|
1492
|
+
const effectiveDirection = activeKey && activeDirection ? activeDirection : baselineDirection;
|
|
1493
|
+
const sorted = (0, import_react4.useMemo)(() => {
|
|
1494
|
+
if (!effectiveKey || !effectiveDirection) return data;
|
|
1495
|
+
const col = columns.find((c) => c.key === effectiveKey);
|
|
765
1496
|
if (!col) return data;
|
|
766
1497
|
const accessor = col.sortAccessor ?? ((row) => {
|
|
767
|
-
const value = row[
|
|
1498
|
+
const value = row[effectiveKey];
|
|
768
1499
|
return typeof value === "string" || typeof value === "number" ? value : null;
|
|
769
1500
|
});
|
|
770
1501
|
const copy = [...data];
|
|
@@ -775,26 +1506,41 @@ function SortableTable({
|
|
|
775
1506
|
if (av == null) return 1;
|
|
776
1507
|
if (bv == null) return -1;
|
|
777
1508
|
if (typeof av === "number" && typeof bv === "number") {
|
|
778
|
-
return
|
|
1509
|
+
return effectiveDirection === "asc" ? av - bv : bv - av;
|
|
779
1510
|
}
|
|
780
1511
|
const as = String(av).toLowerCase();
|
|
781
1512
|
const bs = String(bv).toLowerCase();
|
|
782
|
-
if (as < bs) return
|
|
783
|
-
if (as > bs) return
|
|
1513
|
+
if (as < bs) return effectiveDirection === "asc" ? -1 : 1;
|
|
1514
|
+
if (as > bs) return effectiveDirection === "asc" ? 1 : -1;
|
|
784
1515
|
return 0;
|
|
785
1516
|
});
|
|
786
1517
|
return copy;
|
|
787
|
-
}, [data, columns,
|
|
1518
|
+
}, [data, columns, effectiveKey, effectiveDirection]);
|
|
1519
|
+
const visibleRows = (0, import_react4.useMemo)(() => {
|
|
1520
|
+
if (!pagination) return sorted;
|
|
1521
|
+
const pageSize = Math.max(1, pagination.pageSize);
|
|
1522
|
+
const totalPages = Math.max(1, Math.ceil(sorted.length / pageSize));
|
|
1523
|
+
const page = Math.min(Math.max(1, pagination.page), totalPages);
|
|
1524
|
+
const startIndex = (page - 1) * pageSize;
|
|
1525
|
+
return sorted.slice(startIndex, startIndex + pageSize);
|
|
1526
|
+
}, [pagination, sorted]);
|
|
1527
|
+
const selectedRows = selection ? sorted.filter(selection.isSelected) : [];
|
|
1528
|
+
const selectableRows = selection ? sorted.filter((row) => !isRowDisabled?.(row) && !isRowSelectionDisabled?.(row)) : [];
|
|
1529
|
+
const selectedRowCount = selection ? selectableRows.filter(selection.isSelected).length : 0;
|
|
1530
|
+
const allRowsSelected = selectableRows.length > 0 && selectedRowCount === selectableRows.length;
|
|
1531
|
+
const someRowsSelected = selectedRows.length > 0 && !allRowsSelected;
|
|
788
1532
|
const handleSortClick = (key) => {
|
|
789
1533
|
let nextDirection;
|
|
790
|
-
if (activeKey
|
|
1534
|
+
if (!activeKey || !activeDirection) {
|
|
1535
|
+
nextDirection = baselineKey === key && baselineDirection ? baselineDirection : "asc";
|
|
1536
|
+
} else if (activeKey !== key) {
|
|
791
1537
|
nextDirection = "asc";
|
|
1538
|
+
} else if (baselineKey === key && baselineDirection) {
|
|
1539
|
+
nextDirection = activeDirection === baselineDirection ? baselineDirection === "asc" ? "desc" : "asc" : null;
|
|
792
1540
|
} else if (activeDirection === "asc") {
|
|
793
1541
|
nextDirection = "desc";
|
|
794
|
-
} else if (activeDirection === "desc") {
|
|
795
|
-
nextDirection = null;
|
|
796
1542
|
} else {
|
|
797
|
-
nextDirection =
|
|
1543
|
+
nextDirection = null;
|
|
798
1544
|
}
|
|
799
1545
|
const nextKey = nextDirection === null ? null : key;
|
|
800
1546
|
if (isControlled) {
|
|
@@ -805,75 +1551,140 @@ function SortableTable({
|
|
|
805
1551
|
onSortChange?.(nextKey, nextDirection);
|
|
806
1552
|
}
|
|
807
1553
|
};
|
|
808
|
-
return /* @__PURE__ */ (0,
|
|
809
|
-
header && /* @__PURE__ */ (0,
|
|
810
|
-
|
|
811
|
-
/* @__PURE__ */ (0,
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
1554
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: cn("fractal-sortable-table", `fractal-sortable-table--${size}`, embedded && "fractal-sortable-table--embedded", className), children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "fractal-sortable-table-surface", children: [
|
|
1555
|
+
header && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "fractal-sortable-table-header", children: header }),
|
|
1556
|
+
visibleRows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "fractal-sortable-table-empty", children: emptyMessage || "No data" }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("table", { "aria-label": ariaLabel, className: "fractal-sortable-table-table", children: [
|
|
1557
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("tr", { className: "fractal-sortable-table-thead-row", children: [
|
|
1558
|
+
selection && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
1559
|
+
"th",
|
|
1560
|
+
{
|
|
1561
|
+
className: "fractal-sortable-table-th fractal-sortable-table-selection-cell",
|
|
1562
|
+
scope: "col",
|
|
1563
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
1564
|
+
Checkbox,
|
|
1565
|
+
{
|
|
1566
|
+
"aria-label": selection.selectAllLabel ?? "Select all rows",
|
|
1567
|
+
checked: allRowsSelected,
|
|
1568
|
+
disabled: selectableRows.length === 0 && selectedRows.length === 0,
|
|
1569
|
+
indeterminate: someRowsSelected,
|
|
1570
|
+
onCheckedChange: (checked) => {
|
|
1571
|
+
const rows = checked ? selectableRows : selectedRows;
|
|
1572
|
+
if (selection.onSelectAllChange) {
|
|
1573
|
+
selection.onSelectAllChange(rows, checked);
|
|
1574
|
+
return;
|
|
1575
|
+
}
|
|
1576
|
+
rows.forEach((row) => {
|
|
1577
|
+
if (selection.isSelected(row) !== checked) {
|
|
1578
|
+
selection.onSelectedChange(row, checked);
|
|
1579
|
+
}
|
|
1580
|
+
});
|
|
1581
|
+
}
|
|
1582
|
+
}
|
|
1583
|
+
)
|
|
1584
|
+
}
|
|
1585
|
+
),
|
|
1586
|
+
columns.map((col) => {
|
|
1587
|
+
const isActive = activeKey === col.key && activeDirection !== null;
|
|
1588
|
+
if (!col.sortable) {
|
|
1589
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
1590
|
+
"th",
|
|
1591
|
+
{
|
|
1592
|
+
className: "fractal-sortable-table-th",
|
|
1593
|
+
scope: "col",
|
|
1594
|
+
style: { width: col.width },
|
|
1595
|
+
children: col.header
|
|
1596
|
+
},
|
|
1597
|
+
col.key
|
|
1598
|
+
);
|
|
1599
|
+
}
|
|
1600
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
815
1601
|
"th",
|
|
816
1602
|
{
|
|
817
|
-
className: "fractal-sortable-table-th",
|
|
1603
|
+
className: "fractal-sortable-table-th fractal-sortable-table-th--sortable",
|
|
1604
|
+
scope: "col",
|
|
818
1605
|
style: { width: col.width },
|
|
819
|
-
children:
|
|
1606
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
1607
|
+
"button",
|
|
1608
|
+
{
|
|
1609
|
+
type: "button",
|
|
1610
|
+
className: cn(
|
|
1611
|
+
"fractal-sortable-table-sort-button",
|
|
1612
|
+
isActive && "fractal-sortable-table-sort-button--active"
|
|
1613
|
+
),
|
|
1614
|
+
onClick: () => handleSortClick(col.key),
|
|
1615
|
+
"aria-sort": isActive ? activeDirection === "asc" ? "ascending" : "descending" : "none",
|
|
1616
|
+
children: [
|
|
1617
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { children: col.header }),
|
|
1618
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "fractal-sortable-table-sort-icon", "aria-hidden": "true", children: isActive && activeDirection === "asc" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_fractal_icons10.ArrowUp, { size: 14 }) : isActive && activeDirection === "desc" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_fractal_icons10.ArrowDown, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_fractal_icons10.ArrowsUpDown, { size: 14 }) })
|
|
1619
|
+
]
|
|
1620
|
+
}
|
|
1621
|
+
)
|
|
820
1622
|
},
|
|
821
1623
|
col.key
|
|
822
1624
|
);
|
|
823
|
-
}
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
{
|
|
827
|
-
className: "fractal-sortable-table-th fractal-sortable-table-th--sortable",
|
|
828
|
-
style: { width: col.width },
|
|
829
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
830
|
-
"button",
|
|
831
|
-
{
|
|
832
|
-
type: "button",
|
|
833
|
-
className: cn(
|
|
834
|
-
"fractal-sortable-table-sort-button",
|
|
835
|
-
isActive && "fractal-sortable-table-sort-button--active"
|
|
836
|
-
),
|
|
837
|
-
onClick: () => handleSortClick(col.key),
|
|
838
|
-
"aria-sort": isActive ? activeDirection === "asc" ? "ascending" : "descending" : "none",
|
|
839
|
-
children: [
|
|
840
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: col.header }),
|
|
841
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "fractal-sortable-table-sort-icon", "aria-hidden": "true", children: isActive && activeDirection === "asc" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_fractal_icons3.ArrowUp, { size: 14 }) : isActive && activeDirection === "desc" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_fractal_icons3.ArrowDown, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_fractal_icons3.ArrowsUpDown, { size: 14 }) })
|
|
842
|
-
]
|
|
843
|
-
}
|
|
844
|
-
)
|
|
845
|
-
},
|
|
846
|
-
col.key
|
|
847
|
-
);
|
|
848
|
-
}) }) }),
|
|
849
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("tbody", { children: sorted.map((row, rowIndex) => {
|
|
1625
|
+
})
|
|
1626
|
+
] }) }),
|
|
1627
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("tbody", { children: visibleRows.map((row, rowIndex) => {
|
|
850
1628
|
const highlighted = highlightRow?.(row, rowIndex) ?? false;
|
|
851
|
-
|
|
1629
|
+
const disabled = isRowDisabled?.(row) ?? false;
|
|
1630
|
+
const selectionDisabled = disabled || (isRowSelectionDisabled?.(row) ?? false);
|
|
1631
|
+
const interactive = !disabled && Boolean(onRowClick || onRowDoubleClick);
|
|
1632
|
+
const action = !disabled && rowAction ? {
|
|
1633
|
+
label: rowAction.label(row, rowIndex),
|
|
1634
|
+
icon: rowAction.icon(row, rowIndex)
|
|
1635
|
+
} : null;
|
|
1636
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
852
1637
|
"tr",
|
|
853
1638
|
{
|
|
854
1639
|
className: cn(
|
|
855
1640
|
"fractal-sortable-table-row",
|
|
856
1641
|
highlighted && "fractal-sortable-table-row--highlighted",
|
|
857
|
-
|
|
1642
|
+
interactive && "fractal-sortable-table-row--interactive",
|
|
1643
|
+
disabled && "fractal-sortable-table-row--disabled"
|
|
858
1644
|
),
|
|
859
|
-
|
|
860
|
-
|
|
1645
|
+
"data-disabled": disabled || void 0,
|
|
1646
|
+
onClick: !disabled && onRowClick ? () => onRowClick(row, rowIndex) : void 0,
|
|
1647
|
+
onDoubleClick: !disabled && onRowDoubleClick ? () => onRowDoubleClick(row, rowIndex) : void 0,
|
|
1648
|
+
onKeyDown: interactive ? (event) => {
|
|
861
1649
|
if (event.key === "Enter" || event.key === " ") {
|
|
862
1650
|
event.preventDefault();
|
|
863
|
-
onRowClick
|
|
1651
|
+
const activateRow = onRowClick ?? onRowDoubleClick;
|
|
1652
|
+
activateRow?.(row, rowIndex);
|
|
864
1653
|
}
|
|
865
1654
|
} : void 0,
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
1655
|
+
"aria-label": action?.label,
|
|
1656
|
+
"aria-disabled": disabled || void 0,
|
|
1657
|
+
role: interactive ? "button" : void 0,
|
|
1658
|
+
tabIndex: interactive ? 0 : void 0,
|
|
1659
|
+
children: [
|
|
1660
|
+
selection && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("td", { className: "fractal-sortable-table-td fractal-sortable-table-selection-cell", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
1661
|
+
Checkbox,
|
|
1662
|
+
{
|
|
1663
|
+
"aria-label": selection.getRowLabel(row),
|
|
1664
|
+
checked: !selectionDisabled && selection.isSelected(row),
|
|
1665
|
+
disabled: selectionDisabled,
|
|
1666
|
+
onClick: (event) => event.stopPropagation(),
|
|
1667
|
+
onCheckedChange: (checked) => {
|
|
1668
|
+
if (!selectionDisabled) selection.onSelectedChange(row, checked);
|
|
1669
|
+
}
|
|
1670
|
+
}
|
|
1671
|
+
) }),
|
|
1672
|
+
columns.map((col, columnIndex) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
1673
|
+
"td",
|
|
1674
|
+
{
|
|
1675
|
+
className: cn(
|
|
1676
|
+
"fractal-sortable-table-td",
|
|
1677
|
+
action && columnIndex === columns.length - 1 && "fractal-sortable-table-td--row-action"
|
|
1678
|
+
),
|
|
1679
|
+
style: { width: col.width, textAlign: col.align ?? "left" },
|
|
1680
|
+
children: [
|
|
1681
|
+
col.render(row, rowIndex),
|
|
1682
|
+
action && columnIndex === columns.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "fractal-sortable-table-row-action", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "fractal-sortable-table-row-action__icon", children: action.icon }) })
|
|
1683
|
+
]
|
|
1684
|
+
},
|
|
1685
|
+
col.key
|
|
1686
|
+
))
|
|
1687
|
+
]
|
|
877
1688
|
},
|
|
878
1689
|
rowIndex
|
|
879
1690
|
);
|
|
@@ -883,23 +1694,40 @@ function SortableTable({
|
|
|
883
1694
|
}
|
|
884
1695
|
|
|
885
1696
|
// src/components/Tabs/Tabs.tsx
|
|
886
|
-
var
|
|
887
|
-
var
|
|
1697
|
+
var import_react5 = require("react");
|
|
1698
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
888
1699
|
function Tabs({
|
|
889
1700
|
items,
|
|
890
1701
|
defaultValue,
|
|
891
1702
|
value: controlledValue,
|
|
892
1703
|
onValueChange,
|
|
893
1704
|
className,
|
|
894
|
-
ariaLabel
|
|
1705
|
+
ariaLabel,
|
|
1706
|
+
divider = false,
|
|
1707
|
+
variant = "line"
|
|
895
1708
|
}) {
|
|
896
|
-
const reactId = (0,
|
|
897
|
-
const [internalValue, setInternalValue] = (0,
|
|
1709
|
+
const reactId = (0, import_react5.useId)();
|
|
1710
|
+
const [internalValue, setInternalValue] = (0, import_react5.useState)(
|
|
898
1711
|
defaultValue ?? items.find((i) => !i.disabled)?.id ?? items[0]?.id ?? ""
|
|
899
1712
|
);
|
|
900
1713
|
const isControlled = controlledValue !== void 0;
|
|
901
1714
|
const activeId = isControlled ? controlledValue : internalValue;
|
|
902
|
-
const
|
|
1715
|
+
const tabListRef = (0, import_react5.useRef)(null);
|
|
1716
|
+
const tabRefs = (0, import_react5.useRef)({});
|
|
1717
|
+
const [indicator, setIndicator] = (0, import_react5.useState)(null);
|
|
1718
|
+
(0, import_react5.useLayoutEffect)(() => {
|
|
1719
|
+
const updateIndicator = () => {
|
|
1720
|
+
const activeTab = tabRefs.current[activeId];
|
|
1721
|
+
if (!activeTab) return;
|
|
1722
|
+
setIndicator({ offset: activeTab.offsetLeft, width: activeTab.offsetWidth });
|
|
1723
|
+
};
|
|
1724
|
+
updateIndicator();
|
|
1725
|
+
const list = tabListRef.current;
|
|
1726
|
+
if (!list || typeof ResizeObserver === "undefined") return;
|
|
1727
|
+
const observer = new ResizeObserver(updateIndicator);
|
|
1728
|
+
observer.observe(list);
|
|
1729
|
+
return () => observer.disconnect();
|
|
1730
|
+
}, [activeId, items.length]);
|
|
903
1731
|
const selectTab = (id) => {
|
|
904
1732
|
if (isControlled) {
|
|
905
1733
|
onValueChange?.(id);
|
|
@@ -909,6 +1737,10 @@ function Tabs({
|
|
|
909
1737
|
}
|
|
910
1738
|
};
|
|
911
1739
|
const focusable = items.filter((i) => !i.disabled);
|
|
1740
|
+
const indicatorStyle = indicator ? {
|
|
1741
|
+
"--fractal-tabs-indicator-offset": `${indicator.offset}px`,
|
|
1742
|
+
"--fractal-tabs-indicator-width": `${indicator.width}px`
|
|
1743
|
+
} : void 0;
|
|
912
1744
|
const onKeyDown = (event) => {
|
|
913
1745
|
const currentIndex = focusable.findIndex((i) => i.id === activeId);
|
|
914
1746
|
if (currentIndex === -1) return;
|
|
@@ -934,41 +1766,52 @@ function Tabs({
|
|
|
934
1766
|
selectTab(nextId2);
|
|
935
1767
|
requestAnimationFrame(() => tabRefs.current[nextId2]?.focus());
|
|
936
1768
|
};
|
|
937
|
-
return /* @__PURE__ */ (0,
|
|
938
|
-
/* @__PURE__ */ (0,
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
"
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
id
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
1769
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: cn("fractal-tabs", `fractal-tabs--${variant}`, divider && "fractal-tabs--divider", className), children: [
|
|
1770
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
1771
|
+
"div",
|
|
1772
|
+
{
|
|
1773
|
+
ref: tabListRef,
|
|
1774
|
+
role: "tablist",
|
|
1775
|
+
"aria-label": ariaLabel,
|
|
1776
|
+
className: "fractal-tabs-list",
|
|
1777
|
+
"data-indicator-ready": indicator ? "true" : void 0,
|
|
1778
|
+
style: indicatorStyle,
|
|
1779
|
+
children: items.map((item) => {
|
|
1780
|
+
const isActive = item.id === activeId;
|
|
1781
|
+
const tabId = `${reactId}-tab-${item.id}`;
|
|
1782
|
+
const panelId = `${reactId}-panel-${item.id}`;
|
|
1783
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
1784
|
+
"button",
|
|
1785
|
+
{
|
|
1786
|
+
ref: (el) => {
|
|
1787
|
+
tabRefs.current[item.id] = el;
|
|
1788
|
+
},
|
|
1789
|
+
id: tabId,
|
|
1790
|
+
role: "tab",
|
|
1791
|
+
type: "button",
|
|
1792
|
+
"aria-selected": isActive,
|
|
1793
|
+
"aria-controls": panelId,
|
|
1794
|
+
tabIndex: isActive ? 0 : -1,
|
|
1795
|
+
disabled: item.disabled,
|
|
1796
|
+
className: cn(
|
|
1797
|
+
"fractal-tabs-trigger",
|
|
1798
|
+
isActive && "fractal-tabs-trigger--active",
|
|
1799
|
+
item.disabled && "fractal-tabs-trigger--disabled"
|
|
1800
|
+
),
|
|
1801
|
+
onClick: () => !item.disabled && selectTab(item.id),
|
|
1802
|
+
onKeyDown,
|
|
1803
|
+
children: item.label
|
|
1804
|
+
},
|
|
1805
|
+
item.id
|
|
1806
|
+
);
|
|
1807
|
+
})
|
|
1808
|
+
}
|
|
1809
|
+
),
|
|
967
1810
|
items.map((item) => {
|
|
968
1811
|
const tabId = `${reactId}-tab-${item.id}`;
|
|
969
1812
|
const panelId = `${reactId}-panel-${item.id}`;
|
|
970
1813
|
const isActive = item.id === activeId;
|
|
971
|
-
return /* @__PURE__ */ (0,
|
|
1814
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
972
1815
|
"div",
|
|
973
1816
|
{
|
|
974
1817
|
id: panelId,
|
|
@@ -984,10 +1827,112 @@ function Tabs({
|
|
|
984
1827
|
] });
|
|
985
1828
|
}
|
|
986
1829
|
|
|
1830
|
+
// src/components/ContentSwitcher/ContentSwitcher.tsx
|
|
1831
|
+
var React14 = __toESM(require("react"), 1);
|
|
1832
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
1833
|
+
function ContentSwitcher({ items, value, onValueChange, ariaLabel, fullWidth = false, className }) {
|
|
1834
|
+
const switcherRef = React14.useRef(null);
|
|
1835
|
+
const buttonRefs = React14.useRef([]);
|
|
1836
|
+
const indicatorMotionReadyRef = React14.useRef(false);
|
|
1837
|
+
const activeIndex = items.findIndex((item) => item.value === value);
|
|
1838
|
+
React14.useLayoutEffect(() => {
|
|
1839
|
+
const switcher = switcherRef.current;
|
|
1840
|
+
const activeButton = buttonRefs.current[activeIndex];
|
|
1841
|
+
let motionFrame = 0;
|
|
1842
|
+
if (!switcher || !activeButton) {
|
|
1843
|
+
switcher?.removeAttribute("data-indicator-ready");
|
|
1844
|
+
switcher?.removeAttribute("data-indicator-animate");
|
|
1845
|
+
indicatorMotionReadyRef.current = false;
|
|
1846
|
+
return;
|
|
1847
|
+
}
|
|
1848
|
+
const updateIndicator = () => {
|
|
1849
|
+
const switcherRect = switcher.getBoundingClientRect();
|
|
1850
|
+
const activeButtonRect = activeButton.getBoundingClientRect();
|
|
1851
|
+
switcher.style.setProperty("--fractal-content-switcher-indicator-x", `${activeButtonRect.left - switcherRect.left - switcher.clientLeft}px`);
|
|
1852
|
+
switcher.style.setProperty("--fractal-content-switcher-indicator-y", `${activeButtonRect.top - switcherRect.top - switcher.clientTop}px`);
|
|
1853
|
+
switcher.style.setProperty("--fractal-content-switcher-indicator-width", `${activeButtonRect.width}px`);
|
|
1854
|
+
switcher.style.setProperty("--fractal-content-switcher-indicator-height", `${activeButtonRect.height}px`);
|
|
1855
|
+
switcher.setAttribute("data-indicator-ready", "true");
|
|
1856
|
+
if (!indicatorMotionReadyRef.current && motionFrame === 0) {
|
|
1857
|
+
motionFrame = window.requestAnimationFrame(() => {
|
|
1858
|
+
indicatorMotionReadyRef.current = true;
|
|
1859
|
+
switcher.setAttribute("data-indicator-animate", "true");
|
|
1860
|
+
motionFrame = 0;
|
|
1861
|
+
});
|
|
1862
|
+
}
|
|
1863
|
+
};
|
|
1864
|
+
updateIndicator();
|
|
1865
|
+
if (typeof ResizeObserver === "undefined") {
|
|
1866
|
+
return () => {
|
|
1867
|
+
if (motionFrame !== 0) window.cancelAnimationFrame(motionFrame);
|
|
1868
|
+
};
|
|
1869
|
+
}
|
|
1870
|
+
const resizeObserver = new ResizeObserver(updateIndicator);
|
|
1871
|
+
resizeObserver.observe(switcher);
|
|
1872
|
+
buttonRefs.current.forEach((button) => {
|
|
1873
|
+
if (button) resizeObserver.observe(button);
|
|
1874
|
+
});
|
|
1875
|
+
return () => {
|
|
1876
|
+
resizeObserver.disconnect();
|
|
1877
|
+
if (motionFrame !== 0) window.cancelAnimationFrame(motionFrame);
|
|
1878
|
+
};
|
|
1879
|
+
}, [activeIndex, items.length]);
|
|
1880
|
+
const moveFocus = (index, direction) => {
|
|
1881
|
+
let nextIndex = index;
|
|
1882
|
+
do {
|
|
1883
|
+
nextIndex = (nextIndex + direction + items.length) % items.length;
|
|
1884
|
+
} while (items[nextIndex]?.disabled && nextIndex !== index);
|
|
1885
|
+
if (!items[nextIndex]?.disabled) {
|
|
1886
|
+
buttonRefs.current[nextIndex]?.focus();
|
|
1887
|
+
onValueChange(items[nextIndex].value);
|
|
1888
|
+
}
|
|
1889
|
+
};
|
|
1890
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
1891
|
+
"div",
|
|
1892
|
+
{
|
|
1893
|
+
className: cn("fractal-content-switcher", fullWidth && "fractal-content-switcher--full-width", className),
|
|
1894
|
+
role: "group",
|
|
1895
|
+
"aria-label": ariaLabel,
|
|
1896
|
+
ref: switcherRef,
|
|
1897
|
+
children: [
|
|
1898
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "fractal-content-switcher__indicator", "aria-hidden": true }),
|
|
1899
|
+
items.map((item, index) => {
|
|
1900
|
+
const active = item.value === value;
|
|
1901
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
1902
|
+
"button",
|
|
1903
|
+
{
|
|
1904
|
+
className: cn("fractal-content-switcher__item", active && "fractal-content-switcher__item--active"),
|
|
1905
|
+
type: "button",
|
|
1906
|
+
"aria-pressed": active,
|
|
1907
|
+
disabled: item.disabled,
|
|
1908
|
+
onClick: () => onValueChange(item.value),
|
|
1909
|
+
onKeyDown: (event) => {
|
|
1910
|
+
if (event.key === "ArrowRight") {
|
|
1911
|
+
event.preventDefault();
|
|
1912
|
+
moveFocus(index, 1);
|
|
1913
|
+
}
|
|
1914
|
+
if (event.key === "ArrowLeft") {
|
|
1915
|
+
event.preventDefault();
|
|
1916
|
+
moveFocus(index, -1);
|
|
1917
|
+
}
|
|
1918
|
+
},
|
|
1919
|
+
ref: (element) => {
|
|
1920
|
+
buttonRefs.current[index] = element;
|
|
1921
|
+
},
|
|
1922
|
+
children: item.label
|
|
1923
|
+
},
|
|
1924
|
+
item.value
|
|
1925
|
+
);
|
|
1926
|
+
})
|
|
1927
|
+
]
|
|
1928
|
+
}
|
|
1929
|
+
);
|
|
1930
|
+
}
|
|
1931
|
+
|
|
987
1932
|
// src/components/Disclosure/Disclosure.tsx
|
|
988
|
-
var
|
|
989
|
-
var
|
|
990
|
-
var
|
|
1933
|
+
var import_react6 = require("react");
|
|
1934
|
+
var import_fractal_icons11 = require("@mirror-physics/fractal-icons");
|
|
1935
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
991
1936
|
function Disclosure({
|
|
992
1937
|
title,
|
|
993
1938
|
meta,
|
|
@@ -995,16 +1940,18 @@ function Disclosure({
|
|
|
995
1940
|
defaultOpen = false,
|
|
996
1941
|
open: controlledOpen,
|
|
997
1942
|
onOpenChange,
|
|
1943
|
+
disabled = false,
|
|
998
1944
|
className,
|
|
999
1945
|
variant = "card"
|
|
1000
1946
|
}) {
|
|
1001
|
-
const reactId = (0,
|
|
1947
|
+
const reactId = (0, import_react6.useId)();
|
|
1002
1948
|
const headerId = `${reactId}-header`;
|
|
1003
1949
|
const panelId = `${reactId}-panel`;
|
|
1004
|
-
const [internalOpen, setInternalOpen] = (0,
|
|
1950
|
+
const [internalOpen, setInternalOpen] = (0, import_react6.useState)(defaultOpen);
|
|
1005
1951
|
const isControlled = controlledOpen !== void 0;
|
|
1006
1952
|
const isOpen = isControlled ? controlledOpen : internalOpen;
|
|
1007
1953
|
const toggle = () => {
|
|
1954
|
+
if (disabled) return;
|
|
1008
1955
|
const next = !isOpen;
|
|
1009
1956
|
if (isControlled) {
|
|
1010
1957
|
onOpenChange?.(next);
|
|
@@ -1013,17 +1960,18 @@ function Disclosure({
|
|
|
1013
1960
|
onOpenChange?.(next);
|
|
1014
1961
|
}
|
|
1015
1962
|
};
|
|
1016
|
-
return /* @__PURE__ */ (0,
|
|
1963
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
1017
1964
|
"div",
|
|
1018
1965
|
{
|
|
1019
1966
|
className: cn(
|
|
1020
1967
|
"fractal-disclosure",
|
|
1021
1968
|
variant === "card" && "fractal-disclosure--card",
|
|
1022
1969
|
isOpen && "fractal-disclosure--open",
|
|
1970
|
+
disabled && "fractal-disclosure--disabled",
|
|
1023
1971
|
className
|
|
1024
1972
|
),
|
|
1025
1973
|
children: [
|
|
1026
|
-
/* @__PURE__ */ (0,
|
|
1974
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
1027
1975
|
"button",
|
|
1028
1976
|
{
|
|
1029
1977
|
type: "button",
|
|
@@ -1031,15 +1979,16 @@ function Disclosure({
|
|
|
1031
1979
|
className: "fractal-disclosure-trigger",
|
|
1032
1980
|
"aria-expanded": isOpen,
|
|
1033
1981
|
"aria-controls": panelId,
|
|
1982
|
+
disabled,
|
|
1034
1983
|
onClick: toggle,
|
|
1035
1984
|
children: [
|
|
1036
|
-
/* @__PURE__ */ (0,
|
|
1037
|
-
/* @__PURE__ */ (0,
|
|
1038
|
-
meta && /* @__PURE__ */ (0,
|
|
1985
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "fractal-disclosure-icon", "aria-hidden": "true", children: isOpen ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_fractal_icons11.ChevronDown, { size: 16 }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_fractal_icons11.ChevronRight, { size: 16 }) }),
|
|
1986
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "fractal-disclosure-title", children: title }),
|
|
1987
|
+
meta && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "fractal-disclosure-meta", children: meta })
|
|
1039
1988
|
]
|
|
1040
1989
|
}
|
|
1041
1990
|
),
|
|
1042
|
-
/* @__PURE__ */ (0,
|
|
1991
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
1043
1992
|
"div",
|
|
1044
1993
|
{
|
|
1045
1994
|
id: panelId,
|
|
@@ -1047,7 +1996,7 @@ function Disclosure({
|
|
|
1047
1996
|
"aria-labelledby": headerId,
|
|
1048
1997
|
className: "fractal-disclosure-panel",
|
|
1049
1998
|
hidden: !isOpen,
|
|
1050
|
-
children: /* @__PURE__ */ (0,
|
|
1999
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "fractal-disclosure-panel-inner", children })
|
|
1051
2000
|
}
|
|
1052
2001
|
)
|
|
1053
2002
|
]
|
|
@@ -1055,39 +2004,260 @@ function Disclosure({
|
|
|
1055
2004
|
);
|
|
1056
2005
|
}
|
|
1057
2006
|
|
|
2007
|
+
// src/components/LatticeLoader/LatticeLoader.tsx
|
|
2008
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
2009
|
+
var LATTICE_COUNT = 160;
|
|
2010
|
+
var WAVE_PERIOD = 80;
|
|
2011
|
+
function LatticeLoader({ className, label = "Loading", ...props }) {
|
|
2012
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2013
|
+
"span",
|
|
2014
|
+
{
|
|
2015
|
+
"aria-label": label,
|
|
2016
|
+
className: cn("fractal-lattice-loader", className),
|
|
2017
|
+
role: "progressbar",
|
|
2018
|
+
...props,
|
|
2019
|
+
children: Array.from({ length: LATTICE_COUNT }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2020
|
+
"span",
|
|
2021
|
+
{
|
|
2022
|
+
"aria-hidden": "true",
|
|
2023
|
+
className: "fractal-lattice-loader__cell",
|
|
2024
|
+
style: { "--fractal-lattice-index": index % WAVE_PERIOD }
|
|
2025
|
+
},
|
|
2026
|
+
index
|
|
2027
|
+
))
|
|
2028
|
+
}
|
|
2029
|
+
);
|
|
2030
|
+
}
|
|
2031
|
+
|
|
2032
|
+
// src/components/Ghost/Ghost.tsx
|
|
2033
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
2034
|
+
var toCssLength = (value) => typeof value === "number" ? `${value}px` : value;
|
|
2035
|
+
function Ghost({ className, width, height, radius, style, ...props }) {
|
|
2036
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
2037
|
+
"div",
|
|
2038
|
+
{
|
|
2039
|
+
"aria-hidden": "true",
|
|
2040
|
+
className: cn("fractal-ghost", className),
|
|
2041
|
+
style: {
|
|
2042
|
+
width: toCssLength(width),
|
|
2043
|
+
height: toCssLength(height),
|
|
2044
|
+
borderRadius: toCssLength(radius),
|
|
2045
|
+
...style
|
|
2046
|
+
},
|
|
2047
|
+
...props
|
|
2048
|
+
}
|
|
2049
|
+
);
|
|
2050
|
+
}
|
|
2051
|
+
function GhostLine({ className, size = "md", width = "100%", ...props }) {
|
|
2052
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Ghost, { className: cn("fractal-ghost-line", `fractal-ghost-line--${size}`, className), width, ...props });
|
|
2053
|
+
}
|
|
2054
|
+
function ButtonGhost({ className, size = "md", iconOnly = false, width, ...props }) {
|
|
2055
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Ghost, { className: cn("fractal-ghost-button", `fractal-ghost-button--${size}`, iconOnly && "fractal-ghost-button--icon-only", className), width, ...props });
|
|
2056
|
+
}
|
|
2057
|
+
function CardGhost({ className, lines = 3, showHeader = true, ...props }) {
|
|
2058
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { "aria-hidden": "true", className: cn("fractal-ghost-card", className), ...props, children: [
|
|
2059
|
+
showHeader && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(GhostLine, { width: "38%" }),
|
|
2060
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "fractal-ghost-stack", children: Array.from({ length: lines }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(GhostLine, { width: index === lines - 1 ? "62%" : "100%" }, index)) })
|
|
2061
|
+
] });
|
|
2062
|
+
}
|
|
2063
|
+
function DataTableGhost({
|
|
2064
|
+
className,
|
|
2065
|
+
showHeader = true,
|
|
2066
|
+
headers,
|
|
2067
|
+
columns = 4,
|
|
2068
|
+
rows = 5,
|
|
2069
|
+
columnWidths,
|
|
2070
|
+
size = "md",
|
|
2071
|
+
...props
|
|
2072
|
+
}) {
|
|
2073
|
+
const cells = Array.from({ length: columns }, (_, index) => index);
|
|
2074
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.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_runtime25.jsxs)("table", { className: "fractal-ghost-table__table", children: [
|
|
2075
|
+
(showHeader || headers) && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("tr", { className: "fractal-ghost-table__head-row", children: cells.map((index) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("th", { style: { width: columnWidths?.[index] }, children: headers?.[index] ?? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(GhostLine, { size: "sm", width: index === columns - 1 ? "62%" : "76%" }) }, index)) }) }),
|
|
2076
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("tbody", { children: Array.from({ length: rows }, (_, rowIndex) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("tr", { className: "fractal-ghost-table__row", children: cells.map((columnIndex) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("td", { style: { width: columnWidths?.[columnIndex] }, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(GhostLine, { width: `${[72, 54, 82, 63, 46][(rowIndex + columnIndex) % 5]}%` }) }, columnIndex)) }, rowIndex)) })
|
|
2077
|
+
] }) });
|
|
2078
|
+
}
|
|
2079
|
+
function InputGhost({ className, labelWidth = "26%", ...props }) {
|
|
2080
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(FormFieldGhost, { className, labelWidth, ...props });
|
|
2081
|
+
}
|
|
2082
|
+
function TextareaGhost({ className, labelWidth = "26%", ...props }) {
|
|
2083
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(FormFieldGhost, { className, labelWidth, multiline: true, ...props });
|
|
2084
|
+
}
|
|
2085
|
+
function LabelGhost({ className, width = "26%", ...props }) {
|
|
2086
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(GhostLine, { className: cn("fractal-ghost-label", className), size: "sm", width, ...props });
|
|
2087
|
+
}
|
|
2088
|
+
function FormFieldGhost({ className, labelWidth = "26%", multiline = false, ...props }) {
|
|
2089
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { "aria-hidden": "true", className: cn("fractal-ghost-field", className), ...props, children: [
|
|
2090
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(LabelGhost, { width: labelWidth }),
|
|
2091
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Ghost, { className: cn("fractal-ghost-field__control", multiline && "fractal-ghost-field__control--multiline") })
|
|
2092
|
+
] });
|
|
2093
|
+
}
|
|
2094
|
+
function AlertGhost({ className, ...props }) {
|
|
2095
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { "aria-hidden": "true", className: cn("fractal-ghost-alert", className), ...props, children: [
|
|
2096
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(GhostLine, { width: "30%" }),
|
|
2097
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(GhostLine, { size: "sm", width: "78%" })
|
|
2098
|
+
] });
|
|
2099
|
+
}
|
|
2100
|
+
function CheckboxGhost({ className, ...props }) {
|
|
2101
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { "aria-hidden": "true", className: cn("fractal-ghost-choice", className), ...props, children: [
|
|
2102
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Ghost, { className: "fractal-ghost-choice__control" }),
|
|
2103
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(GhostLine, { width: "42%" })
|
|
2104
|
+
] });
|
|
2105
|
+
}
|
|
2106
|
+
var ToggleGhost = CheckboxGhost;
|
|
2107
|
+
function ChipGhost({ className, width = 74, ...props }) {
|
|
2108
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Ghost, { className: cn("fractal-ghost-chip", className), height: 24, width, ...props });
|
|
2109
|
+
}
|
|
2110
|
+
function LinkGhost({ className, width = 96, ...props }) {
|
|
2111
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(GhostLine, { className: cn("fractal-ghost-link", className), size: "sm", width, ...props });
|
|
2112
|
+
}
|
|
2113
|
+
var TextButtonGhost = LinkGhost;
|
|
2114
|
+
function DropdownGhost({ className, ...props }) {
|
|
2115
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { "aria-hidden": "true", className: cn("fractal-ghost-dropdown", className), ...props, children: [
|
|
2116
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(GhostLine, { width: "38%" }),
|
|
2117
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Ghost, { className: "fractal-ghost-dropdown__chevron" })
|
|
2118
|
+
] });
|
|
2119
|
+
}
|
|
2120
|
+
function ContentSwitcherGhost({ className, options = 3, ...props }) {
|
|
2121
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { "aria-hidden": "true", className: cn("fractal-ghost-switcher", className), ...props, children: Array.from({ length: options }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Ghost, {}, index)) });
|
|
2122
|
+
}
|
|
2123
|
+
var TabsGhost = ContentSwitcherGhost;
|
|
2124
|
+
function DisclosureGhost({ className, ...props }) {
|
|
2125
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { "aria-hidden": "true", className: cn("fractal-ghost-disclosure", className), ...props, children: [
|
|
2126
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Ghost, { className: "fractal-ghost-disclosure__icon" }),
|
|
2127
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(GhostLine, { width: "42%" })
|
|
2128
|
+
] });
|
|
2129
|
+
}
|
|
2130
|
+
function PaginationGhost({ className, pages = 5, ...props }) {
|
|
2131
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { "aria-hidden": "true", className: cn("fractal-ghost-pagination", className), ...props, children: Array.from({ length: pages }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Ghost, {}, index)) });
|
|
2132
|
+
}
|
|
2133
|
+
function FileDropzoneGhost({ className, ...props }) {
|
|
2134
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { "aria-hidden": "true", className: cn("fractal-ghost-dropzone", className), ...props, children: [
|
|
2135
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Ghost, { className: "fractal-ghost-dropzone__icon" }),
|
|
2136
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(GhostLine, { width: "26%" }),
|
|
2137
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(GhostLine, { size: "sm", width: "46%" })
|
|
2138
|
+
] });
|
|
2139
|
+
}
|
|
2140
|
+
function PromptCardGhost({ className, ...props }) {
|
|
2141
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CardGhost, { className: cn("fractal-ghost-prompt-card", className), lines: 4, ...props });
|
|
2142
|
+
}
|
|
2143
|
+
function ConversationGhost({
|
|
2144
|
+
className,
|
|
2145
|
+
"aria-label": ariaLabel = "Loading conversation",
|
|
2146
|
+
...props
|
|
2147
|
+
}) {
|
|
2148
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
2149
|
+
"div",
|
|
2150
|
+
{
|
|
2151
|
+
"aria-busy": "true",
|
|
2152
|
+
"aria-label": ariaLabel,
|
|
2153
|
+
className: cn("fractal-ghost-conversation", className),
|
|
2154
|
+
role: "status",
|
|
2155
|
+
...props,
|
|
2156
|
+
children: [
|
|
2157
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { "aria-hidden": "true", className: "fractal-ghost-conversation__message fractal-ghost-conversation__message--user", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "fractal-ghost-conversation__bubble", children: [
|
|
2158
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(GhostLine, { width: "100%" }),
|
|
2159
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(GhostLine, { width: "86%" }),
|
|
2160
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(GhostLine, { width: "64%" })
|
|
2161
|
+
] }) }),
|
|
2162
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { "aria-hidden": "true", className: "fractal-ghost-conversation__message fractal-ghost-conversation__message--assistant", children: [
|
|
2163
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(GhostLine, { width: "92%" }),
|
|
2164
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(GhostLine, { width: "78%" }),
|
|
2165
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(GhostLine, { width: "58%" })
|
|
2166
|
+
] })
|
|
2167
|
+
]
|
|
2168
|
+
}
|
|
2169
|
+
);
|
|
2170
|
+
}
|
|
2171
|
+
function SortableTableGhost(props) {
|
|
2172
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(DataTableGhost, { ...props });
|
|
2173
|
+
}
|
|
2174
|
+
function SidebarGhost({ className, items = 6, ...props }) {
|
|
2175
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("aside", { "aria-hidden": "true", className: cn("fractal-ghost-sidebar", className), ...props, children: [
|
|
2176
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Ghost, { className: "fractal-ghost-sidebar__brand" }),
|
|
2177
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "fractal-ghost-sidebar__items", children: Array.from({ length: items }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "fractal-ghost-sidebar__item", children: [
|
|
2178
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Ghost, {}),
|
|
2179
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(GhostLine, { width: `${[54, 68, 44, 61][index % 4]}%` })
|
|
2180
|
+
] }, index)) })
|
|
2181
|
+
] });
|
|
2182
|
+
}
|
|
2183
|
+
function ModalGhost({ className, title, lines = 3, ...props }) {
|
|
2184
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(SurfaceGhost, { className: cn("fractal-ghost-modal", className), title, lines, ...props });
|
|
2185
|
+
}
|
|
2186
|
+
function SidePanelGhost({ className, title, lines = 5, ...props }) {
|
|
2187
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(SurfaceGhost, { className: cn("fractal-ghost-side-panel", className), title, lines, ...props });
|
|
2188
|
+
}
|
|
2189
|
+
function SurfaceGhost({ className, title, lines = 3, ...props }) {
|
|
2190
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { "aria-hidden": "true", className: cn("fractal-ghost-surface", className), ...props, children: [
|
|
2191
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "fractal-ghost-surface__header", children: [
|
|
2192
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(GhostLine, { width: "42%" }),
|
|
2193
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Ghost, { className: "fractal-ghost-surface__close" })
|
|
2194
|
+
] }),
|
|
2195
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "fractal-ghost-surface__title", children: title }),
|
|
2196
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "fractal-ghost-stack", children: Array.from({ length: lines }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(GhostLine, { width: index === lines - 1 ? "64%" : "100%" }, index)) })
|
|
2197
|
+
] });
|
|
2198
|
+
}
|
|
2199
|
+
|
|
1058
2200
|
// src/components/Sidebar/Sidebar.tsx
|
|
1059
|
-
var
|
|
1060
|
-
var
|
|
1061
|
-
var Sidebar =
|
|
1062
|
-
({ className, width, style, ...props }, ref) => /* @__PURE__ */ (0,
|
|
2201
|
+
var React15 = __toESM(require("react"), 1);
|
|
2202
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
2203
|
+
var Sidebar = React15.forwardRef(
|
|
2204
|
+
({ className, width, compact = false, style, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
1063
2205
|
"aside",
|
|
1064
2206
|
{
|
|
1065
2207
|
ref,
|
|
1066
2208
|
className: cn("fractal-sidebar", className),
|
|
2209
|
+
"data-compact": compact || void 0,
|
|
1067
2210
|
style: { ...style, ...width ? { "--fractal-sidebar-width": width } : {} },
|
|
1068
2211
|
...props
|
|
1069
2212
|
}
|
|
1070
2213
|
)
|
|
1071
2214
|
);
|
|
1072
2215
|
Sidebar.displayName = "Sidebar";
|
|
1073
|
-
var SidebarHeader =
|
|
1074
|
-
({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
2216
|
+
var SidebarHeader = React15.forwardRef(
|
|
2217
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { ref, className: cn("fractal-sidebar__header", className), ...props })
|
|
1075
2218
|
);
|
|
1076
2219
|
SidebarHeader.displayName = "SidebarHeader";
|
|
1077
|
-
var SidebarBrand =
|
|
1078
|
-
({ className, type = "button", ...props }, ref) => /* @__PURE__ */ (0,
|
|
2220
|
+
var SidebarBrand = React15.forwardRef(
|
|
2221
|
+
({ className, type = "button", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("button", { ref, type, className: cn("fractal-sidebar__brand", className), ...props })
|
|
1079
2222
|
);
|
|
1080
2223
|
SidebarBrand.displayName = "SidebarBrand";
|
|
1081
|
-
|
|
1082
|
-
|
|
2224
|
+
function SidebarAccountMenu({
|
|
2225
|
+
name,
|
|
2226
|
+
items,
|
|
2227
|
+
onSelect,
|
|
2228
|
+
triggerLabel = "Account menu",
|
|
2229
|
+
icon,
|
|
2230
|
+
className
|
|
2231
|
+
}) {
|
|
2232
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
2233
|
+
Dropdown,
|
|
2234
|
+
{
|
|
2235
|
+
align: "left",
|
|
2236
|
+
className: cn("fractal-sidebar__account", className),
|
|
2237
|
+
items,
|
|
2238
|
+
onSelect,
|
|
2239
|
+
panelClassName: "fractal-sidebar__account-panel",
|
|
2240
|
+
selectedValue: "",
|
|
2241
|
+
triggerClassName: "fractal-sidebar__account-trigger",
|
|
2242
|
+
triggerContent: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
|
|
2243
|
+
icon && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "fractal-sidebar__account-icon", "aria-hidden": "true", children: icon }),
|
|
2244
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "fractal-sidebar__account-name", children: name })
|
|
2245
|
+
] }),
|
|
2246
|
+
triggerLabel,
|
|
2247
|
+
triggerVariant: "tertiary"
|
|
2248
|
+
}
|
|
2249
|
+
);
|
|
2250
|
+
}
|
|
2251
|
+
var SidebarNav = React15.forwardRef(
|
|
2252
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("nav", { ref, className: cn("fractal-sidebar__nav", className), ...props })
|
|
1083
2253
|
);
|
|
1084
2254
|
SidebarNav.displayName = "SidebarNav";
|
|
1085
|
-
var SidebarSection =
|
|
1086
|
-
({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
2255
|
+
var SidebarSection = React15.forwardRef(
|
|
2256
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { ref, className: cn("fractal-sidebar__section", className), ...props })
|
|
1087
2257
|
);
|
|
1088
2258
|
SidebarSection.displayName = "SidebarSection";
|
|
1089
|
-
var SidebarNavItem =
|
|
1090
|
-
({ active = false, icon, endAdornment, className, type = "button", children, ...props }, ref) => /* @__PURE__ */ (0,
|
|
2259
|
+
var SidebarNavItem = React15.forwardRef(
|
|
2260
|
+
({ active = false, icon, endAdornment, className, type = "button", children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
1091
2261
|
"button",
|
|
1092
2262
|
{
|
|
1093
2263
|
ref,
|
|
@@ -1097,28 +2267,28 @@ var SidebarNavItem = React10.forwardRef(
|
|
|
1097
2267
|
"aria-current": active ? "page" : void 0,
|
|
1098
2268
|
...props,
|
|
1099
2269
|
children: [
|
|
1100
|
-
icon && /* @__PURE__ */ (0,
|
|
1101
|
-
/* @__PURE__ */ (0,
|
|
1102
|
-
endAdornment && /* @__PURE__ */ (0,
|
|
2270
|
+
icon && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "fractal-sidebar__nav-item-icon", "aria-hidden": "true", children: icon }),
|
|
2271
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "fractal-sidebar__nav-item-label", children }),
|
|
2272
|
+
endAdornment && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "fractal-sidebar__nav-item-end", children: endAdornment })
|
|
1103
2273
|
]
|
|
1104
2274
|
}
|
|
1105
2275
|
)
|
|
1106
2276
|
);
|
|
1107
2277
|
SidebarNavItem.displayName = "SidebarNavItem";
|
|
1108
|
-
var SidebarFooter =
|
|
1109
|
-
({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
2278
|
+
var SidebarFooter = React15.forwardRef(
|
|
2279
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { ref, className: cn("fractal-sidebar__footer", className), ...props })
|
|
1110
2280
|
);
|
|
1111
2281
|
SidebarFooter.displayName = "SidebarFooter";
|
|
1112
2282
|
|
|
1113
2283
|
// src/components/SidePanel/SidePanel.tsx
|
|
1114
2284
|
var import_react_dom2 = require("react-dom");
|
|
1115
|
-
var
|
|
1116
|
-
var
|
|
1117
|
-
function SidePanel({ open, onClose, title, description, children, footer, size = "md", className }) {
|
|
2285
|
+
var import_fractal_icons12 = require("@mirror-physics/fractal-icons");
|
|
2286
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
2287
|
+
function SidePanel({ open, onClose, title, description, children, footer, size = "md", loading = false, loadingLabel = "Loading", className }) {
|
|
1118
2288
|
useEscapeDismiss(80, onClose, open);
|
|
1119
2289
|
if (!open) return null;
|
|
1120
2290
|
return (0, import_react_dom2.createPortal)(
|
|
1121
|
-
/* @__PURE__ */ (0,
|
|
2291
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "fractal-side-panel-overlay", onMouseDown: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
1122
2292
|
"aside",
|
|
1123
2293
|
{
|
|
1124
2294
|
className: cn("fractal-side-panel", `fractal-side-panel--${size}`, className),
|
|
@@ -1127,15 +2297,15 @@ function SidePanel({ open, onClose, title, description, children, footer, size =
|
|
|
1127
2297
|
role: "dialog",
|
|
1128
2298
|
onMouseDown: (event) => event.stopPropagation(),
|
|
1129
2299
|
children: [
|
|
1130
|
-
/* @__PURE__ */ (0,
|
|
1131
|
-
/* @__PURE__ */ (0,
|
|
1132
|
-
/* @__PURE__ */ (0,
|
|
1133
|
-
description && /* @__PURE__ */ (0,
|
|
2300
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("header", { className: "fractal-side-panel__header", children: [
|
|
2301
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "fractal-side-panel__heading", children: [
|
|
2302
|
+
typeof title === "string" ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("h2", { className: "fractal-side-panel__title", children: title }) : /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "fractal-side-panel__title", children: title }),
|
|
2303
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { className: "fractal-side-panel__description", children: description })
|
|
1134
2304
|
] }),
|
|
1135
|
-
/* @__PURE__ */ (0,
|
|
2305
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("button", { type: "button", className: "fractal-side-panel__close", "aria-label": "Close panel", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_fractal_icons12.Close, { size: 18 }) })
|
|
1136
2306
|
] }),
|
|
1137
|
-
/* @__PURE__ */ (0,
|
|
1138
|
-
footer && /* @__PURE__ */ (0,
|
|
2307
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.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_runtime27.jsx)(UILoader, { label: loadingLabel }) : children }),
|
|
2308
|
+
footer && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("footer", { className: "fractal-side-panel__footer", children: footer })
|
|
1139
2309
|
]
|
|
1140
2310
|
}
|
|
1141
2311
|
) }),
|
|
@@ -1144,48 +2314,273 @@ function SidePanel({ open, onClose, title, description, children, footer, size =
|
|
|
1144
2314
|
}
|
|
1145
2315
|
|
|
1146
2316
|
// src/components/Textarea/Textarea.tsx
|
|
1147
|
-
var
|
|
1148
|
-
var
|
|
1149
|
-
var Textarea =
|
|
1150
|
-
({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
2317
|
+
var React16 = __toESM(require("react"), 1);
|
|
2318
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
2319
|
+
var Textarea = React16.forwardRef(
|
|
2320
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("textarea", { ref, className: cn("fractal-textarea", className), ...props })
|
|
1151
2321
|
);
|
|
1152
2322
|
Textarea.displayName = "Textarea";
|
|
2323
|
+
|
|
2324
|
+
// src/components/TextButton/TextButton.tsx
|
|
2325
|
+
var React17 = __toESM(require("react"), 1);
|
|
2326
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
2327
|
+
var TextButton = React17.forwardRef(
|
|
2328
|
+
({ className, icon, iconPosition = "start", size = "md", tone = "primary", children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
2329
|
+
"button",
|
|
2330
|
+
{
|
|
2331
|
+
ref,
|
|
2332
|
+
className: cn("fractal-text-button", `fractal-text-button--${size}`, `fractal-text-button--${tone}`, className),
|
|
2333
|
+
type: "button",
|
|
2334
|
+
...props,
|
|
2335
|
+
children: [
|
|
2336
|
+
icon && iconPosition === "start" && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "fractal-text-button__icon", "aria-hidden": "true", children: icon }),
|
|
2337
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { children }),
|
|
2338
|
+
icon && iconPosition === "end" && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "fractal-text-button__icon", "aria-hidden": "true", children: icon })
|
|
2339
|
+
]
|
|
2340
|
+
}
|
|
2341
|
+
)
|
|
2342
|
+
);
|
|
2343
|
+
TextButton.displayName = "TextButton";
|
|
2344
|
+
|
|
2345
|
+
// src/components/FileDropzone/FileDropzone.tsx
|
|
2346
|
+
var React18 = __toESM(require("react"), 1);
|
|
2347
|
+
var import_fractal_icons13 = require("@mirror-physics/fractal-icons");
|
|
2348
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
2349
|
+
function FileDropzone({
|
|
2350
|
+
files,
|
|
2351
|
+
onFilesChange,
|
|
2352
|
+
accept,
|
|
2353
|
+
multiple = true,
|
|
2354
|
+
disabled = false,
|
|
2355
|
+
title = "Drop files here or click to browse",
|
|
2356
|
+
description = "Files stay attached to this record.",
|
|
2357
|
+
className
|
|
2358
|
+
}) {
|
|
2359
|
+
const inputId = React18.useId();
|
|
2360
|
+
const inputRef = React18.useRef(null);
|
|
2361
|
+
const [isDragging, setIsDragging] = React18.useState(false);
|
|
2362
|
+
const addFiles = (nextFiles) => {
|
|
2363
|
+
if (disabled) return;
|
|
2364
|
+
const additions = Array.from(nextFiles);
|
|
2365
|
+
if (additions.length === 0) return;
|
|
2366
|
+
onFilesChange(multiple ? [...files, ...additions] : additions.slice(0, 1));
|
|
2367
|
+
};
|
|
2368
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: cn("fractal-file-dropzone", className), children: [
|
|
2369
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
2370
|
+
"input",
|
|
2371
|
+
{
|
|
2372
|
+
ref: inputRef,
|
|
2373
|
+
id: inputId,
|
|
2374
|
+
className: "fractal-file-dropzone__input",
|
|
2375
|
+
type: "file",
|
|
2376
|
+
accept,
|
|
2377
|
+
multiple,
|
|
2378
|
+
disabled,
|
|
2379
|
+
onChange: (event) => {
|
|
2380
|
+
if (event.target.files) addFiles(event.target.files);
|
|
2381
|
+
event.target.value = "";
|
|
2382
|
+
}
|
|
2383
|
+
}
|
|
2384
|
+
),
|
|
2385
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
2386
|
+
"button",
|
|
2387
|
+
{
|
|
2388
|
+
className: "fractal-file-dropzone__target",
|
|
2389
|
+
"data-dragging": isDragging || void 0,
|
|
2390
|
+
type: "button",
|
|
2391
|
+
disabled,
|
|
2392
|
+
onClick: () => inputRef.current?.click(),
|
|
2393
|
+
onDragEnter: (event) => {
|
|
2394
|
+
event.preventDefault();
|
|
2395
|
+
if (!disabled) setIsDragging(true);
|
|
2396
|
+
},
|
|
2397
|
+
onDragOver: (event) => event.preventDefault(),
|
|
2398
|
+
onDragLeave: (event) => {
|
|
2399
|
+
event.preventDefault();
|
|
2400
|
+
setIsDragging(false);
|
|
2401
|
+
},
|
|
2402
|
+
onDrop: (event) => {
|
|
2403
|
+
event.preventDefault();
|
|
2404
|
+
setIsDragging(false);
|
|
2405
|
+
addFiles(event.dataTransfer.files);
|
|
2406
|
+
},
|
|
2407
|
+
children: [
|
|
2408
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_fractal_icons13.FileArrowUp, { "aria-hidden": "true", size: 20 }),
|
|
2409
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { className: "fractal-file-dropzone__copy", children: [
|
|
2410
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "fractal-file-dropzone__title", children: title }),
|
|
2411
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "fractal-file-dropzone__description", children: description })
|
|
2412
|
+
] })
|
|
2413
|
+
]
|
|
2414
|
+
}
|
|
2415
|
+
),
|
|
2416
|
+
files.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("ul", { className: "fractal-file-dropzone__files", "aria-label": "Attached files", children: files.map((file, index) => /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("li", { className: "fractal-file-dropzone__file", children: [
|
|
2417
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "fractal-file-dropzone__file-name", children: file.name }),
|
|
2418
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "fractal-file-dropzone__file-meta", children: formatFileSize(file.size) }),
|
|
2419
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
2420
|
+
"button",
|
|
2421
|
+
{
|
|
2422
|
+
className: "fractal-file-dropzone__remove",
|
|
2423
|
+
type: "button",
|
|
2424
|
+
"aria-label": `Remove ${file.name}`,
|
|
2425
|
+
disabled,
|
|
2426
|
+
onClick: () => onFilesChange(files.filter((_, fileIndex) => fileIndex !== index)),
|
|
2427
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_fractal_icons13.Close, { "aria-hidden": "true", size: 14 })
|
|
2428
|
+
}
|
|
2429
|
+
)
|
|
2430
|
+
] }, `${file.name}-${file.size}-${index}`)) })
|
|
2431
|
+
] });
|
|
2432
|
+
}
|
|
2433
|
+
function formatFileSize(bytes) {
|
|
2434
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
2435
|
+
if (bytes < 1024 * 1024) return `${Math.round(bytes / 1024)} KB`;
|
|
2436
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
2437
|
+
}
|
|
2438
|
+
|
|
2439
|
+
// src/components/Pagination/Pagination.tsx
|
|
2440
|
+
var import_fractal_icons14 = require("@mirror-physics/fractal-icons");
|
|
2441
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
2442
|
+
function Pagination({
|
|
2443
|
+
page,
|
|
2444
|
+
pageSize,
|
|
2445
|
+
totalItems,
|
|
2446
|
+
onPageChange,
|
|
2447
|
+
pageSizeOptions,
|
|
2448
|
+
onPageSizeChange,
|
|
2449
|
+
ariaLabel = "Pagination",
|
|
2450
|
+
className
|
|
2451
|
+
}) {
|
|
2452
|
+
const totalPages = Math.max(1, Math.ceil(totalItems / pageSize));
|
|
2453
|
+
const currentPage = Math.min(Math.max(page, 1), totalPages);
|
|
2454
|
+
const start = totalItems === 0 ? 0 : (currentPage - 1) * pageSize + 1;
|
|
2455
|
+
const end = Math.min(currentPage * pageSize, totalItems);
|
|
2456
|
+
const canChangePageSize = pageSizeOptions != null && pageSizeOptions.length > 0 && onPageSizeChange != null;
|
|
2457
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("nav", { className: cn("fractal-pagination", className), "aria-label": ariaLabel, children: [
|
|
2458
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "fractal-pagination__summary", children: totalItems === 0 ? "No results" : `${start}-${end} of ${totalItems}` }),
|
|
2459
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "fractal-pagination__controls", children: [
|
|
2460
|
+
canChangePageSize && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
2461
|
+
Dropdown,
|
|
2462
|
+
{
|
|
2463
|
+
align: "right",
|
|
2464
|
+
className: "fractal-pagination__page-size",
|
|
2465
|
+
direction: "up",
|
|
2466
|
+
items: pageSizeOptions.map((option) => ({
|
|
2467
|
+
value: String(option),
|
|
2468
|
+
description: `${option} per page`
|
|
2469
|
+
})),
|
|
2470
|
+
onSelect: (value) => onPageSizeChange(Number(value)),
|
|
2471
|
+
selectedValue: String(pageSize),
|
|
2472
|
+
size: "sm",
|
|
2473
|
+
triggerLabel: "Results per page",
|
|
2474
|
+
triggerVariant: "tertiary"
|
|
2475
|
+
}
|
|
2476
|
+
),
|
|
2477
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
2478
|
+
"button",
|
|
2479
|
+
{
|
|
2480
|
+
className: "fractal-pagination__button",
|
|
2481
|
+
type: "button",
|
|
2482
|
+
"aria-label": "Previous page",
|
|
2483
|
+
title: "Previous page",
|
|
2484
|
+
disabled: currentPage === 1 || totalItems === 0,
|
|
2485
|
+
onClick: () => onPageChange(currentPage - 1),
|
|
2486
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_fractal_icons14.ArrowLeft, { "aria-hidden": "true", size: 16 })
|
|
2487
|
+
}
|
|
2488
|
+
),
|
|
2489
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("span", { className: "fractal-pagination__page", "aria-current": "page", children: [
|
|
2490
|
+
currentPage,
|
|
2491
|
+
" of ",
|
|
2492
|
+
totalPages
|
|
2493
|
+
] }),
|
|
2494
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
2495
|
+
"button",
|
|
2496
|
+
{
|
|
2497
|
+
className: "fractal-pagination__button",
|
|
2498
|
+
type: "button",
|
|
2499
|
+
"aria-label": "Next page",
|
|
2500
|
+
title: "Next page",
|
|
2501
|
+
disabled: currentPage === totalPages || totalItems === 0,
|
|
2502
|
+
onClick: () => onPageChange(currentPage + 1),
|
|
2503
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_fractal_icons14.ArrowRight, { "aria-hidden": "true", size: 16 })
|
|
2504
|
+
}
|
|
2505
|
+
)
|
|
2506
|
+
] })
|
|
2507
|
+
] });
|
|
2508
|
+
}
|
|
1153
2509
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1154
2510
|
0 && (module.exports = {
|
|
1155
2511
|
Alert,
|
|
1156
2512
|
AlertDescription,
|
|
2513
|
+
AlertGhost,
|
|
1157
2514
|
AlertTitle,
|
|
2515
|
+
Breadcrumbs,
|
|
1158
2516
|
Button,
|
|
2517
|
+
ButtonGhost,
|
|
1159
2518
|
Card,
|
|
1160
2519
|
CardContent,
|
|
1161
2520
|
CardDescription,
|
|
1162
2521
|
CardFooter,
|
|
2522
|
+
CardGhost,
|
|
1163
2523
|
CardHeader,
|
|
1164
2524
|
CardTitle,
|
|
2525
|
+
Checkbox,
|
|
2526
|
+
CheckboxGhost,
|
|
1165
2527
|
Chip,
|
|
2528
|
+
ChipGhost,
|
|
2529
|
+
CodeBlock,
|
|
2530
|
+
ContentSwitcher,
|
|
2531
|
+
ContentSwitcherGhost,
|
|
2532
|
+
ConversationGhost,
|
|
1166
2533
|
DataTable,
|
|
2534
|
+
DataTableGhost,
|
|
1167
2535
|
Disclosure,
|
|
2536
|
+
DisclosureGhost,
|
|
1168
2537
|
Dropdown,
|
|
2538
|
+
DropdownGhost,
|
|
1169
2539
|
FeatureCard,
|
|
2540
|
+
FileDropzone,
|
|
2541
|
+
FileDropzoneGhost,
|
|
1170
2542
|
FolderCard,
|
|
2543
|
+
Ghost,
|
|
2544
|
+
GhostLine,
|
|
1171
2545
|
Input,
|
|
2546
|
+
InputGhost,
|
|
1172
2547
|
Label,
|
|
2548
|
+
LabelGhost,
|
|
2549
|
+
LatticeLoader,
|
|
1173
2550
|
Link,
|
|
2551
|
+
LinkGhost,
|
|
1174
2552
|
Modal,
|
|
2553
|
+
ModalGhost,
|
|
2554
|
+
NumberInput,
|
|
2555
|
+
Pagination,
|
|
2556
|
+
PaginationGhost,
|
|
2557
|
+
PasswordInput,
|
|
1175
2558
|
PromptCard,
|
|
2559
|
+
PromptCardGhost,
|
|
1176
2560
|
PromptGrid,
|
|
1177
2561
|
SidePanel,
|
|
2562
|
+
SidePanelGhost,
|
|
1178
2563
|
Sidebar,
|
|
2564
|
+
SidebarAccountMenu,
|
|
1179
2565
|
SidebarBrand,
|
|
1180
2566
|
SidebarFooter,
|
|
2567
|
+
SidebarGhost,
|
|
1181
2568
|
SidebarHeader,
|
|
1182
2569
|
SidebarNav,
|
|
1183
2570
|
SidebarNavItem,
|
|
1184
2571
|
SidebarSection,
|
|
1185
2572
|
SortableTable,
|
|
2573
|
+
SortableTableGhost,
|
|
2574
|
+
TableSearch,
|
|
1186
2575
|
Tabs,
|
|
2576
|
+
TabsGhost,
|
|
2577
|
+
TextButton,
|
|
2578
|
+
TextButtonGhost,
|
|
1187
2579
|
Textarea,
|
|
2580
|
+
TextareaGhost,
|
|
1188
2581
|
Toggle,
|
|
2582
|
+
ToggleGhost,
|
|
2583
|
+
UILoader,
|
|
1189
2584
|
cn,
|
|
1190
2585
|
useEscapeDismiss
|
|
1191
2586
|
});
|