@particle-academy/react-fancy 1.7.0 → 1.7.2
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 +76 -82
- package/docs/Accordion.md +78 -0
- package/docs/Action.md +76 -0
- package/docs/Autocomplete.md +74 -0
- package/docs/Avatar.md +40 -0
- package/docs/Badge.md +42 -0
- package/docs/Brand.md +44 -0
- package/docs/Breadcrumbs.md +51 -0
- package/docs/Calendar.md +72 -0
- package/docs/Callout.md +46 -0
- package/docs/Canvas.md +102 -0
- package/docs/Card.md +68 -0
- package/docs/Carousel.md +97 -0
- package/docs/Chart.md +126 -0
- package/docs/Checkbox.md +86 -0
- package/docs/ColorPicker.md +49 -0
- package/docs/Command.md +88 -0
- package/docs/Composer.md +60 -0
- package/docs/ContentRenderer.md +68 -0
- package/docs/ContextMenu.md +82 -0
- package/docs/DatePicker.md +64 -0
- package/docs/Diagram.md +119 -0
- package/docs/Dropdown.md +79 -0
- package/docs/Editor.md +84 -0
- package/docs/Emoji.md +40 -0
- package/docs/EmojiSelect.md +47 -0
- package/docs/Field.md +48 -0
- package/docs/FileUpload.md +81 -0
- package/docs/Heading.md +43 -0
- package/docs/Icon.md +75 -0
- package/docs/Input.md +73 -0
- package/docs/Kanban.md +79 -0
- package/docs/Menu.md +71 -0
- package/docs/MobileMenu.md +69 -0
- package/docs/Modal.md +74 -0
- package/docs/MultiSwitch.md +64 -0
- package/docs/Navbar.md +65 -0
- package/docs/OtpInput.md +48 -0
- package/docs/Pagination.md +48 -0
- package/docs/Pillbox.md +53 -0
- package/docs/Popover.md +82 -0
- package/docs/Portal.md +40 -0
- package/docs/Profile.md +52 -0
- package/docs/Progress.md +42 -0
- package/docs/RadioGroup.md +69 -0
- package/docs/Select.md +122 -0
- package/docs/Separator.md +41 -0
- package/docs/Sidebar.md +88 -0
- package/docs/Skeleton.md +44 -0
- package/docs/Slider.md +75 -0
- package/docs/Switch.md +55 -0
- package/docs/Table.md +133 -0
- package/docs/Tabs.md +85 -0
- package/docs/Text.md +44 -0
- package/docs/Textarea.md +62 -0
- package/docs/TimePicker.md +45 -0
- package/docs/Timeline.md +118 -0
- package/docs/Toast.md +79 -0
- package/docs/Tooltip.md +46 -0
- package/docs/hooks.md +180 -0
- package/docs/utilities.md +74 -0
- package/package.json +2 -1
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# FileUpload
|
|
2
|
+
|
|
3
|
+
Compound file upload component with drag-and-drop dropzone and file list display (list or thumbnail mode).
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { FileUpload } from "@particle-academy/react-fancy";
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Basic Usage
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
<FileUpload onChange={(files) => console.log(files)}>
|
|
15
|
+
<FileUpload.Dropzone />
|
|
16
|
+
<FileUpload.List />
|
|
17
|
+
</FileUpload>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Components
|
|
21
|
+
|
|
22
|
+
### `FileUpload` (root)
|
|
23
|
+
|
|
24
|
+
Provides file state context to its children.
|
|
25
|
+
|
|
26
|
+
| Prop | Type | Default | Description |
|
|
27
|
+
|------|------|---------|-------------|
|
|
28
|
+
| `children` | `ReactNode` | **required** | Must contain `Dropzone` and/or `List` |
|
|
29
|
+
| `value` | `File[]` | - | Controlled file list |
|
|
30
|
+
| `onChange` | `(files: File[]) => void` | - | Callback when files change |
|
|
31
|
+
| `accept` | `string` | - | Accepted file types (e.g. `"image/*,.pdf"`) |
|
|
32
|
+
| `multiple` | `boolean` | `true` | Allow multiple files |
|
|
33
|
+
| `maxFiles` | `number` | - | Maximum number of files |
|
|
34
|
+
| `maxSize` | `number` | - | Maximum file size in bytes (files exceeding this are silently filtered) |
|
|
35
|
+
| `disabled` | `boolean` | `false` | Disables upload and removal |
|
|
36
|
+
| `className` | `string` | - | Additional CSS classes on the wrapper |
|
|
37
|
+
|
|
38
|
+
### `FileUpload.Dropzone`
|
|
39
|
+
|
|
40
|
+
Drag-and-drop area that also opens a file picker on click.
|
|
41
|
+
|
|
42
|
+
| Prop | Type | Default | Description |
|
|
43
|
+
|------|------|---------|-------------|
|
|
44
|
+
| `children` | `ReactNode` | Default upload icon + text | Custom dropzone content |
|
|
45
|
+
| `className` | `string` | - | Additional CSS classes |
|
|
46
|
+
|
|
47
|
+
### `FileUpload.List`
|
|
48
|
+
|
|
49
|
+
Displays the uploaded files with remove buttons.
|
|
50
|
+
|
|
51
|
+
| Prop | Type | Default | Description |
|
|
52
|
+
|------|------|---------|-------------|
|
|
53
|
+
| `thumbnail` | `boolean` | `false` | Show image thumbnails in a grid instead of a file list |
|
|
54
|
+
| `className` | `string` | - | Additional CSS classes |
|
|
55
|
+
|
|
56
|
+
## Examples
|
|
57
|
+
|
|
58
|
+
### With file constraints
|
|
59
|
+
|
|
60
|
+
```tsx
|
|
61
|
+
<FileUpload
|
|
62
|
+
accept="image/*"
|
|
63
|
+
maxFiles={5}
|
|
64
|
+
maxSize={5 * 1024 * 1024}
|
|
65
|
+
onChange={setFiles}
|
|
66
|
+
>
|
|
67
|
+
<FileUpload.Dropzone>
|
|
68
|
+
<p>Drop images here (max 5MB each)</p>
|
|
69
|
+
</FileUpload.Dropzone>
|
|
70
|
+
<FileUpload.List thumbnail />
|
|
71
|
+
</FileUpload>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### List mode
|
|
75
|
+
|
|
76
|
+
```tsx
|
|
77
|
+
<FileUpload onChange={handleUpload}>
|
|
78
|
+
<FileUpload.Dropzone />
|
|
79
|
+
<FileUpload.List />
|
|
80
|
+
</FileUpload>
|
|
81
|
+
```
|
package/docs/Heading.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Heading
|
|
2
|
+
|
|
3
|
+
A heading component that renders semantic heading elements with configurable size and weight.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { Heading } from "@particle-academy/react-fancy";
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Basic Usage
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
<Heading>Page Title</Heading>
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Props
|
|
18
|
+
|
|
19
|
+
| Prop | Type | Default | Description |
|
|
20
|
+
|------|------|---------|-------------|
|
|
21
|
+
| as | `"h1" \| "h2" \| "h3" \| "h4" \| "h5" \| "h6"` | `"h2"` | Which heading element to render |
|
|
22
|
+
| size | `"xs" \| "sm" \| "md" \| "lg" \| "xl" \| "2xl"` | `"lg"` | Text size |
|
|
23
|
+
| weight | `"normal" \| "medium" \| "semibold" \| "bold"` | `"bold"` | Font weight |
|
|
24
|
+
|
|
25
|
+
Also extends all native `<h1>`-`<h6>` HTML attributes.
|
|
26
|
+
|
|
27
|
+
## Examples
|
|
28
|
+
|
|
29
|
+
### Page title
|
|
30
|
+
|
|
31
|
+
```tsx
|
|
32
|
+
<Heading as="h1" size="2xl">
|
|
33
|
+
Welcome
|
|
34
|
+
</Heading>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Section heading
|
|
38
|
+
|
|
39
|
+
```tsx
|
|
40
|
+
<Heading as="h3" size="md" weight="semibold">
|
|
41
|
+
Settings
|
|
42
|
+
</Heading>
|
|
43
|
+
```
|
package/docs/Icon.md
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Icon
|
|
2
|
+
|
|
3
|
+
An icon container that resolves icon names from registered icon sets (Lucide by default).
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { Icon, registerIconSet, configureIcons } from "@particle-academy/react-fancy";
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Basic Usage
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
<Icon name="rocket" />
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Props
|
|
18
|
+
|
|
19
|
+
| Prop | Type | Default | Description |
|
|
20
|
+
|------|------|---------|-------------|
|
|
21
|
+
| name | `string` | - | Icon name to resolve from the registered icon set (e.g., `"rocket"`, `"arrow-right"`) |
|
|
22
|
+
| size | `"xs" \| "sm" \| "md" \| "lg" \| "xl"` | `"md"` | Icon container size. Maps to: xs=12px, sm=16px, md=20px, lg=24px, xl=32px |
|
|
23
|
+
| iconSet | `string` | - | Which registered icon set to use (defaults to the configured default) |
|
|
24
|
+
|
|
25
|
+
Also extends all native `<span>` HTML attributes. When `children` are provided, they render instead of the resolved icon.
|
|
26
|
+
|
|
27
|
+
## Icon Configuration
|
|
28
|
+
|
|
29
|
+
### registerIconSet
|
|
30
|
+
|
|
31
|
+
Register a custom icon set by name.
|
|
32
|
+
|
|
33
|
+
```tsx
|
|
34
|
+
import { registerIconSet } from "@particle-academy/react-fancy";
|
|
35
|
+
|
|
36
|
+
registerIconSet("custom", {
|
|
37
|
+
resolve: (name) => MyCustomIconMap[name] ?? null,
|
|
38
|
+
});
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The `IconSet` interface requires a single `resolve` method:
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
interface IconSet {
|
|
45
|
+
resolve: (name: string) => ComponentType<{ className?: string; size?: number }> | null;
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### configureIcons
|
|
50
|
+
|
|
51
|
+
Set the default icon set used when `iconSet` is not specified on `<Icon>`.
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
import { configureIcons } from "@particle-academy/react-fancy";
|
|
55
|
+
|
|
56
|
+
configureIcons({ defaultSet: "custom" });
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The built-in default is `"lucide"`, which resolves kebab-case names (e.g., `"arrow-right"`) to Lucide React icons.
|
|
60
|
+
|
|
61
|
+
## Examples
|
|
62
|
+
|
|
63
|
+
### Different sizes
|
|
64
|
+
|
|
65
|
+
```tsx
|
|
66
|
+
<Icon name="star" size="xs" />
|
|
67
|
+
<Icon name="star" size="md" />
|
|
68
|
+
<Icon name="star" size="xl" />
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Using a specific icon set
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
<Icon name="home" iconSet="custom" size="lg" />
|
|
75
|
+
```
|
package/docs/Input.md
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Input
|
|
2
|
+
|
|
3
|
+
Text input with built-in label, error, prefix/suffix, and leading/trailing icon support.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { Input } from "@particle-academy/react-fancy";
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Basic Usage
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
<Input label="Email" type="email" placeholder="you@example.com" />
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Props
|
|
18
|
+
|
|
19
|
+
Extends all native `<input>` attributes (except `size`, `type`, `prefix`).
|
|
20
|
+
|
|
21
|
+
| Prop | Type | Default | Description |
|
|
22
|
+
|------|------|---------|-------------|
|
|
23
|
+
| `type` | `"text" \| "email" \| "password" \| "number" \| "tel" \| "url" \| "search"` | `"text"` | Input type |
|
|
24
|
+
| `size` | `"xs" \| "sm" \| "md" \| "lg" \| "xl"` | `"md"` | Controls input height and text size |
|
|
25
|
+
| `label` | `string` | - | Wraps input in a `Field` with this label |
|
|
26
|
+
| `description` | `string` | - | Helper text below the input |
|
|
27
|
+
| `error` | `string` | - | Error message (red text below input, red border) |
|
|
28
|
+
| `required` | `boolean` | `false` | Red asterisk on label, sets native `required` |
|
|
29
|
+
| `dirty` | `boolean` | `false` | Amber ring to indicate unsaved changes |
|
|
30
|
+
| `disabled` | `boolean` | `false` | Disables the input |
|
|
31
|
+
| `leading` | `ReactNode` | - | Icon/element positioned inside the input on the left |
|
|
32
|
+
| `trailing` | `ReactNode` | - | Icon/element positioned inside the input on the right |
|
|
33
|
+
| `prefix` | `ReactNode` | - | Affix rendered before the input |
|
|
34
|
+
| `suffix` | `ReactNode` | - | Affix rendered after the input |
|
|
35
|
+
| `prefixPosition` | `"inside" \| "outside"` | - | Whether prefix renders inside or outside the input border |
|
|
36
|
+
| `suffixPosition` | `"inside" \| "outside"` | - | Whether suffix renders inside or outside the input border |
|
|
37
|
+
| `onValueChange` | `(value: string) => void` | - | Convenience callback with the string value directly |
|
|
38
|
+
| `className` | `string` | - | Additional CSS classes on the `<input>` element |
|
|
39
|
+
|
|
40
|
+
## Examples
|
|
41
|
+
|
|
42
|
+
### With leading icon
|
|
43
|
+
|
|
44
|
+
```tsx
|
|
45
|
+
import { Search } from "lucide-react";
|
|
46
|
+
|
|
47
|
+
<Input
|
|
48
|
+
label="Search"
|
|
49
|
+
type="search"
|
|
50
|
+
leading={<Search size={16} />}
|
|
51
|
+
placeholder="Search..."
|
|
52
|
+
/>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### With prefix and suffix
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
<Input prefix="https://" suffix=".com" placeholder="yoursite" />
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Controlled with onValueChange
|
|
62
|
+
|
|
63
|
+
```tsx
|
|
64
|
+
const [email, setEmail] = useState("");
|
|
65
|
+
|
|
66
|
+
<Input
|
|
67
|
+
label="Email"
|
|
68
|
+
type="email"
|
|
69
|
+
value={email}
|
|
70
|
+
onValueChange={setEmail}
|
|
71
|
+
error={email ? undefined : "Required"}
|
|
72
|
+
/>
|
|
73
|
+
```
|
package/docs/Kanban.md
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Kanban
|
|
2
|
+
|
|
3
|
+
A drag-and-drop kanban board using the HTML5 Drag and Drop API. Cards can be moved between columns.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { Kanban } from "@particle-academy/react-fancy";
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Basic Usage
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
<Kanban onCardMove={(cardId, from, to) => console.log(`${cardId}: ${from} -> ${to}`)}>
|
|
15
|
+
<Kanban.Column id="todo" title="To Do">
|
|
16
|
+
<Kanban.Card id="task-1">Design homepage</Kanban.Card>
|
|
17
|
+
<Kanban.Card id="task-2">Write tests</Kanban.Card>
|
|
18
|
+
</Kanban.Column>
|
|
19
|
+
<Kanban.Column id="in-progress" title="In Progress">
|
|
20
|
+
<Kanban.Card id="task-3">Build API</Kanban.Card>
|
|
21
|
+
</Kanban.Column>
|
|
22
|
+
<Kanban.Column id="done" title="Done">
|
|
23
|
+
<Kanban.Card id="task-4">Setup CI/CD</Kanban.Card>
|
|
24
|
+
</Kanban.Column>
|
|
25
|
+
</Kanban>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Props
|
|
29
|
+
|
|
30
|
+
### Kanban (root)
|
|
31
|
+
|
|
32
|
+
| Prop | Type | Default | Description |
|
|
33
|
+
|------|------|---------|-------------|
|
|
34
|
+
| onCardMove | `(cardId: string, fromColumn: string, toColumn: string) => void` | - | Callback when a card is dropped into a different column |
|
|
35
|
+
| className | `string` | - | Additional CSS classes |
|
|
36
|
+
|
|
37
|
+
### Kanban.Column
|
|
38
|
+
|
|
39
|
+
| Prop | Type | Default | Description |
|
|
40
|
+
|------|------|---------|-------------|
|
|
41
|
+
| id | `string` | - | Unique column identifier (required) |
|
|
42
|
+
| title | `string` | - | Column header text |
|
|
43
|
+
| className | `string` | - | Additional CSS classes |
|
|
44
|
+
|
|
45
|
+
### Kanban.Card
|
|
46
|
+
|
|
47
|
+
| Prop | Type | Default | Description |
|
|
48
|
+
|------|------|---------|-------------|
|
|
49
|
+
| id | `string` | - | Unique card identifier (required) |
|
|
50
|
+
| children | `ReactNode` | - | Card content |
|
|
51
|
+
| className | `string` | - | Additional CSS classes |
|
|
52
|
+
|
|
53
|
+
## Stateful Example
|
|
54
|
+
|
|
55
|
+
```tsx
|
|
56
|
+
const [columns, setColumns] = useState({
|
|
57
|
+
todo: ["task-1", "task-2"],
|
|
58
|
+
doing: ["task-3"],
|
|
59
|
+
done: [],
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
function handleMove(cardId: string, from: string, to: string) {
|
|
63
|
+
setColumns((prev) => ({
|
|
64
|
+
...prev,
|
|
65
|
+
[from]: prev[from].filter((id) => id !== cardId),
|
|
66
|
+
[to]: [...prev[to], cardId],
|
|
67
|
+
}));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
<Kanban onCardMove={handleMove}>
|
|
71
|
+
{Object.entries(columns).map(([colId, cards]) => (
|
|
72
|
+
<Kanban.Column key={colId} id={colId} title={colId}>
|
|
73
|
+
{cards.map((id) => (
|
|
74
|
+
<Kanban.Card key={id} id={id}>{id}</Kanban.Card>
|
|
75
|
+
))}
|
|
76
|
+
</Kanban.Column>
|
|
77
|
+
))}
|
|
78
|
+
</Kanban>
|
|
79
|
+
```
|
package/docs/Menu.md
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Menu
|
|
2
|
+
|
|
3
|
+
A navigation menu supporting horizontal/vertical orientation, nested submenus, grouped items, icons, and badges.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { Menu } from "@particle-academy/react-fancy";
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Basic Usage
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
<Menu>
|
|
15
|
+
<Menu.Item href="/" active>Home</Menu.Item>
|
|
16
|
+
<Menu.Item href="/about">About</Menu.Item>
|
|
17
|
+
<Menu.Submenu label="Products" icon={<BoxIcon />}>
|
|
18
|
+
<Menu.Item href="/products/widgets">Widgets</Menu.Item>
|
|
19
|
+
<Menu.Item href="/products/gadgets">Gadgets</Menu.Item>
|
|
20
|
+
</Menu.Submenu>
|
|
21
|
+
</Menu>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Props
|
|
25
|
+
|
|
26
|
+
### Menu (root)
|
|
27
|
+
|
|
28
|
+
| Prop | Type | Default | Description |
|
|
29
|
+
|------|------|---------|-------------|
|
|
30
|
+
| orientation | `"horizontal" \| "vertical"` | `"vertical"` | Layout direction |
|
|
31
|
+
| className | `string` | - | Additional CSS classes |
|
|
32
|
+
|
|
33
|
+
### Menu.Item
|
|
34
|
+
|
|
35
|
+
| Prop | Type | Default | Description |
|
|
36
|
+
|------|------|---------|-------------|
|
|
37
|
+
| children | `ReactNode` | - | Item content |
|
|
38
|
+
| href | `string` | - | Link URL |
|
|
39
|
+
| icon | `ReactNode` | - | Leading icon |
|
|
40
|
+
| active | `boolean` | - | Active state highlight |
|
|
41
|
+
| disabled | `boolean` | - | Disable the item |
|
|
42
|
+
| badge | `ReactNode` | - | Trailing badge element |
|
|
43
|
+
| onClick | `() => void` | - | Click handler |
|
|
44
|
+
| className | `string` | - | Additional CSS classes |
|
|
45
|
+
|
|
46
|
+
### Menu.Submenu
|
|
47
|
+
|
|
48
|
+
| Prop | Type | Default | Description |
|
|
49
|
+
|------|------|---------|-------------|
|
|
50
|
+
| label | `ReactNode` | - | Submenu trigger label (required) |
|
|
51
|
+
| icon | `ReactNode` | - | Leading icon |
|
|
52
|
+
| defaultOpen | `boolean` | - | Whether the submenu starts open |
|
|
53
|
+
| className | `string` | - | Additional CSS classes |
|
|
54
|
+
|
|
55
|
+
### Menu.Group
|
|
56
|
+
|
|
57
|
+
| Prop | Type | Default | Description |
|
|
58
|
+
|------|------|---------|-------------|
|
|
59
|
+
| children | `ReactNode` | - | Grouped items |
|
|
60
|
+
| label | `string` | - | Group heading |
|
|
61
|
+
| className | `string` | - | Additional CSS classes |
|
|
62
|
+
|
|
63
|
+
## Horizontal Menu
|
|
64
|
+
|
|
65
|
+
```tsx
|
|
66
|
+
<Menu orientation="horizontal">
|
|
67
|
+
<Menu.Item href="/" active>Home</Menu.Item>
|
|
68
|
+
<Menu.Item href="/docs">Docs</Menu.Item>
|
|
69
|
+
<Menu.Item href="/pricing" badge={<span>New</span>}>Pricing</Menu.Item>
|
|
70
|
+
</Menu>
|
|
71
|
+
```
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# MobileMenu
|
|
2
|
+
|
|
3
|
+
Mobile navigation components with two variants: a slide-out flyout panel and a fixed bottom tab bar.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { MobileMenu } from "@particle-academy/react-fancy";
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Flyout
|
|
12
|
+
|
|
13
|
+
A slide-out panel from the left or right edge.
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
const [open, setOpen] = useState(false);
|
|
17
|
+
|
|
18
|
+
<button onClick={() => setOpen(true)}>Menu</button>
|
|
19
|
+
|
|
20
|
+
<MobileMenu.Flyout open={open} onClose={() => setOpen(false)} side="left" title="Menu">
|
|
21
|
+
<MobileMenu.Item href="/" icon={<HomeIcon />} active>Home</MobileMenu.Item>
|
|
22
|
+
<MobileMenu.Item href="/about" icon={<InfoIcon />}>About</MobileMenu.Item>
|
|
23
|
+
<MobileMenu.Item href="/contact" icon={<MailIcon />}>Contact</MobileMenu.Item>
|
|
24
|
+
</MobileMenu.Flyout>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Bottom Bar
|
|
28
|
+
|
|
29
|
+
A fixed bottom navigation bar for mobile.
|
|
30
|
+
|
|
31
|
+
```tsx
|
|
32
|
+
<MobileMenu.BottomBar>
|
|
33
|
+
<MobileMenu.Item href="/" icon={<HomeIcon />} active>Home</MobileMenu.Item>
|
|
34
|
+
<MobileMenu.Item href="/search" icon={<SearchIcon />}>Search</MobileMenu.Item>
|
|
35
|
+
<MobileMenu.Item href="/profile" icon={<UserIcon />}>Profile</MobileMenu.Item>
|
|
36
|
+
</MobileMenu.BottomBar>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Props
|
|
40
|
+
|
|
41
|
+
### MobileMenu.Flyout
|
|
42
|
+
|
|
43
|
+
| Prop | Type | Default | Description |
|
|
44
|
+
|------|------|---------|-------------|
|
|
45
|
+
| open | `boolean` | - | Whether the flyout is visible (required) |
|
|
46
|
+
| onClose | `() => void` | - | Callback to close the flyout (required) |
|
|
47
|
+
| side | `"left" \| "right"` | - | Which edge the panel slides from |
|
|
48
|
+
| title | `string` | - | Optional header title |
|
|
49
|
+
| className | `string` | - | Additional CSS classes |
|
|
50
|
+
|
|
51
|
+
### MobileMenu.BottomBar
|
|
52
|
+
|
|
53
|
+
| Prop | Type | Default | Description |
|
|
54
|
+
|------|------|---------|-------------|
|
|
55
|
+
| children | `ReactNode` | - | Menu items |
|
|
56
|
+
| className | `string` | - | Additional CSS classes |
|
|
57
|
+
|
|
58
|
+
### MobileMenu.Item
|
|
59
|
+
|
|
60
|
+
| Prop | Type | Default | Description |
|
|
61
|
+
|------|------|---------|-------------|
|
|
62
|
+
| children | `ReactNode` | - | Item label |
|
|
63
|
+
| href | `string` | - | Link URL |
|
|
64
|
+
| icon | `ReactNode` | - | Icon element |
|
|
65
|
+
| active | `boolean` | - | Active state highlight |
|
|
66
|
+
| disabled | `boolean` | - | Disable the item |
|
|
67
|
+
| badge | `ReactNode` | - | Badge element |
|
|
68
|
+
| onClick | `() => void` | - | Click handler |
|
|
69
|
+
| className | `string` | - | Additional CSS classes |
|
package/docs/Modal.md
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Modal
|
|
2
|
+
|
|
3
|
+
A dialog overlay with backdrop, focus trapping, escape-to-close, and body scroll locking. Renders via a portal.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { Modal } from "@particle-academy/react-fancy";
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Basic Usage
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
const [open, setOpen] = useState(false);
|
|
15
|
+
|
|
16
|
+
<button onClick={() => setOpen(true)}>Open Modal</button>
|
|
17
|
+
|
|
18
|
+
<Modal open={open} onClose={() => setOpen(false)}>
|
|
19
|
+
<Modal.Header>Confirm Action</Modal.Header>
|
|
20
|
+
<Modal.Body>
|
|
21
|
+
<p>Are you sure you want to proceed?</p>
|
|
22
|
+
</Modal.Body>
|
|
23
|
+
<Modal.Footer>
|
|
24
|
+
<button onClick={() => setOpen(false)}>Cancel</button>
|
|
25
|
+
<button onClick={handleConfirm}>Confirm</button>
|
|
26
|
+
</Modal.Footer>
|
|
27
|
+
</Modal>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Props
|
|
31
|
+
|
|
32
|
+
### Modal (root)
|
|
33
|
+
|
|
34
|
+
| Prop | Type | Default | Description |
|
|
35
|
+
|------|------|---------|-------------|
|
|
36
|
+
| open | `boolean` | - | Whether the modal is visible (required) |
|
|
37
|
+
| onClose | `() => void` | - | Callback to close the modal (required) |
|
|
38
|
+
| size | `"sm" \| "md" \| "lg" \| "xl" \| "full"` | `"md"` | Max width of the modal panel |
|
|
39
|
+
| className | `string` | - | Additional CSS classes for the panel |
|
|
40
|
+
|
|
41
|
+
### Modal.Header
|
|
42
|
+
|
|
43
|
+
| Prop | Type | Default | Description |
|
|
44
|
+
|------|------|---------|-------------|
|
|
45
|
+
| children | `ReactNode` | - | Header content |
|
|
46
|
+
| className | `string` | - | Additional CSS classes |
|
|
47
|
+
|
|
48
|
+
### Modal.Body
|
|
49
|
+
|
|
50
|
+
| Prop | Type | Default | Description |
|
|
51
|
+
|------|------|---------|-------------|
|
|
52
|
+
| children | `ReactNode` | - | Body content |
|
|
53
|
+
| className | `string` | - | Additional CSS classes |
|
|
54
|
+
|
|
55
|
+
### Modal.Footer
|
|
56
|
+
|
|
57
|
+
| Prop | Type | Default | Description |
|
|
58
|
+
|------|------|---------|-------------|
|
|
59
|
+
| children | `ReactNode` | - | Footer content (typically action buttons) |
|
|
60
|
+
| className | `string` | - | Additional CSS classes |
|
|
61
|
+
|
|
62
|
+
## Large Modal
|
|
63
|
+
|
|
64
|
+
```tsx
|
|
65
|
+
<Modal open={open} onClose={() => setOpen(false)} size="xl">
|
|
66
|
+
<Modal.Header>Large Content</Modal.Header>
|
|
67
|
+
<Modal.Body>
|
|
68
|
+
<p>This modal uses the xl size variant for wider content.</p>
|
|
69
|
+
</Modal.Body>
|
|
70
|
+
<Modal.Footer>
|
|
71
|
+
<button onClick={() => setOpen(false)}>Close</button>
|
|
72
|
+
</Modal.Footer>
|
|
73
|
+
</Modal>
|
|
74
|
+
```
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# MultiSwitch
|
|
2
|
+
|
|
3
|
+
Segmented control that allows selecting one value from a set of options, with an animated sliding indicator.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { MultiSwitch } from "@particle-academy/react-fancy";
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Basic Usage
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
<MultiSwitch
|
|
15
|
+
list={["Daily", "Weekly", "Monthly"]}
|
|
16
|
+
defaultValue="Weekly"
|
|
17
|
+
/>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Props
|
|
21
|
+
|
|
22
|
+
| Prop | Type | Default | Description |
|
|
23
|
+
|------|------|---------|-------------|
|
|
24
|
+
| `list` | `InputOption[]` | **required** | Options as strings or `{ value, label, disabled? }` |
|
|
25
|
+
| `value` | `V` | - | Controlled selected value |
|
|
26
|
+
| `defaultValue` | `V` | first option | Default selected value (uncontrolled) |
|
|
27
|
+
| `onValueChange` | `(value: V) => void` | - | Callback when selection changes |
|
|
28
|
+
| `linear` | `boolean` | `false` | When true, clicking any button cycles to the next option instead of selecting the clicked one |
|
|
29
|
+
| `label` | `string` | - | Wraps in a `Field` with this label |
|
|
30
|
+
| `description` | `string` | - | Helper text |
|
|
31
|
+
| `error` | `string` | - | Error message |
|
|
32
|
+
| `size` | `"xs" \| "sm" \| "md" \| "lg" \| "xl"` | `"md"` | Controls padding and text size |
|
|
33
|
+
| `dirty` | `boolean` | `false` | Amber ring |
|
|
34
|
+
| `disabled` | `boolean` | `false` | Disables all options |
|
|
35
|
+
| `name` | `string` | - | Form field name (renders a hidden input) |
|
|
36
|
+
| `className` | `string` | - | Additional CSS classes |
|
|
37
|
+
|
|
38
|
+
## Examples
|
|
39
|
+
|
|
40
|
+
### Controlled with label
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
const [interval, setInterval] = useState("monthly");
|
|
44
|
+
|
|
45
|
+
<MultiSwitch
|
|
46
|
+
label="Billing interval"
|
|
47
|
+
list={[
|
|
48
|
+
{ value: "monthly", label: "Monthly" },
|
|
49
|
+
{ value: "yearly", label: "Yearly" },
|
|
50
|
+
]}
|
|
51
|
+
value={interval}
|
|
52
|
+
onValueChange={setInterval}
|
|
53
|
+
/>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Linear cycling
|
|
57
|
+
|
|
58
|
+
```tsx
|
|
59
|
+
<MultiSwitch
|
|
60
|
+
linear
|
|
61
|
+
list={["Off", "Low", "Medium", "High"]}
|
|
62
|
+
defaultValue="Off"
|
|
63
|
+
/>
|
|
64
|
+
```
|
package/docs/Navbar.md
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Navbar
|
|
2
|
+
|
|
3
|
+
A top navigation bar with brand slot, navigation items, and a mobile hamburger toggle.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { Navbar } from "@particle-academy/react-fancy";
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Basic Usage
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
<Navbar>
|
|
15
|
+
<Navbar.Brand>
|
|
16
|
+
<a href="/">MyApp</a>
|
|
17
|
+
</Navbar.Brand>
|
|
18
|
+
<Navbar.Items>
|
|
19
|
+
<Navbar.Item href="/" active>Home</Navbar.Item>
|
|
20
|
+
<Navbar.Item href="/about">About</Navbar.Item>
|
|
21
|
+
<Navbar.Item href="/contact">Contact</Navbar.Item>
|
|
22
|
+
</Navbar.Items>
|
|
23
|
+
<Navbar.Toggle />
|
|
24
|
+
</Navbar>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Props
|
|
28
|
+
|
|
29
|
+
### Navbar (root)
|
|
30
|
+
|
|
31
|
+
| Prop | Type | Default | Description |
|
|
32
|
+
|------|------|---------|-------------|
|
|
33
|
+
| children | `ReactNode` | - | Brand, items, toggle children |
|
|
34
|
+
| className | `string` | - | Additional CSS classes |
|
|
35
|
+
|
|
36
|
+
### Navbar.Brand
|
|
37
|
+
|
|
38
|
+
| Prop | Type | Default | Description |
|
|
39
|
+
|------|------|---------|-------------|
|
|
40
|
+
| children | `ReactNode` | - | Logo or brand element |
|
|
41
|
+
| className | `string` | - | Additional CSS classes |
|
|
42
|
+
|
|
43
|
+
### Navbar.Items
|
|
44
|
+
|
|
45
|
+
| Prop | Type | Default | Description |
|
|
46
|
+
|------|------|---------|-------------|
|
|
47
|
+
| children | `ReactNode` | - | Navigation items |
|
|
48
|
+
| className | `string` | - | Additional CSS classes |
|
|
49
|
+
|
|
50
|
+
### Navbar.Item
|
|
51
|
+
|
|
52
|
+
| Prop | Type | Default | Description |
|
|
53
|
+
|------|------|---------|-------------|
|
|
54
|
+
| children | `ReactNode` | - | Item content |
|
|
55
|
+
| href | `string` | - | Link URL |
|
|
56
|
+
| active | `boolean` | - | Active/current page indicator |
|
|
57
|
+
| className | `string` | - | Additional CSS classes |
|
|
58
|
+
|
|
59
|
+
### Navbar.Toggle
|
|
60
|
+
|
|
61
|
+
| Prop | Type | Default | Description |
|
|
62
|
+
|------|------|---------|-------------|
|
|
63
|
+
| className | `string` | - | Additional CSS classes |
|
|
64
|
+
|
|
65
|
+
The Navbar manages a `mobileOpen` state internally. `Navbar.Toggle` toggles the mobile navigation drawer, and `Navbar.Items` responds to that state.
|