solid-tom-ui 1.0.10 → 1.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +246 -246
- package/dist/README.md +246 -246
- package/dist/components/avatar/avatar.js.map +1 -1
- package/dist/components/badge/badge.js.map +1 -1
- package/dist/components/breadcrumb/breadcrumb.js.map +1 -1
- package/dist/components/button/button.js.map +1 -1
- package/dist/components/carousel/carousel.js.map +1 -1
- package/dist/components/chat-bubble/chatBubble.js.map +1 -1
- package/dist/components/checkbox/checkbox.js.map +1 -1
- package/dist/components/collapse/collapse.js.map +1 -1
- package/dist/components/context-menu/context-menu.js.map +1 -1
- package/dist/components/context-menu/context-menu.store.js.map +1 -1
- package/dist/components/divider/divider.js.map +1 -1
- package/dist/components/dropdown/dropdown.js.map +1 -1
- package/dist/components/dropdown/dropdown.store.js.map +1 -1
- package/dist/components/float-button/float-button.js.map +1 -1
- package/dist/components/hover-3d-image/hover-3d-image.js.map +1 -1
- package/dist/components/image-preview/image-preview.js.map +1 -1
- package/dist/components/input/input.js.map +1 -1
- package/dist/components/input/input.utils.js.map +1 -1
- package/dist/components/input/variants/input-color.js.map +1 -1
- package/dist/components/input/variants/input-date.js.map +1 -1
- package/dist/components/input/variants/input-number.d.ts.map +1 -1
- package/dist/components/input/variants/input-number.js +1 -1
- package/dist/components/input/variants/input-number.js.map +1 -1
- package/dist/components/input/variants/input-otp.js.map +1 -1
- package/dist/components/input/variants/input-password.js.map +1 -1
- package/dist/components/input/variants/input-radio.js.map +1 -1
- package/dist/components/input/variants/input-range.js.map +1 -1
- package/dist/components/input/variants/input-text.d.ts.map +1 -1
- package/dist/components/input/variants/input-text.js +1 -1
- package/dist/components/input/variants/input-text.js.map +1 -1
- package/dist/components/input/variants/input-textarea.js.map +1 -1
- package/dist/components/loading/loading.js.map +1 -1
- package/dist/components/mansory/mansory.js.map +1 -1
- package/dist/components/menu/menu.js.map +1 -1
- package/dist/components/menu/menu.types.d.ts +2 -3
- package/dist/components/menu/menu.types.d.ts.map +1 -1
- package/dist/components/modal/modal.js.map +1 -1
- package/dist/components/modal/modalContext.js.map +1 -1
- package/dist/components/pagination/pagination.js.map +1 -1
- package/dist/components/progress-bar/progress-bar.js.map +1 -1
- package/dist/components/qr-code/qr-code.js.map +1 -1
- package/dist/components/select/select.js.map +1 -1
- package/dist/components/select-zone/select-zone.js.map +1 -1
- package/dist/components/skeleton/skeleton.js.map +1 -1
- package/dist/components/slider/slider.js.map +1 -1
- package/dist/components/splitter/splitter.js.map +1 -1
- package/dist/components/steps/steps.js.map +1 -1
- package/dist/components/swap/swap.js.map +1 -1
- package/dist/components/switch/switch.js.map +1 -1
- package/dist/components/tab/tab.js.map +1 -1
- package/dist/components/table/table.js.map +1 -1
- package/dist/components/timeline/timeline.js.map +1 -1
- package/dist/components/toast/icons/ErrorIcon.js.map +1 -1
- package/dist/components/toast/icons/IconCircle.js.map +1 -1
- package/dist/components/toast/icons/InfoIcon.js.map +1 -1
- package/dist/components/toast/icons/LoaderIcon.js.map +1 -1
- package/dist/components/toast/icons/SuccessIcon.js.map +1 -1
- package/dist/components/toast/icons/WarningIcon.js.map +1 -1
- package/dist/components/toast/toast.js.map +1 -1
- package/dist/components/toast/toast.store.js.map +1 -1
- package/dist/components/tooltip/tooltip.js.map +1 -1
- package/dist/components/tour/tour.js.map +1 -1
- package/dist/components/upload/upload.js.map +1 -1
- package/dist/components/z-index/z-index.context.js.map +1 -1
- package/dist/components/z-index/z-index.js.map +1 -1
- package/dist/components/z-index/z-index.store.js.map +1 -1
- package/dist/components/z-index/z-index.types.js.map +1 -1
- package/dist/package.json +1 -1
- package/dist/skill/avatar.skill.md.txt +255 -255
- package/dist/skill/badge.skill.md.txt +223 -223
- package/dist/skill/breadcrumb.skill.md.txt +177 -177
- package/dist/skill/button.skill.md.txt +198 -198
- package/dist/skill/carousel.skill.md.txt +406 -406
- package/dist/skill/chat-bubble.skill.md.txt +342 -342
- package/dist/skill/checkbox.skill.md.txt +326 -326
- package/dist/skill/code-preview.skill.md.txt +240 -240
- package/dist/skill/collapse.skill.md.txt +329 -329
- package/dist/skill/context-menu.skill.md.txt +233 -233
- package/dist/skill/diff.skill.md.txt +244 -244
- package/dist/skill/divider.skill.md.txt +151 -151
- package/dist/skill/doc.skill.md.txt +191 -191
- package/dist/skill/drawer.skill.md.txt +157 -157
- package/dist/skill/dropdown.skill.md.txt +198 -198
- package/dist/skill/float-button.skill.md.txt +315 -315
- package/dist/skill/hover-3d-image.skill.md.txt +120 -120
- package/dist/skill/iframe.skill.md.txt +114 -114
- package/dist/skill/image-preview.skill.md.txt +162 -162
- package/dist/skill/indicator.skill.md.txt +60 -60
- package/dist/skill/input.skill.md.txt +489 -489
- package/dist/skill/loading.skill.md.txt +127 -127
- package/dist/skill/menu.skill.md.txt +476 -476
- package/dist/skill/modal.skill.md.txt +359 -359
- package/dist/skill/pagination.skill.md.txt +405 -405
- package/dist/skill/progress-bar.skill.md.txt +207 -207
- package/dist/skill/qr-code.skill.md.txt +136 -136
- package/dist/skill/rating.skill.md.txt +167 -167
- package/dist/skill/select-zone.skill.md.txt +93 -93
- package/dist/skill/select.skill.md.txt +663 -663
- package/dist/skill/skeleton.skill.md.txt +192 -192
- package/dist/skill/slider.skill.md.txt +404 -404
- package/dist/skill/splitter.skill.md.txt +411 -411
- package/dist/skill/steps.skill.md.txt +264 -264
- package/dist/skill/swap.skill.md.txt +139 -139
- package/dist/skill/switch.skill.md.txt +191 -191
- package/dist/skill/tab.skill.md.txt +484 -484
- package/dist/skill/table.example.header.md.txt +666 -666
- package/dist/skill/table.skill.md.txt +1407 -1407
- package/dist/skill/text-rotate.skill.md.txt +186 -186
- package/dist/skill/timeline.skill.md.txt +247 -247
- package/dist/skill/toast.skill.md.txt +531 -531
- package/dist/skill/tooltip.skill.md.txt +222 -222
- package/dist/skill/tour.skill.md.txt +156 -156
- package/dist/skill/upload.skill.md.txt +358 -358
- package/dist/utils/cn.js.map +1 -1
- package/dist/utils/element-tracker.js.map +1 -1
- package/dist/utils/helper.js.map +1 -1
- package/dist/utils/hoc.js.map +1 -1
- package/package.json +132 -133
|
@@ -1,198 +1,198 @@
|
|
|
1
|
-
## COMPONENT IDENTITY
|
|
2
|
-
|
|
3
|
-
- **Import**: `import { Button } from 'solid-tom-ui';`
|
|
4
|
-
- **Export**: `Button` (default named export)
|
|
5
|
-
- **Framework**: SolidJS
|
|
6
|
-
- **Runtime**: This is a client-side interactive component
|
|
7
|
-
|
|
8
|
-
## TYPE SIGNATURE
|
|
9
|
-
|
|
10
|
-
```typescript
|
|
11
|
-
import { Button } from 'solid-tom-ui';
|
|
12
|
-
|
|
13
|
-
// variant is REQUIRED. All other props are optional.
|
|
14
|
-
<Button
|
|
15
|
-
variant="default" | "simple" | "solid" | "outline" | "dashed" | "filled" | "text" | "link"
|
|
16
|
-
color?="neutral" | "primary" | "secondary" | "accent" | "info" | "success" | "warning" | "error"
|
|
17
|
-
size?="4xs" | "3xs" | "2xs" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl"
|
|
18
|
-
shape?="circle" | "square" // MUTEX with children — if set, do NOT pass children
|
|
19
|
-
icon?={JSXElement} // SolidJS component/JSX for icon
|
|
20
|
-
iconPlacement?="start" | "end" // default: "start"
|
|
21
|
-
loading?={boolean} // default: false; disables button while true
|
|
22
|
-
loadingOptions?={{ type?: "spinner"|"dots"|"ring"|"ball"|"bars"|"infinity", size?: number }}
|
|
23
|
-
animate?="none" | "translate" | "ripple" // default: "ripple"
|
|
24
|
-
disabled?={boolean} // default: false
|
|
25
|
-
onClick?={(e: MouseEvent) => void}
|
|
26
|
-
class?={string}
|
|
27
|
-
>
|
|
28
|
-
{children} // NOT allowed when shape is set
|
|
29
|
-
</Button>
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
## CLASS SLOTS
|
|
33
|
-
|
|
34
|
-
`Button` is a single-element component — `class` appends to the root `<button>`. No named sub-element slots.
|
|
35
|
-
|
|
36
|
-
> **CSS encoding**: internal CSS classes use short encoded names (e.g. `bu01`, `bu02`) per project convention.
|
|
37
|
-
|
|
38
|
-
## DEFAULTS
|
|
39
|
-
|
|
40
|
-
| Prop | Default |
|
|
41
|
-
| --------------------- | ------------- |
|
|
42
|
-
| `color` | `"secondary"` |
|
|
43
|
-
| `size` | `"sm"` |
|
|
44
|
-
| `iconPlacement` | `"start"` |
|
|
45
|
-
| `loading` | `false` |
|
|
46
|
-
| `disabled` | `false` |
|
|
47
|
-
| `animate` | `"ripple"` |
|
|
48
|
-
| `loadingOptions.type` | `"spinner"` |
|
|
49
|
-
| `loadingOptions.size` | `20` |
|
|
50
|
-
|
|
51
|
-
## CONSTRAINT: shape vs children
|
|
52
|
-
|
|
53
|
-
- `shape="circle"` or `shape="square"` → icon-only button → **children MUST be omitted**
|
|
54
|
-
- No `shape` → text button → children are allowed
|
|
55
|
-
|
|
56
|
-
## VARIANT SEMANTICS
|
|
57
|
-
|
|
58
|
-
| Variant | Visual style | Use case |
|
|
59
|
-
| --------- | ---------------------------- | ----------------------- |
|
|
60
|
-
| `default` | DaisyUI default button style | General neutral action |
|
|
61
|
-
| `simple` | Minimal, no background | Subtle secondary action |
|
|
62
|
-
| `solid` | Filled solid background | Primary CTA |
|
|
63
|
-
| `outline` | Border, transparent bg | Secondary action |
|
|
64
|
-
| `dashed` | Dashed border | Draft / pending action |
|
|
65
|
-
| `filled` | Filled with lighter tone | Highlighted secondary |
|
|
66
|
-
| `text` | No border, no bg, text only | Inline or low-emphasis |
|
|
67
|
-
| `link` | Looks like hyperlink | Navigation action |
|
|
68
|
-
|
|
69
|
-
## COLOR SEMANTICS
|
|
70
|
-
|
|
71
|
-
| Color | Semantic meaning |
|
|
72
|
-
| ----------- | ------------------------- |
|
|
73
|
-
| `neutral` | Gray / no meaning |
|
|
74
|
-
| `primary` | Brand primary |
|
|
75
|
-
| `secondary` | Brand secondary (default) |
|
|
76
|
-
| `accent` | Accent highlight |
|
|
77
|
-
| `info` | Informational |
|
|
78
|
-
| `success` | Positive / confirmed |
|
|
79
|
-
| `warning` | Caution |
|
|
80
|
-
| `error` | Destructive / danger |
|
|
81
|
-
|
|
82
|
-
## USAGE PATTERNS
|
|
83
|
-
|
|
84
|
-
### Basic button
|
|
85
|
-
|
|
86
|
-
```tsx
|
|
87
|
-
<Button variant="solid" color="primary" onClick={handleClick}>
|
|
88
|
-
Submit
|
|
89
|
-
</Button>
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
### With icon (text + icon)
|
|
93
|
-
|
|
94
|
-
```tsx
|
|
95
|
-
import Trash from 'lucide-solid/icons/trash';
|
|
96
|
-
|
|
97
|
-
<Button variant="outline" color="error" icon={<Trash size={16} />} onClick={handleDelete}>
|
|
98
|
-
Delete
|
|
99
|
-
</Button>
|
|
100
|
-
|
|
101
|
-
// Icon at end
|
|
102
|
-
<Button variant="solid" color="primary" icon={<DynamicIcon name="arrow-right" size={16} />} iconPlacement="end">
|
|
103
|
-
Continue
|
|
104
|
-
</Button>
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
### Icon-only button (circle/square shape)
|
|
108
|
-
|
|
109
|
-
```tsx
|
|
110
|
-
// CORRECT: shape set → no children
|
|
111
|
-
<Button variant="solid" color="primary" shape="circle" size="md" icon={<DynamicIcon name="plus" size={16} />} />
|
|
112
|
-
<Button variant="outline" color="neutral" shape="square" size="sm" icon={<Trash size={14} />} />
|
|
113
|
-
|
|
114
|
-
// WRONG: shape + children → TypeScript error
|
|
115
|
-
<Button variant="solid" shape="circle" icon={...}>Label</Button> // ❌ children not allowed with shape
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
### Loading state
|
|
119
|
-
|
|
120
|
-
```tsx
|
|
121
|
-
<Button variant="solid" color="primary" loading={isLoading()}>
|
|
122
|
-
Save
|
|
123
|
-
</Button>
|
|
124
|
-
|
|
125
|
-
// Custom loading indicator
|
|
126
|
-
<Button variant="solid" color="primary" loading={isLoading()} loadingOptions={{ type: 'dots', size: 16 }}>
|
|
127
|
-
Processing
|
|
128
|
-
</Button>
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
### Disabled
|
|
132
|
-
|
|
133
|
-
```tsx
|
|
134
|
-
<Button variant="solid" color="primary" disabled={!isValid()}>
|
|
135
|
-
Submit
|
|
136
|
-
</Button>
|
|
137
|
-
// Note: loading=true also disables the button automatically
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
### Animation control
|
|
141
|
-
|
|
142
|
-
```tsx
|
|
143
|
-
<Button variant="solid" color="primary" animate="none">No animation</Button>
|
|
144
|
-
<Button variant="solid" color="primary" animate="translate">Translate on hover</Button>
|
|
145
|
-
<Button variant="solid" color="primary" animate="ripple">Ripple on click (default)</Button>
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
### Size progression (smallest → largest)
|
|
149
|
-
|
|
150
|
-
```
|
|
151
|
-
4xs → 3xs → 2xs → xs → sm(default) → md → lg → xl → 2xl → 3xl → 4xl
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
## DECISION RULES
|
|
155
|
-
|
|
156
|
-
**Choosing variant:**
|
|
157
|
-
|
|
158
|
-
- User performs the main action → `solid` with `primary`
|
|
159
|
-
- Secondary/cancel action next to primary → `outline` with `neutral` or `secondary`
|
|
160
|
-
- Destructive action (delete, remove) → `solid` or `outline` with `error`
|
|
161
|
-
- Navigation/link-like → `link` or `text`
|
|
162
|
-
- Icon-only toolbar button → `simple` or `text` with appropriate `shape`
|
|
163
|
-
|
|
164
|
-
**Choosing color:**
|
|
165
|
-
|
|
166
|
-
- Confirm / save / create → `primary` or `success`
|
|
167
|
-
- Cancel / back → `neutral`
|
|
168
|
-
- Delete / remove → `error`
|
|
169
|
-
- Warning / irreversible → `warning`
|
|
170
|
-
- Info action → `info`
|
|
171
|
-
|
|
172
|
-
**Choosing size:**
|
|
173
|
-
|
|
174
|
-
- Default UI → `sm` (default)
|
|
175
|
-
- Inside tight spaces (table cells, sidebars) → `xs` or `2xs`
|
|
176
|
-
- Hero CTA → `lg` or `xl`
|
|
177
|
-
|
|
178
|
-
## ANTI-PATTERNS
|
|
179
|
-
|
|
180
|
-
```tsx
|
|
181
|
-
// ❌ Missing required `variant` prop
|
|
182
|
-
<Button color="primary">Click</Button>
|
|
183
|
-
|
|
184
|
-
// ❌ Using shape with children
|
|
185
|
-
<Button variant="solid" shape="circle" icon={<Icon />}>Text</Button>
|
|
186
|
-
|
|
187
|
-
// ❌ Redundant: loading already disables, no need for disabled too
|
|
188
|
-
<Button loading={true} disabled={true}>Save</Button>
|
|
189
|
-
|
|
190
|
-
// ✅ Correct: just use loading
|
|
191
|
-
<Button loading={true}>Save</Button>
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
## ADDITIONAL NATIVE PROPS
|
|
195
|
-
|
|
196
|
-
The `Button` component forwards all standard `HTMLButtonElement` attributes except `onClick`, `class`, `disabled`, and `children` (which are controlled by the component). You can pass `type="submit"`, `form`, `aria-*`, `data-*`, etc.
|
|
197
|
-
|
|
198
|
-
> **Unique IDs**: if this component needs to generate HTML `id` attributes, always use `createUniqueId()` from `solid-js` — never `Math.random()` or `Date.now()`.
|
|
1
|
+
## COMPONENT IDENTITY
|
|
2
|
+
|
|
3
|
+
- **Import**: `import { Button } from 'solid-tom-ui';`
|
|
4
|
+
- **Export**: `Button` (default named export)
|
|
5
|
+
- **Framework**: SolidJS
|
|
6
|
+
- **Runtime**: This is a client-side interactive component
|
|
7
|
+
|
|
8
|
+
## TYPE SIGNATURE
|
|
9
|
+
|
|
10
|
+
```typescript
|
|
11
|
+
import { Button } from 'solid-tom-ui';
|
|
12
|
+
|
|
13
|
+
// variant is REQUIRED. All other props are optional.
|
|
14
|
+
<Button
|
|
15
|
+
variant="default" | "simple" | "solid" | "outline" | "dashed" | "filled" | "text" | "link"
|
|
16
|
+
color?="neutral" | "primary" | "secondary" | "accent" | "info" | "success" | "warning" | "error"
|
|
17
|
+
size?="4xs" | "3xs" | "2xs" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl"
|
|
18
|
+
shape?="circle" | "square" // MUTEX with children — if set, do NOT pass children
|
|
19
|
+
icon?={JSXElement} // SolidJS component/JSX for icon
|
|
20
|
+
iconPlacement?="start" | "end" // default: "start"
|
|
21
|
+
loading?={boolean} // default: false; disables button while true
|
|
22
|
+
loadingOptions?={{ type?: "spinner"|"dots"|"ring"|"ball"|"bars"|"infinity", size?: number }}
|
|
23
|
+
animate?="none" | "translate" | "ripple" // default: "ripple"
|
|
24
|
+
disabled?={boolean} // default: false
|
|
25
|
+
onClick?={(e: MouseEvent) => void}
|
|
26
|
+
class?={string}
|
|
27
|
+
>
|
|
28
|
+
{children} // NOT allowed when shape is set
|
|
29
|
+
</Button>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## CLASS SLOTS
|
|
33
|
+
|
|
34
|
+
`Button` is a single-element component — `class` appends to the root `<button>`. No named sub-element slots.
|
|
35
|
+
|
|
36
|
+
> **CSS encoding**: internal CSS classes use short encoded names (e.g. `bu01`, `bu02`) per project convention.
|
|
37
|
+
|
|
38
|
+
## DEFAULTS
|
|
39
|
+
|
|
40
|
+
| Prop | Default |
|
|
41
|
+
| --------------------- | ------------- |
|
|
42
|
+
| `color` | `"secondary"` |
|
|
43
|
+
| `size` | `"sm"` |
|
|
44
|
+
| `iconPlacement` | `"start"` |
|
|
45
|
+
| `loading` | `false` |
|
|
46
|
+
| `disabled` | `false` |
|
|
47
|
+
| `animate` | `"ripple"` |
|
|
48
|
+
| `loadingOptions.type` | `"spinner"` |
|
|
49
|
+
| `loadingOptions.size` | `20` |
|
|
50
|
+
|
|
51
|
+
## CONSTRAINT: shape vs children
|
|
52
|
+
|
|
53
|
+
- `shape="circle"` or `shape="square"` → icon-only button → **children MUST be omitted**
|
|
54
|
+
- No `shape` → text button → children are allowed
|
|
55
|
+
|
|
56
|
+
## VARIANT SEMANTICS
|
|
57
|
+
|
|
58
|
+
| Variant | Visual style | Use case |
|
|
59
|
+
| --------- | ---------------------------- | ----------------------- |
|
|
60
|
+
| `default` | DaisyUI default button style | General neutral action |
|
|
61
|
+
| `simple` | Minimal, no background | Subtle secondary action |
|
|
62
|
+
| `solid` | Filled solid background | Primary CTA |
|
|
63
|
+
| `outline` | Border, transparent bg | Secondary action |
|
|
64
|
+
| `dashed` | Dashed border | Draft / pending action |
|
|
65
|
+
| `filled` | Filled with lighter tone | Highlighted secondary |
|
|
66
|
+
| `text` | No border, no bg, text only | Inline or low-emphasis |
|
|
67
|
+
| `link` | Looks like hyperlink | Navigation action |
|
|
68
|
+
|
|
69
|
+
## COLOR SEMANTICS
|
|
70
|
+
|
|
71
|
+
| Color | Semantic meaning |
|
|
72
|
+
| ----------- | ------------------------- |
|
|
73
|
+
| `neutral` | Gray / no meaning |
|
|
74
|
+
| `primary` | Brand primary |
|
|
75
|
+
| `secondary` | Brand secondary (default) |
|
|
76
|
+
| `accent` | Accent highlight |
|
|
77
|
+
| `info` | Informational |
|
|
78
|
+
| `success` | Positive / confirmed |
|
|
79
|
+
| `warning` | Caution |
|
|
80
|
+
| `error` | Destructive / danger |
|
|
81
|
+
|
|
82
|
+
## USAGE PATTERNS
|
|
83
|
+
|
|
84
|
+
### Basic button
|
|
85
|
+
|
|
86
|
+
```tsx
|
|
87
|
+
<Button variant="solid" color="primary" onClick={handleClick}>
|
|
88
|
+
Submit
|
|
89
|
+
</Button>
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### With icon (text + icon)
|
|
93
|
+
|
|
94
|
+
```tsx
|
|
95
|
+
import Trash from 'lucide-solid/icons/trash';
|
|
96
|
+
|
|
97
|
+
<Button variant="outline" color="error" icon={<Trash size={16} />} onClick={handleDelete}>
|
|
98
|
+
Delete
|
|
99
|
+
</Button>
|
|
100
|
+
|
|
101
|
+
// Icon at end
|
|
102
|
+
<Button variant="solid" color="primary" icon={<DynamicIcon name="arrow-right" size={16} />} iconPlacement="end">
|
|
103
|
+
Continue
|
|
104
|
+
</Button>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Icon-only button (circle/square shape)
|
|
108
|
+
|
|
109
|
+
```tsx
|
|
110
|
+
// CORRECT: shape set → no children
|
|
111
|
+
<Button variant="solid" color="primary" shape="circle" size="md" icon={<DynamicIcon name="plus" size={16} />} />
|
|
112
|
+
<Button variant="outline" color="neutral" shape="square" size="sm" icon={<Trash size={14} />} />
|
|
113
|
+
|
|
114
|
+
// WRONG: shape + children → TypeScript error
|
|
115
|
+
<Button variant="solid" shape="circle" icon={...}>Label</Button> // ❌ children not allowed with shape
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Loading state
|
|
119
|
+
|
|
120
|
+
```tsx
|
|
121
|
+
<Button variant="solid" color="primary" loading={isLoading()}>
|
|
122
|
+
Save
|
|
123
|
+
</Button>
|
|
124
|
+
|
|
125
|
+
// Custom loading indicator
|
|
126
|
+
<Button variant="solid" color="primary" loading={isLoading()} loadingOptions={{ type: 'dots', size: 16 }}>
|
|
127
|
+
Processing
|
|
128
|
+
</Button>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Disabled
|
|
132
|
+
|
|
133
|
+
```tsx
|
|
134
|
+
<Button variant="solid" color="primary" disabled={!isValid()}>
|
|
135
|
+
Submit
|
|
136
|
+
</Button>
|
|
137
|
+
// Note: loading=true also disables the button automatically
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Animation control
|
|
141
|
+
|
|
142
|
+
```tsx
|
|
143
|
+
<Button variant="solid" color="primary" animate="none">No animation</Button>
|
|
144
|
+
<Button variant="solid" color="primary" animate="translate">Translate on hover</Button>
|
|
145
|
+
<Button variant="solid" color="primary" animate="ripple">Ripple on click (default)</Button>
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Size progression (smallest → largest)
|
|
149
|
+
|
|
150
|
+
```
|
|
151
|
+
4xs → 3xs → 2xs → xs → sm(default) → md → lg → xl → 2xl → 3xl → 4xl
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## DECISION RULES
|
|
155
|
+
|
|
156
|
+
**Choosing variant:**
|
|
157
|
+
|
|
158
|
+
- User performs the main action → `solid` with `primary`
|
|
159
|
+
- Secondary/cancel action next to primary → `outline` with `neutral` or `secondary`
|
|
160
|
+
- Destructive action (delete, remove) → `solid` or `outline` with `error`
|
|
161
|
+
- Navigation/link-like → `link` or `text`
|
|
162
|
+
- Icon-only toolbar button → `simple` or `text` with appropriate `shape`
|
|
163
|
+
|
|
164
|
+
**Choosing color:**
|
|
165
|
+
|
|
166
|
+
- Confirm / save / create → `primary` or `success`
|
|
167
|
+
- Cancel / back → `neutral`
|
|
168
|
+
- Delete / remove → `error`
|
|
169
|
+
- Warning / irreversible → `warning`
|
|
170
|
+
- Info action → `info`
|
|
171
|
+
|
|
172
|
+
**Choosing size:**
|
|
173
|
+
|
|
174
|
+
- Default UI → `sm` (default)
|
|
175
|
+
- Inside tight spaces (table cells, sidebars) → `xs` or `2xs`
|
|
176
|
+
- Hero CTA → `lg` or `xl`
|
|
177
|
+
|
|
178
|
+
## ANTI-PATTERNS
|
|
179
|
+
|
|
180
|
+
```tsx
|
|
181
|
+
// ❌ Missing required `variant` prop
|
|
182
|
+
<Button color="primary">Click</Button>
|
|
183
|
+
|
|
184
|
+
// ❌ Using shape with children
|
|
185
|
+
<Button variant="solid" shape="circle" icon={<Icon />}>Text</Button>
|
|
186
|
+
|
|
187
|
+
// ❌ Redundant: loading already disables, no need for disabled too
|
|
188
|
+
<Button loading={true} disabled={true}>Save</Button>
|
|
189
|
+
|
|
190
|
+
// ✅ Correct: just use loading
|
|
191
|
+
<Button loading={true}>Save</Button>
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## ADDITIONAL NATIVE PROPS
|
|
195
|
+
|
|
196
|
+
The `Button` component forwards all standard `HTMLButtonElement` attributes except `onClick`, `class`, `disabled`, and `children` (which are controlled by the component). You can pass `type="submit"`, `form`, `aria-*`, `data-*`, etc.
|
|
197
|
+
|
|
198
|
+
> **Unique IDs**: if this component needs to generate HTML `id` attributes, always use `createUniqueId()` from `solid-js` — never `Math.random()` or `Date.now()`.
|