@ramme-io/ui 4.1.0 → 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 +4 -3
- package/dist/component-registry.js +55 -52
- package/dist/components/ai/AIChatThread/AIChatThread.js +3 -3
- package/dist/components/ai/NewsSummaryCard/NewsSummaryCard.js +17 -17
- package/dist/components/ai/StockChart/StockChart.js +4 -4
- package/dist/components/auth/LoginPage.d.ts +22 -0
- package/dist/components/auth/LoginPage.js +50 -42
- 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/Select.js +9 -8
- package/dist/components/forms/Textarea.d.ts +13 -11
- package/dist/components/forms/Textarea.js +36 -16
- package/dist/components/layout/Accordion.js +25 -32
- package/dist/components/layout/Card.js +38 -21
- package/dist/components/layout/DetailDrawer.js +36 -37
- package/dist/components/layout/SettingsContainer.js +23 -13
- package/dist/components/layout/Sheet.d.ts +58 -0
- package/dist/components/layout/Sheet.js +144 -0
- package/dist/components/navigation/MobileNav.d.ts +44 -1
- package/dist/components/navigation/MobileNav.js +96 -70
- package/dist/components/navigation/Tabs.js +19 -12
- package/dist/components/ui/icon-loader.d.ts +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +218 -211
- package/dist/lib/hooks/useSheetGesture.d.ts +81 -0
- package/dist/lib/hooks/useSheetGesture.js +70 -0
- package/dist/setupTests.d.ts +1 -0
- package/dist/wizardManifest.js +130 -10
- package/package.json +9 -2
- package/src/wizardManifest.ts +130 -10
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { useState as M, useRef as u, useCallback as T, useEffect as C } from "react";
|
|
2
|
+
const D = 0.5, P = 0.12;
|
|
3
|
+
function y({ current: l, detents: f, velocity: a }) {
|
|
4
|
+
if (!f.length) return null;
|
|
5
|
+
const s = [...f].sort((r, e) => r - e), n = s[0], c = s[s.length - 1];
|
|
6
|
+
if (Math.abs(a) >= D) {
|
|
7
|
+
if (a > 0) {
|
|
8
|
+
const e = s.filter((g) => g < l - 0.01);
|
|
9
|
+
return e.length ? e[e.length - 1] : null;
|
|
10
|
+
}
|
|
11
|
+
const r = s.filter((e) => e > l + 0.01);
|
|
12
|
+
return r.length ? r[0] : c;
|
|
13
|
+
}
|
|
14
|
+
return l < n - P ? null : s.reduce(
|
|
15
|
+
(r, e) => Math.abs(e - l) < Math.abs(r - l) ? e : r
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
function R({
|
|
19
|
+
detents: l,
|
|
20
|
+
initialDetent: f = 0,
|
|
21
|
+
onDismiss: a,
|
|
22
|
+
reducedMotion: s = !1
|
|
23
|
+
}) {
|
|
24
|
+
const n = [...l].sort((t, i) => t - i), [c, r] = M(n[f] ?? n[0]), [e, g] = M(!1), L = u(0), S = u(0), w = u(0), v = u(0), E = u(0), d = u(null), h = T(
|
|
25
|
+
(t, i) => {
|
|
26
|
+
if (!s && t.isPrimary) {
|
|
27
|
+
if (d.current = i ? t.currentTarget : null, i) {
|
|
28
|
+
const o = t.currentTarget.scrollTop <= 0;
|
|
29
|
+
if (c >= n[n.length - 1] - 1e-3 && !o) return;
|
|
30
|
+
}
|
|
31
|
+
L.current = t.clientY, w.current = t.clientY, v.current = t.timeStamp, S.current = c, E.current = 0, g(!0), t.currentTarget.setPointerCapture(t.pointerId);
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
[c, s, n]
|
|
35
|
+
), b = T((t) => h(t, !1), [h]), H = T((t) => h(t, !0), [h]);
|
|
36
|
+
return C(() => {
|
|
37
|
+
if (!e) return;
|
|
38
|
+
const t = (o) => {
|
|
39
|
+
const Y = window.innerHeight || 1, I = o.clientY - L.current, x = o.timeStamp - v.current;
|
|
40
|
+
x > 0 && (E.current = (o.clientY - w.current) / x), w.current = o.clientY, v.current = o.timeStamp;
|
|
41
|
+
let p = S.current - I / Y;
|
|
42
|
+
const m = n[n.length - 1];
|
|
43
|
+
p > m && (p = m + (p - m) * 0.25), r(Math.max(0, Math.min(p, m + 0.05))), d.current && (d.current.scrollTop = 0);
|
|
44
|
+
}, i = () => {
|
|
45
|
+
g(!1);
|
|
46
|
+
const o = y({
|
|
47
|
+
current: c,
|
|
48
|
+
detents: n,
|
|
49
|
+
velocity: E.current
|
|
50
|
+
});
|
|
51
|
+
o === null ? a() : r(o), d.current = null;
|
|
52
|
+
};
|
|
53
|
+
return window.addEventListener("pointermove", t), window.addEventListener("pointerup", i), window.addEventListener("pointercancel", i), () => {
|
|
54
|
+
window.removeEventListener("pointermove", t), window.removeEventListener("pointerup", i), window.removeEventListener("pointercancel", i);
|
|
55
|
+
};
|
|
56
|
+
}, [e, c, a, n]), {
|
|
57
|
+
height: c,
|
|
58
|
+
dragging: e,
|
|
59
|
+
expanded: c >= n[n.length - 1] - 1e-3,
|
|
60
|
+
onPointerDown: b,
|
|
61
|
+
onBodyPointerDown: H,
|
|
62
|
+
setHeight: r
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
export {
|
|
66
|
+
P as DISMISS_THRESHOLD,
|
|
67
|
+
D as FLICK_VELOCITY,
|
|
68
|
+
y as settleTo,
|
|
69
|
+
R as useSheetGesture
|
|
70
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '@testing-library/jest-dom/vitest';
|
package/dist/wizardManifest.js
CHANGED
|
@@ -596,7 +596,7 @@ const e = {
|
|
|
596
596
|
{
|
|
597
597
|
id: "login-page",
|
|
598
598
|
name: "LoginPage",
|
|
599
|
-
version: "1.0.
|
|
599
|
+
version: "1.0.1",
|
|
600
600
|
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.",
|
|
601
601
|
tags: [
|
|
602
602
|
"auth",
|
|
@@ -626,6 +626,21 @@ const e = {
|
|
|
626
626
|
name: "quickProfiles",
|
|
627
627
|
type: "Array<QuickProfile>",
|
|
628
628
|
description: "Optional one-click demo identities, each `{ name, email, role }`."
|
|
629
|
+
},
|
|
630
|
+
{
|
|
631
|
+
name: "signupHref",
|
|
632
|
+
type: "string",
|
|
633
|
+
description: 'Where "Create one" points. Pass `null` to hide that line entirely, which is what an invite-only product wants. Defaults to `/auth/signup`.'
|
|
634
|
+
},
|
|
635
|
+
{
|
|
636
|
+
name: "signupLabel",
|
|
637
|
+
type: "string",
|
|
638
|
+
description: 'Text for that link. Defaults to "Create one".'
|
|
639
|
+
},
|
|
640
|
+
{
|
|
641
|
+
name: "forgotHref",
|
|
642
|
+
type: "string",
|
|
643
|
+
description: 'Where "Forgot?" points. Pass `null` to hide it — a product with no reset email has nothing to link to. Defaults to `#`.'
|
|
629
644
|
}
|
|
630
645
|
],
|
|
631
646
|
importPath: "./components/auth/LoginPage",
|
|
@@ -1961,31 +1976,53 @@ const e = {
|
|
|
1961
1976
|
{
|
|
1962
1977
|
id: "textarea",
|
|
1963
1978
|
name: "Textarea",
|
|
1964
|
-
version: "1.0.
|
|
1965
|
-
description: "A theme-aware
|
|
1979
|
+
version: "1.0.1",
|
|
1980
|
+
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.",
|
|
1966
1981
|
tags: [
|
|
1967
1982
|
"form",
|
|
1968
1983
|
"input",
|
|
1969
|
-
"ui"
|
|
1984
|
+
"ui",
|
|
1985
|
+
"text",
|
|
1986
|
+
"multiline"
|
|
1970
1987
|
],
|
|
1971
1988
|
category: "form",
|
|
1972
1989
|
props: [
|
|
1973
1990
|
{
|
|
1974
1991
|
name: "label",
|
|
1975
1992
|
type: "string",
|
|
1976
|
-
description: "
|
|
1993
|
+
description: "Optional label displayed above the textarea."
|
|
1994
|
+
},
|
|
1995
|
+
{
|
|
1996
|
+
name: "helperText",
|
|
1997
|
+
type: "string",
|
|
1998
|
+
description: "Supporting text rendered below the textarea. Appears in destructive color when error is true."
|
|
1999
|
+
},
|
|
2000
|
+
{
|
|
2001
|
+
name: "error",
|
|
2002
|
+
type: "boolean",
|
|
2003
|
+
description: "If true, applies destructive border styling to indicate a validation error. Defaults to false."
|
|
2004
|
+
},
|
|
2005
|
+
{
|
|
2006
|
+
name: "required",
|
|
2007
|
+
type: "boolean",
|
|
2008
|
+
description: "If true, appends a required (*) indicator next to the label. Defaults to false."
|
|
2009
|
+
},
|
|
2010
|
+
{
|
|
2011
|
+
name: "showOptionalLabel",
|
|
2012
|
+
type: "boolean",
|
|
2013
|
+
description: "If true, appends an (optional) label when the field is not required. Defaults to false."
|
|
1977
2014
|
},
|
|
1978
2015
|
{
|
|
1979
2016
|
name: "containerClassName",
|
|
1980
2017
|
type: "string",
|
|
1981
|
-
description: "
|
|
2018
|
+
description: "Additional CSS classes applied to the outer container div."
|
|
1982
2019
|
}
|
|
1983
2020
|
],
|
|
1984
2021
|
importPath: "./components/forms/Textarea",
|
|
1985
2022
|
filePath: "src/components/forms/Textarea.tsx",
|
|
1986
2023
|
sku: "@atom/form/textarea",
|
|
1987
2024
|
humanLabel: "Textarea",
|
|
1988
|
-
humanDescription: "A theme-aware
|
|
2025
|
+
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."
|
|
1989
2026
|
},
|
|
1990
2027
|
{
|
|
1991
2028
|
id: "toggle-switch",
|
|
@@ -2619,8 +2656,8 @@ const e = {
|
|
|
2619
2656
|
{
|
|
2620
2657
|
id: "mobile-nav",
|
|
2621
2658
|
name: "MobileNav",
|
|
2622
|
-
version: "1.0.
|
|
2623
|
-
description:
|
|
2659
|
+
version: "1.0.3",
|
|
2660
|
+
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.`,
|
|
2624
2661
|
tags: [
|
|
2625
2662
|
"navigation",
|
|
2626
2663
|
"mobile",
|
|
@@ -2669,13 +2706,33 @@ const e = {
|
|
|
2669
2706
|
name: "className",
|
|
2670
2707
|
type: "string",
|
|
2671
2708
|
description: "Additional CSS classes on the root nav bar."
|
|
2709
|
+
},
|
|
2710
|
+
{
|
|
2711
|
+
name: "variant",
|
|
2712
|
+
type: "string",
|
|
2713
|
+
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.`
|
|
2714
|
+
},
|
|
2715
|
+
{
|
|
2716
|
+
name: "isOpen",
|
|
2717
|
+
type: "boolean",
|
|
2718
|
+
description: "Controlled drawer state. Required by 'sheet', which has no trigger of its own; ignored by 'bar'."
|
|
2719
|
+
},
|
|
2720
|
+
{
|
|
2721
|
+
name: "onOpenChange",
|
|
2722
|
+
type: "function",
|
|
2723
|
+
description: "Fired when the sheet wants to close (backdrop, Escape, or an item tapped)."
|
|
2724
|
+
},
|
|
2725
|
+
{
|
|
2726
|
+
name: "children",
|
|
2727
|
+
type: "ReactNode",
|
|
2728
|
+
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."
|
|
2672
2729
|
}
|
|
2673
2730
|
],
|
|
2674
2731
|
importPath: "./components/navigation/MobileNav",
|
|
2675
2732
|
filePath: "src/components/navigation/MobileNav.tsx",
|
|
2676
2733
|
sku: "@molecule/nav/mobile-nav",
|
|
2677
2734
|
humanLabel: "MobileNav",
|
|
2678
|
-
humanDescription:
|
|
2735
|
+
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.`
|
|
2679
2736
|
},
|
|
2680
2737
|
{
|
|
2681
2738
|
id: "pagination",
|
|
@@ -4086,6 +4143,69 @@ const e = {
|
|
|
4086
4143
|
humanLabel: "SettingsContainer",
|
|
4087
4144
|
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."
|
|
4088
4145
|
},
|
|
4146
|
+
{
|
|
4147
|
+
id: "sheet",
|
|
4148
|
+
name: "Sheet",
|
|
4149
|
+
version: "1.0.0",
|
|
4150
|
+
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.",
|
|
4151
|
+
tags: [
|
|
4152
|
+
"layout",
|
|
4153
|
+
"overlay",
|
|
4154
|
+
"sheet",
|
|
4155
|
+
"mobile",
|
|
4156
|
+
"touch",
|
|
4157
|
+
"drawer",
|
|
4158
|
+
"ui"
|
|
4159
|
+
],
|
|
4160
|
+
category: "layout",
|
|
4161
|
+
props: [
|
|
4162
|
+
{
|
|
4163
|
+
name: "isOpen",
|
|
4164
|
+
type: "boolean",
|
|
4165
|
+
description: "Controls the open/closed state. Required."
|
|
4166
|
+
},
|
|
4167
|
+
{
|
|
4168
|
+
name: "onClose",
|
|
4169
|
+
type: "function",
|
|
4170
|
+
description: "Fired when the sheet requests dismissal (flick down, drag below the smallest detent, Escape, overlay tap, or the close button). Required."
|
|
4171
|
+
},
|
|
4172
|
+
{
|
|
4173
|
+
name: "detents",
|
|
4174
|
+
type: "Array<number>",
|
|
4175
|
+
description: "Resting heights as fractions of the viewport, ascending. Defaults to [0.6, 1] — opens at 60%, expands to full."
|
|
4176
|
+
},
|
|
4177
|
+
{
|
|
4178
|
+
name: "initialDetent",
|
|
4179
|
+
type: "number",
|
|
4180
|
+
description: "Index into detents to open at. Defaults to 0."
|
|
4181
|
+
},
|
|
4182
|
+
{
|
|
4183
|
+
name: "title",
|
|
4184
|
+
type: "string",
|
|
4185
|
+
description: "Optional title in the sticky header, beside the close button."
|
|
4186
|
+
},
|
|
4187
|
+
{
|
|
4188
|
+
name: "footer",
|
|
4189
|
+
type: "ReactNode",
|
|
4190
|
+
description: "Optional sticky footer, kept clear of the home indicator."
|
|
4191
|
+
},
|
|
4192
|
+
{
|
|
4193
|
+
name: "overlayDismiss",
|
|
4194
|
+
type: "boolean",
|
|
4195
|
+
description: "Tap the dimmed backdrop to close. Defaults to true."
|
|
4196
|
+
},
|
|
4197
|
+
{
|
|
4198
|
+
name: "className",
|
|
4199
|
+
type: "string",
|
|
4200
|
+
description: "Extra classes for the sheet panel."
|
|
4201
|
+
}
|
|
4202
|
+
],
|
|
4203
|
+
importPath: "./components/layout/Sheet",
|
|
4204
|
+
filePath: "src/components/layout/Sheet.tsx",
|
|
4205
|
+
sku: "@chassis/layout/sheet",
|
|
4206
|
+
humanLabel: "Sheet",
|
|
4207
|
+
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."
|
|
4208
|
+
},
|
|
4089
4209
|
{
|
|
4090
4210
|
id: "sidebar",
|
|
4091
4211
|
name: "Sidebar",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ramme-io/ui",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.1",
|
|
4
4
|
"description": "The structural component library for the Ramme Framework.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"private": false,
|
|
@@ -61,6 +61,8 @@
|
|
|
61
61
|
"@storybook/addon-themes": "^10.5.9",
|
|
62
62
|
"@storybook/react": "^10.5.9",
|
|
63
63
|
"@storybook/react-vite": "^10.5.9",
|
|
64
|
+
"@testing-library/jest-dom": "^6.9.1",
|
|
65
|
+
"@testing-library/react": "^16.3.2",
|
|
64
66
|
"@types/doctrine": "^0.0.9",
|
|
65
67
|
"@types/node": "^20.12.12",
|
|
66
68
|
"@types/react": "^18.3.23",
|
|
@@ -70,16 +72,21 @@
|
|
|
70
72
|
"ag-grid-community": "^31.3.2",
|
|
71
73
|
"ag-grid-react": "^31.3.2",
|
|
72
74
|
"autoprefixer": "^10.4.19",
|
|
75
|
+
"axe-core": "^4.13.0",
|
|
73
76
|
"doctrine": "^3.0.0",
|
|
77
|
+
"jsdom": "^29.0.0",
|
|
74
78
|
"postcss": "^8.4.38",
|
|
75
79
|
"storybook": "^10.5.9",
|
|
76
80
|
"tailwindcss": "^3.4.4",
|
|
77
81
|
"typescript": "^5.4.5",
|
|
78
82
|
"vite": "^5.3.1",
|
|
79
|
-
"vite-plugin-dts": "^3.9.1"
|
|
83
|
+
"vite-plugin-dts": "^3.9.1",
|
|
84
|
+
"vitest": "^2.1.9",
|
|
85
|
+
"vitest-axe": "^0.1.0"
|
|
80
86
|
},
|
|
81
87
|
"scripts": {
|
|
82
88
|
"dev": "vite",
|
|
89
|
+
"test": "vitest run",
|
|
83
90
|
"generate:manifest": "node scripts/generate-manifest.js",
|
|
84
91
|
"generate:registry": "node scripts/generate-registry.js",
|
|
85
92
|
"generate": "npm run generate:manifest && npm run generate:registry",
|
package/src/wizardManifest.ts
CHANGED
|
@@ -600,7 +600,7 @@ export const wizardManifest: WizardManifest = {
|
|
|
600
600
|
{
|
|
601
601
|
"id": "login-page",
|
|
602
602
|
"name": "LoginPage",
|
|
603
|
-
"version": "1.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",
|
|
@@ -1965,31 +1980,53 @@ export const wizardManifest: WizardManifest = {
|
|
|
1965
1980
|
{
|
|
1966
1981
|
"id": "textarea",
|
|
1967
1982
|
"name": "Textarea",
|
|
1968
|
-
"version": "1.0.
|
|
1969
|
-
"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.",
|
|
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": "
|
|
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": "
|
|
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
|
|
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.
|
|
2627
|
-
"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.",
|
|
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": "
|
|
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",
|
|
@@ -4090,6 +4147,69 @@ export const wizardManifest: WizardManifest = {
|
|
|
4090
4147
|
"humanLabel": "SettingsContainer",
|
|
4091
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."
|
|
4092
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
|
+
},
|
|
4093
4213
|
{
|
|
4094
4214
|
"id": "sidebar",
|
|
4095
4215
|
"name": "Sidebar",
|