@particle-academy/react-fancy 1.7.1 → 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.
Files changed (61) hide show
  1. package/docs/Accordion.md +78 -0
  2. package/docs/Action.md +76 -0
  3. package/docs/Autocomplete.md +74 -0
  4. package/docs/Avatar.md +40 -0
  5. package/docs/Badge.md +42 -0
  6. package/docs/Brand.md +44 -0
  7. package/docs/Breadcrumbs.md +51 -0
  8. package/docs/Calendar.md +72 -0
  9. package/docs/Callout.md +46 -0
  10. package/docs/Canvas.md +102 -0
  11. package/docs/Card.md +68 -0
  12. package/docs/Carousel.md +97 -0
  13. package/docs/Chart.md +126 -0
  14. package/docs/Checkbox.md +86 -0
  15. package/docs/ColorPicker.md +49 -0
  16. package/docs/Command.md +88 -0
  17. package/docs/Composer.md +60 -0
  18. package/docs/ContentRenderer.md +68 -0
  19. package/docs/ContextMenu.md +82 -0
  20. package/docs/DatePicker.md +64 -0
  21. package/docs/Diagram.md +119 -0
  22. package/docs/Dropdown.md +79 -0
  23. package/docs/Editor.md +84 -0
  24. package/docs/Emoji.md +40 -0
  25. package/docs/EmojiSelect.md +47 -0
  26. package/docs/Field.md +48 -0
  27. package/docs/FileUpload.md +81 -0
  28. package/docs/Heading.md +43 -0
  29. package/docs/Icon.md +75 -0
  30. package/docs/Input.md +73 -0
  31. package/docs/Kanban.md +79 -0
  32. package/docs/Menu.md +71 -0
  33. package/docs/MobileMenu.md +69 -0
  34. package/docs/Modal.md +74 -0
  35. package/docs/MultiSwitch.md +64 -0
  36. package/docs/Navbar.md +65 -0
  37. package/docs/OtpInput.md +48 -0
  38. package/docs/Pagination.md +48 -0
  39. package/docs/Pillbox.md +53 -0
  40. package/docs/Popover.md +82 -0
  41. package/docs/Portal.md +40 -0
  42. package/docs/Profile.md +52 -0
  43. package/docs/Progress.md +42 -0
  44. package/docs/RadioGroup.md +69 -0
  45. package/docs/Select.md +122 -0
  46. package/docs/Separator.md +41 -0
  47. package/docs/Sidebar.md +88 -0
  48. package/docs/Skeleton.md +44 -0
  49. package/docs/Slider.md +75 -0
  50. package/docs/Switch.md +55 -0
  51. package/docs/Table.md +133 -0
  52. package/docs/Tabs.md +85 -0
  53. package/docs/Text.md +44 -0
  54. package/docs/Textarea.md +62 -0
  55. package/docs/TimePicker.md +45 -0
  56. package/docs/Timeline.md +118 -0
  57. package/docs/Toast.md +79 -0
  58. package/docs/Tooltip.md +46 -0
  59. package/docs/hooks.md +180 -0
  60. package/docs/utilities.md +74 -0
  61. package/package.json +2 -1
@@ -0,0 +1,97 @@
1
+ # Carousel
2
+
3
+ A multi-slide carousel/wizard with auto-play, looping, directional or wizard variants, named slides, and controllable index.
4
+
5
+ ## Import
6
+
7
+ ```tsx
8
+ import { Carousel } from "@particle-academy/react-fancy";
9
+ ```
10
+
11
+ ## Basic Usage
12
+
13
+ ```tsx
14
+ <Carousel>
15
+ <Carousel.Panels>
16
+ <Carousel.Slide>Slide 1 content</Carousel.Slide>
17
+ <Carousel.Slide>Slide 2 content</Carousel.Slide>
18
+ <Carousel.Slide>Slide 3 content</Carousel.Slide>
19
+ </Carousel.Panels>
20
+ <Carousel.Controls />
21
+ <Carousel.Steps />
22
+ </Carousel>
23
+ ```
24
+
25
+ ## Props
26
+
27
+ ### Carousel (root)
28
+
29
+ | Prop | Type | Default | Description |
30
+ |------|------|---------|-------------|
31
+ | defaultIndex | `number` | `0` | Initial slide index (uncontrolled) |
32
+ | activeIndex | `number` | - | Controlled slide index |
33
+ | onIndexChange | `(index: number) => void` | - | Callback when index changes |
34
+ | autoPlay | `boolean` | `false` | Auto-advance slides |
35
+ | interval | `number` | `5000` | Auto-play interval in ms |
36
+ | loop | `boolean` | `false` | Loop back to first slide after last |
37
+ | variant | `"directional" \| "wizard"` | `"directional"` | Visual variant (directional = arrows, wizard = steps) |
38
+ | headless | `boolean` | `false` | Disable default styling for full custom layouts |
39
+ | onFinish | `() => void` | - | Callback when "Finish" is clicked on the last slide (wizard variant) |
40
+ | className | `string` | - | Additional CSS classes |
41
+
42
+ ### Carousel.Panels
43
+
44
+ | Prop | Type | Default | Description |
45
+ |------|------|---------|-------------|
46
+ | children | `ReactNode` | - | Slide elements |
47
+ | className | `string` | - | Additional CSS classes |
48
+ | transition | `"none" \| "fade"` | - | Transition effect between slides |
49
+
50
+ ### Carousel.Slide
51
+
52
+ | Prop | Type | Default | Description |
53
+ |------|------|---------|-------------|
54
+ | children | `ReactNode` | - | Slide content |
55
+ | name | `string` | - | Named identifier (used by Steps display) |
56
+ | className | `string` | - | Additional CSS classes |
57
+
58
+ ### Carousel.Controls
59
+
60
+ | Prop | Type | Default | Description |
61
+ |------|------|---------|-------------|
62
+ | prevLabel | `ReactNode` | - | Custom previous button content |
63
+ | nextLabel | `ReactNode` | - | Custom next button content |
64
+ | finishLabel | `ReactNode` | - | Custom finish button content (wizard, last slide) |
65
+ | className | `string` | - | Additional CSS classes |
66
+
67
+ ### Carousel.Steps
68
+
69
+ | Prop | Type | Default | Description |
70
+ |------|------|---------|-------------|
71
+ | className | `string` | - | Additional CSS classes |
72
+
73
+ ## Wizard Variant
74
+
75
+ ```tsx
76
+ <Carousel variant="wizard" onFinish={() => console.log("done!")}>
77
+ <Carousel.Steps />
78
+ <Carousel.Panels transition="fade">
79
+ <Carousel.Slide name="Account">Step 1: Create account</Carousel.Slide>
80
+ <Carousel.Slide name="Profile">Step 2: Fill profile</Carousel.Slide>
81
+ <Carousel.Slide name="Confirm">Step 3: Confirm details</Carousel.Slide>
82
+ </Carousel.Panels>
83
+ <Carousel.Controls finishLabel="Complete Setup" />
84
+ </Carousel>
85
+ ```
86
+
87
+ ## Auto-Play with Looping
88
+
89
+ ```tsx
90
+ <Carousel autoPlay interval={3000} loop>
91
+ <Carousel.Panels>
92
+ <Carousel.Slide>Banner 1</Carousel.Slide>
93
+ <Carousel.Slide>Banner 2</Carousel.Slide>
94
+ <Carousel.Slide>Banner 3</Carousel.Slide>
95
+ </Carousel.Panels>
96
+ </Carousel>
97
+ ```
package/docs/Chart.md ADDED
@@ -0,0 +1,126 @@
1
+ # Chart
2
+
3
+ A collection of SVG chart components: Bar, HorizontalBar, StackedBar, Line, Area, Pie, Donut, and Sparkline.
4
+
5
+ ## Import
6
+
7
+ ```tsx
8
+ import { Chart } from "@particle-academy/react-fancy";
9
+ ```
10
+
11
+ ## Chart Types
12
+
13
+ ### Chart.Bar
14
+
15
+ ```tsx
16
+ <Chart.Bar
17
+ data={[
18
+ { label: "Jan", value: 30 },
19
+ { label: "Feb", value: 45 },
20
+ { label: "Mar", value: 28 },
21
+ ]}
22
+ height={200}
23
+ showValues
24
+ />
25
+ ```
26
+
27
+ | Prop | Type | Default | Description |
28
+ |------|------|---------|-------------|
29
+ | data | `ChartBarData[]` | - | Array of `{ label, value, color? }` |
30
+ | height | `number` | - | Chart height in px |
31
+ | showValues | `boolean` | - | Display values above bars |
32
+ | className | `string` | - | Additional CSS classes |
33
+
34
+ ### Chart.HorizontalBar
35
+
36
+ Same props as `Chart.Bar`, rendered horizontally.
37
+
38
+ ### Chart.Line
39
+
40
+ ```tsx
41
+ <Chart.Line
42
+ labels={["Jan", "Feb", "Mar", "Apr"]}
43
+ series={[
44
+ { label: "Revenue", data: [100, 200, 150, 300], color: "#3b82f6" },
45
+ { label: "Costs", data: [80, 120, 100, 180], color: "#ef4444" },
46
+ ]}
47
+ height={300}
48
+ showDots
49
+ tooltip
50
+ />
51
+ ```
52
+
53
+ | Prop | Type | Default | Description |
54
+ |------|------|---------|-------------|
55
+ | labels | `string[]` | - | X-axis labels |
56
+ | series | `ChartSeries[]` | - | Array of `{ label, data, color? }` |
57
+ | curve | `"linear" \| "monotone"` | - | Line interpolation |
58
+ | showDots | `boolean` | - | Show data points |
59
+ | fill | `boolean` | - | Fill area under line |
60
+ | fillOpacity | `number` | - | Opacity of fill area |
61
+ | height | `number` | - | Chart height in px |
62
+ | xAxis | `boolean \| { label?, tickCount? }` | - | X-axis config |
63
+ | yAxis | `boolean \| { label?, tickCount? }` | - | Y-axis config |
64
+ | grid | `boolean \| { horizontal?, vertical? }` | - | Grid lines |
65
+ | tooltip | `boolean` | - | Show tooltip on hover |
66
+ | animate | `boolean` | - | Enable animations |
67
+ | responsive | `boolean` | - | Responsive width |
68
+ | className | `string` | - | Additional CSS classes |
69
+
70
+ ### Chart.Area
71
+
72
+ Same as `Chart.Line` without the `fill` prop (area fill is always enabled).
73
+
74
+ ### Chart.StackedBar
75
+
76
+ | Prop | Type | Default | Description |
77
+ |------|------|---------|-------------|
78
+ | labels | `string[]` | - | X-axis labels |
79
+ | series | `ChartSeries[]` | - | Stacked data series |
80
+ | *(plus ChartCommonProps)* | | | height, xAxis, yAxis, grid, tooltip, animate, responsive |
81
+
82
+ ### Chart.Pie
83
+
84
+ ```tsx
85
+ <Chart.Pie
86
+ data={[
87
+ { label: "Desktop", value: 60 },
88
+ { label: "Mobile", value: 35 },
89
+ { label: "Tablet", value: 5 },
90
+ ]}
91
+ size={200}
92
+ showLabels
93
+ />
94
+ ```
95
+
96
+ | Prop | Type | Default | Description |
97
+ |------|------|---------|-------------|
98
+ | data | `ChartPieData[]` | - | Array of `{ label, value, color? }` |
99
+ | size | `number` | - | Diameter in px |
100
+ | showLabels | `boolean` | - | Display labels |
101
+ | tooltip | `boolean` | - | Show tooltip on hover |
102
+ | className | `string` | - | Additional CSS classes |
103
+
104
+ ### Chart.Donut
105
+
106
+ | Prop | Type | Default | Description |
107
+ |------|------|---------|-------------|
108
+ | data | `ChartDonutData[]` | - | Array of `{ label, value, color? }` |
109
+ | size | `number` | - | Diameter in px |
110
+ | strokeWidth | `number` | - | Ring thickness |
111
+ | showLegend | `boolean` | - | Show legend |
112
+ | className | `string` | - | Additional CSS classes |
113
+
114
+ ### Chart.Sparkline
115
+
116
+ ```tsx
117
+ <Chart.Sparkline data={[5, 10, 8, 15, 12, 20]} width={120} height={32} color="#22c55e" />
118
+ ```
119
+
120
+ | Prop | Type | Default | Description |
121
+ |------|------|---------|-------------|
122
+ | data | `number[]` | - | Data points |
123
+ | width | `number` | - | Chart width in px |
124
+ | height | `number` | - | Chart height in px |
125
+ | color | `string` | - | Line color |
126
+ | className | `string` | - | Additional CSS classes |
@@ -0,0 +1,86 @@
1
+ # Checkbox / CheckboxGroup
2
+
3
+ Single checkbox with optional label, and a group component for managing multiple checkbox selections.
4
+
5
+ ## Import
6
+
7
+ ```tsx
8
+ import { Checkbox, CheckboxGroup } from "@particle-academy/react-fancy";
9
+ ```
10
+
11
+ ## Basic Usage
12
+
13
+ ```tsx
14
+ <Checkbox label="I agree to the terms" />
15
+ ```
16
+
17
+ ```tsx
18
+ <CheckboxGroup
19
+ label="Interests"
20
+ list={["Music", "Sports", "Travel"]}
21
+ onValueChange={(values) => console.log(values)}
22
+ />
23
+ ```
24
+
25
+ ## Checkbox Props
26
+
27
+ | Prop | Type | Default | Description |
28
+ |------|------|---------|-------------|
29
+ | `checked` | `boolean` | - | Controlled checked state |
30
+ | `defaultChecked` | `boolean` | `false` | Initial checked state (uncontrolled) |
31
+ | `onCheckedChange` | `(checked: boolean) => void` | - | Callback when checked state changes |
32
+ | `indeterminate` | `boolean` | `false` | Sets the indeterminate visual state |
33
+ | `label` | `string` | - | Label text next to the checkbox |
34
+ | `description` | `string` | - | Helper text below the label |
35
+ | `error` | `string` | - | Error message |
36
+ | `size` | `"xs" \| "sm" \| "md" \| "lg" \| "xl"` | `"md"` | Checkbox size |
37
+ | `dirty` | `boolean` | `false` | Amber ring |
38
+ | `required` | `boolean` | `false` | Red asterisk on label |
39
+ | `disabled` | `boolean` | `false` | Disables the checkbox |
40
+ | `className` | `string` | - | Additional CSS classes |
41
+
42
+ ## CheckboxGroup Props
43
+
44
+ | Prop | Type | Default | Description |
45
+ |------|------|---------|-------------|
46
+ | `list` | `InputOption[]` | **required** | Options as strings or `{ value, label, disabled?, description? }` |
47
+ | `value` | `V[]` | - | Controlled selected values |
48
+ | `defaultValue` | `V[]` | `[]` | Default selected values (uncontrolled) |
49
+ | `onValueChange` | `(values: V[]) => void` | - | Callback when selection changes |
50
+ | `orientation` | `"horizontal" \| "vertical"` | `"vertical"` | Layout direction |
51
+ | `label` | `string` | - | Group label (wraps in `Field`) |
52
+ | `description` | `string` | - | Helper text |
53
+ | `error` | `string` | - | Error message |
54
+ | `size` | `"xs" \| "sm" \| "md" \| "lg" \| "xl"` | `"md"` | Checkbox size |
55
+ | `dirty` | `boolean` | `false` | Amber ring on all checkboxes |
56
+ | `disabled` | `boolean` | `false` | Disables all checkboxes |
57
+
58
+ ## Examples
59
+
60
+ ### Controlled checkbox
61
+
62
+ ```tsx
63
+ const [agreed, setAgreed] = useState(false);
64
+
65
+ <Checkbox
66
+ label="Subscribe to newsletter"
67
+ checked={agreed}
68
+ onCheckedChange={setAgreed}
69
+ />
70
+ ```
71
+
72
+ ### Horizontal checkbox group with objects
73
+
74
+ ```tsx
75
+ <CheckboxGroup
76
+ label="Permissions"
77
+ orientation="horizontal"
78
+ list={[
79
+ { value: "read", label: "Read" },
80
+ { value: "write", label: "Write" },
81
+ { value: "delete", label: "Delete", description: "Dangerous" },
82
+ ]}
83
+ defaultValue={["read"]}
84
+ onValueChange={setPermissions}
85
+ />
86
+ ```
@@ -0,0 +1,49 @@
1
+ # ColorPicker
2
+
3
+ A color picker with a swatch button, hex display, and optional preset colors.
4
+
5
+ ## Import
6
+
7
+ ```tsx
8
+ import { ColorPicker } from "@particle-academy/react-fancy";
9
+ ```
10
+
11
+ ## Basic Usage
12
+
13
+ ```tsx
14
+ <ColorPicker onChange={(color) => console.log(color)} />
15
+ ```
16
+
17
+ ## Props
18
+
19
+ | Prop | Type | Default | Description |
20
+ |------|------|---------|-------------|
21
+ | value | `string` | - | Controlled hex color value |
22
+ | defaultValue | `string` | `"#3b82f6"` | Default hex color (uncontrolled) |
23
+ | onChange | `(color: string) => void` | - | Callback when the color changes |
24
+ | presets | `string[]` | - | Array of preset hex colors shown in the native picker's datalist |
25
+ | size | `"sm" \| "md" \| "lg"` | `"md"` | Swatch and text size |
26
+ | variant | `"outline" \| "filled"` | `"outline"` | Swatch border style |
27
+ | disabled | `boolean` | `false` | Disable interaction |
28
+ | className | `string` | - | Additional CSS classes |
29
+
30
+ Supports both controlled (`value` + `onChange`) and uncontrolled (`defaultValue`) usage.
31
+
32
+ ## Examples
33
+
34
+ ### With presets
35
+
36
+ ```tsx
37
+ <ColorPicker
38
+ defaultValue="#10b981"
39
+ presets={["#ef4444", "#3b82f6", "#10b981", "#f59e0b"]}
40
+ />
41
+ ```
42
+
43
+ ### Controlled
44
+
45
+ ```tsx
46
+ const [color, setColor] = useState("#8b5cf6");
47
+
48
+ <ColorPicker value={color} onChange={setColor} size="lg" />
49
+ ```
@@ -0,0 +1,88 @@
1
+ # Command
2
+
3
+ A command palette (Cmd+K style) with search input, grouped items, keyboard navigation, and focus trapping. Renders via a portal with backdrop.
4
+
5
+ ## Import
6
+
7
+ ```tsx
8
+ import { Command } from "@particle-academy/react-fancy";
9
+ ```
10
+
11
+ ## Basic Usage
12
+
13
+ ```tsx
14
+ const [open, setOpen] = useState(false);
15
+
16
+ useEffect(() => {
17
+ const handler = (e: KeyboardEvent) => {
18
+ if (e.key === "k" && (e.metaKey || e.ctrlKey)) {
19
+ e.preventDefault();
20
+ setOpen(true);
21
+ }
22
+ };
23
+ document.addEventListener("keydown", handler);
24
+ return () => document.removeEventListener("keydown", handler);
25
+ }, []);
26
+
27
+ <Command open={open} onClose={() => setOpen(false)}>
28
+ <Command.Input placeholder="Search commands..." />
29
+ <Command.List>
30
+ <Command.Group heading="Actions">
31
+ <Command.Item onSelect={() => console.log("new")}>New File</Command.Item>
32
+ <Command.Item onSelect={() => console.log("open")}>Open File</Command.Item>
33
+ </Command.Group>
34
+ <Command.Group heading="Settings">
35
+ <Command.Item onSelect={() => console.log("prefs")}>Preferences</Command.Item>
36
+ </Command.Group>
37
+ <Command.Empty>No results found.</Command.Empty>
38
+ </Command.List>
39
+ </Command>
40
+ ```
41
+
42
+ ## Props
43
+
44
+ ### Command (root)
45
+
46
+ | Prop | Type | Default | Description |
47
+ |------|------|---------|-------------|
48
+ | open | `boolean` | - | Whether the palette is visible (required) |
49
+ | onClose | `() => void` | - | Callback to close the palette (required) |
50
+ | className | `string` | - | Additional CSS classes |
51
+
52
+ ### Command.Input
53
+
54
+ | Prop | Type | Default | Description |
55
+ |------|------|---------|-------------|
56
+ | placeholder | `string` | - | Input placeholder text |
57
+ | className | `string` | - | Additional CSS classes |
58
+
59
+ ### Command.List
60
+
61
+ | Prop | Type | Default | Description |
62
+ |------|------|---------|-------------|
63
+ | children | `ReactNode` | - | Groups and items |
64
+ | className | `string` | - | Additional CSS classes |
65
+
66
+ ### Command.Group
67
+
68
+ | Prop | Type | Default | Description |
69
+ |------|------|---------|-------------|
70
+ | children | `ReactNode` | - | Group items |
71
+ | heading | `string` | - | Group heading label |
72
+ | className | `string` | - | Additional CSS classes |
73
+
74
+ ### Command.Item
75
+
76
+ | Prop | Type | Default | Description |
77
+ |------|------|---------|-------------|
78
+ | children | `ReactNode` | - | Item content |
79
+ | value | `string` | - | Searchable value (defaults to text content) |
80
+ | onSelect | `() => void` | - | Callback when item is selected |
81
+ | className | `string` | - | Additional CSS classes |
82
+
83
+ ### Command.Empty
84
+
85
+ | Prop | Type | Default | Description |
86
+ |------|------|---------|-------------|
87
+ | children | `ReactNode` | `"No results found."` | Content shown when no items match |
88
+ | className | `string` | - | Additional CSS classes |
@@ -0,0 +1,60 @@
1
+ # Composer
2
+
3
+ A chat-style message input with auto-growing textarea, Enter-to-submit, action slot, and controlled/uncontrolled value.
4
+
5
+ ## Import
6
+
7
+ ```tsx
8
+ import { Composer } from "@particle-academy/react-fancy";
9
+ ```
10
+
11
+ ## Basic Usage
12
+
13
+ ```tsx
14
+ <Composer
15
+ onSubmit={(message) => console.log("Sent:", message)}
16
+ placeholder="Type a message..."
17
+ />
18
+ ```
19
+
20
+ ## Props
21
+
22
+ | Prop | Type | Default | Description |
23
+ |------|------|---------|-------------|
24
+ | value | `string` | - | Controlled input value |
25
+ | defaultValue | `string` | `""` | Default value (uncontrolled) |
26
+ | onChange | `(value: string) => void` | - | Callback on input change |
27
+ | onSubmit | `(value: string) => void` | - | Callback when Enter is pressed (without Shift) |
28
+ | placeholder | `string` | `"Type a message..."` | Textarea placeholder |
29
+ | actions | `ReactNode` | - | Custom action buttons rendered in the bottom toolbar |
30
+ | disabled | `boolean` | `false` | Disable input and submit |
31
+ | className | `string` | - | Additional CSS classes |
32
+
33
+ ## With Actions
34
+
35
+ ```tsx
36
+ <Composer
37
+ onSubmit={handleSend}
38
+ actions={
39
+ <>
40
+ <button onClick={handleAttach}>Attach</button>
41
+ <button onClick={handleEmoji}>Emoji</button>
42
+ </>
43
+ }
44
+ />
45
+ ```
46
+
47
+ ## Controlled
48
+
49
+ ```tsx
50
+ const [message, setMessage] = useState("");
51
+
52
+ <Composer
53
+ value={message}
54
+ onChange={setMessage}
55
+ onSubmit={(val) => {
56
+ sendMessage(val);
57
+ setMessage("");
58
+ }}
59
+ />
60
+ ```
@@ -0,0 +1,68 @@
1
+ # ContentRenderer
2
+
3
+ Renders HTML or Markdown strings as styled prose, with support for custom tag extensions.
4
+
5
+ ## Import
6
+
7
+ ```tsx
8
+ import { ContentRenderer } from "@particle-academy/react-fancy";
9
+ ```
10
+
11
+ ## Basic Usage
12
+
13
+ ```tsx
14
+ <ContentRenderer value="<h1>Hello</h1><p>World</p>" />
15
+ ```
16
+
17
+ ## Props
18
+
19
+ | Prop | Type | Default | Description |
20
+ |------|------|---------|-------------|
21
+ | value | `string` | - | HTML or Markdown string to render (required) |
22
+ | format | `"html" \| "markdown" \| "auto"` | `"auto"` | Content format. `"auto"` detects based on content |
23
+ | lineSpacing | `number` | `1.6` | Line height |
24
+ | extensions | `RenderExtension[]` | - | Per-instance render extensions (merged with global) |
25
+ | className | `string` | - | Additional CSS classes |
26
+
27
+ ## Render Extensions
28
+
29
+ Extensions let you define custom tags that are rendered by React components. Register globally or pass per-instance:
30
+
31
+ ```tsx
32
+ import { registerExtension } from "@particle-academy/react-fancy";
33
+
34
+ registerExtension({
35
+ tag: "thinking",
36
+ component: ({ content }) => (
37
+ <details className="bg-zinc-100 p-3 rounded">
38
+ <summary>Thinking...</summary>
39
+ <div dangerouslySetInnerHTML={{ __html: content }} />
40
+ </details>
41
+ ),
42
+ block: true,
43
+ });
44
+
45
+ // Content with custom tags
46
+ <ContentRenderer value="<thinking>Some internal reasoning</thinking><p>Final answer.</p>" />
47
+ ```
48
+
49
+ ### RenderExtension
50
+
51
+ | Field | Type | Default | Description |
52
+ |-------|------|---------|-------------|
53
+ | tag | `string` | - | Tag name to match (case-insensitive) |
54
+ | component | `ComponentType<RenderExtensionProps>` | - | React component to render the tag |
55
+ | block | `boolean` | `true` | Block-level (`<div>`) vs inline (`<span>`) wrapping |
56
+
57
+ ### RenderExtensionProps
58
+
59
+ | Prop | Type | Description |
60
+ |------|------|-------------|
61
+ | content | `string` | Inner content of the custom tag |
62
+ | attributes | `Record<string, string>` | Parsed HTML attributes from the opening tag |
63
+
64
+ ## Markdown Rendering
65
+
66
+ ```tsx
67
+ <ContentRenderer value="# Title\n\nParagraph with **bold** text." format="markdown" />
68
+ ```
@@ -0,0 +1,82 @@
1
+ # ContextMenu
2
+
3
+ A right-click context menu that appears at the cursor position. Compound component with Trigger, Content, Item, and Separator.
4
+
5
+ ## Import
6
+
7
+ ```tsx
8
+ import { ContextMenu } from "@particle-academy/react-fancy";
9
+ ```
10
+
11
+ ## Basic Usage
12
+
13
+ ```tsx
14
+ <ContextMenu>
15
+ <ContextMenu.Trigger>
16
+ <div className="w-64 h-32 border border-dashed rounded p-4">
17
+ Right-click here
18
+ </div>
19
+ </ContextMenu.Trigger>
20
+ <ContextMenu.Content>
21
+ <ContextMenu.Item onClick={() => console.log("cut")}>Cut</ContextMenu.Item>
22
+ <ContextMenu.Item onClick={() => console.log("copy")}>Copy</ContextMenu.Item>
23
+ <ContextMenu.Item onClick={() => console.log("paste")}>Paste</ContextMenu.Item>
24
+ <ContextMenu.Separator />
25
+ <ContextMenu.Item danger onClick={() => console.log("delete")}>Delete</ContextMenu.Item>
26
+ </ContextMenu.Content>
27
+ </ContextMenu>
28
+ ```
29
+
30
+ ## Props
31
+
32
+ ### ContextMenu (root)
33
+
34
+ | Prop | Type | Default | Description |
35
+ |------|------|---------|-------------|
36
+ | children | `ReactNode` | - | Trigger and content children |
37
+
38
+ ### ContextMenu.Trigger
39
+
40
+ | Prop | Type | Default | Description |
41
+ |------|------|---------|-------------|
42
+ | children | `ReactNode` | - | Area that responds to right-click |
43
+ | className | `string` | - | Additional CSS classes |
44
+
45
+ ### ContextMenu.Content
46
+
47
+ | Prop | Type | Default | Description |
48
+ |------|------|---------|-------------|
49
+ | children | `ReactNode` | - | Menu items |
50
+ | className | `string` | - | Additional CSS classes |
51
+
52
+ ### ContextMenu.Item
53
+
54
+ | Prop | Type | Default | Description |
55
+ |------|------|---------|-------------|
56
+ | children | `ReactNode` | - | Item content |
57
+ | onClick | `() => void` | - | Click handler |
58
+ | disabled | `boolean` | - | Disable the item |
59
+ | danger | `boolean` | - | Destructive action styling (red) |
60
+ | className | `string` | - | Additional CSS classes |
61
+
62
+ ### ContextMenu.Separator
63
+
64
+ | Prop | Type | Default | Description |
65
+ |------|------|---------|-------------|
66
+ | className | `string` | - | Additional CSS classes |
67
+
68
+ ## Example with Disabled Items
69
+
70
+ ```tsx
71
+ <ContextMenu>
72
+ <ContextMenu.Trigger>
73
+ <div className="p-6 bg-zinc-100 rounded">Right-click target</div>
74
+ </ContextMenu.Trigger>
75
+ <ContextMenu.Content>
76
+ <ContextMenu.Item onClick={handleEdit}>Edit</ContextMenu.Item>
77
+ <ContextMenu.Item disabled>Move (unavailable)</ContextMenu.Item>
78
+ <ContextMenu.Separator />
79
+ <ContextMenu.Item danger onClick={handleRemove}>Remove</ContextMenu.Item>
80
+ </ContextMenu.Content>
81
+ </ContextMenu>
82
+ ```