@g4rcez/components 3.0.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.
- package/dist/ai/SKILL.md +266 -0
- package/dist/ai/docs/Alert.md +167 -0
- package/dist/ai/docs/AnimatedList.md +205 -0
- package/dist/ai/docs/Autocomplete.md +225 -0
- package/dist/ai/docs/Button.md +182 -0
- package/dist/ai/docs/Calendar.md +219 -0
- package/dist/ai/docs/Card.md +174 -0
- package/dist/ai/docs/Checkbox.md +199 -0
- package/dist/ai/docs/CommandPalette.md +293 -0
- package/dist/ai/docs/DatePicker.md +171 -0
- package/dist/ai/docs/Dropdown.md +223 -0
- package/dist/ai/docs/Empty.md +163 -0
- package/dist/ai/docs/Expand.md +143 -0
- package/dist/ai/docs/FileUpload.md +225 -0
- package/dist/ai/docs/Form.md +107 -0
- package/dist/ai/docs/FormReset.md +117 -0
- package/dist/ai/docs/Heading.md +88 -0
- package/dist/ai/docs/Input.md +237 -0
- package/dist/ai/docs/InputField.md +170 -0
- package/dist/ai/docs/List.md +205 -0
- package/dist/ai/docs/Menu.md +166 -0
- package/dist/ai/docs/Modal.md +280 -0
- package/dist/ai/docs/MultiSelect.md +196 -0
- package/dist/ai/docs/Notifications.md +231 -0
- package/dist/ai/docs/PageCalendar.md +271 -0
- package/dist/ai/docs/Polymorph.md +159 -0
- package/dist/ai/docs/Progress.md +145 -0
- package/dist/ai/docs/Radiobox.md +128 -0
- package/dist/ai/docs/RenderOnView.md +138 -0
- package/dist/ai/docs/Resizable.md +159 -0
- package/dist/ai/docs/Select.md +284 -0
- package/dist/ai/docs/Shortcut.md +105 -0
- package/dist/ai/docs/Skeleton.md +166 -0
- package/dist/ai/docs/Slider.md +144 -0
- package/dist/ai/docs/Slot.md +173 -0
- package/dist/ai/docs/Spinner.md +118 -0
- package/dist/ai/docs/Stats.md +137 -0
- package/dist/ai/docs/Step.md +159 -0
- package/dist/ai/docs/Switch.md +167 -0
- package/dist/ai/docs/Table.md +298 -0
- package/dist/ai/docs/Tabs.md +191 -0
- package/dist/ai/docs/Tag.md +224 -0
- package/dist/ai/docs/TaskList.md +144 -0
- package/dist/ai/docs/Textarea.md +167 -0
- package/dist/ai/docs/Timeline.md +210 -0
- package/dist/ai/docs/Toolbar.md +132 -0
- package/dist/ai/docs/Tooltip.md +231 -0
- package/dist/ai/docs/TransferList.md +142 -0
- package/dist/ai/docs/Typography.md +187 -0
- package/dist/ai/docs/Wizard.md +213 -0
- package/dist/ai/docs/index.md +183 -0
- package/dist/components/core/button.d.ts +2 -8
- package/dist/components/core/button.d.ts.map +1 -1
- package/dist/components/core/polymorph.d.ts.map +1 -1
- package/dist/components/core/slot.d.ts +1 -1
- package/dist/components/core/slot.d.ts.map +1 -1
- package/dist/components/core/tag.d.ts +2 -2
- package/dist/components/core/tag.d.ts.map +1 -1
- package/dist/components/core/typography.d.ts.map +1 -1
- package/dist/components/display/alert.d.ts.map +1 -1
- package/dist/components/display/calendar.d.ts.map +1 -1
- package/dist/components/display/card.d.ts.map +1 -1
- package/dist/components/display/list.d.ts.map +1 -1
- package/dist/components/display/notifications.d.ts +2 -0
- package/dist/components/display/notifications.d.ts.map +1 -1
- package/dist/components/display/progress.d.ts.map +1 -1
- package/dist/components/display/skeleton.d.ts.map +1 -1
- package/dist/components/display/step.d.ts.map +1 -1
- package/dist/components/display/tabs.d.ts.map +1 -1
- package/dist/components/floating/command-palette.d.ts +1 -0
- package/dist/components/floating/command-palette.d.ts.map +1 -1
- package/dist/components/floating/dropdown.d.ts +1 -0
- package/dist/components/floating/dropdown.d.ts.map +1 -1
- package/dist/components/floating/menu.d.ts +2 -2
- package/dist/components/floating/menu.d.ts.map +1 -1
- package/dist/components/floating/modal.d.ts +20 -53
- package/dist/components/floating/modal.d.ts.map +1 -1
- package/dist/components/floating/tooltip.d.ts.map +1 -1
- package/dist/components/floating/wizard.d.ts +1 -1
- package/dist/components/floating/wizard.d.ts.map +1 -1
- package/dist/components/form/autocomplete.d.ts.map +1 -1
- package/dist/components/form/date-picker.d.ts.map +1 -1
- package/dist/components/form/free-text.d.ts.map +1 -1
- package/dist/components/form/input-field.d.ts +3 -2
- package/dist/components/form/input-field.d.ts.map +1 -1
- package/dist/components/form/multi-select.d.ts.map +1 -1
- package/dist/components/form/select.d.ts.map +1 -1
- package/dist/components/form/slider.d.ts.map +1 -1
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/page-calendar/calendar-header.d.ts +16 -0
- package/dist/components/page-calendar/calendar-header.d.ts.map +1 -0
- package/dist/components/page-calendar/day-view.d.ts +12 -0
- package/dist/components/page-calendar/day-view.d.ts.map +1 -0
- package/dist/components/page-calendar/event-pill.d.ts +9 -0
- package/dist/components/page-calendar/event-pill.d.ts.map +1 -0
- package/dist/components/page-calendar/index.d.ts +4 -0
- package/dist/components/page-calendar/index.d.ts.map +1 -0
- package/dist/components/page-calendar/month-view.d.ts +11 -0
- package/dist/components/page-calendar/month-view.d.ts.map +1 -0
- package/dist/components/page-calendar/page-calendar.d.ts +18 -0
- package/dist/components/page-calendar/page-calendar.d.ts.map +1 -0
- package/dist/components/page-calendar/page-calendar.types.d.ts +18 -0
- package/dist/components/page-calendar/page-calendar.types.d.ts.map +1 -0
- package/dist/components/page-calendar/page-calendar.utils.d.ts +18 -0
- package/dist/components/page-calendar/page-calendar.utils.d.ts.map +1 -0
- package/dist/components/page-calendar/week-view.d.ts +11 -0
- package/dist/components/page-calendar/week-view.d.ts.map +1 -0
- package/dist/components/table/index.d.ts.map +1 -1
- package/dist/components/table/inner-table.d.ts.map +1 -1
- package/dist/components/table/metadata.d.ts.map +1 -1
- package/dist/components/table/row.d.ts.map +1 -1
- package/dist/components/table/table-lib.d.ts.map +1 -1
- package/dist/components/table/thead.d.ts.map +1 -1
- package/dist/config/context.d.ts.map +1 -1
- package/dist/config/default-translations.d.ts +21 -4
- package/dist/config/default-translations.d.ts.map +1 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/hooks/use-components-provider.d.ts.map +1 -1
- package/dist/hooks/use-form.d.ts +11 -11
- package/dist/hooks/use-form.d.ts.map +1 -1
- package/dist/hooks/use-input-id.d.ts.map +1 -1
- package/dist/hooks/use-preferences.d.ts.map +1 -1
- package/dist/hooks/use-previous.d.ts.map +1 -1
- package/dist/hooks/use-reactive.d.ts.map +1 -1
- package/dist/hooks/use-resize-observer.d.ts.map +1 -1
- package/dist/hooks/use-stable-ref.d.ts.map +1 -1
- package/dist/hooks/use-swipe.d.ts.map +1 -1
- package/dist/hooks/use-translations.d.ts +21 -4
- package/dist/hooks/use-translations.d.ts.map +1 -1
- package/dist/index.css +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +28 -20
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +13862 -12512
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +24 -17
- package/dist/index.umd.js.map +1 -1
- package/dist/lib/dom.d.ts +1 -0
- package/dist/lib/dom.d.ts.map +1 -1
- package/dist/lib/fns.d.ts.map +1 -1
- package/dist/preset/plugin.tailwind.d.ts +9 -0
- package/dist/preset/plugin.tailwind.d.ts.map +1 -0
- package/dist/preset/plugin.tailwind.js +27 -0
- package/dist/preset/preset.tailwind.d.ts +8 -0
- package/dist/preset/preset.tailwind.d.ts.map +1 -0
- package/dist/preset/preset.tailwind.js +54 -0
- package/dist/preset/src/styles/common.d.ts +2 -14
- package/dist/preset/src/styles/common.d.ts.map +1 -1
- package/dist/preset/src/styles/common.js +1 -0
- package/dist/preset/src/styles/dark.d.ts.map +1 -1
- package/dist/preset/src/styles/dark.js +119 -114
- package/dist/preset/src/styles/light.d.ts.map +1 -1
- package/dist/preset/src/styles/light.js +111 -106
- package/dist/preset/src/styles/theme.types.d.ts +17 -8
- package/dist/preset/src/styles/theme.types.d.ts.map +1 -1
- package/dist/styles/common.d.ts +2 -14
- package/dist/styles/common.d.ts.map +1 -1
- package/dist/styles/dark.d.ts.map +1 -1
- package/dist/styles/light.d.ts.map +1 -1
- package/dist/styles/theme.types.d.ts +17 -8
- package/dist/styles/theme.types.d.ts.map +1 -1
- package/package.json +299 -301
- package/dist/components/core/button.jsx +0 -86
- package/dist/components/core/heading.jsx +0 -4
- package/dist/components/core/polymorph.jsx +0 -5
- package/dist/components/core/render-on-view.jsx +0 -31
- package/dist/components/core/resizable.jsx +0 -51
- package/dist/components/core/slot.jsx +0 -163
- package/dist/components/core/tag.jsx +0 -51
- package/dist/components/core/typography.jsx +0 -26
- package/dist/components/display/alert.jsx +0 -56
- package/dist/components/display/calendar.jsx +0 -301
- package/dist/components/display/card.jsx +0 -43
- package/dist/components/display/empty.jsx +0 -11
- package/dist/components/display/list.jsx +0 -81
- package/dist/components/display/notifications.jsx +0 -98
- package/dist/components/display/progress.jsx +0 -13
- package/dist/components/display/shortcut.jsx +0 -23
- package/dist/components/display/skeleton.jsx +0 -14
- package/dist/components/display/spinner.jsx +0 -7
- package/dist/components/display/stats.jsx +0 -20
- package/dist/components/display/step.jsx +0 -131
- package/dist/components/display/tabs.jsx +0 -100
- package/dist/components/display/timeline.jsx +0 -25
- package/dist/components/floating/command-palette.jsx +0 -172
- package/dist/components/floating/dropdown.jsx +0 -53
- package/dist/components/floating/expand.jsx +0 -44
- package/dist/components/floating/menu.jsx +0 -147
- package/dist/components/floating/modal.jsx +0 -241
- package/dist/components/floating/toolbar.jsx +0 -5
- package/dist/components/floating/tooltip.jsx +0 -64
- package/dist/components/floating/wizard.jsx +0 -164
- package/dist/components/form/autocomplete.jsx +0 -275
- package/dist/components/form/checkbox.jsx +0 -12
- package/dist/components/form/date-picker.jsx +0 -115
- package/dist/components/form/file-upload.jsx +0 -133
- package/dist/components/form/form.jsx +0 -10
- package/dist/components/form/formReset.jsx +0 -17
- package/dist/components/form/free-text.jsx +0 -41
- package/dist/components/form/input-field.jsx +0 -54
- package/dist/components/form/input.jsx +0 -36
- package/dist/components/form/multi-select.jsx +0 -328
- package/dist/components/form/radiobox.jsx +0 -6
- package/dist/components/form/select.jsx +0 -42
- package/dist/components/form/slider.jsx +0 -45
- package/dist/components/form/switch.jsx +0 -46
- package/dist/components/form/task-list.jsx +0 -26
- package/dist/components/form/textarea.jsx +0 -12
- package/dist/components/form/transfer-list.jsx +0 -39
- package/dist/components/index.js +0 -43
- package/dist/components/table/filter.jsx +0 -141
- package/dist/components/table/group.jsx +0 -68
- package/dist/components/table/index.jsx +0 -60
- package/dist/components/table/inner-table.jsx +0 -104
- package/dist/components/table/metadata.jsx +0 -37
- package/dist/components/table/pagination.jsx +0 -73
- package/dist/components/table/row.jsx +0 -58
- package/dist/components/table/sort.jsx +0 -105
- package/dist/components/table/table-lib.js +0 -84
- package/dist/components/table/table.context.jsx +0 -4
- package/dist/components/table/thead.jsx +0 -103
- package/dist/config/context.js +0 -12
- package/dist/config/default-translations.jsx +0 -66
- package/dist/config/default-tweaks.js +0 -4
- package/dist/constants.js +0 -2
- package/dist/hooks/use-click-outside.js +0 -17
- package/dist/hooks/use-color-parser.js +0 -9
- package/dist/hooks/use-components-provider.jsx +0 -16
- package/dist/hooks/use-debounce.js +0 -12
- package/dist/hooks/use-floating-ref.js +0 -6
- package/dist/hooks/use-form.js +0 -549
- package/dist/hooks/use-hover.js +0 -18
- package/dist/hooks/use-input-id.js +0 -5
- package/dist/hooks/use-is-coarse-device.js +0 -12
- package/dist/hooks/use-locale.js +0 -10
- package/dist/hooks/use-media-query.js +0 -25
- package/dist/hooks/use-on-event.js +0 -7
- package/dist/hooks/use-parent.js +0 -21
- package/dist/hooks/use-preferences.js +0 -23
- package/dist/hooks/use-previous.js +0 -8
- package/dist/hooks/use-reactive.js +0 -8
- package/dist/hooks/use-remove-scroll.js +0 -61
- package/dist/hooks/use-resize-observer.js +0 -17
- package/dist/hooks/use-stable-ref.js +0 -8
- package/dist/hooks/use-swipe.js +0 -16
- package/dist/hooks/use-translations.js +0 -9
- package/dist/hooks/use-tweaks.js +0 -9
- package/dist/hooks/use-window-size.js +0 -14
- package/dist/lib/combi-keys.js +0 -60
- package/dist/lib/dict.js +0 -39
- package/dist/lib/dom.js +0 -44
- package/dist/lib/fns.js +0 -46
- package/dist/lib/fzf.js +0 -117
- package/dist/lib/keyboard-area.js +0 -14
- package/dist/preset/tailwindcssv4.d.ts +0 -3
- package/dist/preset/tailwindcssv4.d.ts.map +0 -1
- package/dist/preset/tailwindcssv4.js +0 -75
- package/dist/styles/common.js +0 -28
- package/dist/styles/dark.js +0 -209
- package/dist/styles/design-tokens.js +0 -69
- package/dist/styles/light.js +0 -209
- package/dist/styles/theme.js +0 -4
- package/dist/styles/theme.types.js +0 -1
- 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.
|