@particle-academy/react-fancy 2.2.0 → 2.2.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/docs/Action.md CHANGED
@@ -18,7 +18,7 @@ import { Action } from "@particle-academy/react-fancy";
18
18
 
19
19
  | Prop | Type | Default | Description |
20
20
  |------|------|---------|-------------|
21
- | variant | `"default" \| "circle"` | `"default"` | Shape variant |
21
+ | variant | `"default" \| "circle" \| "ghost"` | `"default"` | Shape/fill variant. `"ghost"` is transparent with subtle hover. |
22
22
  | color | `ActionColor` | - | Standalone color (overrides state colors). One of: `"blue"`, `"emerald"`, `"amber"`, `"red"`, `"violet"`, `"indigo"`, `"sky"`, `"rose"`, `"orange"`, `"zinc"` |
23
23
  | size | `"xs" \| "sm" \| "md" \| "lg" \| "xl"` | `"md"` | Button size |
24
24
  | active | `boolean` | - | Active state (blue highlight) |
@@ -74,3 +74,10 @@ Also extends all native `<button>` HTML attributes (except `color`).
74
74
  Read docs
75
75
  </Action>
76
76
  ```
77
+
78
+ ### Ghost variant
79
+
80
+ ```tsx
81
+ <Action variant="ghost" color="red" icon="trash-2">Delete</Action>
82
+ <Action variant="ghost" icon="download">Export</Action>
83
+ ```
package/docs/Editor.md CHANGED
@@ -60,6 +60,7 @@ A visual separator between toolbar groups. No props.
60
60
  | Prop | Type | Default | Description |
61
61
  |------|------|---------|-------------|
62
62
  | className | `string` | - | Additional CSS classes |
63
+ | maxHeight | `number` | - | Max height in px before scrolling. When set, the content area becomes scrollable. |
63
64
 
64
65
  ## Markdown Output
65
66
 
@@ -70,14 +71,81 @@ A visual separator between toolbar groups. No props.
70
71
  </Editor>
71
72
  ```
72
73
 
74
+ ## Scrollable Editor
75
+
76
+ Constrain the editor's height and let it scroll instead of growing the page:
77
+
78
+ ```tsx
79
+ <Editor defaultValue={longHtml}>
80
+ <Editor.Toolbar />
81
+ <Editor.Content maxHeight={320} />
82
+ </Editor>
83
+ ```
84
+
85
+ ## useEditor Hook
86
+
87
+ Access editor state and commands from a child component (typically used inside a custom toolbar):
88
+
89
+ ```tsx
90
+ import { useEditor } from "@particle-academy/react-fancy";
91
+
92
+ function CustomToolbarButtons() {
93
+ const { exec } = useEditor();
94
+ return (
95
+ <>
96
+ <button onClick={() => exec("bold")}>B</button>
97
+ <Editor.Toolbar.Separator />
98
+ <button onClick={() => exec("formatBlock", "h1")}>H1</button>
99
+ </>
100
+ );
101
+ }
102
+ ```
103
+
104
+ ### EditorContextValue
105
+
106
+ | Property | Type | Description |
107
+ |----------|------|-------------|
108
+ | exec | `(command: string, arg?: string) => void` | Execute a `document.execCommand`-style formatting command |
109
+ | insertText | `(text: string) => void` | Insert text at the current cursor position |
110
+ | wrapSelection | `(before: string, after: string) => void` | Wrap the selection with before/after strings |
111
+ | contentRef | `RefObject<HTMLDivElement \| null>` | Ref to the editable content element |
112
+ | outputFormat | `"html" \| "markdown"` | Current output format |
113
+ | lineSpacing | `number` | Current line spacing |
114
+ | placeholder | `string` | Current placeholder text |
115
+ | extensions | `RenderExtension[]` | Merged render extensions (global + instance) |
116
+
117
+ ## Render Extensions
118
+
119
+ Render extensions let you embed custom React components inline using tag names you choose (e.g., `<alert>`, `<questions>`, `<thinking>`). The same extensions work in both `Editor` and `ContentRenderer`.
120
+
121
+ ```tsx
122
+ import type { RenderExtension, RenderExtensionProps } from "@particle-academy/react-fancy";
123
+
124
+ function AlertRenderer({ content, attributes }: RenderExtensionProps) {
125
+ const variant = attributes.type || "info";
126
+ return <div className={`alert alert-${variant}`}>{content}</div>;
127
+ }
128
+
129
+ const extensions: RenderExtension[] = [
130
+ { tag: "alert", component: AlertRenderer },
131
+ ];
132
+
133
+ <Editor extensions={extensions} defaultValue='<alert type="info">Hello</alert>'>
134
+ <Editor.Toolbar />
135
+ <Editor.Content />
136
+ </Editor>
137
+ ```
138
+
139
+ Register extensions globally with `registerExtension` (applies to all instances) or pass them per-instance via the `extensions` prop. Per-instance extensions are merged with global ones.
140
+
73
141
  ## Custom Toolbar
74
142
 
75
143
  ```tsx
76
144
  <Editor defaultValue="">
77
145
  <Editor.Toolbar>
78
- <button onClick={() => exec("bold")}>B</button>
146
+ <CustomToolbarButtons />
79
147
  <Editor.Toolbar.Separator />
80
- <button onClick={() => exec("italic")}>I</button>
148
+ <MoreButtons />
81
149
  </Editor.Toolbar>
82
150
  <Editor.Content />
83
151
  </Editor>
package/docs/Icon.md CHANGED
@@ -5,7 +5,13 @@ An icon container that resolves icon names from registered icon sets (Lucide by
5
5
  ## Import
6
6
 
7
7
  ```tsx
8
- import { Icon, registerIconSet, configureIcons } from "@particle-academy/react-fancy";
8
+ import {
9
+ Icon,
10
+ registerIcons,
11
+ registerIconSet,
12
+ configureIcons,
13
+ } from "@particle-academy/react-fancy";
14
+ import type { IconSet } from "@particle-academy/react-fancy";
9
15
  ```
10
16
 
11
17
  ## Basic Usage
@@ -26,9 +32,29 @@ Also extends all native `<span>` HTML attributes. When `children` are provided,
26
32
 
27
33
  ## Icon Configuration
28
34
 
35
+ Three APIs configure icons: `registerIcons` for tree-shakeable individual Lucide icons, `registerIconSet` for custom icon libraries, and `configureIcons` for choosing the default set.
36
+
37
+ ### registerIcons
38
+
39
+ Register individual icon components into the built-in `"lucide"` set by their kebab-case name. This is the recommended way to opt into tree-shaking — only the icons you import are bundled.
40
+
41
+ ```tsx
42
+ import { registerIcons } from "@particle-academy/react-fancy";
43
+ import { Home, Settings, Mail } from "lucide-react";
44
+
45
+ registerIcons({ Home, Settings, Mail });
46
+
47
+ // Then use them via their kebab-case names:
48
+ <Icon name="home" />
49
+ <Icon name="settings" />
50
+ <Icon name="mail" />
51
+ ```
52
+
53
+ Call this once at app startup (e.g., in `setup-icons.ts`).
54
+
29
55
  ### registerIconSet
30
56
 
31
- Register a custom icon set by name.
57
+ Register a complete custom icon set by name.
32
58
 
33
59
  ```tsx
34
60
  import { registerIconSet } from "@particle-academy/react-fancy";
package/docs/Input.md CHANGED
@@ -42,12 +42,12 @@ Extends all native `<input>` attributes (except `size`, `type`, `prefix`).
42
42
  ### With leading icon
43
43
 
44
44
  ```tsx
45
- import { Search } from "lucide-react";
45
+ import { Input, Icon } from "@particle-academy/react-fancy";
46
46
 
47
47
  <Input
48
48
  label="Search"
49
49
  type="search"
50
- leading={<Search size={16} />}
50
+ leading={<Icon name="search" size="sm" />}
51
51
  placeholder="Search..."
52
52
  />
53
53
  ```
package/docs/Menu.md CHANGED
@@ -11,10 +11,12 @@ import { Menu } from "@particle-academy/react-fancy";
11
11
  ## Basic Usage
12
12
 
13
13
  ```tsx
14
+ import { Menu, Icon } from "@particle-academy/react-fancy";
15
+
14
16
  <Menu>
15
- <Menu.Item href="/" active>Home</Menu.Item>
16
- <Menu.Item href="/about">About</Menu.Item>
17
- <Menu.Submenu label="Products" icon={<BoxIcon />}>
17
+ <Menu.Item href="/" icon={<Icon name="home" size="sm" />} active>Home</Menu.Item>
18
+ <Menu.Item href="/about" icon={<Icon name="info" size="sm" />}>About</Menu.Item>
19
+ <Menu.Submenu label="Products" icon={<Icon name="box" size="sm" />}>
18
20
  <Menu.Item href="/products/widgets">Widgets</Menu.Item>
19
21
  <Menu.Item href="/products/gadgets">Gadgets</Menu.Item>
20
22
  </Menu.Submenu>
@@ -64,8 +66,26 @@ import { Menu } from "@particle-academy/react-fancy";
64
66
 
65
67
  ```tsx
66
68
  <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>
69
+ <Menu.Item href="/" icon={<Icon name="home" size="sm" />} active>Home</Menu.Item>
70
+ <Menu.Item href="/docs" icon={<Icon name="book" size="sm" />}>Docs</Menu.Item>
71
+ <Menu.Item href="/pricing" badge={<Badge size="sm">New</Badge>}>Pricing</Menu.Item>
72
+ </Menu>
73
+ ```
74
+
75
+ ## Grouped Vertical Menu
76
+
77
+ ```tsx
78
+ <Menu orientation="vertical">
79
+ <Menu.Group label="Main">
80
+ <Menu.Item icon={<Icon name="home" size="sm" />} active>Dashboard</Menu.Item>
81
+ <Menu.Item icon={<Icon name="mail" size="sm" />} badge={<Badge size="sm">3</Badge>}>Inbox</Menu.Item>
82
+ </Menu.Group>
83
+ <Menu.Group label="Settings">
84
+ <Menu.Submenu label="Configuration" icon={<Icon name="settings" size="sm" />} defaultOpen>
85
+ <Menu.Item>General</Menu.Item>
86
+ <Menu.Item>Security</Menu.Item>
87
+ </Menu.Submenu>
88
+ <Menu.Item icon={<Icon name="palette" size="sm" />} disabled>Theme (coming soon)</Menu.Item>
89
+ </Menu.Group>
70
90
  </Menu>
71
91
  ```
@@ -8,6 +8,12 @@ Mobile navigation components with two variants: a slide-out flyout panel and a f
8
8
  import { MobileMenu } from "@particle-academy/react-fancy";
9
9
  ```
10
10
 
11
+ ## Import
12
+
13
+ ```tsx
14
+ import { MobileMenu, Icon } from "@particle-academy/react-fancy";
15
+ ```
16
+
11
17
  ## Flyout
12
18
 
13
19
  A slide-out panel from the left or right edge.
@@ -18,9 +24,9 @@ const [open, setOpen] = useState(false);
18
24
  <button onClick={() => setOpen(true)}>Menu</button>
19
25
 
20
26
  <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>
27
+ <MobileMenu.Item href="/" icon={<Icon name="home" />} active>Home</MobileMenu.Item>
28
+ <MobileMenu.Item href="/about" icon={<Icon name="info" />}>About</MobileMenu.Item>
29
+ <MobileMenu.Item href="/contact" icon={<Icon name="mail" />}>Contact</MobileMenu.Item>
24
30
  </MobileMenu.Flyout>
25
31
  ```
26
32
 
@@ -30,9 +36,9 @@ A fixed bottom navigation bar for mobile.
30
36
 
31
37
  ```tsx
32
38
  <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>
39
+ <MobileMenu.Item href="/" icon={<Icon name="home" />} active>Home</MobileMenu.Item>
40
+ <MobileMenu.Item href="/search" icon={<Icon name="search" />}>Search</MobileMenu.Item>
41
+ <MobileMenu.Item href="/profile" icon={<Icon name="user" />}>Profile</MobileMenu.Item>
36
42
  </MobileMenu.BottomBar>
37
43
  ```
38
44
 
package/docs/Sidebar.md CHANGED
@@ -11,9 +11,11 @@ import { Sidebar } from "@particle-academy/react-fancy";
11
11
  ## Basic Usage
12
12
 
13
13
  ```tsx
14
+ import { Sidebar, Icon } from "@particle-academy/react-fancy";
15
+
14
16
  <Sidebar>
15
- <Sidebar.Item href="/" icon={<HomeIcon />} active>Home</Sidebar.Item>
16
- <Sidebar.Item href="/settings" icon={<GearIcon />}>Settings</Sidebar.Item>
17
+ <Sidebar.Item href="/" icon={<Icon name="home" size="sm" />} active>Home</Sidebar.Item>
18
+ <Sidebar.Item href="/settings" icon={<Icon name="settings" size="sm" />}>Settings</Sidebar.Item>
17
19
  <Sidebar.Group label="Projects">
18
20
  <Sidebar.Item href="/project-a">Project A</Sidebar.Item>
19
21
  <Sidebar.Item href="/project-b">Project B</Sidebar.Item>
@@ -77,12 +79,30 @@ import { Sidebar } from "@particle-academy/react-fancy";
77
79
  const [collapsed, setCollapsed] = useState(false);
78
80
 
79
81
  <Sidebar collapsed={collapsed} onCollapsedChange={setCollapsed} collapseMode="icons">
80
- <Sidebar.Item icon={<HomeIcon />}>Dashboard</Sidebar.Item>
81
- <Sidebar.Item icon={<UsersIcon />}>Users</Sidebar.Item>
82
- <Sidebar.Submenu label="Reports" icon={<ChartIcon />} defaultOpen>
82
+ <Sidebar.Item icon={<Icon name="home" size="sm" />}>Dashboard</Sidebar.Item>
83
+ <Sidebar.Item icon={<Icon name="users" size="sm" />}>Users</Sidebar.Item>
84
+ <Sidebar.Submenu label="Reports" icon={<Icon name="bar-chart-3" size="sm" />} defaultOpen>
83
85
  <Sidebar.Item>Monthly</Sidebar.Item>
84
86
  <Sidebar.Item>Yearly</Sidebar.Item>
85
87
  </Sidebar.Submenu>
86
88
  <Sidebar.Toggle />
87
89
  </Sidebar>
88
90
  ```
91
+
92
+ ### collapseMode
93
+
94
+ - `"icons"` (default) — only the icon is shown when collapsed; falls back to the first 3 letters if no icon is provided
95
+ - `"letters"` — the first 3 letters of the label are always shown
96
+
97
+ ## useSidebar Hook
98
+
99
+ Access collapsed state from any child component:
100
+
101
+ ```tsx
102
+ import { useSidebar } from "@particle-academy/react-fancy";
103
+
104
+ function CollapseAware() {
105
+ const { collapsed, setCollapsed } = useSidebar();
106
+ return <button onClick={() => setCollapsed(!collapsed)}>Toggle</button>;
107
+ }
108
+ ```
package/package.json CHANGED
@@ -1,7 +1,13 @@
1
1
  {
2
2
  "name": "@particle-academy/react-fancy",
3
- "version": "2.2.0",
3
+ "version": "2.2.1",
4
4
  "description": "React UI component library — React port of the fancy-flux Blade component library",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/Particle-Academy/react-fancy.git"
8
+ },
9
+ "homepage": "https://github.com/Particle-Academy/react-fancy#readme",
10
+ "bugs": "https://github.com/Particle-Academy/react-fancy/issues",
5
11
  "type": "module",
6
12
  "main": "./dist/index.cjs",
7
13
  "module": "./dist/index.js",