@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.
@@ -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
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@particle-academy/react-fancy",
3
- "version": "3.0.1",
3
+ "version": "3.1.0",
4
4
  "description": "React UI component library — React port of the fancy-flux Blade component library",
5
5
  "repository": {
6
6
  "type": "git",