@g4rcez/components 3.0.0 → 3.0.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.
Files changed (176) hide show
  1. package/dist/ai/SKILL.md +266 -0
  2. package/dist/ai/docs/Alert.md +167 -0
  3. package/dist/ai/docs/AnimatedList.md +205 -0
  4. package/dist/ai/docs/Autocomplete.md +225 -0
  5. package/dist/ai/docs/Button.md +182 -0
  6. package/dist/ai/docs/Calendar.md +219 -0
  7. package/dist/ai/docs/Card.md +174 -0
  8. package/dist/ai/docs/Checkbox.md +199 -0
  9. package/dist/ai/docs/CommandPalette.md +293 -0
  10. package/dist/ai/docs/DatePicker.md +171 -0
  11. package/dist/ai/docs/Dropdown.md +223 -0
  12. package/dist/ai/docs/Empty.md +163 -0
  13. package/dist/ai/docs/Expand.md +143 -0
  14. package/dist/ai/docs/FileUpload.md +225 -0
  15. package/dist/ai/docs/Form.md +107 -0
  16. package/dist/ai/docs/FormReset.md +117 -0
  17. package/dist/ai/docs/Heading.md +88 -0
  18. package/dist/ai/docs/Input.md +237 -0
  19. package/dist/ai/docs/InputField.md +170 -0
  20. package/dist/ai/docs/List.md +205 -0
  21. package/dist/ai/docs/Menu.md +166 -0
  22. package/dist/ai/docs/Modal.md +280 -0
  23. package/dist/ai/docs/MultiSelect.md +196 -0
  24. package/dist/ai/docs/Notifications.md +231 -0
  25. package/dist/ai/docs/PageCalendar.md +271 -0
  26. package/dist/ai/docs/Polymorph.md +159 -0
  27. package/dist/ai/docs/Progress.md +145 -0
  28. package/dist/ai/docs/Radiobox.md +128 -0
  29. package/dist/ai/docs/RenderOnView.md +138 -0
  30. package/dist/ai/docs/Resizable.md +159 -0
  31. package/dist/ai/docs/Select.md +284 -0
  32. package/dist/ai/docs/Shortcut.md +105 -0
  33. package/dist/ai/docs/Skeleton.md +166 -0
  34. package/dist/ai/docs/Slider.md +144 -0
  35. package/dist/ai/docs/Slot.md +173 -0
  36. package/dist/ai/docs/Spinner.md +118 -0
  37. package/dist/ai/docs/Stats.md +137 -0
  38. package/dist/ai/docs/Step.md +159 -0
  39. package/dist/ai/docs/Switch.md +167 -0
  40. package/dist/ai/docs/Table.md +298 -0
  41. package/dist/ai/docs/Tabs.md +191 -0
  42. package/dist/ai/docs/Tag.md +224 -0
  43. package/dist/ai/docs/TaskList.md +144 -0
  44. package/dist/ai/docs/Textarea.md +167 -0
  45. package/dist/ai/docs/Timeline.md +210 -0
  46. package/dist/ai/docs/Toolbar.md +132 -0
  47. package/dist/ai/docs/Tooltip.md +231 -0
  48. package/dist/ai/docs/TransferList.md +142 -0
  49. package/dist/ai/docs/Typography.md +187 -0
  50. package/dist/ai/docs/Wizard.md +213 -0
  51. package/dist/ai/docs/index.md +183 -0
  52. package/dist/components/core/tag.d.ts +1 -1
  53. package/dist/components/core/tag.d.ts.map +1 -1
  54. package/dist/components/display/list.d.ts.map +1 -1
  55. package/dist/components/floating/dropdown.d.ts +1 -0
  56. package/dist/components/floating/dropdown.d.ts.map +1 -1
  57. package/dist/components/floating/menu.d.ts.map +1 -1
  58. package/dist/config/default-translations.d.ts +4 -4
  59. package/dist/hooks/use-translations.d.ts +4 -4
  60. package/dist/hooks/use-translations.d.ts.map +1 -1
  61. package/dist/index.css +1 -1
  62. package/dist/index.js +28 -20
  63. package/dist/index.js.map +1 -1
  64. package/dist/index.mjs +2463 -2458
  65. package/dist/index.mjs.map +1 -1
  66. package/dist/index.umd.js +12 -12
  67. package/dist/index.umd.js.map +1 -1
  68. package/package.json +4 -4
  69. package/dist/components/core/button.jsx +0 -79
  70. package/dist/components/core/heading.jsx +0 -4
  71. package/dist/components/core/polymorph.jsx +0 -5
  72. package/dist/components/core/render-on-view.jsx +0 -31
  73. package/dist/components/core/resizable.jsx +0 -51
  74. package/dist/components/core/slot.jsx +0 -156
  75. package/dist/components/core/tag.jsx +0 -51
  76. package/dist/components/core/typography.jsx +0 -22
  77. package/dist/components/display/alert.jsx +0 -58
  78. package/dist/components/display/calendar.jsx +0 -299
  79. package/dist/components/display/card.jsx +0 -43
  80. package/dist/components/display/empty.jsx +0 -11
  81. package/dist/components/display/list.jsx +0 -81
  82. package/dist/components/display/notifications.jsx +0 -126
  83. package/dist/components/display/progress.jsx +0 -11
  84. package/dist/components/display/shortcut.jsx +0 -23
  85. package/dist/components/display/skeleton.jsx +0 -12
  86. package/dist/components/display/spinner.jsx +0 -7
  87. package/dist/components/display/stats.jsx +0 -20
  88. package/dist/components/display/step.jsx +0 -131
  89. package/dist/components/display/tabs.jsx +0 -98
  90. package/dist/components/display/timeline.jsx +0 -25
  91. package/dist/components/floating/command-palette.jsx +0 -194
  92. package/dist/components/floating/dropdown.jsx +0 -53
  93. package/dist/components/floating/expand.jsx +0 -44
  94. package/dist/components/floating/menu.jsx +0 -147
  95. package/dist/components/floating/modal.jsx +0 -299
  96. package/dist/components/floating/toolbar.jsx +0 -5
  97. package/dist/components/floating/tooltip.jsx +0 -58
  98. package/dist/components/floating/wizard.jsx +0 -161
  99. package/dist/components/form/autocomplete.jsx +0 -279
  100. package/dist/components/form/checkbox.jsx +0 -12
  101. package/dist/components/form/date-picker.jsx +0 -115
  102. package/dist/components/form/file-upload.jsx +0 -133
  103. package/dist/components/form/form.jsx +0 -10
  104. package/dist/components/form/formReset.jsx +0 -17
  105. package/dist/components/form/free-text.jsx +0 -41
  106. package/dist/components/form/input-field.jsx +0 -56
  107. package/dist/components/form/input.jsx +0 -36
  108. package/dist/components/form/multi-select.jsx +0 -328
  109. package/dist/components/form/radiobox.jsx +0 -6
  110. package/dist/components/form/select.jsx +0 -42
  111. package/dist/components/form/slider.jsx +0 -45
  112. package/dist/components/form/switch.jsx +0 -46
  113. package/dist/components/form/task-list.jsx +0 -26
  114. package/dist/components/form/textarea.jsx +0 -12
  115. package/dist/components/form/transfer-list.jsx +0 -39
  116. package/dist/components/index.js +0 -45
  117. package/dist/components/page-calendar/calendar-header.jsx +0 -81
  118. package/dist/components/page-calendar/day-view.jsx +0 -87
  119. package/dist/components/page-calendar/event-pill.jsx +0 -25
  120. package/dist/components/page-calendar/index.js +0 -2
  121. package/dist/components/page-calendar/month-view.jsx +0 -47
  122. package/dist/components/page-calendar/page-calendar.jsx +0 -41
  123. package/dist/components/page-calendar/page-calendar.types.js +0 -1
  124. package/dist/components/page-calendar/page-calendar.utils.js +0 -71
  125. package/dist/components/page-calendar/week-view.jsx +0 -64
  126. package/dist/components/table/filter.jsx +0 -141
  127. package/dist/components/table/group.jsx +0 -68
  128. package/dist/components/table/index.jsx +0 -60
  129. package/dist/components/table/inner-table.jsx +0 -104
  130. package/dist/components/table/metadata.jsx +0 -36
  131. package/dist/components/table/pagination.jsx +0 -73
  132. package/dist/components/table/row.jsx +0 -58
  133. package/dist/components/table/sort.jsx +0 -105
  134. package/dist/components/table/table-lib.js +0 -83
  135. package/dist/components/table/table.context.jsx +0 -4
  136. package/dist/components/table/thead.jsx +0 -103
  137. package/dist/config/context.js +0 -12
  138. package/dist/config/default-translations.jsx +0 -83
  139. package/dist/config/default-tweaks.js +0 -4
  140. package/dist/constants.js +0 -2
  141. package/dist/hooks/use-click-outside.js +0 -17
  142. package/dist/hooks/use-color-parser.js +0 -9
  143. package/dist/hooks/use-components-provider.jsx +0 -19
  144. package/dist/hooks/use-debounce.js +0 -12
  145. package/dist/hooks/use-floating-ref.js +0 -6
  146. package/dist/hooks/use-form.js +0 -550
  147. package/dist/hooks/use-hover.js +0 -18
  148. package/dist/hooks/use-input-id.js +0 -5
  149. package/dist/hooks/use-is-coarse-device.js +0 -12
  150. package/dist/hooks/use-locale.js +0 -10
  151. package/dist/hooks/use-media-query.js +0 -25
  152. package/dist/hooks/use-on-event.js +0 -7
  153. package/dist/hooks/use-parent.js +0 -21
  154. package/dist/hooks/use-preferences.js +0 -23
  155. package/dist/hooks/use-previous.js +0 -9
  156. package/dist/hooks/use-reactive.js +0 -9
  157. package/dist/hooks/use-remove-scroll.js +0 -61
  158. package/dist/hooks/use-resize-observer.js +0 -17
  159. package/dist/hooks/use-stable-ref.js +0 -9
  160. package/dist/hooks/use-swipe.js +0 -17
  161. package/dist/hooks/use-translations.js +0 -9
  162. package/dist/hooks/use-tweaks.js +0 -9
  163. package/dist/hooks/use-window-size.js +0 -14
  164. package/dist/lib/combi-keys.js +0 -60
  165. package/dist/lib/dict.js +0 -39
  166. package/dist/lib/dom.js +0 -62
  167. package/dist/lib/fns.js +0 -46
  168. package/dist/lib/fzf.js +0 -117
  169. package/dist/lib/keyboard-area.js +0 -14
  170. package/dist/styles/common.js +0 -29
  171. package/dist/styles/dark.js +0 -214
  172. package/dist/styles/design-tokens.js +0 -69
  173. package/dist/styles/light.js +0 -214
  174. package/dist/styles/theme.js +0 -4
  175. package/dist/styles/theme.types.js +0 -1
  176. package/dist/types.js +0 -1
@@ -0,0 +1,224 @@
1
+ ---
2
+ title: Tag
3
+ description: A label/badge component for displaying metadata, status, or categorization information.
4
+ package: "@g4rcez/components"
5
+ export: "{ Tag }"
6
+ import: "import { Tag } from '@g4rcez/components/tag'"
7
+ category: core
8
+ ---
9
+
10
+ # Tag
11
+
12
+ A versatile label/badge component for displaying metadata, status, or categorization information. Built with polymorphic capabilities and multiple visual variants.
13
+
14
+ ## Import
15
+
16
+ ```tsx
17
+ import { Tag } from "@g4rcez/components/tag";
18
+ ```
19
+
20
+ ## Props
21
+
22
+ | Prop | Type | Default | Description |
23
+ |------|------|---------|-------------|
24
+ | `theme` | `"primary" \| "secondary" \| "info" \| "warn" \| "danger" \| "success" \| "muted" \| "neutral" \| "custom" \| "disabled" \| "loading"` | `"primary"` | Visual theme/variant of the tag |
25
+ | `size` | `"icon" \| "small" \| "default" \| "big" \| "tiny"` | `"default"` | Size of the tag |
26
+ | `icon` | `React.ReactNode` | - | Icon to display inside the tag |
27
+ | `indicator` | `"primary" \| "secondary" \| "info" \| "warn" \| "danger" \| "success" \| "muted" \| "neutral"` | - | Shows a small colored dot before the label |
28
+ | `loading` | `boolean` | `false` | Overrides theme with pulse animation |
29
+ | `as` | `React.ElementType` | `"span"` | HTML element to render as |
30
+ | `className` | `string` | - | Additional CSS classes |
31
+ | `children` | `React.ReactNode` | - | Tag content |
32
+
33
+ ## Design Tokens
34
+
35
+ Tokens this component reads. Customize by overriding these CSS variables in your theme.
36
+
37
+ | Token | CSS Variable | Purpose |
38
+ |-------|-------------|---------|
39
+ | `bg-tag-primary-bg` | `--tag-primary-bg` | Background for primary theme |
40
+ | `text-tag-primary-text` | `--tag-primary-text` | Text color for primary theme |
41
+ | `bg-tag-secondary-bg` | `--tag-secondary-bg` | Background for secondary theme |
42
+ | `text-tag-secondary-text` | `--tag-secondary-text` | Text color for secondary theme |
43
+ | `bg-tag-info-bg` | `--tag-info-bg` | Background for info theme |
44
+ | `text-tag-info-text` | `--tag-info-text` | Text color for info theme |
45
+ | `bg-tag-warn-bg` | `--tag-warn-bg` | Background for warn theme |
46
+ | `text-tag-warn-text` | `--tag-warn-text` | Text color for warn theme |
47
+ | `bg-tag-danger-bg` | `--tag-danger-bg` | Background for danger theme |
48
+ | `text-tag-danger-text` | `--tag-danger-text` | Text color for danger theme |
49
+ | `bg-tag-success-bg` | `--tag-success-bg` | Background for success theme |
50
+ | `text-tag-success-text` | `--tag-success-text` | Text color for success theme |
51
+ | `bg-tag-muted-bg` | `--tag-muted-bg` | Background for muted theme |
52
+ | `text-tag-muted-text` | `--tag-muted-text` | Text color for muted theme |
53
+ | `bg-disabled` | `--disabled` | Background for disabled/loading states |
54
+ | `border-card-border` | `--card-border` | Border color for neutral theme |
55
+ | `rounded-pill` | `--radius-pill` | Pill border radius applied to all tags |
56
+ | `bg-primary` | `--primary` | Dot color for primary indicator |
57
+ | `bg-secondary` | `--secondary` | Dot color for secondary indicator |
58
+ | `bg-info` | `--info` | Dot color for info indicator |
59
+ | `bg-warn` | `--warn` | Dot color for warn indicator |
60
+ | `bg-danger` | `--danger` | Dot color for danger indicator |
61
+ | `bg-success` | `--success` | Dot color for success indicator |
62
+ | `bg-muted` | `--muted` | Dot color for muted indicator |
63
+
64
+ ## Theme Variants
65
+
66
+ - `primary`: Primary brand color
67
+ - `secondary`: Secondary color scheme
68
+ - `info`: Informational styling
69
+ - `warn`: Warning/caution styling
70
+ - `danger`: Error/destructive styling
71
+ - `success`: Success/positive styling
72
+ - `muted`: Subtle/subdued styling
73
+ - `neutral`: Transparent with card border
74
+ - `custom`: No default styling — supply all classes via `className`
75
+ - `disabled`: Disabled appearance with reduced opacity
76
+ - `loading`: Pulse animation (also triggered by the `loading` boolean prop)
77
+
78
+ ## Examples
79
+
80
+ ### Basic Variants
81
+
82
+ ```tsx
83
+ <Tag theme="primary">Primary</Tag>
84
+ <Tag theme="secondary">Secondary</Tag>
85
+ <Tag theme="info">Info</Tag>
86
+ <Tag theme="warn">Warning</Tag>
87
+ <Tag theme="danger">Error</Tag>
88
+ <Tag theme="success">Success</Tag>
89
+ <Tag theme="muted">Muted</Tag>
90
+ <Tag theme="neutral">Neutral</Tag>
91
+ ```
92
+
93
+ ### Sizes
94
+
95
+ ```tsx
96
+ <Tag size="small">Small</Tag>
97
+ <Tag size="default">Default</Tag>
98
+ <Tag size="big">Big</Tag>
99
+ ```
100
+
101
+ ### With Icons
102
+
103
+ ```tsx
104
+ import { StarIcon, CheckIcon } from "lucide-react";
105
+
106
+ <Tag icon={<StarIcon size={14} />} theme="warn">Featured</Tag>
107
+ <Tag icon={<CheckIcon size={14} />} theme="success">Completed</Tag>
108
+ ```
109
+
110
+ ### With Indicators
111
+
112
+ ```tsx
113
+ <Tag indicator="success">Online</Tag>
114
+ <Tag indicator="danger">Offline</Tag>
115
+ <Tag indicator="warn">Pending</Tag>
116
+ ```
117
+
118
+ ### Status Tags
119
+
120
+ ```tsx
121
+ const statusMap: Record<string, { theme: "success" | "warn" | "muted" | "danger" }> = {
122
+ active: { theme: "success" },
123
+ pending: { theme: "warn" },
124
+ inactive: { theme: "muted" },
125
+ error: { theme: "danger" },
126
+ };
127
+
128
+ const StatusTag = ({ status }: { status: string }) => {
129
+ const config = statusMap[status] ?? statusMap.inactive;
130
+ return (
131
+ <Tag theme={config.theme} indicator={config.theme}>
132
+ {status.charAt(0).toUpperCase() + status.slice(1)}
133
+ </Tag>
134
+ );
135
+ };
136
+ ```
137
+
138
+ ### Loading State
139
+
140
+ ```tsx
141
+ <Tag loading theme="primary">Processing...</Tag>
142
+ ```
143
+
144
+ ### Polymorphic Usage
145
+
146
+ ```tsx
147
+ <Tag as="button" onClick={() => void 0} theme="primary">
148
+ Clickable Tag
149
+ </Tag>
150
+
151
+ <Tag as="a" href="/category/react" theme="info">
152
+ React
153
+ </Tag>
154
+ ```
155
+
156
+ ### Content Categorization
157
+
158
+ ```tsx
159
+ const categories = [
160
+ { name: "React", theme: "info" },
161
+ { name: "TypeScript", theme: "primary" },
162
+ { name: "CSS", theme: "success" },
163
+ ];
164
+
165
+ <div className="flex gap-2 flex-wrap">
166
+ {categories.map((cat) => (
167
+ <Tag key={cat.name} theme={cat.theme as any}>
168
+ {cat.name}
169
+ </Tag>
170
+ ))}
171
+ </div>
172
+ ```
173
+
174
+ ### Notification Badge
175
+
176
+ ```tsx
177
+ import { BellIcon } from "lucide-react";
178
+
179
+ <div className="relative">
180
+ <BellIcon size={24} />
181
+ <Tag
182
+ size="small"
183
+ theme="danger"
184
+ className="absolute -top-2 -right-2 min-w-[20px] h-5 text-xs"
185
+ >
186
+ 3
187
+ </Tag>
188
+ </div>
189
+ ```
190
+
191
+ ## Do
192
+
193
+ - Use `theme="success"` for positive states and `theme="danger"` for errors — keep it consistent
194
+ - Keep tag labels short and scannable
195
+ - Use `indicator` to add extra color meaning without extra text
196
+ - Use `as="button"` when the tag performs an action (e.g., removing a filter)
197
+ - Use design-token classes for wrapper elements (`bg-muted`, `border-border`)
198
+
199
+ ## Don't
200
+
201
+ - Don't pass raw Tailwind color classes (`bg-blue-500`, `text-white`) — use `theme` prop instead
202
+ - Don't use arbitrary Tailwind values (`bg-[#abc]`, `bg-[--my-var]`) — override CSS variables in your `@theme` block
203
+ - Don't use too many different themes on one screen — excessive color variety is distracting
204
+ - Don't use `Tag` as a replacement for `Button` on primary actions
205
+ - Don't combine `icon` and `indicator` on a small tag — it becomes too visually busy
206
+
207
+ ## Accessibility
208
+
209
+ - Uses semantic HTML via the `as` prop (defaults to `<span>`)
210
+ - The indicator dot is `aria-hidden="true"` — it is purely decorative
211
+ - When used as a `button` or `a`, standard keyboard navigation applies
212
+ - Ensure color meaning is supplemented by text — do not rely on color alone
213
+
214
+ ## Data Attributes
215
+
216
+ - `data-component="tag"`: Identifies the component for styling/testing
217
+ - `data-theme`: Current theme variant value
218
+
219
+ ## Notes
220
+
221
+ - The `loading` prop overrides the `theme` value and applies the loading animation
222
+ - Once `loading` becomes `false`, the original `theme` is restored
223
+ - The component forwards refs to the underlying element
224
+ - All standard HTML attributes for the target element are forwarded
@@ -0,0 +1,144 @@
1
+ ---
2
+ title: TaskList
3
+ description: Fieldset container that triggers a celebratory animation when all child tasks are checked.
4
+ package: "@g4rcez/components"
5
+ export: "{ TaskList }"
6
+ import: "import { TaskList } from '@g4rcez/components/task-list'"
7
+ category: form
8
+ ---
9
+
10
+ # TaskList
11
+
12
+ Fieldset container that triggers a celebratory animation when all child tasks are checked.
13
+
14
+ ## Import
15
+
16
+ ```tsx
17
+ import { TaskList } from "@g4rcez/components/task-list";
18
+ import { Checkbox } from "@g4rcez/components/checkbox";
19
+ ```
20
+
21
+ ## Props
22
+
23
+ Accepts all standard HTML `<fieldset>` attributes.
24
+
25
+ | Prop | Type | Default | Description |
26
+ |------|------|---------|-------------|
27
+ | `children` | `React.ReactNode` | — | `Checkbox` components with the `asTask` prop. |
28
+ | `className` | `string` | — | Additional CSS classes for the `<fieldset>`. |
29
+
30
+ ## Design Tokens
31
+
32
+ `TaskList` itself is a plain `<fieldset>` and inherits ambient tokens from its children. No component-scoped tokens are consumed directly. Style the container using semantic tokens:
33
+
34
+ | Token | CSS Variable | Purpose |
35
+ |-------|-------------|---------|
36
+ | `border-border` | `--border` | Optional border around the task group |
37
+ | `bg-background` | `--background` | Container background |
38
+ | `text-foreground` | `--foreground` | Task label text |
39
+
40
+ ## Examples
41
+
42
+ ### Basic task list
43
+
44
+ ```tsx
45
+ import { TaskList } from "@g4rcez/components/task-list";
46
+ import { Checkbox } from "@g4rcez/components/checkbox";
47
+
48
+ export default function OnboardingChecklist() {
49
+ return (
50
+ <TaskList className="flex flex-col gap-sm border border-border rounded-card p-4">
51
+ <Checkbox asTask>Complete initial setup</Checkbox>
52
+ <Checkbox asTask>Upload profile picture</Checkbox>
53
+ <Checkbox asTask>Verify email address</Checkbox>
54
+ </TaskList>
55
+ );
56
+ }
57
+ ```
58
+
59
+ ### Dynamic tasks from state
60
+
61
+ ```tsx
62
+ import { useState } from "react";
63
+ import { TaskList } from "@g4rcez/components/task-list";
64
+ import { Checkbox } from "@g4rcez/components/checkbox";
65
+
66
+ type Task = { id: string; text: string; done: boolean };
67
+
68
+ export default function DynamicTaskList({ tasks }: { tasks: Task[] }) {
69
+ const [items, setItems] = useState(tasks);
70
+
71
+ const toggle = (id: string) =>
72
+ setItems((prev) =>
73
+ prev.map((t) => (t.id === id ? { ...t, done: !t.done } : t))
74
+ );
75
+
76
+ return (
77
+ <TaskList className="flex flex-col gap-sm">
78
+ {items.map((task) => (
79
+ <Checkbox
80
+ key={task.id}
81
+ asTask
82
+ checked={task.done}
83
+ onChange={() => toggle(task.id)}
84
+ >
85
+ {task.text}
86
+ </Checkbox>
87
+ ))}
88
+ </TaskList>
89
+ );
90
+ }
91
+ ```
92
+
93
+ ### Grouped tasks with a legend
94
+
95
+ ```tsx
96
+ import { TaskList } from "@g4rcez/components/task-list";
97
+ import { Checkbox } from "@g4rcez/components/checkbox";
98
+
99
+ export default function ProjectSubtasks() {
100
+ return (
101
+ <TaskList className="flex flex-col gap-sm rounded-card border border-border p-4">
102
+ <legend className="px-1 text-sm font-medium text-foreground">
103
+ Phase 1 — Design
104
+ </legend>
105
+ <Checkbox asTask>Create wireframes</Checkbox>
106
+ <Checkbox asTask>Review with stakeholders</Checkbox>
107
+ <Checkbox asTask>Export design tokens</Checkbox>
108
+ </TaskList>
109
+ );
110
+ }
111
+ ```
112
+
113
+ ## Do
114
+
115
+ - Use `asTask` on every `Checkbox` inside `TaskList` so they are counted for the completion animation.
116
+ - Group closely related tasks — the animation is most meaningful when all items belong to one milestone.
117
+ - Provide adequate vertical spacing between items (`gap-sm`, `gap-base`) for readability.
118
+ - Use design-token classes for wrappers (`bg-background`, `border-border`, `rounded-card`).
119
+
120
+ ## Don't
121
+
122
+ - Don't use `TaskList` for checkboxes that are not tasks (e.g., bulk-selection rows in a table).
123
+ - Don't pack too many unrelated tasks into a single list; split them into smaller groups.
124
+ - Don't pass raw Tailwind color classes (`bg-gray-100`, `border-gray-300`) — use design tokens instead.
125
+ - Don't use arbitrary Tailwind values (`bg-[#abc]`) — override CSS variables in your `@theme` block instead.
126
+
127
+ ## Accessibility
128
+
129
+ - Renders a semantic `<fieldset>` to group related inputs — pair with a `<legend>` for a fully accessible group label.
130
+ - Inherits all accessibility features of the underlying `Checkbox` component.
131
+ - The completion animation (scale + rotate) is visual-only and does not alter keyboard or screen-reader behavior.
132
+
133
+ ## Data Attributes
134
+
135
+ | Attribute | Element | Value | Description |
136
+ |-----------|---------|-------|-------------|
137
+ | `data-component` | `fieldset` | `"task-list"` | Identifies the component. |
138
+ | `data-task` | child `input` | `"true"` | Must be present on child checkbox inputs for them to be counted in the completion check. Set automatically via `asTask`. |
139
+
140
+ ## Notes
141
+
142
+ - The animation is powered by `motion/react`. When all `input[data-task=true]` elements inside the fieldset are checked, a staggered scale + rotate animation fires starting from the last-checked item's index.
143
+ - `TaskList` attaches a single `change` event listener on the `<fieldset>` (event delegation) — no per-item wiring is required.
144
+ - The animation runs once per "all complete" event; unchecking an item and re-checking to completion will replay it.
@@ -0,0 +1,167 @@
1
+ ---
2
+ title: Textarea
3
+ description: Auto-growing multi-line text input built on the InputField foundation.
4
+ package: "@g4rcez/components"
5
+ export: "{ Textarea }"
6
+ import: "import { Textarea } from '@g4rcez/components'"
7
+ category: form
8
+ ---
9
+
10
+ # Textarea
11
+
12
+ Auto-growing multi-line text input built on the InputField foundation.
13
+
14
+ ## Import
15
+
16
+ ```tsx
17
+ import { Textarea } from "@g4rcez/components";
18
+ ```
19
+
20
+ ## Props
21
+
22
+ Inherits all `InputField` props and standard HTML `<textarea>` attributes, plus:
23
+
24
+ | Prop | Type | Default | Description |
25
+ |------|------|---------|-------------|
26
+ | `title` | `Label` | — | Label for the textarea. |
27
+ | `error` | `string` | — | Error message displayed below the field. |
28
+ | `loading` | `boolean` | `false` | Disables the field and signals a pending state. |
29
+ | `rows` | `number` | `2` | Initial number of visible text rows. |
30
+ | `next` | `string` | — | ID of the next element to focus when Enter is pressed (requires `enterKeyHint="next"`). |
31
+ | `placeholder` | `string` | — | Placeholder text. |
32
+ | `required` | `boolean` | — | Marks the field as required. |
33
+ | `className` | `string` | — | Additional CSS classes for the `<textarea>` element. |
34
+
35
+ ## Design Tokens
36
+
37
+ Tokens this component reads. Customize by overriding these CSS variables in your theme.
38
+
39
+ | Token | CSS Variable | Purpose |
40
+ |-------|-------------|---------|
41
+ | `placeholder-input-mask` | `--input-mask` | Placeholder text color |
42
+ | `placeholder-input-mask-error` (via `group-error`) | `--input-mask-error` | Placeholder tint in error state |
43
+ | `text-foreground` | `--foreground` | Input text color |
44
+ | `text-danger` (via `group-error`) | `--danger` | Text color in error state |
45
+ | `bg-transparent` | — | Input background (inherits from field wrapper) |
46
+ | `focus:ring-primary` | `--primary` | Focus ring |
47
+ | `group-focus-within:border-primary` | `--primary` | Border highlight on focus |
48
+ | `group-hover:border-primary` | `--primary` | Border highlight on hover |
49
+ | `h-input-height` | `--input-height` | Base height token (overridden by `rows` in practice) |
50
+ | `px-input-x` | `--input-x` | Horizontal padding |
51
+ | `py-input-y` | `--input-y` | Vertical padding |
52
+
53
+ ## Examples
54
+
55
+ ### Basic usage
56
+
57
+ ```tsx
58
+ import { Textarea } from "@g4rcez/components";
59
+
60
+ export default function BioField() {
61
+ return (
62
+ <Textarea
63
+ title="Bio"
64
+ name="bio"
65
+ placeholder="Tell us about yourself…"
66
+ rows={4}
67
+ onChange={(e) => console.log(e.target.value)}
68
+ />
69
+ );
70
+ }
71
+ ```
72
+
73
+ ### With validation error
74
+
75
+ ```tsx
76
+ import { Textarea } from "@g4rcez/components";
77
+
78
+ export default function MessageField() {
79
+ return (
80
+ <Textarea
81
+ title="Message"
82
+ name="message"
83
+ required
84
+ error="Message is required and must be at least 10 characters."
85
+ placeholder="Enter your message…"
86
+ />
87
+ );
88
+ }
89
+ ```
90
+
91
+ ### Monospace styling for code
92
+
93
+ ```tsx
94
+ import { Textarea } from "@g4rcez/components";
95
+
96
+ export default function CssSnippetField() {
97
+ return (
98
+ <Textarea
99
+ title="CSS Snippet"
100
+ name="css"
101
+ className="font-mono text-sm"
102
+ rows={6}
103
+ placeholder="body { margin: 0; }"
104
+ />
105
+ );
106
+ }
107
+ ```
108
+
109
+ ### Focus-next navigation
110
+
111
+ ```tsx
112
+ import { Textarea } from "@g4rcez/components";
113
+ import { Input } from "@g4rcez/components";
114
+
115
+ export default function MultiFieldForm() {
116
+ return (
117
+ <div className="flex flex-col gap-base">
118
+ <Textarea
119
+ title="Description"
120
+ name="description"
121
+ enterKeyHint="next"
122
+ next="submit-btn"
123
+ rows={3}
124
+ placeholder="Describe the issue…"
125
+ />
126
+ <button id="submit-btn" type="submit" className="btn">
127
+ Submit
128
+ </button>
129
+ </div>
130
+ );
131
+ }
132
+ ```
133
+
134
+ ## Do
135
+
136
+ - Provide a descriptive `title` to label the field.
137
+ - Set a sensible initial `rows` value based on the expected content length.
138
+ - Use `Textarea` whenever the user is expected to provide more than a single line of text.
139
+ - Use design-token classes on wrapper elements (`bg-background`, `text-foreground`, `border-border`).
140
+
141
+ ## Don't
142
+
143
+ - Don't use `Textarea` for single-line inputs like names or emails — use `Input` instead.
144
+ - Don't fix the height with a `className` like `h-32` if you want the auto-resize behavior to work.
145
+ - Don't pass raw Tailwind color classes (`bg-gray-50`, `border-gray-300`) — use design tokens instead.
146
+ - Don't use arbitrary Tailwind values (`bg-[#abc]`) — override CSS variables in your `@theme` block instead.
147
+
148
+ ## Accessibility
149
+
150
+ - Rendered inside an `InputField` which wraps the element with `<fieldset>` and a `<label>` linked via `id`/`for`.
151
+ - Supports `aria-required`, `aria-invalid`, `aria-disabled`, and `aria-readonly` via prop spread.
152
+ - Keyboard navigation follows standard `<textarea>` behavior (Tab to focus, Shift+Tab to leave).
153
+ - When `enterKeyHint="next"` and a `next` id is provided, pressing Enter moves focus to the target element.
154
+
155
+ ## Data Attributes
156
+
157
+ | Attribute | Element | Value | Description |
158
+ |-----------|---------|-------|-------------|
159
+ | `data-component` | `InputField` root | `"textarea"` | Identifies the component. |
160
+ | `data-error` | `InputField` root | truthy string | Present when an error message is supplied. |
161
+ | `data-next` | `<textarea>` | element id | Target element id for Enter-key focus forwarding. |
162
+
163
+ ## Notes
164
+
165
+ - Auto-resize is driven by a native `input` event listener that sets `style.height = "auto"` then `style.height = scrollHeight + "px"` — no JavaScript polling or ResizeObserver involved.
166
+ - The resize handle is set to `resize-y` by default; add `className="resize-none"` to disable it.
167
+ - Built via the shared `createFreeText` factory, which also powers the `Input` component — all `InputField` layout features (left/right slots, optional text, feedback, etc.) are available.