@syscore/ui-library 1.27.3 → 2.0.0-beta-publish-workflow-beta.2

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 (169) hide show
  1. package/client/App.tsx +0 -2
  2. package/client/assets/alert/icon-clear.svg +4 -0
  3. package/client/assets/alert/icon-done.svg +3 -0
  4. package/client/assets/avatar-identity/photo.png +0 -0
  5. package/client/assets/avatar-identity/placeholder-icon.svg +8 -0
  6. package/client/assets/breadcrumb/icon-ellipsis.svg +5 -0
  7. package/client/assets/breadcrumb/icon-home.svg +3 -0
  8. package/client/assets/breadcrumb/icon-separator.svg +3 -0
  9. package/client/assets/button-v01/icon-back.svg +4 -0
  10. package/client/assets/button-v01/icon-check.svg +3 -0
  11. package/client/assets/button-v01/icon-close.svg +4 -0
  12. package/client/assets/button-v01/icon-delete.svg +3 -0
  13. package/client/assets/button-v01/icon-device.svg +3 -0
  14. package/client/assets/dropdown/icon-carrot-contract.svg +3 -0
  15. package/client/assets/dropdown/icon-carrot-expand.svg +3 -0
  16. package/client/assets/dropdown/icon-clear.svg +4 -0
  17. package/client/assets/dropdown/icon-enter.svg +3 -0
  18. package/client/components/icons/UtilityChangeType.tsx +21 -0
  19. package/client/components/ui/alert-dialog-panel.tsx +246 -0
  20. package/client/components/ui/alert-v02.tsx +214 -0
  21. package/client/components/ui/app-bar.tsx +299 -0
  22. package/client/components/ui/avatar-identity.tsx +122 -0
  23. package/client/components/ui/banner.tsx +108 -0
  24. package/client/components/ui/bottom-navigation.tsx +223 -0
  25. package/client/components/ui/breadcrumb-trail.tsx +170 -0
  26. package/client/components/ui/button-v01.tsx +238 -0
  27. package/client/components/ui/button.tsx +2 -0
  28. package/client/components/ui/card.tsx +108 -26
  29. package/client/components/ui/code-badge.tsx +62 -0
  30. package/client/components/ui/date-picker.tsx +188 -0
  31. package/client/components/ui/dropdown.tsx +448 -0
  32. package/client/components/ui/empty-state.tsx +197 -0
  33. package/client/components/ui/file-upload.tsx +214 -0
  34. package/client/components/ui/footer.tsx +179 -0
  35. package/client/components/ui/layout.tsx +1182 -0
  36. package/client/components/ui/pagination-v01.tsx +157 -0
  37. package/client/components/ui/password-field-v01.tsx +67 -0
  38. package/client/components/ui/search-field-v01.tsx +192 -0
  39. package/client/components/ui/section-heading.tsx +49 -0
  40. package/client/components/ui/sidebar.tsx +2 -3
  41. package/client/components/ui/standard-navigation.tsx +8 -2
  42. package/client/components/ui/stepper.tsx +148 -0
  43. package/client/components/ui/switch-v01.tsx +71 -0
  44. package/client/components/ui/system-bar.tsx +119 -0
  45. package/client/components/ui/table-v01.tsx +230 -0
  46. package/client/components/ui/tabs-v01.tsx +99 -0
  47. package/client/components/ui/tag-v02.tsx +113 -0
  48. package/client/components/ui/text-area-v01.tsx +33 -0
  49. package/client/components/ui/text-field-v01.tsx +108 -0
  50. package/client/components/ui/timeline.tsx +181 -0
  51. package/client/components/ui/toast-v01.tsx +206 -0
  52. package/client/components/ui/tooltip.tsx +264 -71
  53. package/client/global.css +9565 -4378
  54. package/client/storybook.css +125 -0
  55. package/client/ui/Accordion.stories.tsx +1 -1
  56. package/client/ui/AlertDialogPanel/AlertDialogPanel.stories.tsx +150 -0
  57. package/client/ui/AlertV02/AlertV02.stories.tsx +188 -0
  58. package/client/ui/AppBar/app-bar.stories.tsx +280 -0
  59. package/client/ui/AspectRatio.stories.tsx +1 -1
  60. package/client/ui/AvatarIdentity/AvatarIdentity.stories.tsx +77 -0
  61. package/client/ui/Banner/banner.stories.tsx +238 -0
  62. package/client/ui/BottomNavigation/bottom-navigation.stories.tsx +285 -0
  63. package/client/ui/BreadcrumbTrail/BreadcrumbTrail.stories.tsx +232 -0
  64. package/client/ui/Button.stories.tsx +1 -1
  65. package/client/ui/ButtonV01/ButtonV01.stories.tsx +417 -0
  66. package/client/ui/Calendar/Calendar.stories.tsx +1 -1
  67. package/client/ui/Card.stories.tsx +285 -168
  68. package/client/ui/Carousel/Carousel.stories.tsx +1 -1
  69. package/client/ui/Chart/Chart.stories.tsx +1 -1
  70. package/client/ui/Checkbox.stories.tsx +1 -1
  71. package/client/ui/Collapsible/Collapsible.stories.tsx +1 -1
  72. package/client/ui/Colors.stories.tsx +1 -1
  73. package/client/ui/Command/Command.stories.tsx +1 -1
  74. package/client/ui/ContextMenu/ContextMenu.stories.tsx +1 -1
  75. package/client/ui/DatePicker/DatePicker.stories.tsx +293 -0
  76. package/client/ui/Dialog.stories.tsx +1 -1
  77. package/client/ui/Drawer/Drawer.stories.tsx +1 -1
  78. package/client/ui/Dropdown/Dropdown.stories.tsx +205 -0
  79. package/client/ui/EmptyState/empty-state.stories.tsx +251 -0
  80. package/client/ui/FileUpload/FileUpload.stories.tsx +218 -0
  81. package/client/ui/Footer/footer.stories.tsx +194 -0
  82. package/client/ui/Form/Form.stories.tsx +1 -1
  83. package/client/ui/Hero.stories.tsx +1 -1
  84. package/client/ui/HoverCard/HoverCard.stories.tsx +1 -1
  85. package/client/ui/Icons.stories.tsx +1 -1
  86. package/client/ui/Input.stories.tsx +1 -1
  87. package/client/ui/InputOTP/InputOTP.stories.tsx +1 -1
  88. package/client/ui/Label.stories.tsx +1 -1
  89. package/client/ui/Layout/Center.stories.tsx +100 -0
  90. package/client/ui/Layout/Columns.stories.tsx +136 -0
  91. package/client/ui/Layout/Container.stories.tsx +104 -0
  92. package/client/ui/Layout/FormLayout.stories.tsx +144 -0
  93. package/client/ui/Layout/Grid.stories.tsx +158 -0
  94. package/client/ui/Layout/GridSpan.stories.tsx +75 -0
  95. package/client/ui/Layout/HStack.stories.tsx +128 -0
  96. package/client/ui/Layout/Layout.stories.tsx +287 -0
  97. package/client/ui/Layout/LayoutContent.stories.tsx +91 -0
  98. package/client/ui/Layout/LayoutFooter.stories.tsx +77 -0
  99. package/client/ui/Layout/LayoutHeader.stories.tsx +104 -0
  100. package/client/ui/Layout/LayoutPanel.stories.tsx +143 -0
  101. package/client/ui/Layout/Positioned.stories.tsx +113 -0
  102. package/client/ui/Layout/Section.stories.tsx +84 -0
  103. package/client/ui/Layout/ShowHide.stories.tsx +99 -0
  104. package/client/ui/Layout/Spacer.stories.tsx +149 -0
  105. package/client/ui/Layout/Stack.stories.tsx +69 -0
  106. package/client/ui/Layout/StackItem.stories.tsx +124 -0
  107. package/client/ui/Layout/VStack.stories.tsx +101 -0
  108. package/client/ui/Layout/controls.ts +33 -0
  109. package/client/ui/Layout/demo.tsx +37 -0
  110. package/client/ui/Menubar/Menubar.stories.tsx +1 -1
  111. package/client/ui/MobileNav.stories.tsx +1 -1
  112. package/client/ui/Navigation.stories.tsx +1 -1
  113. package/client/ui/NavigationMenu/NavigationMenu.stories.tsx +1 -1
  114. package/client/ui/PageHeader.stories.tsx +13 -13
  115. package/client/ui/Pagination/Pagination.stories.tsx +178 -98
  116. package/client/ui/Pagination/PaginationLegacy.stories.tsx +121 -0
  117. package/client/ui/Panel.stories.tsx +1 -1
  118. package/client/ui/Popover/Popover.stories.tsx +1 -1
  119. package/client/ui/Progress/Progress.stories.tsx +1 -1
  120. package/client/ui/RadioGroup/RadioGroup.stories.tsx +1 -1
  121. package/client/ui/Resizable/Resizable.stories.tsx +1 -1
  122. package/client/ui/ScrollArea/ScrollArea.stories.tsx +1 -1
  123. package/client/ui/SearchField/SearchField.stories.tsx +153 -0
  124. package/client/ui/{SearchField.stories.tsx → SearchField/SearchFieldLegacy.stories.tsx} +2 -2
  125. package/client/ui/SectionBadge.stories.tsx +1 -1
  126. package/client/ui/Select.stories.tsx +1 -1
  127. package/client/ui/Separator/Separator.stories.tsx +1 -1
  128. package/client/ui/Sheet/Sheet.stories.tsx +1 -1
  129. package/client/ui/Sidebar/Sidebar.stories.tsx +57 -8
  130. package/client/ui/Skeleton/Skeleton.stories.tsx +1 -1
  131. package/client/ui/Slider/Slider.stories.tsx +1 -1
  132. package/client/ui/StandardNavigation.stories.tsx +1 -1
  133. package/client/ui/Stepper/Stepper.stories.tsx +344 -0
  134. package/client/ui/Switch.stories.tsx +1 -1
  135. package/client/ui/SwitchV01/SwitchV01.stories.tsx +152 -0
  136. package/client/ui/SystemBar/system-bar.stories.tsx +179 -0
  137. package/client/ui/Table/TableV01.stories.tsx +256 -0
  138. package/client/ui/Tabs.stories.tsx +1 -1
  139. package/client/ui/TabsV01/TabsV01.stories.tsx +144 -0
  140. package/client/ui/Tag.stories.tsx +1 -1
  141. package/client/ui/TagV02/TagStatusV02.stories.tsx +132 -0
  142. package/client/ui/TagV02/TagV02.stories.tsx +142 -0
  143. package/client/ui/TextAreaV01/TextAreaV01.stories.tsx +146 -0
  144. package/client/ui/TextFieldV01/PasswordFieldV01.stories.tsx +161 -0
  145. package/client/ui/TextFieldV01/TextFieldV01.stories.tsx +160 -0
  146. package/client/ui/Textarea.stories.tsx +1 -1
  147. package/client/ui/Timeline/timeline.stories.tsx +404 -0
  148. package/client/ui/Toast/Toast.stories.tsx +1 -1
  149. package/client/ui/ToastV01/ToastV01.stories.tsx +201 -0
  150. package/client/ui/Toaster/Toaster.stories.tsx +1 -1
  151. package/client/ui/Toggle.stories.tsx +1 -1
  152. package/client/ui/Tooltip.stories.tsx +287 -114
  153. package/client/ui/Typography.stories.tsx +1 -1
  154. package/dist/index.cjs.js +1 -1
  155. package/dist/index.d.ts +649 -13
  156. package/dist/index.es.js +4405 -653
  157. package/package.json +1 -1
  158. package/client/components/ui/badge.tsx +0 -33
  159. package/client/components/ui/sonner.tsx +0 -26
  160. package/client/components/ui/toggle-group.tsx +0 -76
  161. package/client/ui/Alert/Alert.stories.tsx +0 -82
  162. package/client/ui/AlertDialog/AlertDialog.stories.tsx +0 -106
  163. package/client/ui/Avatar/Avatar.stories.tsx +0 -94
  164. package/client/ui/Badge/Badge.stories.tsx +0 -60
  165. package/client/ui/Breadcrumb/Breadcrumb.stories.tsx +0 -97
  166. package/client/ui/DropdownMenu/DropdownMenu.stories.tsx +0 -139
  167. package/client/ui/Sonner/Sonner.stories.tsx +0 -48
  168. package/client/ui/Table/Table.stories.tsx +0 -135
  169. package/client/ui/ToggleGroup/ToggleGroup.stories.tsx +0 -88
@@ -0,0 +1,132 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { TagStatusV02 } from "../../components/ui/tag-v02";
3
+
4
+ const statuses = ["todo", "low", "medium", "high", "done", "new"] as const;
5
+ const tones = ["light", "dark"] as const;
6
+
7
+ const meta = {
8
+ title: "Components/TagStatus",
9
+ component: TagStatusV02,
10
+ tags: ["autodocs"],
11
+ parameters: {
12
+ layout: "centered",
13
+ docs: {
14
+ description: {
15
+ component: [
16
+ "Read-only status pill, paired with `Components/Tag`.",
17
+ "",
18
+ "Stories are the two tones: **Light** and **Dark**.",
19
+ "Use **Controls** for status and the label.",
20
+ "All Variants shows the full set of **12**.",
21
+ "",
22
+ "---",
23
+ "",
24
+ "## Import",
25
+ "",
26
+ "```tsx",
27
+ `import { TagStatusV02 } from "@syscore/ui-library"`,
28
+ "```",
29
+ "",
30
+ "## How to use",
31
+ "",
32
+ "Renders a `span` — it carries no interaction, so pair it with a real control",
33
+ "if the status is editable. The label defaults to the `status` value and is",
34
+ "uppercased by the overline type style, so pass mixed-case copy freely.",
35
+ "",
36
+ "```tsx",
37
+ `<TagStatusV02 status="high" tone="dark">High</TagStatusV02>`,
38
+ "```",
39
+ "",
40
+ "| Status | Light | Dark |",
41
+ "|--------|-------|------|",
42
+ "| `todo` | grey 100 / 600 | grey 600 / 100 |",
43
+ "| `low` | cyan 100 / 500 | cyan 700 / 100 |",
44
+ "| `medium` | plum 100 / 600 | plum 700 / 100 |",
45
+ "| `high` | coral 100 / 600 | coral 700 / 100 |",
46
+ "| `done` | emerald 100 / 600 | emerald 700 / 100 |",
47
+ "| `new` | gold 200 / 800 | gold 700 / 50 |",
48
+ "",
49
+ "## Props",
50
+ "",
51
+ "| Prop | Values | Default | Effect |",
52
+ "|------|--------|---------|--------|",
53
+ '| `status` | `"todo"` \\| `"low"` \\| `"medium"` \\| `"high"` \\| `"done"` \\| `"new"` | `"todo"` | Semantic status |',
54
+ '| `tone` | `"light"` \\| `"dark"` | `"light"` | Tinted background vs solid (stories) |',
55
+ "| `children` | `ReactNode` | the `status` value | Label |",
56
+ ].join("\n"),
57
+ },
58
+ },
59
+ },
60
+ argTypes: {
61
+ status: { control: "inline-radio", options: [...statuses] },
62
+ children: { control: "text", name: "label" },
63
+ tone: { table: { disable: true } },
64
+ },
65
+ args: {
66
+ status: "todo",
67
+ },
68
+ } satisfies Meta<typeof TagStatusV02>;
69
+
70
+ export default meta;
71
+ type Story = StoryObj<typeof meta>;
72
+
73
+ export const Light: Story = {
74
+ args: { tone: "light" },
75
+ };
76
+
77
+ export const Dark: Story = {
78
+ args: { tone: "dark" },
79
+ };
80
+
81
+ export const AllVariants: Story = {
82
+ name: "All Variants",
83
+ parameters: { layout: "padded" },
84
+ argTypes: { status: { table: { disable: true } } },
85
+ render: () => (
86
+ <div
87
+ style={{
88
+ display: "grid",
89
+ gridTemplateColumns: "minmax(0, 1fr)",
90
+ justifyItems: "center",
91
+ gap: 40,
92
+ width: "100%",
93
+ }}
94
+ >
95
+ {tones.map((tone) => (
96
+ <section key={tone} style={{ width: "100%", maxWidth: 460 }}>
97
+ <h3
98
+ style={{
99
+ margin: "0 0 16px",
100
+ fontSize: 14,
101
+ fontWeight: 600,
102
+ textTransform: "uppercase",
103
+ letterSpacing: 0.5,
104
+ color: "#52545d",
105
+ textAlign: "center",
106
+ }}
107
+ >
108
+ Status · {tone}
109
+ </h3>
110
+ <div
111
+ style={{
112
+ display: "grid",
113
+ gridTemplateColumns: "repeat(auto-fill, minmax(120px, 1fr))",
114
+ maxWidth: 416,
115
+ margin: "0 auto",
116
+ gap: 16,
117
+ justifyItems: "center",
118
+ }}
119
+ >
120
+ {statuses.map((status) => (
121
+ <TagStatusV02
122
+ key={`${tone}-${status}`}
123
+ status={status}
124
+ tone={tone}
125
+ />
126
+ ))}
127
+ </div>
128
+ </section>
129
+ ))}
130
+ </div>
131
+ ),
132
+ };
@@ -0,0 +1,142 @@
1
+ import * as React from "react";
2
+ import type { Meta, StoryObj } from "@storybook/react";
3
+ import { TagV02 } from "../../components/ui/tag-v02";
4
+
5
+ const states = ["active", "inactive"] as const;
6
+ const changeTypes = ["mild", "medium", "hot"] as const;
7
+
8
+ const meta = {
9
+ title: "Components/Tag",
10
+ component: TagV02,
11
+ tags: ["autodocs"],
12
+ parameters: {
13
+ layout: "centered",
14
+ docs: {
15
+ description: {
16
+ component: [
17
+ "Filter chip. Existing `Components/TagLegacy` (`Tag`) is unchanged.",
18
+ "",
19
+ "Stories are the two states: **Active** and **Inactive**.",
20
+ "Use **Controls** for the label and the optional dot and change glyph.",
21
+ "Status pills live separately at `Components/TagStatus`.",
22
+ "",
23
+ "---",
24
+ "",
25
+ "## Import",
26
+ "",
27
+ "```tsx",
28
+ `import { TagV02 } from "@syscore/ui-library"`,
29
+ "```",
30
+ "",
31
+ "## How to use",
32
+ "",
33
+ "Renders a `button` with `aria-pressed`, so it reads as a toggle to assistive",
34
+ "tech. Drive `state` from your own selection state.",
35
+ "",
36
+ "```tsx",
37
+ "const [on, setOn] = useState(false)",
38
+ "",
39
+ "<TagV02",
40
+ ` state={on ? "active" : "inactive"}`,
41
+ " onClick={() => setOn(!on)}",
42
+ " dot",
43
+ " change",
44
+ ">",
45
+ " Tag",
46
+ "</TagV02>",
47
+ "```",
48
+ "",
49
+ "| Situation | Use |",
50
+ "|-----------|-----|",
51
+ '| Selected filter | `state="active"` |',
52
+ '| Unselected filter | `state="inactive"` (default) |',
53
+ "| Branded marker | `dot` |",
54
+ "| Change-type marker | `change`, with `changeType` |",
55
+ "",
56
+ "## Props",
57
+ "",
58
+ "| Prop | Values | Default | Effect |",
59
+ "|------|--------|---------|--------|",
60
+ '| `state` | `"active"` \\| `"inactive"` | `"inactive"` | Selection state (stories) |',
61
+ "| `dot` | `boolean` | `false` | 12px branded dot after the label |",
62
+ "| `change` | `boolean` | `false` | Change-type triangle after the dot |",
63
+ '| `changeType` | `"mild"` \\| `"medium"` \\| `"hot"` | `"mild"` | Which triangle |',
64
+ "| `children` | `ReactNode` | — | Label (14px/19.6, weight 500) |",
65
+ "| `disabled` | `boolean` | `false` | Dims and blocks interaction |",
66
+ ].join("\n"),
67
+ },
68
+ },
69
+ },
70
+ argTypes: {
71
+ dot: { control: "boolean" },
72
+ change: { control: "boolean" },
73
+ changeType: { control: "inline-radio", options: [...changeTypes] },
74
+ children: { control: "text", name: "label" },
75
+ disabled: { control: "boolean" },
76
+ state: { table: { disable: true } },
77
+ },
78
+ args: {
79
+ children: "Tag",
80
+ dot: true,
81
+ change: true,
82
+ changeType: "mild",
83
+ disabled: false,
84
+ },
85
+ } satisfies Meta<typeof TagV02>;
86
+
87
+ export default meta;
88
+ type Story = StoryObj<typeof meta>;
89
+
90
+ export const Active: Story = {
91
+ args: { state: "active" },
92
+ };
93
+
94
+ export const Inactive: Story = {
95
+ args: { state: "inactive" },
96
+ };
97
+
98
+ const sectionHeading: React.CSSProperties = {
99
+ margin: "0 0 16px",
100
+ fontSize: 14,
101
+ fontWeight: 600,
102
+ textTransform: "uppercase",
103
+ letterSpacing: 0.5,
104
+ color: "#52545d",
105
+ textAlign: "center",
106
+ };
107
+
108
+ const row: React.CSSProperties = {
109
+ display: "flex",
110
+ flexWrap: "wrap",
111
+ justifyContent: "center",
112
+ alignItems: "center",
113
+ gap: 16,
114
+ };
115
+
116
+ export const AllVariants: Story = {
117
+ name: "All Variants",
118
+ parameters: { layout: "padded" },
119
+ argTypes: { state: { table: { disable: true } } },
120
+ render: (args) => (
121
+ <div
122
+ style={{
123
+ display: "grid",
124
+ gridTemplateColumns: "minmax(0, 1fr)",
125
+ justifyItems: "center",
126
+ gap: 40,
127
+ width: "100%",
128
+ }}
129
+ >
130
+ <section style={{ width: "100%", maxWidth: 460 }}>
131
+ <h3 style={sectionHeading}>Base</h3>
132
+ <div style={row}>
133
+ {states.map((state) => (
134
+ <TagV02 key={state} {...args} state={state}>
135
+ Tag
136
+ </TagV02>
137
+ ))}
138
+ </div>
139
+ </section>
140
+ </div>
141
+ ),
142
+ };
@@ -0,0 +1,146 @@
1
+ import * as React from "react";
2
+ import type { Meta, StoryObj } from "@storybook/react";
3
+ import { TextAreaV01 } from "../../components/ui/text-area-v01";
4
+
5
+ const SHORT =
6
+ "Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
7
+
8
+ const LONG =
9
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla";
10
+
11
+ const FILLED =
12
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat.";
13
+
14
+ const DISABLED =
15
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. ";
16
+
17
+ const specimens = [
18
+ { name: "Default", props: {} },
19
+ { name: "Focus", props: { focused: true } },
20
+ { name: "Active", props: { focused: true, defaultValue: SHORT } },
21
+ { name: "In progress", props: { focused: true, defaultValue: LONG } },
22
+ { name: "Filled", props: { defaultValue: FILLED } },
23
+ { name: "Disabled", props: { disabled: true, defaultValue: DISABLED } },
24
+ ] as const;
25
+
26
+ const sectionHeading: React.CSSProperties = {
27
+ margin: "0 0 20px",
28
+ fontSize: 14,
29
+ fontWeight: 600,
30
+ textTransform: "uppercase",
31
+ letterSpacing: 0.5,
32
+ color: "#52545d",
33
+ };
34
+
35
+ const meta = {
36
+ title: "Components/TextArea",
37
+ component: TextAreaV01,
38
+ tags: ["autodocs"],
39
+ parameters: {
40
+ layout: "centered",
41
+ docs: {
42
+ description: {
43
+ component: [
44
+ "Multi-line input. Existing `Components/TextareaLegacy` (`Textarea`) is unchanged.",
45
+ "",
46
+ "Stories are the six states: **Default**, **Focus**, **Active**,",
47
+ "**In progress**, **Filled** and **Disabled**. Use **Controls** for the",
48
+ "placeholder and value. All Variants shows every state.",
49
+ "",
50
+ "---",
51
+ "",
52
+ "## Import",
53
+ "",
54
+ "```tsx",
55
+ `import { TextAreaV01 } from "@syscore/ui-library"`,
56
+ "```",
57
+ "",
58
+ "## How to use",
59
+ "",
60
+ "It starts at 112px and grows with the content, so Active, In progress and",
61
+ "Filled differ only by how much text they hold. Focus styling comes from",
62
+ "`:focus`, so it needs no prop in real use — `focused` only holds the ring",
63
+ "still for these specimens.",
64
+ "",
65
+ "```tsx",
66
+ "<TextAreaV01",
67
+ ` placeholder="Tell us what you think"`,
68
+ " value={note}",
69
+ " onChange={(e) => setNote(e.target.value)}",
70
+ "/>",
71
+ "```",
72
+ "",
73
+ "## Props",
74
+ "",
75
+ "| Prop | Values | Default | Effect |",
76
+ "|------|--------|---------|--------|",
77
+ '| `placeholder` | `string` | `"Tell us what you think"` | Empty-state text |',
78
+ "| `value` / `defaultValue` | `string` | — | Content |",
79
+ "| `disabled` | `boolean` | `false` | Grey fill, not editable |",
80
+ "| `focused` | `boolean` | `false` | Holds the focus ring for specimens |",
81
+ "",
82
+ "Growth uses `field-sizing: content`. Where that is unsupported the box keeps",
83
+ "its 112px height and scrolls instead.",
84
+ ].join("\n"),
85
+ },
86
+ },
87
+ },
88
+ argTypes: {
89
+ placeholder: { control: "text" },
90
+ disabled: { control: "boolean" },
91
+ rows: { table: { disable: true } },
92
+ focused: { table: { disable: true } },
93
+ value: { table: { disable: true } },
94
+ },
95
+ args: {
96
+ placeholder: "Tell us what you think",
97
+ },
98
+ } satisfies Meta<typeof TextAreaV01>;
99
+
100
+ export default meta;
101
+ type Story = StoryObj<typeof meta>;
102
+
103
+ export const Default: Story = {};
104
+
105
+ export const Focus: Story = {
106
+ args: { focused: true, autoFocus: true },
107
+ };
108
+
109
+ export const Active: Story = {
110
+ args: { focused: true, autoFocus: true, defaultValue: SHORT },
111
+ };
112
+
113
+ export const InProgress: Story = {
114
+ name: "In progress",
115
+ args: { focused: true, autoFocus: true, defaultValue: LONG },
116
+ };
117
+
118
+ export const Filled: Story = {
119
+ args: { defaultValue: FILLED },
120
+ };
121
+
122
+ export const Disabled: Story = {
123
+ args: { disabled: true, defaultValue: DISABLED },
124
+ };
125
+
126
+ export const AllVariants: Story = {
127
+ name: "All Variants",
128
+ parameters: { layout: "padded" },
129
+ render: (args) => (
130
+ <div
131
+ style={{
132
+ display: "flex",
133
+ flexDirection: "column",
134
+ gap: 56,
135
+ padding: "32px 24px 48px",
136
+ }}
137
+ >
138
+ {specimens.map((specimen) => (
139
+ <section key={specimen.name}>
140
+ <h3 style={sectionHeading}>{specimen.name}</h3>
141
+ <TextAreaV01 placeholder={args.placeholder} {...specimen.props} />
142
+ </section>
143
+ ))}
144
+ </div>
145
+ ),
146
+ };
@@ -0,0 +1,161 @@
1
+ import * as React from "react";
2
+ import type { Meta, StoryObj } from "@storybook/react";
3
+ import { PasswordFieldV01 } from "../../components/ui/password-field-v01";
4
+
5
+ const specimens = [
6
+ { name: "Default", props: {} },
7
+ { name: "Focus", props: { focused: true } },
8
+ {
9
+ name: "Active",
10
+ props: { focused: true, defaultValue: "aaaaaghdovnmnvbj" },
11
+ },
12
+ { name: "Filled", props: { defaultValue: "aaaaaghdovnmnvbj" } },
13
+ {
14
+ name: "Error",
15
+ props: { error: true, helperText: "Helper text goes here" },
16
+ },
17
+ {
18
+ name: "Warning",
19
+ props: { warning: true, helperText: "Helper text goes here" },
20
+ },
21
+ { name: "Disabled", props: { disabled: true } },
22
+ ] as const;
23
+
24
+ const sectionHeading: React.CSSProperties = {
25
+ margin: "0 0 20px",
26
+ fontSize: 14,
27
+ fontWeight: 600,
28
+ textTransform: "uppercase",
29
+ letterSpacing: 0.5,
30
+ color: "#52545d",
31
+ };
32
+
33
+ const meta = {
34
+ title: "Components/PasswordField",
35
+ component: PasswordFieldV01,
36
+ tags: ["autodocs"],
37
+ parameters: {
38
+ layout: "centered",
39
+ docs: {
40
+ description: {
41
+ component: [
42
+ "Password input — the text field plus a show/hide toggle.",
43
+ "",
44
+ "Stories are the seven states: **Default**, **Focus**, **Active**, **Filled**,",
45
+ "**Error**, **Warning** and **Disabled**. Use **Controls** for the label,",
46
+ "placeholder and helper text. All Variants shows every state.",
47
+ "",
48
+ "---",
49
+ "",
50
+ "## Import",
51
+ "",
52
+ "```tsx",
53
+ `import { PasswordFieldV01 } from "@syscore/ui-library"`,
54
+ "```",
55
+ "",
56
+ "## How to use",
57
+ "",
58
+ "It wraps `TextFieldV01`, so every state and prop carries over. The toggle",
59
+ "flips the input between `password` and `text` and is uncontrolled by",
60
+ "default; pass `visible` to drive it yourself.",
61
+ "",
62
+ "```tsx",
63
+ "<PasswordFieldV01",
64
+ ` label="Password"`,
65
+ " value={password}",
66
+ " onChange={(e) => setPassword(e.target.value)}",
67
+ " error={tooShort}",
68
+ ` helperText={tooShort ? "Use at least 12 characters" : undefined}`,
69
+ "/>",
70
+ "```",
71
+ "",
72
+ "The toggle is a real button carrying `aria-pressed` and a label that reads",
73
+ "Show password / Hide password.",
74
+ "",
75
+ "## Props",
76
+ "",
77
+ "| Prop | Values | Default | Effect |",
78
+ "|------|--------|---------|--------|",
79
+ "| `visible` | `boolean` | — | Controlled reveal |",
80
+ "| `defaultVisible` | `boolean` | `false` | Uncontrolled reveal |",
81
+ "| `onVisibleChange` | `(visible: boolean) => void` | — | Fires on toggle |",
82
+ "| `warning` | `boolean` | `false` | Bronze border, tinted fill, bronze message |",
83
+ "| `error` | `boolean` | `false` | Coral border, tinted fill, coral message |",
84
+ "",
85
+ "Everything else matches `Components/TextField`.",
86
+ ].join("\n"),
87
+ },
88
+ },
89
+ },
90
+ argTypes: {
91
+ label: { control: "text" },
92
+ placeholder: { control: "text" },
93
+ helperText: { control: "text" },
94
+ error: { control: "boolean" },
95
+ warning: { control: "boolean" },
96
+ disabled: { control: "boolean" },
97
+ defaultVisible: { control: "boolean" },
98
+ focused: { table: { disable: true } },
99
+ visible: { table: { disable: true } },
100
+ value: { table: { disable: true } },
101
+ },
102
+ args: {
103
+ label: "Label",
104
+ placeholder: "Placeholder",
105
+ },
106
+ } satisfies Meta<typeof PasswordFieldV01>;
107
+
108
+ export default meta;
109
+ type Story = StoryObj<typeof meta>;
110
+
111
+ export const Default: Story = {};
112
+
113
+ export const Focus: Story = {
114
+ args: { focused: true },
115
+ };
116
+
117
+ export const Active: Story = {
118
+ args: { focused: true, defaultValue: "aaaaaghdovnmnvbj" },
119
+ };
120
+
121
+ export const Filled: Story = {
122
+ args: { defaultValue: "aaaaaghdovnmnvbj" },
123
+ };
124
+
125
+ export const Error: Story = {
126
+ args: { error: true, helperText: "Helper text goes here" },
127
+ };
128
+
129
+ export const Warning: Story = {
130
+ args: { warning: true, helperText: "Helper text goes here" },
131
+ };
132
+
133
+ export const Disabled: Story = {
134
+ args: { disabled: true },
135
+ };
136
+
137
+ export const AllVariants: Story = {
138
+ name: "All Variants",
139
+ parameters: { layout: "padded" },
140
+ render: (args) => (
141
+ <div
142
+ style={{
143
+ display: "flex",
144
+ flexDirection: "column",
145
+ gap: 56,
146
+ padding: "32px 24px 48px",
147
+ }}
148
+ >
149
+ {specimens.map((specimen) => (
150
+ <section key={specimen.name}>
151
+ <h3 style={sectionHeading}>{specimen.name}</h3>
152
+ <PasswordFieldV01
153
+ label={args.label}
154
+ placeholder={args.placeholder}
155
+ {...specimen.props}
156
+ />
157
+ </section>
158
+ ))}
159
+ </div>
160
+ ),
161
+ };