@particle-academy/react-fancy 4.12.0 → 4.13.0
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 +5 -4
- package/dist/index.cjs +919 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +269 -4
- package/dist/index.d.ts +269 -4
- package/dist/index.js +919 -2
- package/dist/index.js.map +1 -1
- package/docs/AccordionPanel.md +6 -6
- package/docs/Action.md +3 -82
- package/docs/FileBrowser.md +231 -0
- package/docs/utilities.md +5 -4
- package/package.json +1 -1
package/docs/AccordionPanel.md
CHANGED
|
@@ -22,22 +22,22 @@ import { AccordionPanel } from "@particle-academy/react-fancy";
|
|
|
22
22
|
```tsx
|
|
23
23
|
<AccordionPanel orientation="horizontal" defaultValue={["wishlist"]}>
|
|
24
24
|
<AccordionPanel.Section id="home" pinned>
|
|
25
|
-
<
|
|
25
|
+
<Button icon="home" />
|
|
26
26
|
</AccordionPanel.Section>
|
|
27
27
|
|
|
28
28
|
<AccordionPanel.Section id="wishlist">
|
|
29
29
|
<AccordionPanel.Trigger />
|
|
30
30
|
<AccordionPanel.Content>
|
|
31
|
-
<
|
|
32
|
-
<
|
|
33
|
-
<
|
|
31
|
+
<Button icon="list">Wishlist</Button>
|
|
32
|
+
<Button icon="mail">Feedback</Button>
|
|
33
|
+
<Button icon="file-text">Plans</Button>
|
|
34
34
|
</AccordionPanel.Content>
|
|
35
35
|
</AccordionPanel.Section>
|
|
36
36
|
|
|
37
37
|
<AccordionPanel.Section id="board">
|
|
38
38
|
<AccordionPanel.Trigger />
|
|
39
39
|
<AccordionPanel.Content>
|
|
40
|
-
<
|
|
40
|
+
<Button icon="grid">Board</Button>
|
|
41
41
|
</AccordionPanel.Content>
|
|
42
42
|
</AccordionPanel.Section>
|
|
43
43
|
</AccordionPanel>
|
|
@@ -55,7 +55,7 @@ When closed, the Trigger renders as a standalone chevron button. When open, the
|
|
|
55
55
|
{({ open }) => (open ? "Collapse" : "Expand")}
|
|
56
56
|
</AccordionPanel.Trigger>
|
|
57
57
|
<AccordionPanel.Content>
|
|
58
|
-
<
|
|
58
|
+
<Button>Releases</Button>
|
|
59
59
|
</AccordionPanel.Content>
|
|
60
60
|
</AccordionPanel.Section>
|
|
61
61
|
```
|
package/docs/Action.md
CHANGED
|
@@ -10,86 +10,7 @@
|
|
|
10
10
|
> ```
|
|
11
11
|
>
|
|
12
12
|
> `ActionProps` → `ButtonProps`, `ActionColor` → `ButtonColor` (also deprecated
|
|
13
|
-
> aliases).
|
|
13
|
+
> aliases).
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
## Import
|
|
18
|
-
|
|
19
|
-
```tsx
|
|
20
|
-
import { Action } from "@particle-academy/react-fancy"; // deprecated — prefer Button
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
## Basic Usage
|
|
24
|
-
|
|
25
|
-
```tsx
|
|
26
|
-
<Action>Click me</Action> // identical to <Button>Click me</Button>
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
## Props
|
|
30
|
-
|
|
31
|
-
| Prop | Type | Default | Description |
|
|
32
|
-
|------|------|---------|-------------|
|
|
33
|
-
| variant | `"default" \| "circle" \| "ghost"` | `"default"` | Shape/fill variant. `"ghost"` is transparent with subtle hover. |
|
|
34
|
-
| color | `ActionColor` | - | Standalone color (overrides state colors). One of: `"blue"`, `"emerald"`, `"amber"`, `"red"`, `"violet"`, `"indigo"`, `"sky"`, `"rose"`, `"orange"`, `"zinc"` |
|
|
35
|
-
| size | `"xs" \| "sm" \| "md" \| "lg" \| "xl"` | `"md"` | Button size |
|
|
36
|
-
| active | `boolean` | - | Active state (blue highlight) |
|
|
37
|
-
| checked | `boolean` | - | Checked state (emerald highlight) |
|
|
38
|
-
| warn | `boolean` | - | Warning state (amber highlight) |
|
|
39
|
-
| alert | `boolean` | - | Pulsing animation on the entire button |
|
|
40
|
-
| icon | `string` | - | Leading icon slug resolved via the Icon component |
|
|
41
|
-
| iconTrailing | `string` | - | Trailing icon slug |
|
|
42
|
-
| iconPlace | `string` | `"left"` | Icon placement. Supports: `"left"`, `"right"`, `"top"`, `"bottom"`, and compound positions like `"top left"`, `"bottom right"` |
|
|
43
|
-
| alertIcon | `string` | - | Pulsing alert icon slug |
|
|
44
|
-
| alertIconTrailing | `boolean` | - | Position alert icon on trailing side |
|
|
45
|
-
| emoji | `string` | - | Leading emoji slug |
|
|
46
|
-
| emojiTrailing | `string` | - | Trailing emoji slug |
|
|
47
|
-
| avatar | `string` | - | Avatar image URL |
|
|
48
|
-
| avatarTrailing | `boolean` | - | Position avatar on trailing side |
|
|
49
|
-
| badge | `string` | - | Badge text |
|
|
50
|
-
| badgeTrailing | `boolean` | - | Position badge on trailing side |
|
|
51
|
-
| sort | `string` | `"eiab"` | Sort order of decorative elements: `e`=emoji, `i`=icon, `a`=avatar, `b`=badge |
|
|
52
|
-
| loading | `boolean` | `false` | Show loading spinner (disables the button) |
|
|
53
|
-
| disabled | `boolean` | - | Disable the button |
|
|
54
|
-
| href | `string` | - | Render as an anchor tag instead of a button. Sanitized to a safe-protocol allow-list (since v2.5.0) — `javascript:`, `data:`, `vbscript:` are silently dropped and the component renders a `<button>` instead of an `<a>`. |
|
|
55
|
-
|
|
56
|
-
Also extends all native `<button>` HTML attributes (except `color`).
|
|
57
|
-
|
|
58
|
-
## Examples
|
|
59
|
-
|
|
60
|
-
### Icon button with color
|
|
61
|
-
|
|
62
|
-
```tsx
|
|
63
|
-
<Action icon="pencil" color="blue" size="lg">
|
|
64
|
-
Edit
|
|
65
|
-
</Action>
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
### Circle icon button
|
|
69
|
-
|
|
70
|
-
```tsx
|
|
71
|
-
<Action variant="circle" icon="plus" color="emerald" />
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
### Loading state with badge
|
|
75
|
-
|
|
76
|
-
```tsx
|
|
77
|
-
<Action loading badge="3" badgeTrailing>
|
|
78
|
-
Messages
|
|
79
|
-
</Action>
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
### Link button with trailing icon
|
|
83
|
-
|
|
84
|
-
```tsx
|
|
85
|
-
<Action href="/docs" iconTrailing="arrow-right">
|
|
86
|
-
Read docs
|
|
87
|
-
</Action>
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
### Ghost variant
|
|
91
|
-
|
|
92
|
-
```tsx
|
|
93
|
-
<Action variant="ghost" color="red" icon="trash-2">Delete</Action>
|
|
94
|
-
<Action variant="ghost" icon="download">Export</Action>
|
|
95
|
-
```
|
|
15
|
+
Do not use `Action` in new code, examples, or generated snippets — always use
|
|
16
|
+
`Button`. Full, current documentation lives in **[Button](./Button.md)**.
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
# FileBrowser
|
|
2
|
+
|
|
3
|
+
Remote-capable file/folder browser + directory picker. Browses any tree the host can describe — local FS, HTTP, an MCP bridge, or a remote machine streaming snapshots — through two feeding modes that can be combined:
|
|
4
|
+
|
|
5
|
+
- **Provider mode (lazy pull):** supply `provider.loadChildren(path)`. Folders load on first expand with per-node loading and error states. The tree is never walked eagerly.
|
|
6
|
+
- **Snapshot mode (streamed push):** pass a JSON-friendly `snapshot` tree and replace/patch it as chunks arrive (relay / WebSocket / MCP). The snapshot is the source of truth for every path it covers; with a provider also present, unknown-depth folders stay lazily loadable (hybrid).
|
|
7
|
+
|
|
8
|
+
Fully controlled per the Human+ component contract; every row carries a `data-path` stable handle. Read-only in v1 — no content preview (pair with fancy-code's `FileViewer`) and no write operations.
|
|
9
|
+
|
|
10
|
+
## Import
|
|
11
|
+
|
|
12
|
+
```tsx
|
|
13
|
+
import { FileBrowser } from "@particle-academy/react-fancy";
|
|
14
|
+
import type { FileEntry, FileSnapshotNode } from "@particle-academy/react-fancy";
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Basic Usage — provider mode
|
|
18
|
+
|
|
19
|
+
Any async listing works. A fake in-memory FS:
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
const FS: Record<string, FileEntry[]> = {
|
|
23
|
+
"/": [
|
|
24
|
+
{ path: "/src", name: "src", kind: "dir", hasChildren: true },
|
|
25
|
+
{ path: "/package.json", name: "package.json", kind: "file", size: 1204, mtime: "2026-07-01T10:00:00Z" },
|
|
26
|
+
{ path: "/README.md", name: "README.md", kind: "file", size: 5310, mtime: "2026-06-28T09:30:00Z" },
|
|
27
|
+
],
|
|
28
|
+
"/src": [
|
|
29
|
+
{ path: "/src/App.tsx", name: "App.tsx", kind: "file", size: 2048 },
|
|
30
|
+
{ path: "/src/components", name: "components", kind: "dir", hasChildren: true },
|
|
31
|
+
],
|
|
32
|
+
"/src/components": [
|
|
33
|
+
{ path: "/src/components/Button.tsx", name: "Button.tsx", kind: "file", size: 980 },
|
|
34
|
+
],
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const provider = {
|
|
38
|
+
loadChildren: async (path: string) => {
|
|
39
|
+
await new Promise((r) => setTimeout(r, 300)); // network latency
|
|
40
|
+
const entries = FS[path];
|
|
41
|
+
if (!entries) throw new Error(`No such directory: ${path}`);
|
|
42
|
+
return entries;
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const [selected, setSelected] = useState<string | null>(null);
|
|
47
|
+
|
|
48
|
+
<FileBrowser
|
|
49
|
+
provider={provider}
|
|
50
|
+
value={selected}
|
|
51
|
+
onChange={(value) => setSelected(value as string | null)}
|
|
52
|
+
className="h-80"
|
|
53
|
+
/>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Each folder is fetched once, on first expand (or when it becomes the current directory). Failed loads show an inline error with a Retry button and fire `onError(path, error)`.
|
|
57
|
+
|
|
58
|
+
## Snapshot mode — streamed tree
|
|
59
|
+
|
|
60
|
+
Feed a JSON-friendly tree and update it from outside as chunks land. The component re-derives everything from the new value — selection, expansion, and current path survive because paths are the identity:
|
|
61
|
+
|
|
62
|
+
```tsx
|
|
63
|
+
const [tree, setTree] = useState<FileSnapshotNode[]>([
|
|
64
|
+
{ path: "/logs", name: "logs", kind: "dir" }, // children unknown so far
|
|
65
|
+
]);
|
|
66
|
+
|
|
67
|
+
// Later, as the remote machine pushes a chunk over your transport:
|
|
68
|
+
socket.on("fs-chunk", (chunk: FileSnapshotNode[]) => {
|
|
69
|
+
setTree((prev) => mergeChunk(prev, chunk)); // host-side merge — any shape works
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
<FileBrowser snapshot={tree} select="file" className="h-80" />
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
- `children: []` marks a known-empty folder (no expand affordance, same as `hasChildren: false`); `children: undefined` marks unknown depth.
|
|
76
|
+
- Without a provider, unknown-depth folders are not expandable (there is nothing to load them with).
|
|
77
|
+
- **Hybrid:** pass `snapshot` *and* `provider` — the snapshot seeds instantly, the provider lazily fills folders the snapshot left unknown. Where the snapshot speaks, it wins.
|
|
78
|
+
|
|
79
|
+
## Directory picker
|
|
80
|
+
|
|
81
|
+
```tsx
|
|
82
|
+
const [dir, setDir] = useState<string | null>(null);
|
|
83
|
+
|
|
84
|
+
<Modal open={open} onClose={() => setOpen(false)}>
|
|
85
|
+
<Modal.Header>Choose a folder</Modal.Header>
|
|
86
|
+
<Modal.Body>
|
|
87
|
+
<FileBrowser
|
|
88
|
+
provider={provider}
|
|
89
|
+
select="directory"
|
|
90
|
+
value={dir}
|
|
91
|
+
onChange={(value) => setDir(value as string | null)}
|
|
92
|
+
defaultPath="/"
|
|
93
|
+
className="h-72"
|
|
94
|
+
/>
|
|
95
|
+
</Modal.Body>
|
|
96
|
+
<Modal.Footer>
|
|
97
|
+
<Button disabled={!dir} onClick={() => pick(dir!)}>Select {dir ?? "…"}</Button>
|
|
98
|
+
</Modal.Footer>
|
|
99
|
+
</Modal>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
With `select="directory"`, files stay visible and browsable but only folders are selectable. Double-click a folder (or use the path input) to drill into it.
|
|
103
|
+
|
|
104
|
+
## Multiple selection
|
|
105
|
+
|
|
106
|
+
```tsx
|
|
107
|
+
const [paths, setPaths] = useState<string[]>([]);
|
|
108
|
+
|
|
109
|
+
<FileBrowser
|
|
110
|
+
provider={provider}
|
|
111
|
+
select="both"
|
|
112
|
+
multiple
|
|
113
|
+
value={paths}
|
|
114
|
+
onChange={(value) => setPaths(value as string[])}
|
|
115
|
+
/>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
In `multiple` mode `value` is `string[]` and clicking (or Space) toggles membership. Disabled entries (`disabled: true`) can never be selected.
|
|
119
|
+
|
|
120
|
+
## Props
|
|
121
|
+
|
|
122
|
+
### FileBrowser (root)
|
|
123
|
+
|
|
124
|
+
| Prop | Type | Default | Description |
|
|
125
|
+
|------|------|---------|-------------|
|
|
126
|
+
| provider | `FileBrowserProvider` | - | Async data source — `loadChildren(path) => Promise<FileEntry[]>`, called lazily per folder |
|
|
127
|
+
| snapshot | `FileSnapshotNode[]` | - | JSON-friendly tree value, replaceable/patchable from outside; combinable with `provider` (hybrid) |
|
|
128
|
+
| select | `"file" \| "directory" \| "both"` | `"file"` | Which entry kinds are selectable |
|
|
129
|
+
| multiple | `boolean` | `false` | Multi-select; `value` becomes `string[]` |
|
|
130
|
+
| value | `string \| string[] \| null` | - | Controlled selection (paths) |
|
|
131
|
+
| defaultValue | `string \| string[] \| null` | - | Initial selection (uncontrolled) |
|
|
132
|
+
| onChange | `(value, entries: FileEntry[]) => void` | - | Selection callback (next value + matching known entries) |
|
|
133
|
+
| path | `string` | - | Controlled current directory |
|
|
134
|
+
| defaultPath | `string` | `"/"` | Initial current directory (uncontrolled) |
|
|
135
|
+
| onPathChange | `(path: string) => void` | - | Current-directory callback |
|
|
136
|
+
| expandedPaths | `string[]` | - | Controlled expanded folders |
|
|
137
|
+
| defaultExpandedPaths | `string[]` | - | Initially expanded folders (uncontrolled) |
|
|
138
|
+
| onExpandedChange | `(paths: string[]) => void` | - | Expanded-set callback |
|
|
139
|
+
| sort | `FileSort` | - | Controlled sort order |
|
|
140
|
+
| defaultSort | `FileSort` | `{ by: "name", direction: "asc" }` | Initial sort (uncontrolled) |
|
|
141
|
+
| onSortChange | `(sort: FileSort) => void` | - | Sort callback |
|
|
142
|
+
| filter | `string` | - | Controlled name filter (client-side, over loaded nodes) |
|
|
143
|
+
| defaultFilter | `string` | `""` | Initial filter (uncontrolled) |
|
|
144
|
+
| onFilterChange | `(filter: string) => void` | - | Filter callback |
|
|
145
|
+
| onError | `(path: string, error: unknown) => void` | - | Provider load failure callback |
|
|
146
|
+
| indentSize | `number` | `16` | Indent per nesting level in px |
|
|
147
|
+
| showIcons | `boolean` | `true` | Show file/folder icons |
|
|
148
|
+
| className | `string` | - | Extra classes on the outer shell |
|
|
149
|
+
| children | `ReactNode` | PathBar + Toolbar + Tree | Custom compound layout |
|
|
150
|
+
|
|
151
|
+
### FileEntry
|
|
152
|
+
|
|
153
|
+
| Field | Type | Description |
|
|
154
|
+
|-------|------|-------------|
|
|
155
|
+
| path | `string` | Stable identity — POSIX-style path (required) |
|
|
156
|
+
| name | `string` | Display name (required) |
|
|
157
|
+
| kind | `"file" \| "dir"` | Entry kind (required) |
|
|
158
|
+
| size | `number` | Bytes; shown on file rows and used by size sorting |
|
|
159
|
+
| mtime | `string` | ISO 8601 timestamp; used by mtime sorting |
|
|
160
|
+
| hasChildren | `boolean` | Dirs: `false` = known-empty (no chevron), `undefined` = unknown (loadable with a provider), `true` = has children |
|
|
161
|
+
| disabled | `boolean` | Dimmed; cannot be selected, expanded, or navigated into |
|
|
162
|
+
|
|
163
|
+
### FileSnapshotNode
|
|
164
|
+
|
|
165
|
+
`FileEntry` plus `children?: FileSnapshotNode[]` — `[]` = known-empty, `undefined` = unknown depth.
|
|
166
|
+
|
|
167
|
+
### FileSort
|
|
168
|
+
|
|
169
|
+
`{ by: "name" | "size" | "mtime"; direction: "asc" | "desc" }`. Directories always sort before files; ties break by name.
|
|
170
|
+
|
|
171
|
+
## Path bar
|
|
172
|
+
|
|
173
|
+
The breadcrumb trail navigates on click. The pencil button (or double-clicking the trail) switches to an editable path input: type a POSIX-style path and press **Enter** to navigate — in provider mode the target directory loads on arrival. **Escape** or blur cancels. Input is normalized (`\` → `/`, collapsed slashes, `.`/`..` resolved). Navigating clears the name filter.
|
|
174
|
+
|
|
175
|
+
## Keyboard navigation
|
|
176
|
+
|
|
177
|
+
The tree uses ARIA `tree`/`treeitem`/`group` semantics with a roving tabindex — one Tab stop for the whole tree.
|
|
178
|
+
|
|
179
|
+
| Key | Action |
|
|
180
|
+
|-----|--------|
|
|
181
|
+
| `↓` / `↑` | Move focus through visible rows |
|
|
182
|
+
| `→` | Expand a collapsed folder (lazy-loads it); on an expanded folder, move to its first child |
|
|
183
|
+
| `←` | Collapse an expanded folder; otherwise move focus to the parent row |
|
|
184
|
+
| `Home` / `End` | First / last visible row |
|
|
185
|
+
| `Enter` | Select (if selectable) and toggle a folder; on a non-selectable, non-expandable folder, navigate into it |
|
|
186
|
+
| `Space` | Toggle selection |
|
|
187
|
+
|
|
188
|
+
## Sorting and filtering
|
|
189
|
+
|
|
190
|
+
The toolbar sorts by **Name**, **Size**, or **Modified** (click the active field to flip direction — directories always list first) and filters by name. The filter is client-side over *loaded* nodes only: it never triggers loads, and a folder stays visible while it matches or any loaded descendant matches.
|
|
191
|
+
|
|
192
|
+
## Custom layout
|
|
193
|
+
|
|
194
|
+
The default layout is `PathBar + Toolbar + Tree`. Pass children to rearrange or omit chrome:
|
|
195
|
+
|
|
196
|
+
```tsx
|
|
197
|
+
<FileBrowser provider={provider} select="file" className="h-80">
|
|
198
|
+
<FileBrowser.Toolbar filterPlaceholder="Search files" />
|
|
199
|
+
<FileBrowser.Tree ariaLabel="Project files" />
|
|
200
|
+
<FileBrowser.PathBar editable={false} />
|
|
201
|
+
</FileBrowser>
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
`useFileBrowser()` exposes the full context (entries, statuses, selection, navigation, sort/filter) for fully custom subcomponents.
|
|
205
|
+
|
|
206
|
+
## Agent bridge (Human+)
|
|
207
|
+
|
|
208
|
+
Every row carries `data-path` — paths are the stable handles agents target, never indexes. The controlled props (`value`, `path`, `expandedPaths`) plus the provider/snapshot contract are the full agent surface.
|
|
209
|
+
|
|
210
|
+
A `registerFilesBridge(server, { adapter })` ships later in `@particle-academy/agent-integrations`, exposing MCP tools over this surface — `files_list(path)`, `files_expand(path)` / `files_collapse(path)`, `files_select(paths)`, `files_navigate(path)`, `files_request_snapshot(path, depth)` — with each mutation emitting an `AgentActivity` event so presence, undo, and coaching layers compose for free.
|
|
211
|
+
|
|
212
|
+
## SSR
|
|
213
|
+
|
|
214
|
+
SSR-safe: no browser APIs outside event handlers, and rendering is deterministic (name sorting is pinned to a fixed locale so server and client order identically). In provider mode the server renders the loading state; hydration kicks off the first load.
|
|
215
|
+
|
|
216
|
+
## Data Attributes
|
|
217
|
+
|
|
218
|
+
| Attribute | Element |
|
|
219
|
+
|-----------|---------|
|
|
220
|
+
| `data-react-fancy-file-browser` | Root shell |
|
|
221
|
+
| `data-react-fancy-file-browser-path` | Path bar |
|
|
222
|
+
| `data-react-fancy-file-browser-path-segment` | Breadcrumb segment |
|
|
223
|
+
| `data-react-fancy-file-browser-path-input` | Editable path input |
|
|
224
|
+
| `data-react-fancy-file-browser-toolbar` | Toolbar |
|
|
225
|
+
| `data-react-fancy-file-browser-filter` | Name filter box |
|
|
226
|
+
| `data-react-fancy-file-browser-sort` | Sort control group (buttons carry `data-sort-field`) |
|
|
227
|
+
| `data-react-fancy-file-browser-tree` | Tree pane (`role="tree"`) |
|
|
228
|
+
| `data-react-fancy-file-browser-node` | Tree item (also carries `data-path` + `data-kind`) |
|
|
229
|
+
| `data-react-fancy-file-browser-row` | Visual row inside a tree item |
|
|
230
|
+
| `data-react-fancy-file-browser-node-children` | Children group of an expanded folder |
|
|
231
|
+
| `data-react-fancy-file-browser-status` | Loading / error / empty placeholder rows |
|
package/docs/utilities.md
CHANGED
|
@@ -55,12 +55,13 @@ type Color =
|
|
|
55
55
|
type Variant = "solid" | "outline" | "ghost" | "soft";
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
-
###
|
|
58
|
+
### ButtonColor
|
|
59
|
+
|
|
60
|
+
Standalone color accepted by `Button` and friends — an alias of `Color` (the
|
|
61
|
+
full palette above). `ActionColor` remains as a deprecated alias.
|
|
59
62
|
|
|
60
63
|
```ts
|
|
61
|
-
type
|
|
62
|
-
| "blue" | "emerald" | "amber" | "red" | "violet"
|
|
63
|
-
| "indigo" | "sky" | "rose" | "orange" | "zinc";
|
|
64
|
+
type ButtonColor = Color;
|
|
64
65
|
```
|
|
65
66
|
|
|
66
67
|
### Placement
|