@ramme-io/ui 4.1.0 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +4 -3
  2. package/dist/component-registry.js +55 -52
  3. package/dist/components/ai/AIChatThread/AIChatThread.js +3 -3
  4. package/dist/components/ai/NewsSummaryCard/NewsSummaryCard.js +17 -17
  5. package/dist/components/ai/StockChart/StockChart.js +35 -35
  6. package/dist/components/auth/LoginPage.d.ts +22 -0
  7. package/dist/components/auth/LoginPage.js +50 -42
  8. package/dist/components/data-display/StatusBadge.d.ts +4 -3
  9. package/dist/components/data-display/StatusBadge.js +18 -18
  10. package/dist/components/feedback/Alert.js +19 -19
  11. package/dist/components/forms/ComboBox.js +2 -2
  12. package/dist/components/forms/DatePicker.js +37 -32
  13. package/dist/components/forms/FileUpload.js +39 -37
  14. package/dist/components/forms/Input.js +19 -18
  15. package/dist/components/forms/MultiSelect.js +9 -8
  16. package/dist/components/forms/SegmentedControl.js +10 -10
  17. package/dist/components/forms/Select.js +9 -8
  18. package/dist/components/forms/Textarea.d.ts +13 -11
  19. package/dist/components/forms/Textarea.js +36 -16
  20. package/dist/components/layout/Accordion.js +25 -32
  21. package/dist/components/layout/Card.js +38 -21
  22. package/dist/components/layout/DetailDrawer.d.ts +9 -1
  23. package/dist/components/layout/DetailDrawer.js +60 -51
  24. package/dist/components/layout/Drawer.js +47 -39
  25. package/dist/components/layout/Modal.js +28 -23
  26. package/dist/components/layout/SettingsContainer.js +23 -13
  27. package/dist/components/layout/Sheet.d.ts +58 -0
  28. package/dist/components/layout/Sheet.js +146 -0
  29. package/dist/components/navigation/MobileNav.d.ts +44 -1
  30. package/dist/components/navigation/MobileNav.js +96 -70
  31. package/dist/components/navigation/Tabs.js +19 -12
  32. package/dist/components/ui/icon-loader.d.ts +1 -1
  33. package/dist/index.css +1 -1
  34. package/dist/index.d.ts +3 -0
  35. package/dist/index.js +218 -209
  36. package/dist/lib/hooks/useDialogFocus.d.ts +1 -0
  37. package/dist/lib/hooks/useDialogFocus.js +46 -0
  38. package/dist/lib/hooks/useSheetGesture.d.ts +81 -0
  39. package/dist/lib/hooks/useSheetGesture.js +70 -0
  40. package/dist/setupTests.d.ts +1 -0
  41. package/dist/wizardManifest.js +139 -14
  42. package/package.json +9 -2
  43. package/src/wizardManifest.ts +139 -14
  44. package/tailwind.preset.js +8 -0
@@ -600,7 +600,7 @@ export const wizardManifest: WizardManifest = {
600
600
  {
601
601
  "id": "login-page",
602
602
  "name": "LoginPage",
603
- "version": "1.0.0",
603
+ "version": "1.0.1",
604
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.",
605
605
  "tags": [
606
606
  "auth",
@@ -630,6 +630,21 @@ export const wizardManifest: WizardManifest = {
630
630
  "name": "quickProfiles",
631
631
  "type": "Array<QuickProfile>",
632
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 `#`."
633
648
  }
634
649
  ],
635
650
  "importPath": "./components/auth/LoginPage",
@@ -1087,7 +1102,7 @@ export const wizardManifest: WizardManifest = {
1087
1102
  {
1088
1103
  "id": "status-badge",
1089
1104
  "name": "StatusBadge",
1090
- "version": "1.0.1",
1105
+ "version": "1.0.2",
1091
1106
  "description": "A consistent status indicator featuring a color-coded dot and an optional text label. Essential for IoT devices and system states.",
1092
1107
  "tags": [
1093
1108
  "status",
@@ -1106,7 +1121,7 @@ export const wizardManifest: WizardManifest = {
1106
1121
  {
1107
1122
  "name": "color",
1108
1123
  "type": "string",
1109
- "description": "Tailwind background class for the dot (e.g. 'bg-emerald-500'). Overrides the `status` preset's color when both are given."
1124
+ "description": "Background class for the dot (e.g. 'bg-success'). Use a semantic token — a numeric shade does not adapt to the active theme. Overrides the `status` preset's colour when both are given."
1110
1125
  },
1111
1126
  {
1112
1127
  "name": "label",
@@ -1965,31 +1980,53 @@ export const wizardManifest: WizardManifest = {
1965
1980
  {
1966
1981
  "id": "textarea",
1967
1982
  "name": "Textarea",
1968
- "version": "1.0.0",
1969
- "description": "A theme-aware textarea component for multi-line text input.",
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.",
1970
1985
  "tags": [
1971
1986
  "form",
1972
1987
  "input",
1973
- "ui"
1988
+ "ui",
1989
+ "text",
1990
+ "multiline"
1974
1991
  ],
1975
1992
  "category": "form",
1976
1993
  "props": [
1977
1994
  {
1978
1995
  "name": "label",
1979
1996
  "type": "string",
1980
- "description": "An optional label to display above the textarea."
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."
1981
2018
  },
1982
2019
  {
1983
2020
  "name": "containerClassName",
1984
2021
  "type": "string",
1985
- "description": "Optional additional CSS classes for the container div."
2022
+ "description": "Additional CSS classes applied to the outer container div."
1986
2023
  }
1987
2024
  ],
1988
2025
  "importPath": "./components/forms/Textarea",
1989
2026
  "filePath": "src/components/forms/Textarea.tsx",
1990
2027
  "sku": "@atom/form/textarea",
1991
2028
  "humanLabel": "Textarea",
1992
- "humanDescription": "A theme-aware textarea component for multi-line text input."
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."
1993
2030
  },
1994
2031
  {
1995
2032
  "id": "toggle-switch",
@@ -2623,8 +2660,8 @@ export const wizardManifest: WizardManifest = {
2623
2660
  {
2624
2661
  "id": "mobile-nav",
2625
2662
  "name": "MobileNav",
2626
- "version": "1.0.0",
2627
- "description": "A fixed bottom tab bar for mobile screens, providing native-feeling navigation with primary icon+label tabs and a \"More\" drawer for secondary links. Hidden on md: and up via Tailwind. Designed as the mobile counterpart to the desktop Sidebar.",
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.",
2628
2665
  "tags": [
2629
2666
  "navigation",
2630
2667
  "mobile",
@@ -2673,13 +2710,33 @@ export const wizardManifest: WizardManifest = {
2673
2710
  "name": "className",
2674
2711
  "type": "string",
2675
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."
2676
2733
  }
2677
2734
  ],
2678
2735
  "importPath": "./components/navigation/MobileNav",
2679
2736
  "filePath": "src/components/navigation/MobileNav.tsx",
2680
2737
  "sku": "@molecule/nav/mobile-nav",
2681
2738
  "humanLabel": "MobileNav",
2682
- "humanDescription": "A fixed bottom tab bar for mobile screens, providing native-feeling navigation with primary icon+label tabs and a \"More\" drawer for secondary links. Hidden on md: and up via Tailwind. Designed as the mobile counterpart to the desktop Sidebar."
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."
2683
2740
  },
2684
2741
  {
2685
2742
  "id": "pagination",
@@ -3618,7 +3675,7 @@ export const wizardManifest: WizardManifest = {
3618
3675
  {
3619
3676
  "id": "detail-drawer",
3620
3677
  "name": "DetailDrawer",
3621
- "version": "1.0.0",
3678
+ "version": "1.0.2",
3622
3679
  "description": "A resizable side panel for inspecting one record without leaving the list. Strategic purpose: the master-detail companion — `push` compresses its siblings in a flex layout so the list stays visible and usable, while `overlay` floats above the page like a classic drawer. Use this for \"click a row, see the detail\" flows; use Modal when the task must block everything else.",
3623
3680
  "tags": [
3624
3681
  "layout",
@@ -3643,7 +3700,7 @@ export const wizardManifest: WizardManifest = {
3643
3700
  {
3644
3701
  "name": "variant",
3645
3702
  "type": "string",
3646
- "description": "'push' compresses sibling flex content so the list stays visible; 'overlay' floats fixed above the page. Defaults to push."
3703
+ "description": "'push' compresses sibling flex content so the list stays visible; 'overlay' floats fixed above the page. Defaults to overlay."
3647
3704
  },
3648
3705
  {
3649
3706
  "name": "side",
@@ -3675,6 +3732,11 @@ export const wizardManifest: WizardManifest = {
3675
3732
  "type": "number",
3676
3733
  "description": "Upper bound for resizing. Defaults to 60% of the window width."
3677
3734
  },
3735
+ {
3736
+ "name": "title",
3737
+ "type": "string",
3738
+ "description": "Names the panel for assistive technology. Not rendered: there is no header row to put it in, and adding one is a design decision. Without it an overlay announces only as \"dialog\"."
3739
+ },
3678
3740
  {
3679
3741
  "name": "children",
3680
3742
  "type": "ReactNode",
@@ -4090,6 +4152,69 @@ export const wizardManifest: WizardManifest = {
4090
4152
  "humanLabel": "SettingsContainer",
4091
4153
  "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."
4092
4154
  },
4155
+ {
4156
+ "id": "sheet",
4157
+ "name": "Sheet",
4158
+ "version": "1.0.0",
4159
+ "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.",
4160
+ "tags": [
4161
+ "layout",
4162
+ "overlay",
4163
+ "sheet",
4164
+ "mobile",
4165
+ "touch",
4166
+ "drawer",
4167
+ "ui"
4168
+ ],
4169
+ "category": "layout",
4170
+ "props": [
4171
+ {
4172
+ "name": "isOpen",
4173
+ "type": "boolean",
4174
+ "description": "Controls the open/closed state. Required."
4175
+ },
4176
+ {
4177
+ "name": "onClose",
4178
+ "type": "function",
4179
+ "description": "Fired when the sheet requests dismissal (flick down, drag below the smallest detent, Escape, overlay tap, or the close button). Required."
4180
+ },
4181
+ {
4182
+ "name": "detents",
4183
+ "type": "Array<number>",
4184
+ "description": "Resting heights as fractions of the viewport, ascending. Defaults to [0.6, 1] — opens at 60%, expands to full."
4185
+ },
4186
+ {
4187
+ "name": "initialDetent",
4188
+ "type": "number",
4189
+ "description": "Index into detents to open at. Defaults to 0."
4190
+ },
4191
+ {
4192
+ "name": "title",
4193
+ "type": "string",
4194
+ "description": "Optional title in the sticky header, beside the close button."
4195
+ },
4196
+ {
4197
+ "name": "footer",
4198
+ "type": "ReactNode",
4199
+ "description": "Optional sticky footer, kept clear of the home indicator."
4200
+ },
4201
+ {
4202
+ "name": "overlayDismiss",
4203
+ "type": "boolean",
4204
+ "description": "Tap the dimmed backdrop to close. Defaults to true."
4205
+ },
4206
+ {
4207
+ "name": "className",
4208
+ "type": "string",
4209
+ "description": "Extra classes for the sheet panel."
4210
+ }
4211
+ ],
4212
+ "importPath": "./components/layout/Sheet",
4213
+ "filePath": "src/components/layout/Sheet.tsx",
4214
+ "sku": "@chassis/layout/sheet",
4215
+ "humanLabel": "Sheet",
4216
+ "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."
4217
+ },
4093
4218
  {
4094
4219
  "id": "sidebar",
4095
4220
  "name": "Sidebar",
@@ -38,6 +38,11 @@ module.exports = {
38
38
  destructive: {
39
39
  DEFAULT: 'rgb(var(--app-danger-color) / <alpha-value>)',
40
40
  foreground: 'rgb(var(--app-danger-foreground-color) / <alpha-value>)',
41
+ // Severity text on the PAGE ground, not on the fill. `DEFAULT` is the
42
+ // fill and fails as body copy (success on white is 2.8:1); `strong` is
43
+ // the per-theme value that passes. Named `strong` rather than `text`
44
+ // so the utility reads `text-destructive-strong`, not `-text-text`.
45
+ strong: 'rgb(var(--app-danger-text-color) / <alpha-value>)',
41
46
  },
42
47
  accent: {
43
48
  DEFAULT: 'rgb(var(--app-accent-color) / <alpha-value>)',
@@ -56,14 +61,17 @@ module.exports = {
56
61
  info: {
57
62
  DEFAULT: 'rgb(var(--app-info-color) / <alpha-value>)',
58
63
  foreground: 'rgb(var(--app-info-foreground-color) / <alpha-value>)',
64
+ strong: 'rgb(var(--app-info-text-color) / <alpha-value>)',
59
65
  },
60
66
  success: {
61
67
  DEFAULT: 'rgb(var(--app-success-color) / <alpha-value>)',
62
68
  foreground: 'rgb(var(--app-success-foreground-color) / <alpha-value>)',
69
+ strong: 'rgb(var(--app-success-text-color) / <alpha-value>)',
63
70
  },
64
71
  warning: {
65
72
  DEFAULT: 'rgb(var(--app-warning-color) / <alpha-value>)',
66
73
  foreground: 'rgb(var(--app-warning-foreground-color) / <alpha-value>)',
74
+ strong: 'rgb(var(--app-warning-text-color) / <alpha-value>)',
67
75
  },
68
76
  error: {
69
77
  DEFAULT: 'rgb(var(--app-danger-color) / <alpha-value>)',