@sovereignfs/ui 0.23.0 → 0.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Button.module.css +75 -8
- package/dist/Calendar.module.css +126 -0
- package/dist/Card.module.css +4 -2
- package/dist/Checkbox.module.css +14 -2
- package/dist/CodeTextarea.module.css +53 -0
- package/dist/ConfirmDialog.module.css +109 -0
- package/dist/DatePicker.module.css +57 -0
- package/dist/Dialog.module.css +73 -46
- package/dist/DragHandleRow.module.css +9 -3
- package/dist/Drawer.module.css +61 -0
- package/dist/Icon.module.css +5 -0
- package/dist/Menu.module.css +82 -0
- package/dist/NavTabs.module.css +4 -2
- package/dist/OverlayHeader.module.css +98 -0
- package/dist/Popover.module.css +31 -1
- package/dist/SegmentedControl.module.css +4 -2
- package/dist/Sheet.module.css +55 -0
- package/dist/SplitPane.module.css +85 -0
- package/dist/StatusBadge.module.css +59 -0
- package/dist/SystemBanner.module.css +4 -2
- package/dist/Tabs.module.css +4 -2
- package/dist/TagInput.module.css +141 -0
- package/dist/Toast.module.css +4 -2
- package/dist/Tooltip.module.css +6 -1
- package/dist/index.d.ts +493 -17
- package/dist/index.js +1390 -209
- package/dist/tokens/primitives.css +19 -0
- package/dist/tokens/semantic.css +13 -0
- package/package.json +1 -1
- package/src/__tests__/motion.test.tsx +105 -0
- package/src/components/Button/Button.module.css +75 -8
- package/src/components/Button/Button.stories.tsx +6 -0
- package/src/components/Button/Button.tsx +17 -1
- package/src/components/Button/__tests__/Button.test.tsx +19 -0
- package/src/components/Calendar/Calendar.module.css +126 -0
- package/src/components/Calendar/Calendar.tsx +213 -0
- package/src/components/Calendar/__tests__/Calendar.test.tsx +98 -0
- package/src/components/Calendar/dateUtils.ts +97 -0
- package/src/components/Card/Card.module.css +4 -2
- package/src/components/Checkbox/Checkbox.module.css +14 -2
- package/src/components/Checkbox/Checkbox.tsx +22 -12
- package/src/components/CodeTextarea/CodeTextarea.module.css +53 -0
- package/src/components/CodeTextarea/CodeTextarea.stories.tsx +77 -0
- package/src/components/CodeTextarea/CodeTextarea.tsx +36 -0
- package/src/components/ConfirmDialog/ConfirmDialog.module.css +109 -0
- package/src/components/ConfirmDialog/ConfirmDialog.tsx +124 -0
- package/src/components/ConfirmDialog/__tests__/ConfirmDialog.test.tsx +146 -0
- package/src/components/DatePicker/DatePicker.module.css +57 -0
- package/src/components/DatePicker/DatePicker.tsx +103 -0
- package/src/components/DatePicker/__tests__/DatePicker.test.tsx +89 -0
- package/src/components/Dialog/Dialog.module.css +73 -46
- package/src/components/Dialog/Dialog.stories.tsx +51 -1
- package/src/components/Dialog/Dialog.tsx +86 -22
- package/src/components/Dialog/__tests__/Dialog.test.tsx +67 -3
- package/src/components/DragHandleRow/DragHandleRow.module.css +9 -3
- package/src/components/Drawer/Drawer.module.css +61 -0
- package/src/components/Drawer/Drawer.tsx +117 -13
- package/src/components/Drawer/__tests__/Drawer.test.tsx +123 -2
- package/src/components/Icon/Icon.module.css +5 -0
- package/src/components/Icon/Icon.stories.tsx +4 -3
- package/src/components/Icon/Icon.tsx +1 -1
- package/src/components/Icon/icons/calendar.tsx +23 -0
- package/src/components/Icon/icons/ellipsis-vertical.tsx +22 -0
- package/src/components/Icon/icons/index.ts +8 -4
- package/src/components/Icon/icons/sliders-horizontal.tsx +9 -9
- package/src/components/Menu/Menu.module.css +82 -0
- package/src/components/Menu/Menu.tsx +137 -0
- package/src/components/Menu/__tests__/Menu.test.tsx +197 -0
- package/src/components/NavTabs/NavTabs.module.css +4 -2
- package/src/components/OverlayHeader/OverlayHeader.module.css +98 -0
- package/src/components/OverlayHeader/OverlayHeader.tsx +62 -0
- package/src/components/OverlayHeader/__tests__/OverlayHeader.test.tsx +51 -0
- package/src/components/Popover/Popover.module.css +31 -1
- package/src/components/Popover/Popover.stories.tsx +126 -1
- package/src/components/Popover/Popover.tsx +140 -7
- package/src/components/SegmentedControl/SegmentedControl.module.css +4 -2
- package/src/components/Sheet/Sheet.module.css +55 -0
- package/src/components/Sheet/Sheet.tsx +151 -0
- package/src/components/Sheet/__tests__/Sheet.test.tsx +99 -0
- package/src/components/SplitPane/SplitPane.module.css +85 -0
- package/src/components/SplitPane/SplitPane.stories.tsx +160 -0
- package/src/components/SplitPane/SplitPane.tsx +149 -0
- package/src/components/SplitPane/__tests__/SplitPane.test.tsx +51 -0
- package/src/components/StatusBadge/StatusBadge.module.css +59 -0
- package/src/components/StatusBadge/StatusBadge.stories.tsx +74 -0
- package/src/components/StatusBadge/StatusBadge.tsx +65 -0
- package/src/components/SystemBanner/SystemBanner.module.css +4 -2
- package/src/components/Tabs/Tabs.module.css +4 -2
- package/src/components/TagInput/TagInput.module.css +141 -0
- package/src/components/TagInput/TagInput.stories.tsx +109 -0
- package/src/components/TagInput/TagInput.tsx +174 -0
- package/src/components/TagInput/__tests__/TagInput.test.tsx +69 -0
- package/src/components/Toast/Toast.module.css +4 -2
- package/src/components/Tooltip/Tooltip.module.css +6 -1
- package/src/hooks/__tests__/useDoubleTap.test.tsx +117 -0
- package/src/hooks/__tests__/useIsMobile.test.tsx +80 -0
- package/src/hooks/__tests__/useLongPress.test.tsx +158 -0
- package/src/hooks/index.ts +4 -0
- package/src/hooks/useDoubleTap.ts +91 -0
- package/src/hooks/useIsMobile.ts +33 -0
- package/src/hooks/useLongPress.ts +185 -0
- package/src/index.ts +30 -1
- package/src/motion.ts +78 -0
- package/src/stories/DesignSystemOverview.stories.tsx +292 -4
- package/src/stories/InteractionHooks.stories.tsx +388 -0
- package/src/stories/TokenGallery.stories.tsx +85 -1
- package/src/tokens/primitives.css +19 -0
- package/src/tokens/semantic.css +13 -0
- package/src/components/Icon/icons/terminal.tsx +0 -19
|
@@ -11,7 +11,11 @@ import { EmptyState } from '../components/EmptyState/EmptyState';
|
|
|
11
11
|
import { FormField } from '../components/FormField/FormField';
|
|
12
12
|
import { Icon } from '../components/Icon/Icon';
|
|
13
13
|
import { Input } from '../components/Input/Input';
|
|
14
|
+
import { CodeTextarea } from '../components/CodeTextarea/CodeTextarea';
|
|
14
15
|
import { Textarea } from '../components/Textarea/Textarea';
|
|
16
|
+
import { StatusBadge } from '../components/StatusBadge/StatusBadge';
|
|
17
|
+
import { SplitPane } from '../components/SplitPane/SplitPane';
|
|
18
|
+
import { TagInput } from '../components/TagInput/TagInput';
|
|
15
19
|
import { NavTabs } from '../components/NavTabs/NavTabs';
|
|
16
20
|
import { PageHeader } from '../components/PageHeader/PageHeader';
|
|
17
21
|
import { Popover } from '../components/Popover/Popover';
|
|
@@ -25,6 +29,12 @@ import { Toggle } from '../components/Toggle/Toggle';
|
|
|
25
29
|
import { Tooltip } from '../components/Tooltip/Tooltip';
|
|
26
30
|
import { Checkbox } from '../components/Checkbox/Checkbox';
|
|
27
31
|
import { DragHandleRow } from '../components/DragHandleRow/DragHandleRow';
|
|
32
|
+
import { OverlayHeader } from '../components/OverlayHeader/OverlayHeader';
|
|
33
|
+
import { Sheet } from '../components/Sheet/Sheet';
|
|
34
|
+
import { ConfirmDialog } from '../components/ConfirmDialog/ConfirmDialog';
|
|
35
|
+
import { Menu } from '../components/Menu/Menu';
|
|
36
|
+
import { Calendar } from '../components/Calendar/Calendar';
|
|
37
|
+
import { DatePicker } from '../components/DatePicker/DatePicker';
|
|
28
38
|
|
|
29
39
|
// ---------------------------------------------------------------------------
|
|
30
40
|
// Shared primitives
|
|
@@ -170,6 +180,8 @@ const COLOR_GROUPS: Array<{
|
|
|
170
180
|
{ token: '--sv-color-text-muted', name: 'text-muted' },
|
|
171
181
|
{ token: '--sv-color-text-subtle', name: 'text-subtle' },
|
|
172
182
|
{ token: '--sv-color-text-on-accent', name: 'text-on-accent' },
|
|
183
|
+
{ token: '--sv-color-text-on-error', name: 'text-on-error' },
|
|
184
|
+
{ token: '--sv-color-text-on-success', name: 'text-on-success' },
|
|
173
185
|
],
|
|
174
186
|
},
|
|
175
187
|
{
|
|
@@ -197,6 +209,7 @@ const COLOR_GROUPS: Array<{
|
|
|
197
209
|
{ token: '--sv-color-error-surface', name: 'error-surface' },
|
|
198
210
|
{ token: '--sv-color-error-text', name: 'error-text' },
|
|
199
211
|
{ token: '--sv-color-error-border', name: 'error-border' },
|
|
212
|
+
{ token: '--sv-color-error-solid', name: 'error-solid' },
|
|
200
213
|
],
|
|
201
214
|
},
|
|
202
215
|
{
|
|
@@ -215,6 +228,7 @@ const COLOR_GROUPS: Array<{
|
|
|
215
228
|
{ token: '--sv-color-success-surface', name: 'success-surface' },
|
|
216
229
|
{ token: '--sv-color-success-text', name: 'success-text' },
|
|
217
230
|
{ token: '--sv-color-success-border', name: 'success-border' },
|
|
231
|
+
{ token: '--sv-color-success-solid', name: 'success-solid' },
|
|
218
232
|
],
|
|
219
233
|
},
|
|
220
234
|
{
|
|
@@ -548,6 +562,150 @@ function PopoverDemo() {
|
|
|
548
562
|
);
|
|
549
563
|
}
|
|
550
564
|
|
|
565
|
+
function OverlayHeaderDemo() {
|
|
566
|
+
return (
|
|
567
|
+
<div
|
|
568
|
+
style={{
|
|
569
|
+
width: '100%',
|
|
570
|
+
maxWidth: 360,
|
|
571
|
+
border: '1px solid var(--sv-color-border)',
|
|
572
|
+
borderRadius: 'var(--sv-radius-lg)',
|
|
573
|
+
overflow: 'hidden',
|
|
574
|
+
}}
|
|
575
|
+
>
|
|
576
|
+
<OverlayHeader
|
|
577
|
+
title="Edit list"
|
|
578
|
+
onClose={() => {}}
|
|
579
|
+
onBack={() => {}}
|
|
580
|
+
action={
|
|
581
|
+
<Button size="sm" variant="ghost" onClick={() => {}}>
|
|
582
|
+
Save
|
|
583
|
+
</Button>
|
|
584
|
+
}
|
|
585
|
+
/>
|
|
586
|
+
</div>
|
|
587
|
+
);
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
function SheetDemo() {
|
|
591
|
+
const [open, setOpen] = useState(false);
|
|
592
|
+
return (
|
|
593
|
+
<>
|
|
594
|
+
<Button size="sm" onClick={() => setOpen(true)}>
|
|
595
|
+
Open sheet
|
|
596
|
+
</Button>
|
|
597
|
+
{/* Storybook has no --sv-shell-header-height/--sv-shell-footer-height, so
|
|
598
|
+
the panel fills this fixed-height preview box instead of the real
|
|
599
|
+
app's header-to-footer region — same component, just no shell
|
|
600
|
+
around it here. */}
|
|
601
|
+
<div
|
|
602
|
+
style={{
|
|
603
|
+
position: 'relative',
|
|
604
|
+
width: '100%',
|
|
605
|
+
maxWidth: 360,
|
|
606
|
+
height: 280,
|
|
607
|
+
marginTop: 12,
|
|
608
|
+
border: '1px solid var(--sv-color-border)',
|
|
609
|
+
borderRadius: 'var(--sv-radius-lg)',
|
|
610
|
+
overflow: 'hidden',
|
|
611
|
+
}}
|
|
612
|
+
>
|
|
613
|
+
<div style={{ position: 'absolute', inset: 0 }}>
|
|
614
|
+
<Sheet
|
|
615
|
+
open={open}
|
|
616
|
+
onClose={() => setOpen(false)}
|
|
617
|
+
title="Task detail"
|
|
618
|
+
aria-label="Task detail"
|
|
619
|
+
>
|
|
620
|
+
<div
|
|
621
|
+
style={{
|
|
622
|
+
padding: 16,
|
|
623
|
+
fontFamily: ff,
|
|
624
|
+
fontSize: 14,
|
|
625
|
+
color: 'var(--sv-color-text-muted)',
|
|
626
|
+
}}
|
|
627
|
+
>
|
|
628
|
+
Full-page overlay content — same pattern the tasks plugin used for its task-detail and
|
|
629
|
+
list-edit panels.
|
|
630
|
+
</div>
|
|
631
|
+
</Sheet>
|
|
632
|
+
</div>
|
|
633
|
+
</div>
|
|
634
|
+
</>
|
|
635
|
+
);
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
function ConfirmDialogDemo() {
|
|
639
|
+
const [open, setOpen] = useState(false);
|
|
640
|
+
return (
|
|
641
|
+
<>
|
|
642
|
+
<Button size="sm" variant="destructive" onClick={() => setOpen(true)}>
|
|
643
|
+
Remove passkey
|
|
644
|
+
</Button>
|
|
645
|
+
<ConfirmDialog
|
|
646
|
+
open={open}
|
|
647
|
+
onClose={() => setOpen(false)}
|
|
648
|
+
onConfirm={() => setOpen(false)}
|
|
649
|
+
title="Remove passkey"
|
|
650
|
+
message="You will no longer be able to sign in with this passkey."
|
|
651
|
+
confirmLabel="Remove"
|
|
652
|
+
destructive
|
|
653
|
+
/>
|
|
654
|
+
</>
|
|
655
|
+
);
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
function MenuDemo() {
|
|
659
|
+
const [open, setOpen] = useState(false);
|
|
660
|
+
const [sortBy, setSortBy] = useState<'manual' | 'title' | 'due'>('manual');
|
|
661
|
+
return (
|
|
662
|
+
<Menu
|
|
663
|
+
open={open}
|
|
664
|
+
onClose={() => setOpen(false)}
|
|
665
|
+
aria-label="List actions"
|
|
666
|
+
align="left"
|
|
667
|
+
trigger={
|
|
668
|
+
<Button size="sm" variant="ghost" onClick={() => setOpen((o) => !o)}>
|
|
669
|
+
<Icon name="settings" size="sm" aria-hidden /> Actions
|
|
670
|
+
</Button>
|
|
671
|
+
}
|
|
672
|
+
items={[
|
|
673
|
+
{ type: 'label', label: 'Sort by' },
|
|
674
|
+
{ label: 'Manual', checked: sortBy === 'manual', onSelect: () => setSortBy('manual') },
|
|
675
|
+
{ label: 'Title', checked: sortBy === 'title', onSelect: () => setSortBy('title') },
|
|
676
|
+
{ label: 'Due date', checked: sortBy === 'due', onSelect: () => setSortBy('due') },
|
|
677
|
+
{ type: 'separator' },
|
|
678
|
+
{ label: 'Rename', icon: 'pencil', onSelect: () => {} },
|
|
679
|
+
{ label: 'Duplicate', icon: 'plus', onSelect: () => {} },
|
|
680
|
+
{ label: 'Delete', icon: 'trash-2', destructive: true, onSelect: () => {} },
|
|
681
|
+
]}
|
|
682
|
+
/>
|
|
683
|
+
);
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
function CalendarDemo() {
|
|
687
|
+
const [value, setValue] = useState<Date | null>(new Date());
|
|
688
|
+
return (
|
|
689
|
+
<div style={{ width: '100%', maxWidth: 320 }}>
|
|
690
|
+
<Calendar value={value} onChange={setValue} aria-label="Example calendar" />
|
|
691
|
+
</div>
|
|
692
|
+
);
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
function DatePickerDemo() {
|
|
696
|
+
const [value, setValue] = useState<Date | null>(null);
|
|
697
|
+
return (
|
|
698
|
+
<div style={{ width: '100%', maxWidth: 240 }}>
|
|
699
|
+
<DatePicker
|
|
700
|
+
value={value}
|
|
701
|
+
onChange={setValue}
|
|
702
|
+
aria-label="Due date"
|
|
703
|
+
placeholder="Select date"
|
|
704
|
+
/>
|
|
705
|
+
</div>
|
|
706
|
+
);
|
|
707
|
+
}
|
|
708
|
+
|
|
551
709
|
function ToastDemo() {
|
|
552
710
|
const { show } = useToast();
|
|
553
711
|
return (
|
|
@@ -567,6 +725,11 @@ function ToastDemo() {
|
|
|
567
725
|
);
|
|
568
726
|
}
|
|
569
727
|
|
|
728
|
+
function TagInputDemo() {
|
|
729
|
+
const [tags, setTags] = useState(['draft', 'frontmatter']);
|
|
730
|
+
return <TagInput value={tags} onChange={setTags} aria-label="Tags" />;
|
|
731
|
+
}
|
|
732
|
+
|
|
570
733
|
// ---------------------------------------------------------------------------
|
|
571
734
|
// Main component
|
|
572
735
|
// ---------------------------------------------------------------------------
|
|
@@ -1184,7 +1347,7 @@ font-weight: var(--sv-font-weight-bold); /* 700 */`}</Code>
|
|
|
1184
1347
|
<section style={{ marginBottom: 'var(--sv-space-12)' }}>
|
|
1185
1348
|
<SectionHeader
|
|
1186
1349
|
title="Component gallery"
|
|
1187
|
-
subtitle="All
|
|
1350
|
+
subtitle="All 22 components — click each story in the sidebar for the full API, variants, and controls."
|
|
1188
1351
|
/>
|
|
1189
1352
|
|
|
1190
1353
|
<div style={{ marginBottom: 'var(--sv-space-6)' }}>
|
|
@@ -1206,7 +1369,7 @@ font-weight: var(--sv-font-weight-bold); /* 700 */`}</Code>
|
|
|
1206
1369
|
<ComponentCard
|
|
1207
1370
|
name="Button"
|
|
1208
1371
|
importLine="import { Button } from '@sovereignfs/ui';"
|
|
1209
|
-
usage="Primary interactive control. Four variants: primary, secondary, ghost, destructive. Two sizes: md (default), sm."
|
|
1372
|
+
usage="Primary interactive control. Four variants: primary, secondary, ghost, destructive. Two sizes: md (default), sm. loading disables the button, sets aria-busy, and shows a spinner. 44px min-height under (pointer: coarse); hover behind (hover: hover)."
|
|
1210
1373
|
>
|
|
1211
1374
|
<Button>Primary</Button>
|
|
1212
1375
|
<Button variant="secondary">Secondary</Button>
|
|
@@ -1214,6 +1377,7 @@ font-weight: var(--sv-font-weight-bold); /* 700 */`}</Code>
|
|
|
1214
1377
|
<Button variant="destructive" size="sm">
|
|
1215
1378
|
Delete
|
|
1216
1379
|
</Button>
|
|
1380
|
+
<Button loading>Saving…</Button>
|
|
1217
1381
|
</ComponentCard>
|
|
1218
1382
|
|
|
1219
1383
|
{/* Badge */}
|
|
@@ -1232,6 +1396,18 @@ font-weight: var(--sv-font-weight-bold); /* 700 */`}</Code>
|
|
|
1232
1396
|
<Badge variant="mono">v1.2.0</Badge>
|
|
1233
1397
|
</ComponentCard>
|
|
1234
1398
|
|
|
1399
|
+
{/* StatusBadge */}
|
|
1400
|
+
<ComponentCard
|
|
1401
|
+
name="StatusBadge"
|
|
1402
|
+
importLine="import { StatusBadge } from '@sovereignfs/ui';"
|
|
1403
|
+
usage="Inline status indicator for editor sync, draft, conflict, and delete-pending states. RSC-safe."
|
|
1404
|
+
>
|
|
1405
|
+
<StatusBadge status="draft" />
|
|
1406
|
+
<StatusBadge status="synced" />
|
|
1407
|
+
<StatusBadge status="conflict" />
|
|
1408
|
+
<StatusBadge status="pending-delete" />
|
|
1409
|
+
</ComponentCard>
|
|
1410
|
+
|
|
1235
1411
|
{/* Input */}
|
|
1236
1412
|
<ComponentCard
|
|
1237
1413
|
name="Input"
|
|
@@ -1244,6 +1420,15 @@ font-weight: var(--sv-font-weight-bold); /* 700 */`}</Code>
|
|
|
1244
1420
|
</div>
|
|
1245
1421
|
</ComponentCard>
|
|
1246
1422
|
|
|
1423
|
+
{/* TagInput */}
|
|
1424
|
+
<ComponentCard
|
|
1425
|
+
name="TagInput"
|
|
1426
|
+
importLine="import { TagInput } from '@sovereignfs/ui';"
|
|
1427
|
+
usage="Controlled multi-value input for tags and frontmatter arrays. Enter/comma adds, Backspace removes, paste can split multiple tags."
|
|
1428
|
+
>
|
|
1429
|
+
<TagInputDemo />
|
|
1430
|
+
</ComponentCard>
|
|
1431
|
+
|
|
1247
1432
|
{/* Select */}
|
|
1248
1433
|
<ComponentCard
|
|
1249
1434
|
name="Select"
|
|
@@ -1331,11 +1516,38 @@ font-weight: var(--sv-font-weight-bold); /* 700 */`}</Code>
|
|
|
1331
1516
|
<ComponentCard
|
|
1332
1517
|
name="Drawer"
|
|
1333
1518
|
importLine="import { Drawer } from '@sovereignfs/ui';"
|
|
1334
|
-
usage="Bottom-sheet panel
|
|
1519
|
+
usage="Bottom-sheet panel. Esc, scrim-click, or swipe-down on the built-in grab handle to dismiss. snapHeight: 'content' (default, capped 80dvh) or 'half' (fixed 50dvh). Respects safe-area-inset-bottom."
|
|
1335
1520
|
>
|
|
1336
1521
|
<DrawerDemo />
|
|
1337
1522
|
</ComponentCard>
|
|
1338
1523
|
|
|
1524
|
+
{/* OverlayHeader */}
|
|
1525
|
+
<ComponentCard
|
|
1526
|
+
name="OverlayHeader"
|
|
1527
|
+
importLine="import { OverlayHeader } from '@sovereignfs/ui';"
|
|
1528
|
+
usage="Shared fixed secondary header for Dialog's mobile mode, Sheet, and Drawer: title + close, optional back button, trailing action, and a second row for tab strips."
|
|
1529
|
+
>
|
|
1530
|
+
<OverlayHeaderDemo />
|
|
1531
|
+
</ComponentCard>
|
|
1532
|
+
|
|
1533
|
+
{/* Sheet */}
|
|
1534
|
+
<ComponentCard
|
|
1535
|
+
name="Sheet"
|
|
1536
|
+
importLine="import { Sheet } from '@sovereignfs/ui';"
|
|
1537
|
+
usage="Full-page overlay filling a plugin's content area between the shell header and footer — for detail views (task detail, list edit). No desktop equivalent; a desktop layout shows the same content inline instead."
|
|
1538
|
+
>
|
|
1539
|
+
<SheetDemo />
|
|
1540
|
+
</ComponentCard>
|
|
1541
|
+
|
|
1542
|
+
{/* ConfirmDialog */}
|
|
1543
|
+
<ComponentCard
|
|
1544
|
+
name="ConfirmDialog"
|
|
1545
|
+
importLine="import { ConfirmDialog } from '@sovereignfs/ui';"
|
|
1546
|
+
usage="Small, content-sized confirm/cancel prompt. Same presentation on desktop and mobile — not a full-screen sheet. destructive for a solid red confirm action; pending + error for an async onConfirm."
|
|
1547
|
+
>
|
|
1548
|
+
<ConfirmDialogDemo />
|
|
1549
|
+
</ComponentCard>
|
|
1550
|
+
|
|
1339
1551
|
{/* Popover */}
|
|
1340
1552
|
<ComponentCard
|
|
1341
1553
|
name="Popover"
|
|
@@ -1345,6 +1557,33 @@ font-weight: var(--sv-font-weight-bold); /* 700 */`}</Code>
|
|
|
1345
1557
|
<PopoverDemo />
|
|
1346
1558
|
</ComponentCard>
|
|
1347
1559
|
|
|
1560
|
+
{/* Menu */}
|
|
1561
|
+
<ComponentCard
|
|
1562
|
+
name="Menu"
|
|
1563
|
+
importLine="import { Menu } from '@sovereignfs/ui';"
|
|
1564
|
+
usage="Adaptive action menu: Popover on desktop, Drawer on mobile. Same items list renders in both — for '⋯' row/list actions. Entries can be a plain item, a { type: 'label' } section heading, a { type: 'separator' } divider, or a checkable item (pass checked on every item in the group) for a mutually-exclusive set like sort order."
|
|
1565
|
+
>
|
|
1566
|
+
<MenuDemo />
|
|
1567
|
+
</ComponentCard>
|
|
1568
|
+
|
|
1569
|
+
{/* Calendar */}
|
|
1570
|
+
<ComponentCard
|
|
1571
|
+
name="Calendar"
|
|
1572
|
+
importLine="import { Calendar } from '@sovereignfs/ui';"
|
|
1573
|
+
usage="Keyboard-navigable month grid. Date-only (no time/range yet). Arrow keys, Home/End, PageUp/PageDown, Enter/Space to select."
|
|
1574
|
+
>
|
|
1575
|
+
<CalendarDemo />
|
|
1576
|
+
</ComponentCard>
|
|
1577
|
+
|
|
1578
|
+
{/* DatePicker */}
|
|
1579
|
+
<ComponentCard
|
|
1580
|
+
name="DatePicker"
|
|
1581
|
+
importLine="import { DatePicker } from '@sovereignfs/ui';"
|
|
1582
|
+
usage="Form field pairing a trigger with Calendar: Popover on desktop, Drawer on mobile. Built-in trigger, unlike Menu's caller-supplied one."
|
|
1583
|
+
>
|
|
1584
|
+
<DatePickerDemo />
|
|
1585
|
+
</ComponentCard>
|
|
1586
|
+
|
|
1348
1587
|
{/* SystemBanner */}
|
|
1349
1588
|
<ComponentCard
|
|
1350
1589
|
name="SystemBanner"
|
|
@@ -1412,6 +1651,55 @@ font-weight: var(--sv-font-weight-bold); /* 700 */`}</Code>
|
|
|
1412
1651
|
/>
|
|
1413
1652
|
</ComponentCard>
|
|
1414
1653
|
|
|
1654
|
+
{/* CodeTextarea */}
|
|
1655
|
+
<ComponentCard
|
|
1656
|
+
name="CodeTextarea"
|
|
1657
|
+
importLine="import { CodeTextarea } from '@sovereignfs/ui';"
|
|
1658
|
+
usage="Monospace textarea for Markdown, YAML, JSON, and raw frontmatter editing. Pair with FormField for labels and validation."
|
|
1659
|
+
>
|
|
1660
|
+
<CodeTextarea
|
|
1661
|
+
aria-label="YAML source"
|
|
1662
|
+
defaultValue={'title: Release notes\ntags:\n - launch'}
|
|
1663
|
+
rows={5}
|
|
1664
|
+
style={{ width: '100%' }}
|
|
1665
|
+
/>
|
|
1666
|
+
</ComponentCard>
|
|
1667
|
+
|
|
1668
|
+
{/* SplitPane */}
|
|
1669
|
+
<ComponentCard
|
|
1670
|
+
name="SplitPane"
|
|
1671
|
+
importLine="import { SplitPane } from '@sovereignfs/ui';"
|
|
1672
|
+
usage="Responsive editor/preview or list/detail layout. Desktop panes are resizable with pointer and keyboard controls; mobile stacks to one column."
|
|
1673
|
+
>
|
|
1674
|
+
<SplitPane
|
|
1675
|
+
defaultPrimarySize={44}
|
|
1676
|
+
primary={
|
|
1677
|
+
<div
|
|
1678
|
+
style={{
|
|
1679
|
+
padding: 'var(--sv-space-3)',
|
|
1680
|
+
fontFamily: ffm,
|
|
1681
|
+
fontSize: 'var(--sv-font-size-xs)',
|
|
1682
|
+
color: 'var(--sv-color-text-primary)',
|
|
1683
|
+
}}
|
|
1684
|
+
>
|
|
1685
|
+
# Draft
|
|
1686
|
+
</div>
|
|
1687
|
+
}
|
|
1688
|
+
secondary={
|
|
1689
|
+
<div
|
|
1690
|
+
style={{
|
|
1691
|
+
padding: 'var(--sv-space-3)',
|
|
1692
|
+
fontFamily: ff,
|
|
1693
|
+
fontSize: 'var(--sv-font-size-sm)',
|
|
1694
|
+
color: 'var(--sv-color-text-primary)',
|
|
1695
|
+
}}
|
|
1696
|
+
>
|
|
1697
|
+
Draft preview
|
|
1698
|
+
</div>
|
|
1699
|
+
}
|
|
1700
|
+
/>
|
|
1701
|
+
</ComponentCard>
|
|
1702
|
+
|
|
1415
1703
|
{/* PageHeader */}
|
|
1416
1704
|
<ComponentCard
|
|
1417
1705
|
name="PageHeader"
|
|
@@ -1514,7 +1802,7 @@ font-weight: var(--sv-font-weight-bold); /* 700 */`}</Code>
|
|
|
1514
1802
|
<ComponentCard
|
|
1515
1803
|
name="Checkbox"
|
|
1516
1804
|
importLine="import { Checkbox } from '@sovereignfs/ui';"
|
|
1517
|
-
usage="Accessible checkbox with optional animated strike-through on the label when checked. Used in task lists."
|
|
1805
|
+
usage="Accessible checkbox with optional animated strike-through on the label when checked. Used in task lists. Tap target expands to 44px under (pointer: coarse) without growing the visible 18px box."
|
|
1518
1806
|
>
|
|
1519
1807
|
{(() => {
|
|
1520
1808
|
const [a, setA] = useState(false);
|