@ramme-io/ui 4.0.1 → 4.1.1
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/README.md +159 -7
- package/dist/blocks/ai/Actions.js +2 -2
- package/dist/blocks/ai/PromptInput.js +6 -6
- package/dist/component-registry.js +389 -359
- package/dist/components/ai/AIChatThread/AIChatThread.js +81 -73
- package/dist/components/ai/ArchitectureReferenceCard/ArchitectureReferenceCard.d.ts +28 -0
- package/dist/components/ai/ArchitectureReferenceCard/ArchitectureReferenceCard.js +70 -0
- package/dist/components/ai/ArchitectureReferenceCard/index.d.ts +2 -0
- package/dist/components/ai/CounterpartyGraphCard/CounterpartyGraphCard.d.ts +30 -0
- package/dist/components/ai/CounterpartyGraphCard/CounterpartyGraphCard.js +82 -0
- package/dist/components/ai/CounterpartyGraphCard/index.d.ts +2 -0
- package/dist/components/ai/DivergenceMetricsCard/DivergenceMetricsCard.d.ts +29 -0
- package/dist/components/ai/DivergenceMetricsCard/DivergenceMetricsCard.js +69 -0
- package/dist/components/ai/DivergenceMetricsCard/index.d.ts +2 -0
- package/dist/components/ai/KeyInjectionOverlay.d.ts +10 -0
- package/dist/components/ai/KeyInjectionOverlay.js +11 -11
- package/dist/components/ai/NewsSummaryCard/NewsSummaryCard.js +17 -17
- package/dist/components/ai/StockChart/StockChart.js +4 -4
- package/dist/components/auth/AuthLayout.js +4 -4
- package/dist/components/auth/LoginPage.d.ts +22 -0
- package/dist/components/auth/LoginPage.js +50 -42
- package/dist/components/data-display/CodeBlock.d.ts +33 -7
- package/dist/components/data-display/CodeBlock.js +134 -41
- package/dist/components/data-display/Table.js +8 -8
- package/dist/components/feedback/EmptyState.js +9 -9
- package/dist/components/feedback/ToastProvider.js +4 -4
- package/dist/components/forms/Checkbox.js +5 -5
- package/dist/components/forms/ComboBox.js +2 -2
- package/dist/components/forms/DatePicker.js +37 -32
- package/dist/components/forms/FileUpload.js +39 -37
- package/dist/components/forms/Input.js +19 -18
- package/dist/components/forms/MultiSelect.js +9 -8
- package/dist/components/forms/Radio.js +6 -6
- package/dist/components/forms/SegmentedControl.d.ts +1 -1
- package/dist/components/forms/SegmentedControl.js +28 -11
- package/dist/components/forms/Select.js +9 -8
- package/dist/components/forms/Textarea.d.ts +13 -11
- package/dist/components/forms/Textarea.js +36 -16
- package/dist/components/forms/ToggleSwitch.js +9 -9
- package/dist/components/layout/AboutRamme.d.ts +8 -0
- package/dist/components/layout/Accordion.js +25 -32
- package/dist/components/layout/AppShell.js +7 -7
- package/dist/components/layout/Card.js +38 -21
- package/dist/components/layout/DetailDrawer.js +37 -38
- package/dist/components/layout/Drawer.js +50 -51
- package/dist/components/layout/List.js +9 -9
- package/dist/components/layout/Modal.js +5 -5
- package/dist/components/layout/PageHeader.js +7 -7
- package/dist/components/layout/SectionHeader.js +4 -4
- package/dist/components/layout/SettingsContainer.d.ts +12 -0
- package/dist/components/layout/SettingsContainer.js +30 -18
- package/dist/components/layout/Sheet.d.ts +58 -0
- package/dist/components/layout/Sheet.js +144 -0
- package/dist/components/layout/Sidebar.js +1 -1
- package/dist/components/layout/UserNav.d.ts +13 -0
- package/dist/components/layout/UserNav.js +17 -17
- package/dist/components/molecular/ConnectorOverlay.d.ts +12 -0
- package/dist/components/navigation/Breadcrumbs.js +8 -8
- package/dist/components/navigation/Menu.js +6 -6
- package/dist/components/navigation/MobileNav.d.ts +44 -1
- package/dist/components/navigation/MobileNav.js +97 -71
- package/dist/components/navigation/Pagination.js +46 -41
- package/dist/components/navigation/Stepper.js +17 -17
- package/dist/components/navigation/Tabs.js +18 -11
- package/dist/components/theme/ThemeLab.d.ts +7 -1
- package/dist/components/theme/ThemeLab.js +175 -154
- package/dist/components/ui/icon-loader.d.ts +1 -1
- package/dist/contexts/ThemeContext.js +111 -82
- package/dist/data/mockData.d.ts +0 -3
- package/dist/index.css +1 -1
- package/dist/index.d.ts +10 -0
- package/dist/index.js +222 -197
- package/dist/lib/hooks/useBodyScrollLock.d.ts +27 -0
- package/dist/lib/hooks/useBodyScrollLock.js +18 -0
- package/dist/lib/hooks/useSheetGesture.d.ts +81 -0
- package/dist/lib/hooks/useSheetGesture.js +70 -0
- package/dist/lib/theme/themeUtils.d.ts +21 -0
- package/dist/lib/theme/themeUtils.js +31 -17
- package/dist/setupTests.d.ts +1 -0
- package/dist/wizardManifest.js +364 -19
- package/package.json +10 -4
- package/src/wizardManifest.ts +364 -19
- package/tailwind.preset.js +98 -10
package/src/wizardManifest.ts
CHANGED
|
@@ -402,6 +402,25 @@ export const wizardManifest: WizardManifest = {
|
|
|
402
402
|
"humanLabel": "AIChatThread",
|
|
403
403
|
"humanDescription": "A complete chat surface — message history, streaming indicator, error banner, provider/model attribution, and the composer. Strategic purpose: the presentational half of a chat feature, driven entirely by props from kernel's useRammeAI(). It holds no transport of its own, and takes a `renderMessage` override so products can add markdown or rich rendering without pulling those deps into @ramme-io/ui."
|
|
404
404
|
},
|
|
405
|
+
{
|
|
406
|
+
"id": "architecture-reference-card",
|
|
407
|
+
"name": "ArchitectureReferenceCard",
|
|
408
|
+
"version": "1.0.0",
|
|
409
|
+
"description": "AI-generated card summarizing this platform's own data architecture — stack, data model, AI pipelines, and sentinel fleet",
|
|
410
|
+
"tags": [
|
|
411
|
+
"ai",
|
|
412
|
+
"architecture",
|
|
413
|
+
"reference",
|
|
414
|
+
"generative-ui"
|
|
415
|
+
],
|
|
416
|
+
"category": "ai",
|
|
417
|
+
"props": [],
|
|
418
|
+
"importPath": "./components/ai/ArchitectureReferenceCard/ArchitectureReferenceCard",
|
|
419
|
+
"filePath": "src/components/ai/ArchitectureReferenceCard/ArchitectureReferenceCard.tsx",
|
|
420
|
+
"sku": "@molecule/ai/architecture-reference-card",
|
|
421
|
+
"humanLabel": "ArchitectureReferenceCard",
|
|
422
|
+
"humanDescription": "AI-generated card summarizing this platform's own data architecture — stack, data model, AI pipelines, and sentinel fleet"
|
|
423
|
+
},
|
|
405
424
|
{
|
|
406
425
|
"id": "company-profile-card",
|
|
407
426
|
"name": "CompanyProfileCard",
|
|
@@ -429,6 +448,77 @@ export const wizardManifest: WizardManifest = {
|
|
|
429
448
|
"humanLabel": "CompanyProfileCard",
|
|
430
449
|
"humanDescription": "A company summary for a ticker — sector, industry, and description — fetched on demand and cached. Strategic purpose: a generative-UI block an AI tool call can render directly into a chat thread. Surfaces its own provenance, distinguishing a live fetch from a cached or stale answer instead of presenting all three as equally fresh."
|
|
431
450
|
},
|
|
451
|
+
{
|
|
452
|
+
"id": "counterparty-graph-card",
|
|
453
|
+
"name": "CounterpartyGraphCard",
|
|
454
|
+
"version": "1.0.0",
|
|
455
|
+
"description": "AI-generated counterparty relationship card showing suppliers, customers, partners, and competitors inferred from alternative signals",
|
|
456
|
+
"tags": [
|
|
457
|
+
"ai",
|
|
458
|
+
"counterparty",
|
|
459
|
+
"graph",
|
|
460
|
+
"relationships",
|
|
461
|
+
"generative-ui"
|
|
462
|
+
],
|
|
463
|
+
"category": "ai",
|
|
464
|
+
"props": [],
|
|
465
|
+
"importPath": "./components/ai/CounterpartyGraphCard/CounterpartyGraphCard",
|
|
466
|
+
"filePath": "src/components/ai/CounterpartyGraphCard/CounterpartyGraphCard.tsx",
|
|
467
|
+
"sku": "@molecule/ai/counterparty-graph-card",
|
|
468
|
+
"humanLabel": "CounterpartyGraphCard",
|
|
469
|
+
"humanDescription": "AI-generated counterparty relationship card showing suppliers, customers, partners, and competitors inferred from alternative signals"
|
|
470
|
+
},
|
|
471
|
+
{
|
|
472
|
+
"id": "divergence-metrics-card",
|
|
473
|
+
"name": "DivergenceMetricsCard",
|
|
474
|
+
"version": "1.0.0",
|
|
475
|
+
"description": "AI-generated card showing operational and customer divergence scores — a signed delta between expected and observed performance",
|
|
476
|
+
"tags": [
|
|
477
|
+
"ai",
|
|
478
|
+
"divergence",
|
|
479
|
+
"metrics",
|
|
480
|
+
"generative-ui"
|
|
481
|
+
],
|
|
482
|
+
"category": "ai",
|
|
483
|
+
"props": [],
|
|
484
|
+
"importPath": "./components/ai/DivergenceMetricsCard/DivergenceMetricsCard",
|
|
485
|
+
"filePath": "src/components/ai/DivergenceMetricsCard/DivergenceMetricsCard.tsx",
|
|
486
|
+
"sku": "@molecule/ai/divergence-metrics-card",
|
|
487
|
+
"humanLabel": "DivergenceMetricsCard",
|
|
488
|
+
"humanDescription": "AI-generated card showing operational and customer divergence scores — a signed delta between expected and observed performance"
|
|
489
|
+
},
|
|
490
|
+
{
|
|
491
|
+
"id": "key-injection-overlay",
|
|
492
|
+
"name": "KeyInjectionOverlay",
|
|
493
|
+
"version": "1.0.0",
|
|
494
|
+
"description": "Blocks the app and collects an AI provider key when the gateway reports one is missing or expired. Strategic purpose: the BYOK prompt, in one place, so a key request looks the same everywhere and never becomes an inline form somebody rebuilds per feature. Renders nothing unless status is 'BYOK_REQUIRED' or 'KEY_EXPIRED', so it can stay mounted at the shell level.",
|
|
495
|
+
"tags": [
|
|
496
|
+
"ai",
|
|
497
|
+
"byok",
|
|
498
|
+
"overlay",
|
|
499
|
+
"auth",
|
|
500
|
+
"gateway",
|
|
501
|
+
"key"
|
|
502
|
+
],
|
|
503
|
+
"category": "ai",
|
|
504
|
+
"props": [
|
|
505
|
+
{
|
|
506
|
+
"name": "status",
|
|
507
|
+
"type": "string",
|
|
508
|
+
"description": "Gateway status. The overlay shows only for 'BYOK_REQUIRED' or 'KEY_EXPIRED'."
|
|
509
|
+
},
|
|
510
|
+
{
|
|
511
|
+
"name": "setSessionKey",
|
|
512
|
+
"type": "function",
|
|
513
|
+
"description": "Receives the entered key when the form is submitted."
|
|
514
|
+
}
|
|
515
|
+
],
|
|
516
|
+
"importPath": "./components/ai/KeyInjectionOverlay",
|
|
517
|
+
"filePath": "src/components/ai/KeyInjectionOverlay.tsx",
|
|
518
|
+
"sku": "@molecule/ai/key-injection-overlay",
|
|
519
|
+
"humanLabel": "KeyInjectionOverlay",
|
|
520
|
+
"humanDescription": "Blocks the app and collects an AI provider key when the gateway reports one is missing or expired. Strategic purpose: the BYOK prompt, in one place, so a key request looks the same everywhere and never becomes an inline form somebody rebuilds per feature. Renders nothing unless status is 'BYOK_REQUIRED' or 'KEY_EXPIRED', so it can stay mounted at the shell level."
|
|
521
|
+
},
|
|
432
522
|
{
|
|
433
523
|
"id": "live-quote-card",
|
|
434
524
|
"name": "LiveQuoteCard",
|
|
@@ -510,7 +600,7 @@ export const wizardManifest: WizardManifest = {
|
|
|
510
600
|
{
|
|
511
601
|
"id": "login-page",
|
|
512
602
|
"name": "LoginPage",
|
|
513
|
-
"version": "1.0.
|
|
603
|
+
"version": "1.0.1",
|
|
514
604
|
"description": "The standard sign-in screen — email and password, with inline error and loading states already wired. Strategic purpose: a drop-in credential form so products don't rebuild one; `quickProfiles` adds one-click demo personas, which is what makes a prototype instantly explorable without real accounts.",
|
|
515
605
|
"tags": [
|
|
516
606
|
"auth",
|
|
@@ -540,6 +630,21 @@ export const wizardManifest: WizardManifest = {
|
|
|
540
630
|
"name": "quickProfiles",
|
|
541
631
|
"type": "Array<QuickProfile>",
|
|
542
632
|
"description": "Optional one-click demo identities, each `{ name, email, role }`."
|
|
633
|
+
},
|
|
634
|
+
{
|
|
635
|
+
"name": "signupHref",
|
|
636
|
+
"type": "string",
|
|
637
|
+
"description": "Where \"Create one\" points. Pass `null` to hide that line entirely, which is what an invite-only product wants. Defaults to `/auth/signup`."
|
|
638
|
+
},
|
|
639
|
+
{
|
|
640
|
+
"name": "signupLabel",
|
|
641
|
+
"type": "string",
|
|
642
|
+
"description": "Text for that link. Defaults to \"Create one\"."
|
|
643
|
+
},
|
|
644
|
+
{
|
|
645
|
+
"name": "forgotHref",
|
|
646
|
+
"type": "string",
|
|
647
|
+
"description": "Where \"Forgot?\" points. Pass `null` to hide it — a product with no reset email has nothing to link to. Defaults to `#`."
|
|
543
648
|
}
|
|
544
649
|
],
|
|
545
650
|
"importPath": "./components/auth/LoginPage",
|
|
@@ -755,31 +860,58 @@ export const wizardManifest: WizardManifest = {
|
|
|
755
860
|
{
|
|
756
861
|
"id": "code-block",
|
|
757
862
|
"name": "CodeBlock",
|
|
758
|
-
"version": "1.0.
|
|
759
|
-
"description": "
|
|
863
|
+
"version": "1.0.1",
|
|
864
|
+
"description": "The one way to show code. Syntax-highlighted, theme-aware, with a copy button that works on touch and outside secure contexts. Use for every snippet in docs and tutorials — do not hand-roll a <pre>. Long lines scroll inside the block so the page never scrolls sideways on a phone.",
|
|
760
865
|
"tags": [
|
|
761
866
|
"ui",
|
|
762
867
|
"data-display",
|
|
763
|
-
"code"
|
|
868
|
+
"code",
|
|
869
|
+
"docs",
|
|
870
|
+
"tutorial"
|
|
764
871
|
],
|
|
765
872
|
"category": "ui",
|
|
766
873
|
"props": [
|
|
767
874
|
{
|
|
768
875
|
"name": "code",
|
|
769
876
|
"type": "string",
|
|
770
|
-
"description": "The
|
|
877
|
+
"description": "The snippet to display. Outer blank lines are trimmed."
|
|
771
878
|
},
|
|
772
879
|
{
|
|
773
880
|
"name": "language",
|
|
774
881
|
"type": "string",
|
|
775
|
-
"description": "
|
|
882
|
+
"description": "Prism language id — 'tsx', 'bash', 'css', 'json'. Defaults to 'tsx'."
|
|
883
|
+
},
|
|
884
|
+
{
|
|
885
|
+
"name": "filename",
|
|
886
|
+
"type": "string",
|
|
887
|
+
"description": "Header label. Prefer a real path like 'src/App.tsx'; falls back to the language."
|
|
888
|
+
},
|
|
889
|
+
{
|
|
890
|
+
"name": "showLineNumbers",
|
|
891
|
+
"type": "boolean",
|
|
892
|
+
"description": "Show gutter line numbers. Use when the surrounding prose cites line numbers."
|
|
893
|
+
},
|
|
894
|
+
{
|
|
895
|
+
"name": "highlightLines",
|
|
896
|
+
"type": "number[]",
|
|
897
|
+
"description": "1-based lines to emphasise, for \"change this line\" steps."
|
|
898
|
+
},
|
|
899
|
+
{
|
|
900
|
+
"name": "wrap",
|
|
901
|
+
"type": "boolean",
|
|
902
|
+
"description": "Wrap long lines instead of scrolling them. Off by default."
|
|
903
|
+
},
|
|
904
|
+
{
|
|
905
|
+
"name": "hideCopy",
|
|
906
|
+
"type": "boolean",
|
|
907
|
+
"description": "Hide the copy button, for snippets that are not meant to be run."
|
|
776
908
|
}
|
|
777
909
|
],
|
|
778
910
|
"importPath": "./components/data-display/CodeBlock",
|
|
779
911
|
"filePath": "src/components/data-display/CodeBlock.tsx",
|
|
780
912
|
"sku": "@atom/primitive/code-block",
|
|
781
913
|
"humanLabel": "CodeBlock",
|
|
782
|
-
"humanDescription": "
|
|
914
|
+
"humanDescription": "The one way to show code. Syntax-highlighted, theme-aware, with a copy button that works on touch and outside secure contexts. Use for every snippet in docs and tutorials — do not hand-roll a <pre>. Long lines scroll inside the block so the page never scrolls sideways on a phone."
|
|
783
915
|
},
|
|
784
916
|
{
|
|
785
917
|
"id": "data-table",
|
|
@@ -1752,8 +1884,8 @@ export const wizardManifest: WizardManifest = {
|
|
|
1752
1884
|
{
|
|
1753
1885
|
"id": "segmented-control",
|
|
1754
1886
|
"name": "SegmentedControl",
|
|
1755
|
-
"version": "1.0.
|
|
1756
|
-
"description": "A theme-aware linear toggle component. Ideal for switching between discrete modes (e.g., \"Map / List\").",
|
|
1887
|
+
"version": "1.0.1",
|
|
1888
|
+
"description": "A theme-aware linear toggle component. Ideal for switching between discrete modes (e.g., \"Map / List\"). Every size clears the 24px WCAG 2.5.8 (AA) target-size minimum — xs 24px, sm ~25px, md ~36px. None reaches the 44px 2.5.5 (AAA) figure, so for a primary control on a touch screen prefer md or give the control its own 44px row; xs and sm are density sizes for pointer-driven toolbars.",
|
|
1757
1889
|
"tags": [
|
|
1758
1890
|
"input",
|
|
1759
1891
|
"toggle",
|
|
@@ -1767,7 +1899,7 @@ export const wizardManifest: WizardManifest = {
|
|
|
1767
1899
|
"filePath": "src/components/forms/SegmentedControl.tsx",
|
|
1768
1900
|
"sku": "@atom/form/segmented-control",
|
|
1769
1901
|
"humanLabel": "SegmentedControl",
|
|
1770
|
-
"humanDescription": "A theme-aware linear toggle component. Ideal for switching between discrete modes (e.g., \"Map / List\")."
|
|
1902
|
+
"humanDescription": "A theme-aware linear toggle component. Ideal for switching between discrete modes (e.g., \"Map / List\"). Every size clears the 24px WCAG 2.5.8 (AA) target-size minimum — xs 24px, sm ~25px, md ~36px. None reaches the 44px 2.5.5 (AAA) figure, so for a primary control on a touch screen prefer md or give the control its own 44px row; xs and sm are density sizes for pointer-driven toolbars."
|
|
1771
1903
|
},
|
|
1772
1904
|
{
|
|
1773
1905
|
"id": "select",
|
|
@@ -1848,31 +1980,53 @@ export const wizardManifest: WizardManifest = {
|
|
|
1848
1980
|
{
|
|
1849
1981
|
"id": "textarea",
|
|
1850
1982
|
"name": "Textarea",
|
|
1851
|
-
"version": "1.0.
|
|
1852
|
-
"description": "A theme-aware
|
|
1983
|
+
"version": "1.0.1",
|
|
1984
|
+
"description": "A theme-aware multi-line text input with label, helper text, and validation state support. Strategic purpose: the multi-line sibling of Input, styled identically so the two are indistinguishable when stacked in one form. Forwards all standard HTML textarea attributes via spread.",
|
|
1853
1985
|
"tags": [
|
|
1854
1986
|
"form",
|
|
1855
1987
|
"input",
|
|
1856
|
-
"ui"
|
|
1988
|
+
"ui",
|
|
1989
|
+
"text",
|
|
1990
|
+
"multiline"
|
|
1857
1991
|
],
|
|
1858
1992
|
"category": "form",
|
|
1859
1993
|
"props": [
|
|
1860
1994
|
{
|
|
1861
1995
|
"name": "label",
|
|
1862
1996
|
"type": "string",
|
|
1863
|
-
"description": "
|
|
1997
|
+
"description": "Optional label displayed above the textarea."
|
|
1998
|
+
},
|
|
1999
|
+
{
|
|
2000
|
+
"name": "helperText",
|
|
2001
|
+
"type": "string",
|
|
2002
|
+
"description": "Supporting text rendered below the textarea. Appears in destructive color when error is true."
|
|
2003
|
+
},
|
|
2004
|
+
{
|
|
2005
|
+
"name": "error",
|
|
2006
|
+
"type": "boolean",
|
|
2007
|
+
"description": "If true, applies destructive border styling to indicate a validation error. Defaults to false."
|
|
2008
|
+
},
|
|
2009
|
+
{
|
|
2010
|
+
"name": "required",
|
|
2011
|
+
"type": "boolean",
|
|
2012
|
+
"description": "If true, appends a required (*) indicator next to the label. Defaults to false."
|
|
2013
|
+
},
|
|
2014
|
+
{
|
|
2015
|
+
"name": "showOptionalLabel",
|
|
2016
|
+
"type": "boolean",
|
|
2017
|
+
"description": "If true, appends an (optional) label when the field is not required. Defaults to false."
|
|
1864
2018
|
},
|
|
1865
2019
|
{
|
|
1866
2020
|
"name": "containerClassName",
|
|
1867
2021
|
"type": "string",
|
|
1868
|
-
"description": "
|
|
2022
|
+
"description": "Additional CSS classes applied to the outer container div."
|
|
1869
2023
|
}
|
|
1870
2024
|
],
|
|
1871
2025
|
"importPath": "./components/forms/Textarea",
|
|
1872
2026
|
"filePath": "src/components/forms/Textarea.tsx",
|
|
1873
2027
|
"sku": "@atom/form/textarea",
|
|
1874
2028
|
"humanLabel": "Textarea",
|
|
1875
|
-
"humanDescription": "A theme-aware
|
|
2029
|
+
"humanDescription": "A theme-aware multi-line text input with label, helper text, and validation state support. Strategic purpose: the multi-line sibling of Input, styled identically so the two are indistinguishable when stacked in one form. Forwards all standard HTML textarea attributes via spread."
|
|
1876
2030
|
},
|
|
1877
2031
|
{
|
|
1878
2032
|
"id": "toggle-switch",
|
|
@@ -2242,6 +2396,48 @@ export const wizardManifest: WizardManifest = {
|
|
|
2242
2396
|
"humanLabel": "SectionHeader",
|
|
2243
2397
|
"humanDescription": "A simple, consistent header for organizing sections of content within a page."
|
|
2244
2398
|
},
|
|
2399
|
+
{
|
|
2400
|
+
"id": "connector-overlay",
|
|
2401
|
+
"name": "ConnectorOverlay",
|
|
2402
|
+
"version": "1.0.0",
|
|
2403
|
+
"description": "Covers a panel while its data source is connecting, and explains itself when the connection fails. Strategic purpose: the standard treatment for a live region that has no data yet — telemetry panels, market feeds, device dashboards — so every product says the same thing about a dead socket instead of inventing a spinner. Renders nothing once status is 'connected', so it can stay mounted.",
|
|
2404
|
+
"tags": [
|
|
2405
|
+
"feedback",
|
|
2406
|
+
"overlay",
|
|
2407
|
+
"connection",
|
|
2408
|
+
"realtime",
|
|
2409
|
+
"loading",
|
|
2410
|
+
"error"
|
|
2411
|
+
],
|
|
2412
|
+
"category": "feedback",
|
|
2413
|
+
"props": [
|
|
2414
|
+
{
|
|
2415
|
+
"name": "status",
|
|
2416
|
+
"type": "string",
|
|
2417
|
+
"description": "'connecting' | 'connected' | 'error'. Renders null when connected."
|
|
2418
|
+
},
|
|
2419
|
+
{
|
|
2420
|
+
"name": "message",
|
|
2421
|
+
"type": "ReactNode",
|
|
2422
|
+
"description": "Replaces the default copy for the current status."
|
|
2423
|
+
},
|
|
2424
|
+
{
|
|
2425
|
+
"name": "onRetry",
|
|
2426
|
+
"type": "function",
|
|
2427
|
+
"description": "Shows a retry action in the error state when provided."
|
|
2428
|
+
},
|
|
2429
|
+
{
|
|
2430
|
+
"name": "className",
|
|
2431
|
+
"type": "string",
|
|
2432
|
+
"description": "Additional CSS classes."
|
|
2433
|
+
}
|
|
2434
|
+
],
|
|
2435
|
+
"importPath": "./components/molecular/ConnectorOverlay",
|
|
2436
|
+
"filePath": "src/components/molecular/ConnectorOverlay.tsx",
|
|
2437
|
+
"sku": "@molecule/feedback/connector-overlay",
|
|
2438
|
+
"humanLabel": "ConnectorOverlay",
|
|
2439
|
+
"humanDescription": "Covers a panel while its data source is connecting, and explains itself when the connection fails. Strategic purpose: the standard treatment for a live region that has no data yet — telemetry panels, market feeds, device dashboards — so every product says the same thing about a dead socket instead of inventing a spinner. Renders nothing once status is 'connected', so it can stay mounted."
|
|
2440
|
+
},
|
|
2245
2441
|
{
|
|
2246
2442
|
"id": "data-card",
|
|
2247
2443
|
"name": "DataCard",
|
|
@@ -2464,8 +2660,8 @@ export const wizardManifest: WizardManifest = {
|
|
|
2464
2660
|
{
|
|
2465
2661
|
"id": "mobile-nav",
|
|
2466
2662
|
"name": "MobileNav",
|
|
2467
|
-
"version": "1.0.
|
|
2468
|
-
"description": "
|
|
2663
|
+
"version": "1.0.3",
|
|
2664
|
+
"description": "Mobile navigation, in two shapes. 'bar' is a fixed bottom tab bar with icon+label tabs and a \"More\" drawer for secondary links. 'sheet' drops the bar entirely and puts every destination in a bottom drawer the host opens from its own trigger — the right choice when a mobile browser's toolbar already owns the bottom edge. Hidden on md: and up via Tailwind. The mobile counterpart to the desktop Sidebar.",
|
|
2469
2665
|
"tags": [
|
|
2470
2666
|
"navigation",
|
|
2471
2667
|
"mobile",
|
|
@@ -2514,13 +2710,33 @@ export const wizardManifest: WizardManifest = {
|
|
|
2514
2710
|
"name": "className",
|
|
2515
2711
|
"type": "string",
|
|
2516
2712
|
"description": "Additional CSS classes on the root nav bar."
|
|
2713
|
+
},
|
|
2714
|
+
{
|
|
2715
|
+
"name": "variant",
|
|
2716
|
+
"type": "string",
|
|
2717
|
+
"description": "'bar' (default) renders the fixed bottom tab bar with a \"More\" Drawer. 'sheet' renders no bar at all and puts every destination in a Sheet — opening at 60% and growing to full as you drag or scroll it up — which the host opens itself — use it when a top header can hold the trigger, since a fixed bar and a mobile browser's own toolbar stack into ~120px of lost screen."
|
|
2718
|
+
},
|
|
2719
|
+
{
|
|
2720
|
+
"name": "isOpen",
|
|
2721
|
+
"type": "boolean",
|
|
2722
|
+
"description": "Controlled drawer state. Required by 'sheet', which has no trigger of its own; ignored by 'bar'."
|
|
2723
|
+
},
|
|
2724
|
+
{
|
|
2725
|
+
"name": "onOpenChange",
|
|
2726
|
+
"type": "function",
|
|
2727
|
+
"description": "Fired when the sheet wants to close (backdrop, Escape, or an item tapped)."
|
|
2728
|
+
},
|
|
2729
|
+
{
|
|
2730
|
+
"name": "children",
|
|
2731
|
+
"type": "ReactNode",
|
|
2732
|
+
"description": "Extra content rendered in the panel body after the destinations, scrolling with them. The mirror of drawerHeader; use it instead of drawerFooter when the content belongs with the list rather than pinned under it."
|
|
2517
2733
|
}
|
|
2518
2734
|
],
|
|
2519
2735
|
"importPath": "./components/navigation/MobileNav",
|
|
2520
2736
|
"filePath": "src/components/navigation/MobileNav.tsx",
|
|
2521
2737
|
"sku": "@molecule/nav/mobile-nav",
|
|
2522
2738
|
"humanLabel": "MobileNav",
|
|
2523
|
-
"humanDescription": "
|
|
2739
|
+
"humanDescription": "Mobile navigation, in two shapes. 'bar' is a fixed bottom tab bar with icon+label tabs and a \"More\" drawer for secondary links. 'sheet' drops the bar entirely and puts every destination in a bottom drawer the host opens from its own trigger — the right choice when a mobile browser's toolbar already owns the bottom edge. Hidden on md: and up via Tailwind. The mobile counterpart to the desktop Sidebar."
|
|
2524
2740
|
},
|
|
2525
2741
|
{
|
|
2526
2742
|
"id": "pagination",
|
|
@@ -2982,6 +3198,26 @@ export const wizardManifest: WizardManifest = {
|
|
|
2982
3198
|
"humanLabel": "AuthLayout",
|
|
2983
3199
|
"humanDescription": "The centred, chrome-free frame for unauthenticated screens, rendering the matched child route via an Outlet. Strategic purpose: sign-in and sign-up must not show the app shell's sidebar or header — wrap those routes in this instead of conditionally hiding chrome inside AppShell."
|
|
2984
3200
|
},
|
|
3201
|
+
{
|
|
3202
|
+
"id": "about-ramme",
|
|
3203
|
+
"name": "AboutRamme",
|
|
3204
|
+
"version": "1.0.0",
|
|
3205
|
+
"description": "The \"About\" panel for a Settings Console — what the framework is, which packages make it up, and why it is built this way. Strategic purpose: ships the explanation with the framework so every product's about screen stays accurate as the architecture moves, instead of each one carrying a copy that goes stale. Takes no props; drop it into a settings tab.",
|
|
3206
|
+
"tags": [
|
|
3207
|
+
"layout",
|
|
3208
|
+
"settings",
|
|
3209
|
+
"about",
|
|
3210
|
+
"documentation",
|
|
3211
|
+
"panel"
|
|
3212
|
+
],
|
|
3213
|
+
"category": "layout",
|
|
3214
|
+
"props": [],
|
|
3215
|
+
"importPath": "./components/layout/AboutRamme",
|
|
3216
|
+
"filePath": "src/components/layout/AboutRamme.tsx",
|
|
3217
|
+
"sku": "@chassis/layout/about-ramme",
|
|
3218
|
+
"humanLabel": "AboutRamme",
|
|
3219
|
+
"humanDescription": "The \"About\" panel for a Settings Console — what the framework is, which packages make it up, and why it is built this way. Strategic purpose: ships the explanation with the framework so every product's about screen stays accurate as the architecture moves, instead of each one carrying a copy that goes stale. Takes no props; drop it into a settings tab."
|
|
3220
|
+
},
|
|
2985
3221
|
{
|
|
2986
3222
|
"id": "accordion-item",
|
|
2987
3223
|
"name": "AccordionItem",
|
|
@@ -3911,6 +4147,69 @@ export const wizardManifest: WizardManifest = {
|
|
|
3911
4147
|
"humanLabel": "SettingsContainer",
|
|
3912
4148
|
"humanDescription": "The canonical settings page arrangement, with a fixed slot per section so every app's settings read the same way. Strategic purpose: settings sprawl fast — this pins the section order and navigation so General, AI Gateway, Theme Lab, and About always live in the same place."
|
|
3913
4149
|
},
|
|
4150
|
+
{
|
|
4151
|
+
"id": "sheet",
|
|
4152
|
+
"name": "Sheet",
|
|
4153
|
+
"version": "1.0.0",
|
|
4154
|
+
"description": "A bottom sheet that opens at a partial height and grows to full screen as you drag or scroll it up. Strategic purpose: the native-feeling surface for mobile navigation, settings and pickers — reachable by thumb, dismissed by flicking down. Use instead of Drawer when the surface is primarily touched.",
|
|
4155
|
+
"tags": [
|
|
4156
|
+
"layout",
|
|
4157
|
+
"overlay",
|
|
4158
|
+
"sheet",
|
|
4159
|
+
"mobile",
|
|
4160
|
+
"touch",
|
|
4161
|
+
"drawer",
|
|
4162
|
+
"ui"
|
|
4163
|
+
],
|
|
4164
|
+
"category": "layout",
|
|
4165
|
+
"props": [
|
|
4166
|
+
{
|
|
4167
|
+
"name": "isOpen",
|
|
4168
|
+
"type": "boolean",
|
|
4169
|
+
"description": "Controls the open/closed state. Required."
|
|
4170
|
+
},
|
|
4171
|
+
{
|
|
4172
|
+
"name": "onClose",
|
|
4173
|
+
"type": "function",
|
|
4174
|
+
"description": "Fired when the sheet requests dismissal (flick down, drag below the smallest detent, Escape, overlay tap, or the close button). Required."
|
|
4175
|
+
},
|
|
4176
|
+
{
|
|
4177
|
+
"name": "detents",
|
|
4178
|
+
"type": "Array<number>",
|
|
4179
|
+
"description": "Resting heights as fractions of the viewport, ascending. Defaults to [0.6, 1] — opens at 60%, expands to full."
|
|
4180
|
+
},
|
|
4181
|
+
{
|
|
4182
|
+
"name": "initialDetent",
|
|
4183
|
+
"type": "number",
|
|
4184
|
+
"description": "Index into detents to open at. Defaults to 0."
|
|
4185
|
+
},
|
|
4186
|
+
{
|
|
4187
|
+
"name": "title",
|
|
4188
|
+
"type": "string",
|
|
4189
|
+
"description": "Optional title in the sticky header, beside the close button."
|
|
4190
|
+
},
|
|
4191
|
+
{
|
|
4192
|
+
"name": "footer",
|
|
4193
|
+
"type": "ReactNode",
|
|
4194
|
+
"description": "Optional sticky footer, kept clear of the home indicator."
|
|
4195
|
+
},
|
|
4196
|
+
{
|
|
4197
|
+
"name": "overlayDismiss",
|
|
4198
|
+
"type": "boolean",
|
|
4199
|
+
"description": "Tap the dimmed backdrop to close. Defaults to true."
|
|
4200
|
+
},
|
|
4201
|
+
{
|
|
4202
|
+
"name": "className",
|
|
4203
|
+
"type": "string",
|
|
4204
|
+
"description": "Extra classes for the sheet panel."
|
|
4205
|
+
}
|
|
4206
|
+
],
|
|
4207
|
+
"importPath": "./components/layout/Sheet",
|
|
4208
|
+
"filePath": "src/components/layout/Sheet.tsx",
|
|
4209
|
+
"sku": "@chassis/layout/sheet",
|
|
4210
|
+
"humanLabel": "Sheet",
|
|
4211
|
+
"humanDescription": "A bottom sheet that opens at a partial height and grows to full screen as you drag or scroll it up. Strategic purpose: the native-feeling surface for mobile navigation, settings and pickers — reachable by thumb, dismissed by flicking down. Use instead of Drawer when the surface is primarily touched."
|
|
4212
|
+
},
|
|
3914
4213
|
{
|
|
3915
4214
|
"id": "sidebar",
|
|
3916
4215
|
"name": "Sidebar",
|
|
@@ -4126,6 +4425,52 @@ export const wizardManifest: WizardManifest = {
|
|
|
4126
4425
|
"sku": "@chassis/layout/user-nav",
|
|
4127
4426
|
"humanLabel": "UserNav",
|
|
4128
4427
|
"humanDescription": "The signed-in user's avatar menu — identity plus account actions. Strategic purpose: the standard account affordance for the app shell's header, with logout, settings, profile, and an optional theme toggle already wired. Compose extra entries with ButtonItem rather than rebuilding the menu."
|
|
4428
|
+
},
|
|
4429
|
+
{
|
|
4430
|
+
"id": "button-item",
|
|
4431
|
+
"name": "ButtonItem",
|
|
4432
|
+
"version": "1.0.0",
|
|
4433
|
+
"description": "A single row inside a UserNav menu — icon, label, action. Strategic purpose: the sanctioned way to add an entry to the account menu, so extra actions match the built-in ones instead of arriving as a hand-styled button. Use `variant=\"destructive\"` for anything that removes or signs out.",
|
|
4434
|
+
"tags": [
|
|
4435
|
+
"layout",
|
|
4436
|
+
"navigation",
|
|
4437
|
+
"menu",
|
|
4438
|
+
"item",
|
|
4439
|
+
"user-nav"
|
|
4440
|
+
],
|
|
4441
|
+
"category": "layout",
|
|
4442
|
+
"props": [
|
|
4443
|
+
{
|
|
4444
|
+
"name": "icon",
|
|
4445
|
+
"type": "string",
|
|
4446
|
+
"description": "Lucide icon name shown before the label."
|
|
4447
|
+
},
|
|
4448
|
+
{
|
|
4449
|
+
"name": "label",
|
|
4450
|
+
"type": "string",
|
|
4451
|
+
"description": "The menu entry text."
|
|
4452
|
+
},
|
|
4453
|
+
{
|
|
4454
|
+
"name": "onClick",
|
|
4455
|
+
"type": "function",
|
|
4456
|
+
"description": "Called when the entry is activated."
|
|
4457
|
+
},
|
|
4458
|
+
{
|
|
4459
|
+
"name": "variant",
|
|
4460
|
+
"type": "string",
|
|
4461
|
+
"description": "'default' | 'destructive'. Destructive tints the row for sign-out and delete."
|
|
4462
|
+
},
|
|
4463
|
+
{
|
|
4464
|
+
"name": "className",
|
|
4465
|
+
"type": "string",
|
|
4466
|
+
"description": "Additional CSS classes."
|
|
4467
|
+
}
|
|
4468
|
+
],
|
|
4469
|
+
"importPath": "./components/layout/UserNav",
|
|
4470
|
+
"filePath": "src/components/layout/UserNav.tsx",
|
|
4471
|
+
"sku": "@chassis/layout/button-item",
|
|
4472
|
+
"humanLabel": "ButtonItem",
|
|
4473
|
+
"humanDescription": "A single row inside a UserNav menu — icon, label, action. Strategic purpose: the sanctioned way to add an entry to the account menu, so extra actions match the built-in ones instead of arriving as a hand-styled button. Use `variant=\"destructive\"` for anything that removes or signs out."
|
|
4129
4474
|
}
|
|
4130
4475
|
],
|
|
4131
4476
|
"utils": [],
|
package/tailwind.preset.js
CHANGED
|
@@ -71,6 +71,14 @@ module.exports = {
|
|
|
71
71
|
},
|
|
72
72
|
|
|
73
73
|
// ─── Specialized Sub-Systems ───
|
|
74
|
+
// Categorical accents for colour-coded content. Distinct from `chart`:
|
|
75
|
+
// chart series collapse to one hue under a custom theme (see
|
|
76
|
+
// themeUtils.ts), these stay four hues on all five themes.
|
|
77
|
+
'accent-1': 'rgb(var(--app-accent-1) / <alpha-value>)',
|
|
78
|
+
'accent-2': 'rgb(var(--app-accent-2) / <alpha-value>)',
|
|
79
|
+
'accent-3': 'rgb(var(--app-accent-3) / <alpha-value>)',
|
|
80
|
+
'accent-4': 'rgb(var(--app-accent-4) / <alpha-value>)',
|
|
81
|
+
|
|
74
82
|
chart: {
|
|
75
83
|
1: 'rgb(var(--app-chart-1) / <alpha-value>)',
|
|
76
84
|
2: 'rgb(var(--app-chart-2) / <alpha-value>)',
|
|
@@ -105,17 +113,97 @@ module.exports = {
|
|
|
105
113
|
mono: ['var(--app-font-mono)', 'Menlo', 'monospace'],
|
|
106
114
|
},
|
|
107
115
|
|
|
108
|
-
// ─── Fluid Typography Scale
|
|
109
|
-
//
|
|
110
|
-
//
|
|
116
|
+
// ─── Fluid Typography Scale ───────────────────────
|
|
117
|
+
// The values live in framework/ui/src/index.css as --app-step-*, generated
|
|
118
|
+
// with the Utopia method (utopia.fyi/type/calculator) and fluid between a
|
|
119
|
+
// 360px and a 1240px viewport. They are referenced here rather than inlined
|
|
120
|
+
// for the same reason borderRadius is: a CSS variable can be re-pointed per
|
|
121
|
+
// theme (.dark/.corporate/.midnight/.blueprint) and adjusted at runtime
|
|
122
|
+
// through useTheme, which a literal in this file cannot.
|
|
123
|
+
//
|
|
124
|
+
// These REPLACE Tailwind's static defaults, so every existing text-sm /
|
|
125
|
+
// text-2xl / … call site becomes fluid with no edit. Each entry is a
|
|
126
|
+
// [size, { lineHeight, letterSpacing }] tuple — Tailwind's own scale pairs a
|
|
127
|
+
// line-height with every size, and dropping to a bare string (as the old
|
|
128
|
+
// fluid-* keys did) silently inherits whatever leading is in scope.
|
|
111
129
|
fontSize: {
|
|
112
|
-
'
|
|
113
|
-
'
|
|
114
|
-
'
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
'
|
|
118
|
-
'
|
|
130
|
+
'2xs': ['var(--app-step--3)', { lineHeight: 'var(--app-leading-base)' }],
|
|
131
|
+
xs: ['var(--app-step--2)', { lineHeight: 'var(--app-leading-base)' }],
|
|
132
|
+
sm: ['var(--app-step--1)', { lineHeight: 'var(--app-leading-relaxed)' }],
|
|
133
|
+
base: ['var(--app-step-0)', { lineHeight: 'var(--app-leading-relaxed)' }],
|
|
134
|
+
lg: ['var(--app-step-1)', { lineHeight: 'var(--app-leading-relaxed)' }],
|
|
135
|
+
xl: ['var(--app-step-2)', { lineHeight: 'var(--app-leading-snug)' }],
|
|
136
|
+
'2xl': ['var(--app-step-3)', { lineHeight: 'var(--app-leading-snug)' }],
|
|
137
|
+
'3xl': ['var(--app-step-4)', { lineHeight: 'var(--app-leading-snug)' }],
|
|
138
|
+
'4xl': ['var(--app-step-5)', { lineHeight: 'var(--app-leading-tight)' }],
|
|
139
|
+
'5xl': ['var(--app-step-6)', { lineHeight: 'var(--app-leading-tight)' }],
|
|
140
|
+
'6xl': ['var(--app-step-7)', { lineHeight: 'var(--app-leading-tight)' }],
|
|
141
|
+
'7xl': ['var(--app-step-8)', { lineHeight: 'var(--app-leading-none)' }],
|
|
142
|
+
'8xl': ['var(--app-step-9)', { lineHeight: 'var(--app-leading-none)' }],
|
|
143
|
+
'9xl': ['var(--app-step-10)', { lineHeight: 'var(--app-leading-none)' }],
|
|
144
|
+
|
|
145
|
+
// Back-compat aliases. text-fluid-* predates this scale and is still used
|
|
146
|
+
// in Card, ActivityFeed and MobileNav; they now resolve to the same steps
|
|
147
|
+
// as their plain counterparts. Prefer the plain names in new code.
|
|
148
|
+
'fluid-xs': ['var(--app-step--2)', { lineHeight: 'var(--app-leading-base)' }],
|
|
149
|
+
'fluid-sm': ['var(--app-step--1)', { lineHeight: 'var(--app-leading-relaxed)' }],
|
|
150
|
+
'fluid-base': ['var(--app-step-0)', { lineHeight: 'var(--app-leading-relaxed)' }],
|
|
151
|
+
'fluid-lg': ['var(--app-step-1)', { lineHeight: 'var(--app-leading-relaxed)' }],
|
|
152
|
+
'fluid-xl': ['var(--app-step-2)', { lineHeight: 'var(--app-leading-snug)' }],
|
|
153
|
+
'fluid-2xl': ['var(--app-step-3)', { lineHeight: 'var(--app-leading-snug)' }],
|
|
154
|
+
'fluid-3xl': ['var(--app-step-4)', { lineHeight: 'var(--app-leading-snug)' }],
|
|
155
|
+
},
|
|
156
|
+
|
|
157
|
+
// ─── Leading ──────────────────────────────────────
|
|
158
|
+
// Unitless, so they multiply whichever step they land on.
|
|
159
|
+
lineHeight: {
|
|
160
|
+
none: 'var(--app-leading-none)',
|
|
161
|
+
tight: 'var(--app-leading-tight)',
|
|
162
|
+
snug: 'var(--app-leading-snug)',
|
|
163
|
+
normal: 'var(--app-leading-base)',
|
|
164
|
+
relaxed: 'var(--app-leading-relaxed)',
|
|
165
|
+
},
|
|
166
|
+
|
|
167
|
+
// ─── Tracking ─────────────────────────────────────
|
|
168
|
+
// Replaces the hand-written tracking-[0.12em..0.3em] arbitrary values.
|
|
169
|
+
letterSpacing: {
|
|
170
|
+
tighter: 'var(--app-tracking-tighter)',
|
|
171
|
+
tight: 'var(--app-tracking-tight)',
|
|
172
|
+
normal: 'var(--app-tracking-normal)',
|
|
173
|
+
wide: 'var(--app-tracking-wide)',
|
|
174
|
+
wider: 'var(--app-tracking-wider)',
|
|
175
|
+
widest: 'var(--app-tracking-widest)',
|
|
176
|
+
},
|
|
177
|
+
|
|
178
|
+
// ─── Readable measure ─────────────────────────────
|
|
179
|
+
// ch-based, so line length tracks font size. max-w-prose is rem-based and
|
|
180
|
+
// drifts off a comfortable measure as soon as the base size changes.
|
|
181
|
+
maxWidth: {
|
|
182
|
+
measure: 'var(--app-measure)',
|
|
183
|
+
'measure-narrow': 'var(--app-measure-narrow)',
|
|
184
|
+
},
|
|
185
|
+
|
|
186
|
+
// ─── Layering Scale ───────────────────────────────
|
|
187
|
+
// One named order for everything that overlays, because "z-50" was the
|
|
188
|
+
// only overlay layer this framework had: Modal, Drawer, DetailDrawer,
|
|
189
|
+
// ToastProvider, Menu, UserNav, Sidebar and AIChatPanel all sat on it,
|
|
190
|
+
// so which one won was decided by portal mount order rather than intent.
|
|
191
|
+
// A toast confirming what you just did could land behind the modal you
|
|
192
|
+
// did it in.
|
|
193
|
+
//
|
|
194
|
+
// Read it top to bottom — each layer must clear the one above it in this
|
|
195
|
+
// list. Use the name, never a bare number, so the order stays arguable in
|
|
196
|
+
// one place instead of in eleven files.
|
|
197
|
+
zIndex: {
|
|
198
|
+
raised: '10', // lifted within its own pane — cards, in-flow overlays
|
|
199
|
+
sticky: '20', // sticky headers and toolbars inside a scroll region
|
|
200
|
+
nav: '30', // app chrome that outranks sticky page content
|
|
201
|
+
fab: '40', // floating action buttons over the page
|
|
202
|
+
scrim: '45', // a backdrop, under its own panel but over the app
|
|
203
|
+
drawer: '50', // drawers, modals, full-screen surfaces and overlays
|
|
204
|
+
popover: '60', // menus, dropdowns, tooltips — must clear a drawer
|
|
205
|
+
// they were opened from
|
|
206
|
+
toast: '70', // notifications — must clear everything, always
|
|
119
207
|
},
|
|
120
208
|
|
|
121
209
|
// ─── Fluid Spacing Scale (clamp) ──────────────────
|