@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,173 @@
1
+ ---
2
+ title: Slot
3
+ description: A composition primitive that merges its props into a single child element, enabling the asChild pattern.
4
+ package: "@g4rcez/components"
5
+ export: "{ Slot, Slottable, createSlot, createSlottable }"
6
+ import: "import { Slot, Slottable } from '@g4rcez/components'"
7
+ category: core
8
+ ---
9
+
10
+ # Slot
11
+
12
+ A composition primitive that merges its props into a single child element. This enables the `asChild` pattern — letting consumers supply their own element while still receiving component-level styles, event handlers, and ARIA attributes. The implementation follows the Radix UI `Slot` pattern.
13
+
14
+ ## Import
15
+
16
+ ```tsx
17
+ import { Slot, Slottable } from "@g4rcez/components";
18
+ ```
19
+
20
+ ## Exports
21
+
22
+ | Export | Description |
23
+ |--------|-------------|
24
+ | `Slot` | Merges props into the single child element |
25
+ | `Slottable` | Marks which child is the slot target when the component has internal structure |
26
+ | `createSlot(ownerName)` | Factory to create a named `Slot` (for building design-system components) |
27
+ | `createSlottable(ownerName)` | Factory to create a named `Slottable` |
28
+
29
+ ## Props
30
+
31
+ ### Slot
32
+
33
+ | Prop | Type | Default | Description |
34
+ |------|------|---------|-------------|
35
+ | `children` | `React.ReactNode` | - | A single valid React element that will receive all of Slot's props |
36
+ | `ref` | `React.ForwardedRef<HTMLElement>` | - | Forwarded to the child element |
37
+ | `...props` | `React.HTMLAttributes<HTMLElement>` | - | Props merged into the child |
38
+
39
+ ### Slottable
40
+
41
+ | Prop | Type | Default | Description |
42
+ |------|------|---------|-------------|
43
+ | `children` | `React.ReactNode` | - | The element to render as the slot target |
44
+
45
+ ## Design Tokens
46
+
47
+ None — `Slot` is a structural/composition primitive that applies no styles of its own. Any classes passed to `Slot` are merged into the child element's `className`.
48
+
49
+ ## How It Works
50
+
51
+ 1. `Slot` receives props and a single child element.
52
+ 2. It merges `className`, `style`, and event handlers from `Slot`'s own props with those of the child.
53
+ 3. For event handlers: both the `Slot`'s and the child's handlers are called (child first).
54
+ 4. For `className`: values are joined with a space.
55
+ 5. For `style`: `Slot`'s style is spread first, then the child's style overrides.
56
+ 6. The child's element type is rendered — `Slot` itself renders no DOM element.
57
+
58
+ ## Examples
59
+
60
+ ### The asChild Pattern
61
+
62
+ ```tsx
63
+ interface ButtonProps {
64
+ asChild?: boolean;
65
+ children: React.ReactNode;
66
+ className?: string;
67
+ }
68
+
69
+ const StyledButton = ({ asChild, children, ...props }: ButtonProps) => {
70
+ const Component = asChild ? Slot : "button";
71
+ return (
72
+ <Component
73
+ className="inline-flex items-center rounded-button bg-button-primary-bg text-button-primary-text px-4 py-2 font-medium"
74
+ {...props}
75
+ >
76
+ {children}
77
+ </Component>
78
+ );
79
+ };
80
+
81
+ // Renders a <button>
82
+ <StyledButton>Click me</StyledButton>
83
+
84
+ // Renders an <a> with all button styles applied
85
+ <StyledButton asChild>
86
+ <a href="/dashboard">Go to Dashboard</a>
87
+ </StyledButton>
88
+ ```
89
+
90
+ ### Using Slottable for Internal Structure
91
+
92
+ When your component wraps children with additional internal elements, use `Slottable` to mark which child is the slot target.
93
+
94
+ ```tsx
95
+ import { CheckIcon } from "lucide-react";
96
+
97
+ const IconButton = ({ asChild, children, ...props }: { asChild?: boolean; children: React.ReactNode }) => {
98
+ const Component = asChild ? Slot : "button";
99
+ return (
100
+ <Component
101
+ className="inline-flex items-center gap-1.5 rounded-button bg-button-success-bg text-button-success-text px-4 py-2"
102
+ {...props}
103
+ >
104
+ <Slottable>{children}</Slottable>
105
+ <CheckIcon size={14} aria-hidden="true" />
106
+ </Component>
107
+ );
108
+ };
109
+
110
+ // Renders <button> with icon
111
+ <IconButton>Confirm</IconButton>
112
+
113
+ // Renders <a> with icon — the <a> is the slot target
114
+ <IconButton asChild>
115
+ <a href="/confirm">Confirm</a>
116
+ </IconButton>
117
+ ```
118
+
119
+ ### Creating a Named Slot
120
+
121
+ Use `createSlot` when building your own design-system components for better DevTools display names.
122
+
123
+ ```tsx
124
+ import { createSlot, createSlottable } from "@g4rcez/components";
125
+
126
+ const CardSlot = createSlot("Card");
127
+ const CardSlottable = createSlottable("Card");
128
+ ```
129
+
130
+ ### Merging Event Handlers
131
+
132
+ Both handlers are called when both the `Slot` and the child define the same event.
133
+
134
+ ```tsx
135
+ <Slot onClick={() => console.log("slot handler")}>
136
+ <button onClick={() => console.log("child handler")}>
137
+ Click me
138
+ </button>
139
+ </Slot>
140
+ // Logs: "child handler", then "slot handler"
141
+ ```
142
+
143
+ ## Do
144
+
145
+ - Use `Slot` when building reusable components that should support any element type via `asChild`
146
+ - Use `Slottable` when your component wraps children with internal structure (icons, labels)
147
+ - Pass accessibility attributes (`aria-*`, `role`) to `Slot` — they will be merged into the child
148
+ - Use design-token classes in the `className` passed to `Slot` (`rounded-button`, `bg-button-primary-bg`)
149
+
150
+ ## Don't
151
+
152
+ - Don't pass multiple direct children to `Slot` without using `Slottable` — `Slot` expects a single valid element
153
+ - Don't use `Slot` when the element type is fixed and will never change
154
+ - Don't pass raw Tailwind color classes (`bg-blue-500`, `text-white`) in `Slot` className — use design tokens
155
+ - Don't use arbitrary Tailwind values (`bg-[#abc]`) — override CSS variables in your `@theme` block
156
+
157
+ ## Accessibility
158
+
159
+ - `Slot` merges `aria-*` and `role` props into the child element transparently
160
+ - The final rendered element's semantics depend entirely on the child element type
161
+ - Event handlers from both `Slot` and the child are composed — neither is silently dropped
162
+
163
+ ## Data Attributes
164
+
165
+ - `Slot` and `Slottable` use `displayName` for React DevTools identification but add no DOM attributes
166
+ - Any `data-*` attributes passed to `Slot` are merged into the child element
167
+
168
+ ## Notes
169
+
170
+ - Supports `React.lazy` children via `React.use` when available in the React version
171
+ - Ref composition: if both `Slot` and the child have refs, they are composed via `composeRefs`
172
+ - `Slottable` uses an internal symbol (`__radixId`) to identify itself — do not attempt to replicate this check
173
+ - React Fragment children are supported: the composed ref is not applied to `Fragment` (React 19 compatibility)
@@ -0,0 +1,118 @@
1
+ ---
2
+ title: Spinner
3
+ description: Animated loading indicator for unknown-duration operations, available as an inline Spinner or a full-container Loading wrapper.
4
+ package: "@g4rcez/components"
5
+ export: "{ Spinner, Loading }"
6
+ import: "import { Spinner, Loading } from '@g4rcez/components'"
7
+ category: display
8
+ ---
9
+
10
+ # Spinner
11
+
12
+ Animated loading indicator for unknown-duration operations, available as an inline `Spinner` or a full-container `Loading` wrapper.
13
+
14
+ ## Import
15
+
16
+ ```tsx
17
+ import { Spinner, Loading } from "@g4rcez/components";
18
+ ```
19
+
20
+ ## Props
21
+
22
+ ### Spinner
23
+
24
+ | Prop | Type | Default | Description |
25
+ |------|------|---------|-------------|
26
+ | `className` | `string` | — | Additional classes to customize size, color, or border |
27
+
28
+ Default appearance: `size-12 border-4 border-background border-b-primary animate-spin rounded-full`.
29
+
30
+ ### Loading
31
+
32
+ No props. Renders a centered `Spinner` inside a `flex h-full w-full items-center justify-center p-12` container.
33
+
34
+ ## Design Tokens
35
+
36
+ Tokens this component reads. Customize by overriding these CSS variables in your theme.
37
+
38
+ | Token | CSS Variable | Purpose |
39
+ |-------|-------------|---------|
40
+ | `border-background` | `--background` | Inactive spinner ring color |
41
+ | `border-b-primary` | `--primary` | Active spinner arc color |
42
+
43
+ ## Examples
44
+
45
+ ### Default Spinner
46
+
47
+ ```tsx
48
+ <Spinner />
49
+ ```
50
+
51
+ ### Full-Container Loading State
52
+
53
+ ```tsx
54
+ {isLoading ? <Loading /> : <Content />}
55
+ ```
56
+
57
+ ### Custom Size
58
+
59
+ ```tsx
60
+ <Spinner className="size-6 border-2" />
61
+ ```
62
+
63
+ ### Spinner Inside a Button
64
+
65
+ ```tsx
66
+ <button type="submit" disabled={isSubmitting} className="flex items-center gap-2 px-4 py-2 bg-primary text-primary-foreground rounded-button">
67
+ {isSubmitting && <Spinner className="size-4 border-2 border-primary-foreground border-b-transparent" />}
68
+ {isSubmitting ? "Saving…" : "Save"}
69
+ </button>
70
+ ```
71
+
72
+ ### Centered in a Card
73
+
74
+ ```tsx
75
+ import { Card } from "@g4rcez/components/card";
76
+
77
+ <Card title="Analytics">
78
+ <div className="h-64 flex items-center justify-center">
79
+ <Spinner />
80
+ </div>
81
+ </Card>
82
+ ```
83
+
84
+ ### Lazy Component Fallback
85
+
86
+ ```tsx
87
+ import { Suspense } from "react";
88
+ import { Loading } from "@g4rcez/components";
89
+
90
+ <Suspense fallback={<Loading />}>
91
+ <HeavyComponent />
92
+ </Suspense>
93
+ ```
94
+
95
+ ## Do
96
+
97
+ - Use `Loading` for full-page or large-section loading states where the parent already has a defined height.
98
+ - Use `Spinner` inline (e.g. inside buttons) when an action is being processed.
99
+ - Ensure the parent container of `Loading` has a defined height so the spinner centers correctly.
100
+ - Provide a relevant `aria-label` or `aria-description` if the Portuguese default ("Carregando...") is not appropriate.
101
+
102
+ ## Don't
103
+
104
+ - Don't pass raw Tailwind color classes (`border-blue-500`) for the spinner border — use design tokens (`border-primary`) instead.
105
+ - Don't use arbitrary Tailwind values (`border-[#abc]`) — override CSS variables in your `@theme` block.
106
+ - Don't leave a `Spinner` visible indefinitely; always handle error states or timeouts.
107
+ - Don't render many spinners simultaneously on a single screen — it is visually disorienting.
108
+
109
+ ## Accessibility
110
+
111
+ - `Spinner` includes `aria-busy="true"` and `aria-description="Carregando..."` so assistive technologies know content is loading.
112
+ - For non-Portuguese applications, pass a `className` and wrap with a visually hidden `<span aria-live="polite">` if you need a localized announcement.
113
+
114
+ ## Notes
115
+
116
+ - The spinning effect comes from Tailwind's `animate-spin` utility (`animation: spin 1s linear infinite`).
117
+ - The arc effect is achieved via `border-background` for the full ring and `border-b-primary` for the colored arc — one border property per side.
118
+ - `Loading` is a thin wrapper; prefer `Loading` over manually composing `flex items-center justify-center` wrappers every time.
@@ -0,0 +1,137 @@
1
+ ---
2
+ title: Stats
3
+ description: Metric display card with a prominent icon, value, and optional footer for trend or contextual data.
4
+ package: "@g4rcez/components"
5
+ export: "{ Stats }"
6
+ import: "import { Stats } from '@g4rcez/components/stats'"
7
+ category: display
8
+ ---
9
+
10
+ # Stats
11
+
12
+ Metric display card with a prominent icon, value, and optional footer for trend or contextual data.
13
+
14
+ ## Import
15
+
16
+ ```tsx
17
+ import { Stats } from "@g4rcez/components/stats";
18
+ ```
19
+
20
+ ## Props
21
+
22
+ | Prop | Type | Default | Description |
23
+ |------|------|---------|-------------|
24
+ | `title` | `Label` | — | Metric label displayed above the value |
25
+ | `Icon` | `React.FC<{ className: string }>` | — | Icon component to display (Lucide recommended) |
26
+ | `iconContainer` | `string` | — | Additional classes for the icon background container |
27
+ | `footer` | `React.ReactElement` | — | Optional footer area for trend data or context |
28
+ | `children` | `React.ReactNode` | — | The metric value (e.g. a number, formatted string) |
29
+
30
+ ## Design Tokens
31
+
32
+ Tokens this component reads. Customize by overriding these CSS variables in your theme.
33
+
34
+ | Token | CSS Variable | Purpose |
35
+ |-------|-------------|---------|
36
+ | `bg-card-background` | `--card-background` | Card surface |
37
+ | `border-card-border` | `--card-border` | Card border and divider |
38
+ | `rounded-card` | `--radius-card` | Corner radius |
39
+ | `shadow-shadow-card` | `--shadow-card` | Card drop shadow |
40
+ | `bg-primary` | `--primary` | Icon container background (default) |
41
+ | `text-primary-foreground` | `--primary-foreground` | Icon color (default) |
42
+ | `divide-card-border` | `--card-border` | Divider between header and footer |
43
+
44
+ ## Examples
45
+
46
+ ### Basic Metric
47
+
48
+ ```tsx
49
+ import { UsersIcon } from "lucide-react";
50
+
51
+ <Stats title="Active Users" Icon={UsersIcon}>
52
+ 1,234
53
+ </Stats>
54
+ ```
55
+
56
+ ### With Footer Trend
57
+
58
+ ```tsx
59
+ import { TrendingUpIcon, DollarSignIcon } from "lucide-react";
60
+
61
+ <Stats
62
+ title="Revenue"
63
+ Icon={DollarSignIcon}
64
+ iconContainer="bg-success"
65
+ footer={
66
+ <div className="flex items-center gap-1 text-success text-sm font-medium">
67
+ <TrendingUpIcon size={14} />
68
+ <span>+12% from last month</span>
69
+ </div>
70
+ }
71
+ >
72
+ $45,200.00
73
+ </Stats>
74
+ ```
75
+
76
+ ### Custom Icon Container Theme
77
+
78
+ ```tsx
79
+ import { AlertCircleIcon } from "lucide-react";
80
+
81
+ <Stats
82
+ title="Error Rate"
83
+ Icon={AlertCircleIcon}
84
+ iconContainer="bg-danger"
85
+ >
86
+ 0.3%
87
+ </Stats>
88
+ ```
89
+
90
+ ### Dashboard Grid
91
+
92
+ ```tsx
93
+ import { UsersIcon, ClockIcon, TargetIcon } from "lucide-react";
94
+
95
+ <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
96
+ <Stats title="Users" Icon={UsersIcon}>1.2k</Stats>
97
+ <Stats title="Sessions" Icon={ClockIcon}>450</Stats>
98
+ <Stats title="Conversion" Icon={TargetIcon}>3.2%</Stats>
99
+ </div>
100
+ ```
101
+
102
+ ### With Skeleton Loading
103
+
104
+ ```tsx
105
+ import { BarChartIcon } from "lucide-react";
106
+ import { Skeleton } from "@g4rcez/components";
107
+
108
+ <Stats title="Page Views" Icon={BarChartIcon}>
109
+ {isLoading ? <Skeleton className="h-9 w-24" /> : "48,301"}
110
+ </Stats>
111
+ ```
112
+
113
+ ## Do
114
+
115
+ - Use clear, descriptive icons that relate to the metric shown.
116
+ - Keep the metric value prominent and concise — one or two tokens, not a sentence.
117
+ - Use `iconContainer` with design-token color classes (`bg-success`, `bg-danger`) to differentiate metric types visually.
118
+ - Use the `footer` prop to provide trend context (period-over-period comparison).
119
+
120
+ ## Don't
121
+
122
+ - Don't pass raw Tailwind color classes (`bg-green-500`, `text-red-600`) to `iconContainer` or `footer` — use design tokens instead.
123
+ - Don't use arbitrary Tailwind values (`bg-[#abc]`) — override CSS variables in your `@theme` block.
124
+ - Don't place too many `Stats` cards without logical grouping — they lose impact when overused.
125
+ - Don't put long sentences as `title` or `children`; they should be scannable at a glance.
126
+
127
+ ## Accessibility
128
+
129
+ - The metric label uses an `<h3>` element for proper heading hierarchy within a dashboard context.
130
+ - The icon renders via `props.Icon` with a `className` prop applied; Lucide icons include accessible SVG structure.
131
+ - Consider adding `aria-label` to the icon container if the icon carries essential meaning not conveyed by the title.
132
+
133
+ ## Notes
134
+
135
+ - The icon container is sized via `size-10` with `p-8` padding, producing a square aspect ratio. Use `iconContainer` to adjust (`bg-success`, `bg-danger`, etc.).
136
+ - `children` renders in a `<p>` with `text-4xl font-semibold` — pass a pre-formatted string for custom number formatting.
137
+ - The footer section only renders when `footer` is provided; otherwise the divider is omitted.
@@ -0,0 +1,159 @@
1
+ ---
2
+ title: Step
3
+ description: Animated multi-step progress indicator with status tracking for checkout flows, onboarding, and wizards.
4
+ package: "@g4rcez/components"
5
+ export: "{ Step }"
6
+ import: "import { Steps, Step } from '@g4rcez/components'"
7
+ category: display
8
+ ---
9
+
10
+ # Step
11
+
12
+ Animated multi-step progress indicator with status tracking for checkout flows, onboarding, and wizards.
13
+
14
+ ## Import
15
+
16
+ ```tsx
17
+ import { Steps, Step } from "@g4rcez/components";
18
+ ```
19
+
20
+ ## Props
21
+
22
+ ### Steps (Container)
23
+
24
+ | Prop | Type | Default | Description |
25
+ |------|------|---------|-------------|
26
+ | `currentStep` | `number` | — | Index of the currently active step |
27
+ | `steps` | `number` | — | Total number of steps |
28
+ | `children` | `React.ReactNode` | — | `Step` components |
29
+
30
+ ### Step
31
+
32
+ | Prop | Type | Default | Description |
33
+ |------|------|---------|-------------|
34
+ | `step` | `number` | — | Index of this step |
35
+ | `currentStep` | `number` | — | Index of the currently active step (usually from parent) |
36
+ | `title` | `Label` | — | Step label |
37
+ | `status` | `StepStatus` | — | Override automatic status (`"active" \| "inactive" \| "complete" \| "error"`) |
38
+ | `titleClassName` | `string` | — | Additional classes for the title text |
39
+
40
+ Standard `<button>` props are also forwarded (e.g. `onClick`, `disabled`).
41
+
42
+ ## Step Statuses
43
+
44
+ | Status | Visual | Icon |
45
+ |--------|--------|------|
46
+ | `active` | Primary color ring | Step number |
47
+ | `inactive` | Muted border | Step number |
48
+ | `complete` | Success color fill | Animated check mark |
49
+ | `error` | Danger color fill | Animated X mark |
50
+
51
+ Status is derived automatically from `step` vs. `currentStep` unless overridden via `status`.
52
+
53
+ ## Design Tokens
54
+
55
+ Tokens this component reads. Customize by overriding these CSS variables in your theme.
56
+
57
+ | Token | CSS Variable | Purpose |
58
+ |-------|-------------|---------|
59
+ | `bg-primary` / `border-primary` | `--primary-DEFAULT` | Active step fill and border |
60
+ | `text-primary-foreground` | `--primary-foreground` | Active step text |
61
+ | `bg-success` / `border-success` | `--success-DEFAULT` | Complete step fill and border |
62
+ | `text-success-foreground` | `--success-foreground` | Complete step check icon |
63
+ | `bg-danger` / `border-danger` | `--danger-DEFAULT` / `--danger-hover` | Error step fill and border |
64
+ | `text-danger-foreground` | `--danger-foreground` | Error step X icon |
65
+ | `text-disabled` | `--disabled` | Inactive step text |
66
+ | `bg-card-border` / `border-card-border` | `--card-border` | Connector line and inactive border |
67
+ | `bg-background` | `--background` | Inactive step background |
68
+
69
+ ## Examples
70
+
71
+ ### Basic Steps
72
+
73
+ ```tsx
74
+ <Steps currentStep={2} steps={3}>
75
+ <Step step={1} currentStep={2} title="Account" />
76
+ <Step step={2} currentStep={2} title="Profile" />
77
+ <Step step={3} currentStep={2} title="Review" />
78
+ </Steps>
79
+ ```
80
+
81
+ ### Interactive Wizard
82
+
83
+ ```tsx
84
+ function Wizard() {
85
+ const [currentStep, setCurrentStep] = useState(1);
86
+
87
+ return (
88
+ <div className="space-y-8">
89
+ <Steps currentStep={currentStep} steps={4}>
90
+ <Step step={1} currentStep={currentStep} title="Account" onClick={() => setCurrentStep(1)} />
91
+ <Step step={2} currentStep={currentStep} title="Profile" onClick={() => setCurrentStep(2)} />
92
+ <Step step={3} currentStep={currentStep} title="Payment" onClick={() => setCurrentStep(3)} />
93
+ <Step step={4} currentStep={currentStep} title="Review" onClick={() => setCurrentStep(4)} />
94
+ </Steps>
95
+
96
+ <div className="p-6 rounded-card border border-card-border bg-card-background">
97
+ {currentStep === 1 && <AccountForm />}
98
+ {currentStep === 2 && <ProfileForm />}
99
+ {currentStep === 3 && <PaymentForm />}
100
+ {currentStep === 4 && <ReviewSummary />}
101
+ </div>
102
+ </div>
103
+ );
104
+ }
105
+ ```
106
+
107
+ ### With Error State
108
+
109
+ ```tsx
110
+ <Steps currentStep={2} steps={3}>
111
+ <Step step={1} currentStep={2} title="Identity" />
112
+ <Step step={2} currentStep={2} title="Payment" status="error" />
113
+ <Step step={3} currentStep={2} title="Finish" />
114
+ </Steps>
115
+ ```
116
+
117
+ ### Checkout Flow
118
+
119
+ ```tsx
120
+ function CheckoutSteps({ step }: { step: number }) {
121
+ return (
122
+ <Steps currentStep={step} steps={3}>
123
+ <Step step={1} currentStep={step} title="Cart" />
124
+ <Step step={2} currentStep={step} title="Shipping" />
125
+ <Step step={3} currentStep={step} title="Confirmation" />
126
+ </Steps>
127
+ );
128
+ }
129
+ ```
130
+
131
+ ## Do
132
+
133
+ - Provide clear, concise `title` labels for each step.
134
+ - Keep the total number of steps manageable (3–5 is ideal).
135
+ - Use `status="error"` to clearly indicate where a user needs to return and fix a problem.
136
+ - Use `onClick` on `Step` to enable backward navigation in wizards.
137
+
138
+ ## Don't
139
+
140
+ - Don't pass raw Tailwind color classes for step styling — the component derives colors from CSS variables.
141
+ - Don't use arbitrary Tailwind values (`bg-[#abc]`) — override CSS variables in your `@theme` block.
142
+ - Don't hide critical information in steps the user hasn't yet seen.
143
+ - Don't use `Step` for non-linear navigation without a clear sequential intent.
144
+
145
+ ## Accessibility
146
+
147
+ - Each `Step` renders as a `<button>` element, making it focusable and keyboard-operable.
148
+ - Icons use `aria-hidden` to prevent redundant screen reader announcements.
149
+ - The `Steps` container provides a logical visual grouping for the process.
150
+
151
+ ## Data Attributes
152
+
153
+ - `data-step` — the step index number, applied to each step's `<button>`.
154
+
155
+ ## Notes
156
+
157
+ - Connector lines between steps are shown only on `xl` breakpoints (hidden on smaller screens where steps stack vertically).
158
+ - Animations use Framer Motion (`motion/react`): the step circle animates between status colors, and the check/X icons draw in with `pathLength`.
159
+ - The `Steps` component tracks `previousStep` internally to orchestrate staggered transition delays when jumping multiple steps at once.