@particle-academy/react-fancy 3.0.1 → 3.1.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 +11 -0
- package/dist/index.cjs +790 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +234 -1
- package/dist/index.d.ts +234 -1
- package/dist/index.js +787 -3
- package/dist/index.js.map +1 -1
- package/docs/MagicWand.md +65 -0
- package/docs/MoodMeter.md +63 -0
- package/docs/PromptInput.md +69 -0
- package/docs/ReasonTag.md +63 -0
- package/package.json +1 -1
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# MagicWand
|
|
2
|
+
|
|
3
|
+
Selection-anchored floating toolbar for text inputs. When the user highlights text in the wrapped `<Textarea>`, a small pill of AI quick-actions floats above the selection. Clicking an action runs a host callback whose return value replaces the highlighted text in-place.
|
|
4
|
+
|
|
5
|
+
Promoted from the dreaming sandbox on 2026-05-12.
|
|
6
|
+
|
|
7
|
+
## Import
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { MagicWand, type MagicWandAction } from "@particle-academy/react-fancy";
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Basic Usage
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
const [body, setBody] = useState("…");
|
|
17
|
+
|
|
18
|
+
const actions: MagicWandAction[] = [
|
|
19
|
+
{
|
|
20
|
+
id: "rephrase",
|
|
21
|
+
label: "Rephrase",
|
|
22
|
+
hint: "same meaning, different words",
|
|
23
|
+
run: async (selection) => await ai.rephrase(selection),
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
id: "shorten",
|
|
27
|
+
label: "Shorten",
|
|
28
|
+
run: async (selection) => await ai.shorten(selection),
|
|
29
|
+
},
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
<MagicWand value={body} onValueChange={setBody} actions={actions} />;
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Props
|
|
36
|
+
|
|
37
|
+
| Prop | Type | Default | Description |
|
|
38
|
+
|------|------|---------|-------------|
|
|
39
|
+
| value | `string` | — | Controlled textarea value. |
|
|
40
|
+
| onValueChange | `(v: string) => void` | — | Fires on every edit. |
|
|
41
|
+
| actions | `MagicWandAction[]` | — | Action list. Each invokes a callback with the selection. |
|
|
42
|
+
| appearance | `"floating" \| "pill"` | `"floating"` | `"pill"` is icon-only and compact. |
|
|
43
|
+
| autoHide | `boolean` | `true` | Hide the wand on click-away or scroll. |
|
|
44
|
+
| rows | `number` | `6` | Textarea rows. |
|
|
45
|
+
| placeholder | `string` | — | Textarea placeholder. |
|
|
46
|
+
| onAction | `(action, selection, replacement) => void` | — | Fires after an action successfully runs. |
|
|
47
|
+
|
|
48
|
+
## Action shape
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
type MagicWandAction = {
|
|
52
|
+
id: string;
|
|
53
|
+
label: string;
|
|
54
|
+
hint?: string;
|
|
55
|
+
tag?: string;
|
|
56
|
+
run: (selection: string, range: { start: number; end: number; text: string }) => Promise<string> | string;
|
|
57
|
+
};
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The string `run` returns becomes the replacement for the selected range. The wand patches `value` and emits `onAction`.
|
|
61
|
+
|
|
62
|
+
## Notes
|
|
63
|
+
|
|
64
|
+
- The toolbar position is computed by mirroring the textarea into a hidden div and measuring the selected substring's bounding rect — works for typical chat composers; less accurate for textareas that resize while the toolbar is open.
|
|
65
|
+
- In `"pill"` mode each action shows only the first character of its label, useful when toolbar real estate is tight.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# MoodMeter
|
|
2
|
+
|
|
3
|
+
A 2D draggable pad that captures a value AND the confidence in that value on the same handle. The halo around the handle shrinks as confidence rises — uncertain readings literally look fuzzier.
|
|
4
|
+
|
|
5
|
+
Promoted from the dreaming sandbox on 2026-05-12.
|
|
6
|
+
|
|
7
|
+
## Import
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { MoodMeter } from "@particle-academy/react-fancy";
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Basic Usage
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
const [value, setValue] = useState(60);
|
|
17
|
+
const [confidence, setConfidence] = useState(0.74);
|
|
18
|
+
|
|
19
|
+
<MoodMeter
|
|
20
|
+
min={30}
|
|
21
|
+
max={200}
|
|
22
|
+
value={value}
|
|
23
|
+
confidence={confidence}
|
|
24
|
+
onChange={(v, c) => {
|
|
25
|
+
setValue(v);
|
|
26
|
+
setConfidence(c);
|
|
27
|
+
}}
|
|
28
|
+
posted={{ value: 60, confidence: 0.74 }}
|
|
29
|
+
prefix="$"
|
|
30
|
+
suffix="k"
|
|
31
|
+
/>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Why
|
|
35
|
+
|
|
36
|
+
When AIs post a number, humans immediately ask "how sure are you?". Making confidence an explicit sibling of value — and letting the user drag either independently — turns vague "AI suggestion" UX into something you can argue with precisely.
|
|
37
|
+
|
|
38
|
+
## Props
|
|
39
|
+
|
|
40
|
+
| Prop | Type | Default | Description |
|
|
41
|
+
|------|------|---------|-------------|
|
|
42
|
+
| min | `number` | — | Range minimum. |
|
|
43
|
+
| max | `number` | — | Range maximum. |
|
|
44
|
+
| step | `number` | `(max-min)/100` | Step for value snapping. |
|
|
45
|
+
| value | `number` | — | Current value (controlled). |
|
|
46
|
+
| confidence | `number` | — | Current confidence 0..1 (controlled). |
|
|
47
|
+
| onChange | `(value, confidence) => void` | — | Fires on drag / pointer events. |
|
|
48
|
+
| posted | `{ value, confidence }` | — | Optional agent post — renders as a dashed ghost handle. |
|
|
49
|
+
| width | `number` | `320` | Pad width in pixels. |
|
|
50
|
+
| height | `number` | `220` | Pad height in pixels. |
|
|
51
|
+
| showGrid | `boolean` | `true` | Show the grid + axis labels. |
|
|
52
|
+
| color | `string` | `"#0ea5e9"` | User handle colour. |
|
|
53
|
+
| postedColor | `string` | `"#a855f7"` | Ghost handle colour. |
|
|
54
|
+
| prefix | `string` | `""` | Prefix for the value label (e.g. `"$"`). |
|
|
55
|
+
| suffix | `string` | `""` | Suffix for the value label (e.g. `"k"`, `"%"`). |
|
|
56
|
+
| formatValue | `(v) => string` | — | Override the label formatting. |
|
|
57
|
+
| className | `string` | — | Applied to the pad. |
|
|
58
|
+
|
|
59
|
+
## Pad Axes
|
|
60
|
+
|
|
61
|
+
- **x-axis** → value range `[min..max]`
|
|
62
|
+
- **y-axis** → confidence `[0..1]` (top = sure)
|
|
63
|
+
- **halo radius** → scales inversely with confidence (large halo = unsure)
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# PromptInput
|
|
2
|
+
|
|
3
|
+
The chat composer every AI app rebuilds. Auto-growing multi-line input with slash commands, @ mentions, drop-to-attach, keyboard submit, and a live token-budget meter.
|
|
4
|
+
|
|
5
|
+
Promoted from the dreaming sandbox on 2026-05-12.
|
|
6
|
+
|
|
7
|
+
## Import
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { PromptInput } from "@particle-academy/react-fancy";
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Basic Usage
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
<PromptInput
|
|
17
|
+
budgetTokens={32000}
|
|
18
|
+
commands={[
|
|
19
|
+
{ name: "/explain", hint: "explain the selected text" },
|
|
20
|
+
{ name: "/rewrite", hint: "rewrite in a different tone" },
|
|
21
|
+
]}
|
|
22
|
+
mentions={[
|
|
23
|
+
{ id: "planner", name: "Planner", kind: "agent" },
|
|
24
|
+
{ id: "ada", name: "Ada", kind: "person" },
|
|
25
|
+
{ id: "readme", name: "README.md", kind: "file" },
|
|
26
|
+
]}
|
|
27
|
+
onSubmit={(text, attachments) => send(text, attachments)}
|
|
28
|
+
/>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Features
|
|
32
|
+
|
|
33
|
+
- Auto-resizes up to `maxHeight`.
|
|
34
|
+
- `/` opens a filtered command palette. ↑/↓ navigate, Enter inserts.
|
|
35
|
+
- `@` opens a mention picker filtered against `mentions`.
|
|
36
|
+
- Drop files anywhere on the input to attach. Chip bar shows attachments.
|
|
37
|
+
- ⌘+Enter (or Ctrl+Enter) submits. Plain Enter inserts a newline.
|
|
38
|
+
- Token-budget meter colours green → amber → red as headroom drops.
|
|
39
|
+
|
|
40
|
+
## Props
|
|
41
|
+
|
|
42
|
+
| Prop | Type | Default | Description |
|
|
43
|
+
|------|------|---------|-------------|
|
|
44
|
+
| budgetTokens | `number` | — | Token budget for the meter. |
|
|
45
|
+
| commands | `PromptCmd[]` | `[]` | Slash commands. Names must start with `/`. |
|
|
46
|
+
| mentions | `PromptMention[]` | `[]` | `{ id, name, kind }`. `kind` is free-form (`"agent"`, `"file"`, `"person"`, …). |
|
|
47
|
+
| onSubmit | `(text, attachments) => void` | — | Called on ⌘/Ctrl+Enter or send button. |
|
|
48
|
+
| showHint | `boolean` | `true` | Show the "⌘ + Enter to send" hint. |
|
|
49
|
+
| placeholder | `string` | `"Ask anything…"` | Placeholder text. |
|
|
50
|
+
| charsPerToken | `number` | `4` | Rough estimator for the token meter. |
|
|
51
|
+
| mentionColor | `Record<string, string>` | sensible defaults | Override the chip colour per mention kind. |
|
|
52
|
+
| maxHeight | `number` | `280` | Max textarea height in pixels. |
|
|
53
|
+
|
|
54
|
+
## Types
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
type PromptCmd = { name: string; hint: string };
|
|
58
|
+
type PromptMention = { id: string; name: string; kind: string };
|
|
59
|
+
type PromptAttachment = { id: string; name: string; bytes: number };
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Defaults
|
|
63
|
+
|
|
64
|
+
| Mention kind | Default colour |
|
|
65
|
+
|--------------|----------------|
|
|
66
|
+
| `"agent"` | violet |
|
|
67
|
+
| `"file"` | emerald |
|
|
68
|
+
| `"person"` | blue |
|
|
69
|
+
| other | zinc |
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# ReasonTag
|
|
2
|
+
|
|
3
|
+
Wrap any value with a small affordance that reveals the agent's reasoning, sources, and confidence on hover or click. Explainability becomes a primitive instead of an afterthought.
|
|
4
|
+
|
|
5
|
+
Promoted from the dreaming sandbox on 2026-05-12.
|
|
6
|
+
|
|
7
|
+
## Import
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { ReasonTag } from "@particle-academy/react-fancy";
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Basic Usage
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
<ReasonTag
|
|
17
|
+
value="$1.4M"
|
|
18
|
+
reason="Projected Q3 ARR after stacking renewals."
|
|
19
|
+
confidence={0.91}
|
|
20
|
+
sources={[{ label: "Q2 actuals · CRM export" }]}
|
|
21
|
+
by="Forecaster"
|
|
22
|
+
/>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Props
|
|
26
|
+
|
|
27
|
+
| Prop | Type | Default | Description |
|
|
28
|
+
|------|------|---------|-------------|
|
|
29
|
+
| value | `ReactNode` | — | The wrapped value (number, label, short phrase). |
|
|
30
|
+
| reason | `string` | — | Free-text rationale shown in the popover. |
|
|
31
|
+
| confidence | `number` | `1` | 0..1 — drives the colour tier (green ≥ 0.85, amber ≥ 0.6, red below). |
|
|
32
|
+
| sources | `ReasonTagSource[]` | `[]` | `{ label, href? }` list rendered in the popover. |
|
|
33
|
+
| by | `string` | — | Optional author / agent name shown in the popover header. |
|
|
34
|
+
| theme | `"dot" \| "underline" \| "chip"` | `"dot"` | Visual treatment for the trigger. |
|
|
35
|
+
| pinned | `boolean` | `false` | When true, the reason is rendered inline as a margin annotation (no popover). |
|
|
36
|
+
| onFollowUp | `() => void` | — | Optional callback for the "ask follow-up" action in the popover. |
|
|
37
|
+
| className | `string` | — | Applied to the trigger element. |
|
|
38
|
+
|
|
39
|
+
## Confidence Tiers
|
|
40
|
+
|
|
41
|
+
| Range | Colour | Label |
|
|
42
|
+
|-------|--------|-------|
|
|
43
|
+
| ≥ 0.85 | emerald | high |
|
|
44
|
+
| ≥ 0.6 | amber | medium |
|
|
45
|
+
| < 0.6 | red | low |
|
|
46
|
+
|
|
47
|
+
Quick visual scan tells you which suggestions deserve a closer look without opening any tooltips.
|
|
48
|
+
|
|
49
|
+
## Examples
|
|
50
|
+
|
|
51
|
+
### Three visual styles
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
<ReasonTag value="42" reason="…" theme="dot" />
|
|
55
|
+
<ReasonTag value="42" reason="…" theme="underline" />
|
|
56
|
+
<ReasonTag value="42" reason="…" theme="chip" />
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Always-visible inline annotation
|
|
60
|
+
|
|
61
|
+
```tsx
|
|
62
|
+
<ReasonTag value="$60k" reason="Expansion uplift applied at the historical rate." pinned />
|
|
63
|
+
```
|