@nucleux/ai-icons 0.0.0-stage → 0.6.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Nucleux
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,47 @@
1
- # Temporary Holding Version
1
+ # @nucleux/ai-icons
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Icons — a small, stable AI mark vocabulary: action, generated, working and tool use — Nucleux agentic UI for React.
4
+
5
+ Part of **[Nucleux](https://github.com/intelligaia-open-labs/nucleux)** — agentic UI components for React. Install a single component, or the full kit via [`@nucleux/react`](https://www.npmjs.com/package/@nucleux/react).
6
+
7
+ ## Exports
8
+
9
+ - **`AiIcons`** — the AI presence mark. `variant`: `sparkle` (default) / `thinking-orb` (animated, for active states) / `branded-mark`; `size` sm/md/lg (24/32/40); `tone` solid/outline; `label` (accessible name — omit when words sit beside it); `glyph` (branded-mark content)
10
+ - **`AiIcon`** — one AI *meaning* with its mark and its words. `role`: `ai-action` / `generated-content` / `agent-working` (turns, announced in a polite live region) / `tool-use`; `label` (required); `showLabel`
11
+ - **`AiIconProvider`** (`glyphs`) + **`useAiGlyph(role)`** — choose the approved glyph per role once for the whole product; the approved lists don't overlap
12
+ - Glyphs: **`AiSparkleIcon`**, **`AiGeneratedIcon`**, **`AiWorkingIcon`** (`still`), **`AiWandIcon`**, **`AiRegenerateIcon`**, **`AiToolIcon`**; maps **`aiGlyphs`**, **`defaultAiIconGlyphs`**
13
+
14
+ ## Rules
15
+
16
+ - The sparkle is the universal default; the orb is for active state only; never a photo or human face.
17
+ - Every mark travels with words — a visible label, or an accessible name.
18
+ - Only the working mark moves, only while work happens, and it holds still under reduced motion.
19
+ - `@nucleux/iconography`, `@nucleux/agent-avatar` and `@nucleux/disclosure` draw from these same glyphs.
20
+
21
+ ## Install
22
+
23
+ ```bash
24
+ pnpm add @nucleux/ai-icons @nucleux/tokens
25
+ ```
26
+
27
+ `react` / `react-dom` are peer dependencies.
28
+
29
+ ## Usage
30
+
31
+ ```tsx
32
+ import { AiIcons, AiIcon, AiIconProvider } from "@nucleux/ai-icons";
33
+
34
+ <AiIcon role="ai-action" label="Rewrite" />
35
+ <AiIcon role="agent-working" label="Rewriting release note…" />
36
+ <AiIcon role="generated-content" label="Generated with AI" />
37
+ <AiIcons variant="thinking-orb" /> <span role="status">Aria is thinking…</span>
38
+
39
+ <AiIconProvider glyphs={{ "ai-action": "wand" }}>{app}</AiIconProvider>
40
+ ```
41
+
42
+ Requires the theme once in your app: `import "@nucleux/tokens/styles.css";`
43
+ and the Tailwind preset from `@nucleux/tokens/preset`.
44
+
45
+ ## License
46
+
47
+ MIT © Nucleux
package/dist/index.cjs ADDED
@@ -0,0 +1,261 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var React = require('react');
5
+ var lucideReact = require('lucide-react');
6
+ var utils = require('@nucleux/utils');
7
+ var color = require('@nucleux/color');
8
+ var jsxRuntime = require('react/jsx-runtime');
9
+
10
+ function _interopNamespace(e) {
11
+ if (e && e.__esModule) return e;
12
+ var n = Object.create(null);
13
+ if (e) {
14
+ Object.keys(e).forEach(function (k) {
15
+ if (k !== 'default') {
16
+ var d = Object.getOwnPropertyDescriptor(e, k);
17
+ Object.defineProperty(n, k, d.get ? d : {
18
+ enumerable: true,
19
+ get: function () { return e[k]; }
20
+ });
21
+ }
22
+ });
23
+ }
24
+ n.default = e;
25
+ return Object.freeze(n);
26
+ }
27
+
28
+ var React__namespace = /*#__PURE__*/_interopNamespace(React);
29
+
30
+ // src/index.tsx
31
+ function glyphA11y(props) {
32
+ const named = props["aria-label"] != null || props["aria-labelledby"] != null;
33
+ return named ? { role: "img" } : { "aria-hidden": true };
34
+ }
35
+ var AiSparkleIcon = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
36
+ "svg",
37
+ {
38
+ ref,
39
+ viewBox: "0 0 24 24",
40
+ width: 16,
41
+ height: 16,
42
+ fill: "currentColor",
43
+ focusable: "false",
44
+ "data-ai-glyph": "sparkle",
45
+ className: utils.cn("size-4 shrink-0", className),
46
+ ...glyphA11y(props),
47
+ ...props,
48
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 3c.6 4.8 3.2 7.4 9 9-5.8 1.6-8.4 4.2-9 9-.6-4.8-3.2-7.4-9-9 5.8-1.6 8.4-4.2 9-9z" })
49
+ }
50
+ ));
51
+ AiSparkleIcon.displayName = "AiSparkleIcon";
52
+ var AiGeneratedIcon = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
53
+ "svg",
54
+ {
55
+ ref,
56
+ viewBox: "0 0 24 24",
57
+ width: 16,
58
+ height: 16,
59
+ fill: "none",
60
+ stroke: "currentColor",
61
+ strokeWidth: 1.8,
62
+ strokeLinejoin: "round",
63
+ focusable: "false",
64
+ "data-ai-glyph": "generated",
65
+ className: utils.cn("size-4 shrink-0", className),
66
+ ...glyphA11y(props),
67
+ ...props,
68
+ children: [
69
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5 4h14a1 1 0 0 1 1 1v11a1 1 0 0 1-1 1h-7l-4 3v-3H5a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1z" }),
70
+ /* @__PURE__ */ jsxRuntime.jsx(
71
+ "path",
72
+ {
73
+ d: "M12 6.5c.3 2.2 1.3 3.2 3.5 3.5-2.2.3-3.2 1.3-3.5 3.5-.3-2.2-1.3-3.2-3.5-3.5 2.2-.3 3.2-1.3 3.5-3.5z",
74
+ fill: "currentColor",
75
+ stroke: "none"
76
+ }
77
+ )
78
+ ]
79
+ }
80
+ ));
81
+ AiGeneratedIcon.displayName = "AiGeneratedIcon";
82
+ var AiWorkingIcon = React__namespace.forwardRef(
83
+ ({ still = false, className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
84
+ "svg",
85
+ {
86
+ ref,
87
+ viewBox: "0 0 24 24",
88
+ width: 16,
89
+ height: 16,
90
+ fill: "none",
91
+ stroke: "currentColor",
92
+ strokeWidth: 2.2,
93
+ strokeLinecap: "round",
94
+ focusable: "false",
95
+ "data-ai-glyph": "working",
96
+ className: utils.cn("size-4 shrink-0", !still && "animate-spin motion-reduce:animate-none", className),
97
+ ...glyphA11y(props),
98
+ ...props,
99
+ children: [
100
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "8.5", opacity: 0.25 }),
101
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 3.5a8.5 8.5 0 0 1 8.5 8.5" })
102
+ ]
103
+ }
104
+ )
105
+ );
106
+ AiWorkingIcon.displayName = "AiWorkingIcon";
107
+ function lucideGlyph(Icon, name, displayName) {
108
+ const Glyph = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
109
+ Icon,
110
+ {
111
+ ref,
112
+ focusable: "false",
113
+ "data-ai-glyph": name,
114
+ className: utils.cn("size-4 shrink-0", className),
115
+ ...glyphA11y(props),
116
+ ...props
117
+ }
118
+ ));
119
+ Glyph.displayName = displayName;
120
+ return Glyph;
121
+ }
122
+ var AiWandIcon = lucideGlyph(
123
+ lucideReact.WandSparkles,
124
+ "wand",
125
+ "AiWandIcon"
126
+ );
127
+ var AiRegenerateIcon = lucideGlyph(
128
+ lucideReact.RefreshCw,
129
+ "regenerate",
130
+ "AiRegenerateIcon"
131
+ );
132
+ var AiToolIcon = lucideGlyph(lucideReact.Wrench, "tool", "AiToolIcon");
133
+ var aiGlyphs = {
134
+ sparkle: AiSparkleIcon,
135
+ wand: AiWandIcon,
136
+ regenerate: AiRegenerateIcon,
137
+ generated: AiGeneratedIcon,
138
+ working: AiWorkingIcon,
139
+ tool: AiToolIcon
140
+ };
141
+ var defaultAiIconGlyphs = {
142
+ "ai-action": "sparkle",
143
+ "generated-content": "generated",
144
+ "agent-working": "working",
145
+ "tool-use": "tool"
146
+ };
147
+ var AiIconContext = React__namespace.createContext(defaultAiIconGlyphs);
148
+ function AiIconProvider({ glyphs, children }) {
149
+ const value = React__namespace.useMemo(() => ({ ...defaultAiIconGlyphs, ...glyphs }), [glyphs]);
150
+ return /* @__PURE__ */ jsxRuntime.jsx(AiIconContext.Provider, { value, children });
151
+ }
152
+ AiIconProvider.displayName = "AiIconProvider";
153
+ function useAiGlyph(role) {
154
+ const glyphs = React__namespace.useContext(AiIconContext);
155
+ return aiGlyphs[glyphs[role]];
156
+ }
157
+ var roleClasses = {
158
+ "ai-action": "text-foreground [&>svg]:text-brand",
159
+ "agent-working": "text-foreground [&>svg]:text-brand",
160
+ "tool-use": "text-muted-foreground",
161
+ "generated-content": "rounded-full border border-brand/30 bg-background px-2 py-0.5 text-xs font-medium text-foreground [&>svg]:size-3.5 [&>svg]:text-brand"
162
+ };
163
+ var AiIcon = React__namespace.forwardRef(
164
+ ({ role, label, showLabel = true, className, ...props }, ref) => {
165
+ const Glyph = useAiGlyph(role);
166
+ return /* @__PURE__ */ jsxRuntime.jsxs(
167
+ "span",
168
+ {
169
+ ref,
170
+ "data-ai-role": role,
171
+ role: role === "agent-working" ? "status" : void 0,
172
+ "aria-live": role === "agent-working" ? "polite" : void 0,
173
+ className: utils.cn("inline-flex items-center gap-1.5 text-sm", roleClasses[role], className),
174
+ ...props,
175
+ children: [
176
+ /* @__PURE__ */ jsxRuntime.jsx(Glyph, {}),
177
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: showLabel ? void 0 : "sr-only", children: label })
178
+ ]
179
+ }
180
+ );
181
+ }
182
+ );
183
+ AiIcon.displayName = "AiIcon";
184
+ var sizeClasses = {
185
+ sm: "size-6 text-xs [&>svg]:size-3.5",
186
+ md: "size-8 text-sm [&>svg]:size-4",
187
+ lg: "size-10 text-lg [&>svg]:size-5"
188
+ };
189
+ var AiIcons = React__namespace.forwardRef(
190
+ ({ variant = "sparkle", size = "md", tone = "solid", label, glyph, className, ...props }, ref) => {
191
+ const Sparkle = useAiGlyph("ai-action");
192
+ const a11y = label ? { role: "img", "aria-label": label } : { "aria-hidden": true };
193
+ const base = "inline-grid shrink-0 place-items-center font-semibold";
194
+ if (variant === "thinking-orb") {
195
+ return /* @__PURE__ */ jsxRuntime.jsx(
196
+ "span",
197
+ {
198
+ ref,
199
+ "data-variant": variant,
200
+ className: utils.cn(
201
+ base,
202
+ "rounded-full bg-gradient-to-br from-brand to-primary shadow-sm",
203
+ color.aiColorClasses.working,
204
+ sizeClasses[size],
205
+ className
206
+ ),
207
+ ...a11y,
208
+ ...props
209
+ }
210
+ );
211
+ }
212
+ const toneClasses = tone === "solid" ? "bg-primary text-primary-foreground" : "border border-border bg-background text-foreground";
213
+ if (variant === "branded-mark") {
214
+ const content = glyph ?? (label ? label.charAt(0).toLowerCase() : /* @__PURE__ */ jsxRuntime.jsx(Sparkle, {}));
215
+ return /* @__PURE__ */ jsxRuntime.jsx(
216
+ "span",
217
+ {
218
+ ref,
219
+ "data-variant": variant,
220
+ className: utils.cn(
221
+ base,
222
+ "rounded-[28%] font-serif italic",
223
+ tone === "solid" ? "bg-gradient-to-br from-primary to-primary/70 text-primary-foreground" : toneClasses,
224
+ sizeClasses[size],
225
+ className
226
+ ),
227
+ ...a11y,
228
+ ...props,
229
+ children: content
230
+ }
231
+ );
232
+ }
233
+ return /* @__PURE__ */ jsxRuntime.jsx(
234
+ "span",
235
+ {
236
+ ref,
237
+ "data-variant": variant,
238
+ className: utils.cn(base, "rounded-[22%]", toneClasses, sizeClasses[size], className),
239
+ ...a11y,
240
+ ...props,
241
+ children: /* @__PURE__ */ jsxRuntime.jsx(Sparkle, {})
242
+ }
243
+ );
244
+ }
245
+ );
246
+ AiIcons.displayName = "AiIcons";
247
+
248
+ exports.AiGeneratedIcon = AiGeneratedIcon;
249
+ exports.AiIcon = AiIcon;
250
+ exports.AiIconProvider = AiIconProvider;
251
+ exports.AiIcons = AiIcons;
252
+ exports.AiRegenerateIcon = AiRegenerateIcon;
253
+ exports.AiSparkleIcon = AiSparkleIcon;
254
+ exports.AiToolIcon = AiToolIcon;
255
+ exports.AiWandIcon = AiWandIcon;
256
+ exports.AiWorkingIcon = AiWorkingIcon;
257
+ exports.aiGlyphs = aiGlyphs;
258
+ exports.defaultAiIconGlyphs = defaultAiIconGlyphs;
259
+ exports.useAiGlyph = useAiGlyph;
260
+ //# sourceMappingURL=index.cjs.map
261
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.tsx"],"names":["React","jsx","cn","jsxs","WandSparkles","RefreshCw","Wrench","aiColorClasses"],"mappings":"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","file":"index.cjs","sourcesContent":["import * as React from \"react\";\nimport { RefreshCw, WandSparkles, Wrench } from \"lucide-react\";\nimport { cn } from \"@nucleux/utils\";\nimport { aiColorClasses } from \"@nucleux/color\";\n\n/* -------------------------------------------------------------------------- */\n/* Glyphs */\n/* -------------------------------------------------------------------------- */\n\nexport type AiGlyphProps = React.SVGProps<SVGSVGElement>;\n\n/** Decorative unless the caller names it. */\nfunction glyphA11y(props: AiGlyphProps) {\n const named = props[\"aria-label\"] != null || props[\"aria-labelledby\"] != null;\n return named ? { role: \"img\" as const } : { \"aria-hidden\": true as const };\n}\n\n/**\n * The four-point AI sparkle — the reserved mark for \"this runs AI\" (generate).\n * The same drawing appears on the agent avatar and the disclosure chip.\n * Decorative (`aria-hidden`) unless given an `aria-label`.\n */\nexport const AiSparkleIcon = React.forwardRef<SVGSVGElement, AiGlyphProps>(({ className, ...props }, ref) => (\n <svg\n ref={ref}\n viewBox=\"0 0 24 24\"\n width={16}\n height={16}\n fill=\"currentColor\"\n focusable=\"false\"\n data-ai-glyph=\"sparkle\"\n className={cn(\"size-4 shrink-0\", className)}\n {...glyphA11y(props)}\n {...props}\n >\n <path d=\"M12 3c.6 4.8 3.2 7.4 9 9-5.8 1.6-8.4 4.2-9 9-.6-4.8-3.2-7.4-9-9 5.8-1.6 8.4-4.2 9-9z\" />\n </svg>\n));\nAiSparkleIcon.displayName = \"AiSparkleIcon\";\n\n/**\n * The \"generated with AI\" mark: a content outline carrying the sparkle. Used\n * only on content AI wrote or changed, never on controls.\n */\nexport const AiGeneratedIcon = React.forwardRef<SVGSVGElement, AiGlyphProps>(({ className, ...props }, ref) => (\n <svg\n ref={ref}\n viewBox=\"0 0 24 24\"\n width={16}\n height={16}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={1.8}\n strokeLinejoin=\"round\"\n focusable=\"false\"\n data-ai-glyph=\"generated\"\n className={cn(\"size-4 shrink-0\", className)}\n {...glyphA11y(props)}\n {...props}\n >\n <path d=\"M5 4h14a1 1 0 0 1 1 1v11a1 1 0 0 1-1 1h-7l-4 3v-3H5a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1z\" />\n <path\n d=\"M12 6.5c.3 2.2 1.3 3.2 3.5 3.5-2.2.3-3.2 1.3-3.5 3.5-.3-2.2-1.3-3.2-3.5-3.5 2.2-.3 3.2-1.3 3.5-3.5z\"\n fill=\"currentColor\"\n stroke=\"none\"\n />\n </svg>\n));\nAiGeneratedIcon.displayName = \"AiGeneratedIcon\";\n\nexport interface AiWorkingIconProps extends AiGlyphProps {\n /** Hold the mark still (it only turns while work is happening). */\n still?: boolean;\n}\n\n/**\n * The \"agent working\" mark: a turning arc. The only AI mark that moves, and\n * only while work is happening; it holds still under reduced motion.\n */\nexport const AiWorkingIcon = React.forwardRef<SVGSVGElement, AiWorkingIconProps>(\n ({ still = false, className, ...props }, ref) => (\n <svg\n ref={ref}\n viewBox=\"0 0 24 24\"\n width={16}\n height={16}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2.2}\n strokeLinecap=\"round\"\n focusable=\"false\"\n data-ai-glyph=\"working\"\n className={cn(\"size-4 shrink-0\", !still && \"animate-spin motion-reduce:animate-none\", className)}\n {...glyphA11y(props)}\n {...props}\n >\n <circle cx=\"12\" cy=\"12\" r=\"8.5\" opacity={0.25} />\n <path d=\"M12 3.5a8.5 8.5 0 0 1 8.5 8.5\" />\n </svg>\n ),\n);\nAiWorkingIcon.displayName = \"AiWorkingIcon\";\n\nfunction lucideGlyph(Icon: React.ComponentType<AiGlyphProps>, name: string, displayName: string) {\n const Glyph = React.forwardRef<SVGSVGElement, AiGlyphProps>(({ className, ...props }, ref) => (\n <Icon\n ref={ref}\n focusable=\"false\"\n data-ai-glyph={name}\n className={cn(\"size-4 shrink-0\", className)}\n {...glyphA11y(props)}\n {...props}\n />\n ));\n Glyph.displayName = displayName;\n return Glyph;\n}\n\n/** The \"transform\" mark (wand): for AI actions that change something the user already has — rewrite, enhance, restyle. */\nexport const AiWandIcon = lucideGlyph(\n WandSparkles as unknown as React.ComponentType<AiGlyphProps>,\n \"wand\",\n \"AiWandIcon\",\n);\n/** The \"regenerate\" mark: run the same AI action again. */\nexport const AiRegenerateIcon = lucideGlyph(\n RefreshCw as unknown as React.ComponentType<AiGlyphProps>,\n \"regenerate\",\n \"AiRegenerateIcon\",\n);\n/** The \"tool use\" mark: on the lines that say which tool the agent used. */\nexport const AiToolIcon = lucideGlyph(Wrench as unknown as React.ComponentType<AiGlyphProps>, \"tool\", \"AiToolIcon\");\n\n/* -------------------------------------------------------------------------- */\n/* Roles and the approved glyph lists */\n/* -------------------------------------------------------------------------- */\n\n/** The four AI meanings. Each has its own mark, used for that meaning only. */\nexport type AiIconRole = \"ai-action\" | \"generated-content\" | \"agent-working\" | \"tool-use\";\n\n/** Every reserved glyph by name. */\nexport type AiGlyphName = \"sparkle\" | \"wand\" | \"regenerate\" | \"generated\" | \"working\" | \"tool\";\n\n/**\n * Approved glyphs per role. The lists do not overlap, so two meanings can\n * never share a mark.\n */\nexport interface AiIconGlyphs {\n \"ai-action\"?: \"sparkle\" | \"wand\";\n \"generated-content\"?: \"generated\";\n \"agent-working\"?: \"working\";\n \"tool-use\"?: \"tool\";\n}\n\n/** The reserved glyph components, by name. */\nexport const aiGlyphs: Record<AiGlyphName, React.ComponentType<AiGlyphProps>> = {\n sparkle: AiSparkleIcon,\n wand: AiWandIcon,\n regenerate: AiRegenerateIcon,\n generated: AiGeneratedIcon,\n working: AiWorkingIcon,\n tool: AiToolIcon,\n};\n\n/** The default glyph for each role. */\nexport const defaultAiIconGlyphs: Required<AiIconGlyphs> = {\n \"ai-action\": \"sparkle\",\n \"generated-content\": \"generated\",\n \"agent-working\": \"working\",\n \"tool-use\": \"tool\",\n};\n\nconst AiIconContext = React.createContext<Required<AiIconGlyphs>>(defaultAiIconGlyphs);\n\nexport interface AiIconProviderProps {\n /** Product-wide choice of approved glyph per role. Set once; unset roles keep the default. */\n glyphs?: AiIconGlyphs;\n children?: React.ReactNode;\n}\n\n/**\n * Sets the approved glyph for each AI role once for the whole product.\n * Every `AiIcon`, `AiIcons`, `Iconography` and `Disclosure` under it uses\n * the same choice, so a meaning keeps one mark everywhere.\n */\nexport function AiIconProvider({ glyphs, children }: AiIconProviderProps) {\n const value = React.useMemo(() => ({ ...defaultAiIconGlyphs, ...glyphs }), [glyphs]);\n return <AiIconContext.Provider value={value}>{children}</AiIconContext.Provider>;\n}\nAiIconProvider.displayName = \"AiIconProvider\";\n\n/** The glyph component the nearest `AiIconProvider` approved for a role. */\nexport function useAiGlyph(role: AiIconRole): React.ComponentType<AiGlyphProps> {\n const glyphs = React.useContext(AiIconContext);\n return aiGlyphs[glyphs[role]];\n}\n\n/* -------------------------------------------------------------------------- */\n/* AiIcon — a meaning, with its mark and its words */\n/* -------------------------------------------------------------------------- */\n\nexport interface AiIconProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, \"role\"> {\n /**\n * Which AI meaning this is: `ai-action` (a control runs AI),\n * `generated-content` (AI wrote this), `agent-working` (the agent is\n * working now — announced politely) or `tool-use` (the agent used a tool).\n */\n role: AiIconRole;\n /** The words that travel with the mark (\"Rewrite\", \"Generated with AI\", \"Rewriting release note…\"). Required: a mark is never alone. */\n label: React.ReactNode;\n /** Show the words visibly (default) or keep them for assistive tech only. */\n showLabel?: boolean;\n}\n\nconst roleClasses: Record<AiIconRole, string> = {\n \"ai-action\": \"text-foreground [&>svg]:text-brand\",\n \"agent-working\": \"text-foreground [&>svg]:text-brand\",\n \"tool-use\": \"text-muted-foreground\",\n \"generated-content\":\n \"rounded-full border border-brand/30 bg-background px-2 py-0.5 text-xs font-medium text-foreground [&>svg]:size-3.5 [&>svg]:text-brand\",\n};\n\n/**\n * One AI meaning drawn with its reserved mark and its words. The product\n * names the meaning; the component maps it to the approved glyph (see\n * `AiIconProvider`). `agent-working` turns its mark and announces its words\n * in a polite live region; the rest are static. For a control that runs\n * AI, use `Iconography`, which puts the `ai-action` mark on a Button.\n */\nexport const AiIcon = React.forwardRef<HTMLSpanElement, AiIconProps>(\n ({ role, label, showLabel = true, className, ...props }, ref) => {\n const Glyph = useAiGlyph(role);\n return (\n <span\n ref={ref}\n data-ai-role={role}\n role={role === \"agent-working\" ? \"status\" : undefined}\n aria-live={role === \"agent-working\" ? \"polite\" : undefined}\n className={cn(\"inline-flex items-center gap-1.5 text-sm\", roleClasses[role], className)}\n {...props}\n >\n <Glyph />\n <span className={showLabel ? undefined : \"sr-only\"}>{label}</span>\n </span>\n );\n },\n);\nAiIcon.displayName = \"AiIcon\";\n\n/* -------------------------------------------------------------------------- */\n/* AiIcons — the AI presence mark */\n/* -------------------------------------------------------------------------- */\n\nexport type AiIconsVariant = \"sparkle\" | \"thinking-orb\" | \"branded-mark\";\nexport type AiIconsSize = \"sm\" | \"md\" | \"lg\";\nexport type AiIconsTone = \"solid\" | \"outline\";\n\nconst sizeClasses: Record<AiIconsSize, string> = {\n sm: \"size-6 text-xs [&>svg]:size-3.5\",\n md: \"size-8 text-sm [&>svg]:size-4\",\n lg: \"size-10 text-lg [&>svg]:size-5\",\n};\n\nexport interface AiIconsProps extends React.HTMLAttributes<HTMLSpanElement> {\n /**\n * `sparkle` (the universal \"AI\" mark in a tile), `thinking-orb` (an\n * animated orb for active, listening or generating states) or\n * `branded-mark` (your product's own shape or letter).\n */\n variant?: AiIconsVariant;\n /** 24 / 32 / 40 px. */\n size?: AiIconsSize;\n /** `solid` (filled tile) or `outline` (bordered tile). Sparkle and branded mark only. */\n tone?: AiIconsTone;\n /** Accessible name. Omit when words sit beside the mark — it is then decorative. */\n label?: string;\n /** Content of the branded mark (a letter or your SVG). Defaults to the first letter of `label`, else the sparkle. */\n glyph?: React.ReactNode;\n}\n\n/**\n * The AI presence mark: one stable symbol that tells people the AI is here.\n * `sparkle` is the default; `thinking-orb` is the active state and pulses\n * (still under reduced motion — pair it with words such as an `AiIcon`\n * `agent-working` line); `branded-mark` carries your product's own shape.\n * Never a photo or a human face.\n */\nexport const AiIcons = React.forwardRef<HTMLSpanElement, AiIconsProps>(\n ({ variant = \"sparkle\", size = \"md\", tone = \"solid\", label, glyph, className, ...props }, ref) => {\n const Sparkle = useAiGlyph(\"ai-action\");\n const a11y = label ? { role: \"img\" as const, \"aria-label\": label } : { \"aria-hidden\": true as const };\n const base = \"inline-grid shrink-0 place-items-center font-semibold\";\n\n if (variant === \"thinking-orb\") {\n return (\n <span\n ref={ref}\n data-variant={variant}\n className={cn(\n base,\n \"rounded-full bg-gradient-to-br from-brand to-primary shadow-sm\",\n aiColorClasses.working,\n sizeClasses[size],\n className,\n )}\n {...a11y}\n {...props}\n />\n );\n }\n\n const toneClasses =\n tone === \"solid\"\n ? \"bg-primary text-primary-foreground\"\n : \"border border-border bg-background text-foreground\";\n\n if (variant === \"branded-mark\") {\n const content = glyph ?? (label ? label.charAt(0).toLowerCase() : <Sparkle />);\n return (\n <span\n ref={ref}\n data-variant={variant}\n className={cn(\n base,\n \"rounded-[28%] font-serif italic\",\n tone === \"solid\" ? \"bg-gradient-to-br from-primary to-primary/70 text-primary-foreground\" : toneClasses,\n sizeClasses[size],\n className,\n )}\n {...a11y}\n {...props}\n >\n {content}\n </span>\n );\n }\n\n return (\n <span\n ref={ref}\n data-variant={variant}\n className={cn(base, \"rounded-[22%]\", toneClasses, sizeClasses[size], className)}\n {...a11y}\n {...props}\n >\n <Sparkle />\n </span>\n );\n },\n);\nAiIcons.displayName = \"AiIcons\";\n"]}
@@ -0,0 +1,112 @@
1
+ import * as React from 'react';
2
+
3
+ type AiGlyphProps = React.SVGProps<SVGSVGElement>;
4
+ /**
5
+ * The four-point AI sparkle — the reserved mark for "this runs AI" (generate).
6
+ * The same drawing appears on the agent avatar and the disclosure chip.
7
+ * Decorative (`aria-hidden`) unless given an `aria-label`.
8
+ */
9
+ declare const AiSparkleIcon: React.ForwardRefExoticComponent<Omit<AiGlyphProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
10
+ /**
11
+ * The "generated with AI" mark: a content outline carrying the sparkle. Used
12
+ * only on content AI wrote or changed, never on controls.
13
+ */
14
+ declare const AiGeneratedIcon: React.ForwardRefExoticComponent<Omit<AiGlyphProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
15
+ interface AiWorkingIconProps extends AiGlyphProps {
16
+ /** Hold the mark still (it only turns while work is happening). */
17
+ still?: boolean;
18
+ }
19
+ /**
20
+ * The "agent working" mark: a turning arc. The only AI mark that moves, and
21
+ * only while work is happening; it holds still under reduced motion.
22
+ */
23
+ declare const AiWorkingIcon: React.ForwardRefExoticComponent<Omit<AiWorkingIconProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
24
+ /** The "transform" mark (wand): for AI actions that change something the user already has — rewrite, enhance, restyle. */
25
+ declare const AiWandIcon: React.ForwardRefExoticComponent<Omit<AiGlyphProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
26
+ /** The "regenerate" mark: run the same AI action again. */
27
+ declare const AiRegenerateIcon: React.ForwardRefExoticComponent<Omit<AiGlyphProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
28
+ /** The "tool use" mark: on the lines that say which tool the agent used. */
29
+ declare const AiToolIcon: React.ForwardRefExoticComponent<Omit<AiGlyphProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
30
+ /** The four AI meanings. Each has its own mark, used for that meaning only. */
31
+ type AiIconRole = "ai-action" | "generated-content" | "agent-working" | "tool-use";
32
+ /** Every reserved glyph by name. */
33
+ type AiGlyphName = "sparkle" | "wand" | "regenerate" | "generated" | "working" | "tool";
34
+ /**
35
+ * Approved glyphs per role. The lists do not overlap, so two meanings can
36
+ * never share a mark.
37
+ */
38
+ interface AiIconGlyphs {
39
+ "ai-action"?: "sparkle" | "wand";
40
+ "generated-content"?: "generated";
41
+ "agent-working"?: "working";
42
+ "tool-use"?: "tool";
43
+ }
44
+ /** The reserved glyph components, by name. */
45
+ declare const aiGlyphs: Record<AiGlyphName, React.ComponentType<AiGlyphProps>>;
46
+ /** The default glyph for each role. */
47
+ declare const defaultAiIconGlyphs: Required<AiIconGlyphs>;
48
+ interface AiIconProviderProps {
49
+ /** Product-wide choice of approved glyph per role. Set once; unset roles keep the default. */
50
+ glyphs?: AiIconGlyphs;
51
+ children?: React.ReactNode;
52
+ }
53
+ /**
54
+ * Sets the approved glyph for each AI role once for the whole product.
55
+ * Every `AiIcon`, `AiIcons`, `Iconography` and `Disclosure` under it uses
56
+ * the same choice, so a meaning keeps one mark everywhere.
57
+ */
58
+ declare function AiIconProvider({ glyphs, children }: AiIconProviderProps): React.JSX.Element;
59
+ declare namespace AiIconProvider {
60
+ var displayName: string;
61
+ }
62
+ /** The glyph component the nearest `AiIconProvider` approved for a role. */
63
+ declare function useAiGlyph(role: AiIconRole): React.ComponentType<AiGlyphProps>;
64
+ interface AiIconProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, "role"> {
65
+ /**
66
+ * Which AI meaning this is: `ai-action` (a control runs AI),
67
+ * `generated-content` (AI wrote this), `agent-working` (the agent is
68
+ * working now — announced politely) or `tool-use` (the agent used a tool).
69
+ */
70
+ role: AiIconRole;
71
+ /** The words that travel with the mark ("Rewrite", "Generated with AI", "Rewriting release note…"). Required: a mark is never alone. */
72
+ label: React.ReactNode;
73
+ /** Show the words visibly (default) or keep them for assistive tech only. */
74
+ showLabel?: boolean;
75
+ }
76
+ /**
77
+ * One AI meaning drawn with its reserved mark and its words. The product
78
+ * names the meaning; the component maps it to the approved glyph (see
79
+ * `AiIconProvider`). `agent-working` turns its mark and announces its words
80
+ * in a polite live region; the rest are static. For a control that runs
81
+ * AI, use `Iconography`, which puts the `ai-action` mark on a Button.
82
+ */
83
+ declare const AiIcon: React.ForwardRefExoticComponent<AiIconProps & React.RefAttributes<HTMLSpanElement>>;
84
+ type AiIconsVariant = "sparkle" | "thinking-orb" | "branded-mark";
85
+ type AiIconsSize = "sm" | "md" | "lg";
86
+ type AiIconsTone = "solid" | "outline";
87
+ interface AiIconsProps extends React.HTMLAttributes<HTMLSpanElement> {
88
+ /**
89
+ * `sparkle` (the universal "AI" mark in a tile), `thinking-orb` (an
90
+ * animated orb for active, listening or generating states) or
91
+ * `branded-mark` (your product's own shape or letter).
92
+ */
93
+ variant?: AiIconsVariant;
94
+ /** 24 / 32 / 40 px. */
95
+ size?: AiIconsSize;
96
+ /** `solid` (filled tile) or `outline` (bordered tile). Sparkle and branded mark only. */
97
+ tone?: AiIconsTone;
98
+ /** Accessible name. Omit when words sit beside the mark — it is then decorative. */
99
+ label?: string;
100
+ /** Content of the branded mark (a letter or your SVG). Defaults to the first letter of `label`, else the sparkle. */
101
+ glyph?: React.ReactNode;
102
+ }
103
+ /**
104
+ * The AI presence mark: one stable symbol that tells people the AI is here.
105
+ * `sparkle` is the default; `thinking-orb` is the active state and pulses
106
+ * (still under reduced motion — pair it with words such as an `AiIcon`
107
+ * `agent-working` line); `branded-mark` carries your product's own shape.
108
+ * Never a photo or a human face.
109
+ */
110
+ declare const AiIcons: React.ForwardRefExoticComponent<AiIconsProps & React.RefAttributes<HTMLSpanElement>>;
111
+
112
+ export { AiGeneratedIcon, type AiGlyphName, type AiGlyphProps, AiIcon, type AiIconGlyphs, type AiIconProps, AiIconProvider, type AiIconProviderProps, type AiIconRole, AiIcons, type AiIconsProps, type AiIconsSize, type AiIconsTone, type AiIconsVariant, AiRegenerateIcon, AiSparkleIcon, AiToolIcon, AiWandIcon, AiWorkingIcon, type AiWorkingIconProps, aiGlyphs, defaultAiIconGlyphs, useAiGlyph };
@@ -0,0 +1,112 @@
1
+ import * as React from 'react';
2
+
3
+ type AiGlyphProps = React.SVGProps<SVGSVGElement>;
4
+ /**
5
+ * The four-point AI sparkle — the reserved mark for "this runs AI" (generate).
6
+ * The same drawing appears on the agent avatar and the disclosure chip.
7
+ * Decorative (`aria-hidden`) unless given an `aria-label`.
8
+ */
9
+ declare const AiSparkleIcon: React.ForwardRefExoticComponent<Omit<AiGlyphProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
10
+ /**
11
+ * The "generated with AI" mark: a content outline carrying the sparkle. Used
12
+ * only on content AI wrote or changed, never on controls.
13
+ */
14
+ declare const AiGeneratedIcon: React.ForwardRefExoticComponent<Omit<AiGlyphProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
15
+ interface AiWorkingIconProps extends AiGlyphProps {
16
+ /** Hold the mark still (it only turns while work is happening). */
17
+ still?: boolean;
18
+ }
19
+ /**
20
+ * The "agent working" mark: a turning arc. The only AI mark that moves, and
21
+ * only while work is happening; it holds still under reduced motion.
22
+ */
23
+ declare const AiWorkingIcon: React.ForwardRefExoticComponent<Omit<AiWorkingIconProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
24
+ /** The "transform" mark (wand): for AI actions that change something the user already has — rewrite, enhance, restyle. */
25
+ declare const AiWandIcon: React.ForwardRefExoticComponent<Omit<AiGlyphProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
26
+ /** The "regenerate" mark: run the same AI action again. */
27
+ declare const AiRegenerateIcon: React.ForwardRefExoticComponent<Omit<AiGlyphProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
28
+ /** The "tool use" mark: on the lines that say which tool the agent used. */
29
+ declare const AiToolIcon: React.ForwardRefExoticComponent<Omit<AiGlyphProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
30
+ /** The four AI meanings. Each has its own mark, used for that meaning only. */
31
+ type AiIconRole = "ai-action" | "generated-content" | "agent-working" | "tool-use";
32
+ /** Every reserved glyph by name. */
33
+ type AiGlyphName = "sparkle" | "wand" | "regenerate" | "generated" | "working" | "tool";
34
+ /**
35
+ * Approved glyphs per role. The lists do not overlap, so two meanings can
36
+ * never share a mark.
37
+ */
38
+ interface AiIconGlyphs {
39
+ "ai-action"?: "sparkle" | "wand";
40
+ "generated-content"?: "generated";
41
+ "agent-working"?: "working";
42
+ "tool-use"?: "tool";
43
+ }
44
+ /** The reserved glyph components, by name. */
45
+ declare const aiGlyphs: Record<AiGlyphName, React.ComponentType<AiGlyphProps>>;
46
+ /** The default glyph for each role. */
47
+ declare const defaultAiIconGlyphs: Required<AiIconGlyphs>;
48
+ interface AiIconProviderProps {
49
+ /** Product-wide choice of approved glyph per role. Set once; unset roles keep the default. */
50
+ glyphs?: AiIconGlyphs;
51
+ children?: React.ReactNode;
52
+ }
53
+ /**
54
+ * Sets the approved glyph for each AI role once for the whole product.
55
+ * Every `AiIcon`, `AiIcons`, `Iconography` and `Disclosure` under it uses
56
+ * the same choice, so a meaning keeps one mark everywhere.
57
+ */
58
+ declare function AiIconProvider({ glyphs, children }: AiIconProviderProps): React.JSX.Element;
59
+ declare namespace AiIconProvider {
60
+ var displayName: string;
61
+ }
62
+ /** The glyph component the nearest `AiIconProvider` approved for a role. */
63
+ declare function useAiGlyph(role: AiIconRole): React.ComponentType<AiGlyphProps>;
64
+ interface AiIconProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, "role"> {
65
+ /**
66
+ * Which AI meaning this is: `ai-action` (a control runs AI),
67
+ * `generated-content` (AI wrote this), `agent-working` (the agent is
68
+ * working now — announced politely) or `tool-use` (the agent used a tool).
69
+ */
70
+ role: AiIconRole;
71
+ /** The words that travel with the mark ("Rewrite", "Generated with AI", "Rewriting release note…"). Required: a mark is never alone. */
72
+ label: React.ReactNode;
73
+ /** Show the words visibly (default) or keep them for assistive tech only. */
74
+ showLabel?: boolean;
75
+ }
76
+ /**
77
+ * One AI meaning drawn with its reserved mark and its words. The product
78
+ * names the meaning; the component maps it to the approved glyph (see
79
+ * `AiIconProvider`). `agent-working` turns its mark and announces its words
80
+ * in a polite live region; the rest are static. For a control that runs
81
+ * AI, use `Iconography`, which puts the `ai-action` mark on a Button.
82
+ */
83
+ declare const AiIcon: React.ForwardRefExoticComponent<AiIconProps & React.RefAttributes<HTMLSpanElement>>;
84
+ type AiIconsVariant = "sparkle" | "thinking-orb" | "branded-mark";
85
+ type AiIconsSize = "sm" | "md" | "lg";
86
+ type AiIconsTone = "solid" | "outline";
87
+ interface AiIconsProps extends React.HTMLAttributes<HTMLSpanElement> {
88
+ /**
89
+ * `sparkle` (the universal "AI" mark in a tile), `thinking-orb` (an
90
+ * animated orb for active, listening or generating states) or
91
+ * `branded-mark` (your product's own shape or letter).
92
+ */
93
+ variant?: AiIconsVariant;
94
+ /** 24 / 32 / 40 px. */
95
+ size?: AiIconsSize;
96
+ /** `solid` (filled tile) or `outline` (bordered tile). Sparkle and branded mark only. */
97
+ tone?: AiIconsTone;
98
+ /** Accessible name. Omit when words sit beside the mark — it is then decorative. */
99
+ label?: string;
100
+ /** Content of the branded mark (a letter or your SVG). Defaults to the first letter of `label`, else the sparkle. */
101
+ glyph?: React.ReactNode;
102
+ }
103
+ /**
104
+ * The AI presence mark: one stable symbol that tells people the AI is here.
105
+ * `sparkle` is the default; `thinking-orb` is the active state and pulses
106
+ * (still under reduced motion — pair it with words such as an `AiIcon`
107
+ * `agent-working` line); `branded-mark` carries your product's own shape.
108
+ * Never a photo or a human face.
109
+ */
110
+ declare const AiIcons: React.ForwardRefExoticComponent<AiIconsProps & React.RefAttributes<HTMLSpanElement>>;
111
+
112
+ export { AiGeneratedIcon, type AiGlyphName, type AiGlyphProps, AiIcon, type AiIconGlyphs, type AiIconProps, AiIconProvider, type AiIconProviderProps, type AiIconRole, AiIcons, type AiIconsProps, type AiIconsSize, type AiIconsTone, type AiIconsVariant, AiRegenerateIcon, AiSparkleIcon, AiToolIcon, AiWandIcon, AiWorkingIcon, type AiWorkingIconProps, aiGlyphs, defaultAiIconGlyphs, useAiGlyph };
package/dist/index.js ADDED
@@ -0,0 +1,228 @@
1
+ "use client";
2
+ import * as React from 'react';
3
+ import { Wrench, RefreshCw, WandSparkles } from 'lucide-react';
4
+ import { cn } from '@nucleux/utils';
5
+ import { aiColorClasses } from '@nucleux/color';
6
+ import { jsx, jsxs } from 'react/jsx-runtime';
7
+
8
+ // src/index.tsx
9
+ function glyphA11y(props) {
10
+ const named = props["aria-label"] != null || props["aria-labelledby"] != null;
11
+ return named ? { role: "img" } : { "aria-hidden": true };
12
+ }
13
+ var AiSparkleIcon = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
14
+ "svg",
15
+ {
16
+ ref,
17
+ viewBox: "0 0 24 24",
18
+ width: 16,
19
+ height: 16,
20
+ fill: "currentColor",
21
+ focusable: "false",
22
+ "data-ai-glyph": "sparkle",
23
+ className: cn("size-4 shrink-0", className),
24
+ ...glyphA11y(props),
25
+ ...props,
26
+ children: /* @__PURE__ */ jsx("path", { d: "M12 3c.6 4.8 3.2 7.4 9 9-5.8 1.6-8.4 4.2-9 9-.6-4.8-3.2-7.4-9-9 5.8-1.6 8.4-4.2 9-9z" })
27
+ }
28
+ ));
29
+ AiSparkleIcon.displayName = "AiSparkleIcon";
30
+ var AiGeneratedIcon = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxs(
31
+ "svg",
32
+ {
33
+ ref,
34
+ viewBox: "0 0 24 24",
35
+ width: 16,
36
+ height: 16,
37
+ fill: "none",
38
+ stroke: "currentColor",
39
+ strokeWidth: 1.8,
40
+ strokeLinejoin: "round",
41
+ focusable: "false",
42
+ "data-ai-glyph": "generated",
43
+ className: cn("size-4 shrink-0", className),
44
+ ...glyphA11y(props),
45
+ ...props,
46
+ children: [
47
+ /* @__PURE__ */ jsx("path", { d: "M5 4h14a1 1 0 0 1 1 1v11a1 1 0 0 1-1 1h-7l-4 3v-3H5a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1z" }),
48
+ /* @__PURE__ */ jsx(
49
+ "path",
50
+ {
51
+ d: "M12 6.5c.3 2.2 1.3 3.2 3.5 3.5-2.2.3-3.2 1.3-3.5 3.5-.3-2.2-1.3-3.2-3.5-3.5 2.2-.3 3.2-1.3 3.5-3.5z",
52
+ fill: "currentColor",
53
+ stroke: "none"
54
+ }
55
+ )
56
+ ]
57
+ }
58
+ ));
59
+ AiGeneratedIcon.displayName = "AiGeneratedIcon";
60
+ var AiWorkingIcon = React.forwardRef(
61
+ ({ still = false, className, ...props }, ref) => /* @__PURE__ */ jsxs(
62
+ "svg",
63
+ {
64
+ ref,
65
+ viewBox: "0 0 24 24",
66
+ width: 16,
67
+ height: 16,
68
+ fill: "none",
69
+ stroke: "currentColor",
70
+ strokeWidth: 2.2,
71
+ strokeLinecap: "round",
72
+ focusable: "false",
73
+ "data-ai-glyph": "working",
74
+ className: cn("size-4 shrink-0", !still && "animate-spin motion-reduce:animate-none", className),
75
+ ...glyphA11y(props),
76
+ ...props,
77
+ children: [
78
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "8.5", opacity: 0.25 }),
79
+ /* @__PURE__ */ jsx("path", { d: "M12 3.5a8.5 8.5 0 0 1 8.5 8.5" })
80
+ ]
81
+ }
82
+ )
83
+ );
84
+ AiWorkingIcon.displayName = "AiWorkingIcon";
85
+ function lucideGlyph(Icon, name, displayName) {
86
+ const Glyph = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
87
+ Icon,
88
+ {
89
+ ref,
90
+ focusable: "false",
91
+ "data-ai-glyph": name,
92
+ className: cn("size-4 shrink-0", className),
93
+ ...glyphA11y(props),
94
+ ...props
95
+ }
96
+ ));
97
+ Glyph.displayName = displayName;
98
+ return Glyph;
99
+ }
100
+ var AiWandIcon = lucideGlyph(
101
+ WandSparkles,
102
+ "wand",
103
+ "AiWandIcon"
104
+ );
105
+ var AiRegenerateIcon = lucideGlyph(
106
+ RefreshCw,
107
+ "regenerate",
108
+ "AiRegenerateIcon"
109
+ );
110
+ var AiToolIcon = lucideGlyph(Wrench, "tool", "AiToolIcon");
111
+ var aiGlyphs = {
112
+ sparkle: AiSparkleIcon,
113
+ wand: AiWandIcon,
114
+ regenerate: AiRegenerateIcon,
115
+ generated: AiGeneratedIcon,
116
+ working: AiWorkingIcon,
117
+ tool: AiToolIcon
118
+ };
119
+ var defaultAiIconGlyphs = {
120
+ "ai-action": "sparkle",
121
+ "generated-content": "generated",
122
+ "agent-working": "working",
123
+ "tool-use": "tool"
124
+ };
125
+ var AiIconContext = React.createContext(defaultAiIconGlyphs);
126
+ function AiIconProvider({ glyphs, children }) {
127
+ const value = React.useMemo(() => ({ ...defaultAiIconGlyphs, ...glyphs }), [glyphs]);
128
+ return /* @__PURE__ */ jsx(AiIconContext.Provider, { value, children });
129
+ }
130
+ AiIconProvider.displayName = "AiIconProvider";
131
+ function useAiGlyph(role) {
132
+ const glyphs = React.useContext(AiIconContext);
133
+ return aiGlyphs[glyphs[role]];
134
+ }
135
+ var roleClasses = {
136
+ "ai-action": "text-foreground [&>svg]:text-brand",
137
+ "agent-working": "text-foreground [&>svg]:text-brand",
138
+ "tool-use": "text-muted-foreground",
139
+ "generated-content": "rounded-full border border-brand/30 bg-background px-2 py-0.5 text-xs font-medium text-foreground [&>svg]:size-3.5 [&>svg]:text-brand"
140
+ };
141
+ var AiIcon = React.forwardRef(
142
+ ({ role, label, showLabel = true, className, ...props }, ref) => {
143
+ const Glyph = useAiGlyph(role);
144
+ return /* @__PURE__ */ jsxs(
145
+ "span",
146
+ {
147
+ ref,
148
+ "data-ai-role": role,
149
+ role: role === "agent-working" ? "status" : void 0,
150
+ "aria-live": role === "agent-working" ? "polite" : void 0,
151
+ className: cn("inline-flex items-center gap-1.5 text-sm", roleClasses[role], className),
152
+ ...props,
153
+ children: [
154
+ /* @__PURE__ */ jsx(Glyph, {}),
155
+ /* @__PURE__ */ jsx("span", { className: showLabel ? void 0 : "sr-only", children: label })
156
+ ]
157
+ }
158
+ );
159
+ }
160
+ );
161
+ AiIcon.displayName = "AiIcon";
162
+ var sizeClasses = {
163
+ sm: "size-6 text-xs [&>svg]:size-3.5",
164
+ md: "size-8 text-sm [&>svg]:size-4",
165
+ lg: "size-10 text-lg [&>svg]:size-5"
166
+ };
167
+ var AiIcons = React.forwardRef(
168
+ ({ variant = "sparkle", size = "md", tone = "solid", label, glyph, className, ...props }, ref) => {
169
+ const Sparkle = useAiGlyph("ai-action");
170
+ const a11y = label ? { role: "img", "aria-label": label } : { "aria-hidden": true };
171
+ const base = "inline-grid shrink-0 place-items-center font-semibold";
172
+ if (variant === "thinking-orb") {
173
+ return /* @__PURE__ */ jsx(
174
+ "span",
175
+ {
176
+ ref,
177
+ "data-variant": variant,
178
+ className: cn(
179
+ base,
180
+ "rounded-full bg-gradient-to-br from-brand to-primary shadow-sm",
181
+ aiColorClasses.working,
182
+ sizeClasses[size],
183
+ className
184
+ ),
185
+ ...a11y,
186
+ ...props
187
+ }
188
+ );
189
+ }
190
+ const toneClasses = tone === "solid" ? "bg-primary text-primary-foreground" : "border border-border bg-background text-foreground";
191
+ if (variant === "branded-mark") {
192
+ const content = glyph ?? (label ? label.charAt(0).toLowerCase() : /* @__PURE__ */ jsx(Sparkle, {}));
193
+ return /* @__PURE__ */ jsx(
194
+ "span",
195
+ {
196
+ ref,
197
+ "data-variant": variant,
198
+ className: cn(
199
+ base,
200
+ "rounded-[28%] font-serif italic",
201
+ tone === "solid" ? "bg-gradient-to-br from-primary to-primary/70 text-primary-foreground" : toneClasses,
202
+ sizeClasses[size],
203
+ className
204
+ ),
205
+ ...a11y,
206
+ ...props,
207
+ children: content
208
+ }
209
+ );
210
+ }
211
+ return /* @__PURE__ */ jsx(
212
+ "span",
213
+ {
214
+ ref,
215
+ "data-variant": variant,
216
+ className: cn(base, "rounded-[22%]", toneClasses, sizeClasses[size], className),
217
+ ...a11y,
218
+ ...props,
219
+ children: /* @__PURE__ */ jsx(Sparkle, {})
220
+ }
221
+ );
222
+ }
223
+ );
224
+ AiIcons.displayName = "AiIcons";
225
+
226
+ export { AiGeneratedIcon, AiIcon, AiIconProvider, AiIcons, AiRegenerateIcon, AiSparkleIcon, AiToolIcon, AiWandIcon, AiWorkingIcon, aiGlyphs, defaultAiIconGlyphs, useAiGlyph };
227
+ //# sourceMappingURL=index.js.map
228
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.tsx"],"names":[],"mappings":";;;;;;;AAYA,SAAS,UAAU,KAAA,EAAqB;AACtC,EAAA,MAAM,QAAQ,KAAA,CAAM,YAAY,KAAK,IAAA,IAAQ,KAAA,CAAM,iBAAiB,CAAA,IAAK,IAAA;AACzE,EAAA,OAAO,QAAQ,EAAE,IAAA,EAAM,OAAe,GAAI,EAAE,eAAe,IAAA,EAAc;AAC3E;AAOO,IAAM,aAAA,GAAsB,iBAAwC,CAAC,EAAE,WAAW,GAAG,KAAA,IAAS,GAAA,qBACnG,GAAA;AAAA,EAAC,KAAA;AAAA,EAAA;AAAA,IACC,GAAA;AAAA,IACA,OAAA,EAAQ,WAAA;AAAA,IACR,KAAA,EAAO,EAAA;AAAA,IACP,MAAA,EAAQ,EAAA;AAAA,IACR,IAAA,EAAK,cAAA;AAAA,IACL,SAAA,EAAU,OAAA;AAAA,IACV,eAAA,EAAc,SAAA;AAAA,IACd,SAAA,EAAW,EAAA,CAAG,iBAAA,EAAmB,SAAS,CAAA;AAAA,IACzC,GAAG,UAAU,KAAK,CAAA;AAAA,IAClB,GAAG,KAAA;AAAA,IAEJ,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,sFAAA,EAAuF;AAAA;AACjG,CACD;AACD,aAAA,CAAc,WAAA,GAAc,eAAA;AAMrB,IAAM,eAAA,GAAwB,iBAAwC,CAAC,EAAE,WAAW,GAAG,KAAA,IAAS,GAAA,qBACrG,IAAA;AAAA,EAAC,KAAA;AAAA,EAAA;AAAA,IACC,GAAA;AAAA,IACA,OAAA,EAAQ,WAAA;AAAA,IACR,KAAA,EAAO,EAAA;AAAA,IACP,MAAA,EAAQ,EAAA;AAAA,IACR,IAAA,EAAK,MAAA;AAAA,IACL,MAAA,EAAO,cAAA;AAAA,IACP,WAAA,EAAa,GAAA;AAAA,IACb,cAAA,EAAe,OAAA;AAAA,IACf,SAAA,EAAU,OAAA;AAAA,IACV,eAAA,EAAc,WAAA;AAAA,IACd,SAAA,EAAW,EAAA,CAAG,iBAAA,EAAmB,SAAS,CAAA;AAAA,IACzC,GAAG,UAAU,KAAK,CAAA;AAAA,IAClB,GAAG,KAAA;AAAA,IAEJ,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,GAAE,oFAAA,EAAqF,CAAA;AAAA,sBAC7F,GAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,CAAA,EAAE,qGAAA;AAAA,UACF,IAAA,EAAK,cAAA;AAAA,UACL,MAAA,EAAO;AAAA;AAAA;AACT;AAAA;AACF,CACD;AACD,eAAA,CAAgB,WAAA,GAAc,iBAAA;AAWvB,IAAM,aAAA,GAAsB,KAAA,CAAA,UAAA;AAAA,EACjC,CAAC,EAAE,KAAA,GAAQ,KAAA,EAAO,WAAW,GAAG,KAAA,IAAS,GAAA,qBACvC,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,GAAA;AAAA,MACA,OAAA,EAAQ,WAAA;AAAA,MACR,KAAA,EAAO,EAAA;AAAA,MACP,MAAA,EAAQ,EAAA;AAAA,MACR,IAAA,EAAK,MAAA;AAAA,MACL,MAAA,EAAO,cAAA;AAAA,MACP,WAAA,EAAa,GAAA;AAAA,MACb,aAAA,EAAc,OAAA;AAAA,MACd,SAAA,EAAU,OAAA;AAAA,MACV,eAAA,EAAc,SAAA;AAAA,MACd,WAAW,EAAA,CAAG,iBAAA,EAAmB,CAAC,KAAA,IAAS,2CAA2C,SAAS,CAAA;AAAA,MAC9F,GAAG,UAAU,KAAK,CAAA;AAAA,MAClB,GAAG,KAAA;AAAA,MAEJ,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,QAAA,EAAA,EAAO,IAAG,IAAA,EAAK,EAAA,EAAG,MAAK,CAAA,EAAE,KAAA,EAAM,SAAS,IAAA,EAAM,CAAA;AAAA,wBAC/C,GAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,+BAAA,EAAgC;AAAA;AAAA;AAAA;AAG9C;AACA,aAAA,CAAc,WAAA,GAAc,eAAA;AAE5B,SAAS,WAAA,CAAY,IAAA,EAAyC,IAAA,EAAc,WAAA,EAAqB;AAC/F,EAAA,MAAM,KAAA,GAAc,iBAAwC,CAAC,EAAE,WAAW,GAAG,KAAA,IAAS,GAAA,qBACpF,GAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,GAAA;AAAA,MACA,SAAA,EAAU,OAAA;AAAA,MACV,eAAA,EAAe,IAAA;AAAA,MACf,SAAA,EAAW,EAAA,CAAG,iBAAA,EAAmB,SAAS,CAAA;AAAA,MACzC,GAAG,UAAU,KAAK,CAAA;AAAA,MAClB,GAAG;AAAA;AAAA,GAEP,CAAA;AACD,EAAA,KAAA,CAAM,WAAA,GAAc,WAAA;AACpB,EAAA,OAAO,KAAA;AACT;AAGO,IAAM,UAAA,GAAa,WAAA;AAAA,EACxB,YAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF;AAEO,IAAM,gBAAA,GAAmB,WAAA;AAAA,EAC9B,SAAA;AAAA,EACA,YAAA;AAAA,EACA;AACF;AAEO,IAAM,UAAA,GAAa,WAAA,CAAY,MAAA,EAAwD,MAAA,EAAQ,YAAY;AAwB3G,IAAM,QAAA,GAAmE;AAAA,EAC9E,OAAA,EAAS,aAAA;AAAA,EACT,IAAA,EAAM,UAAA;AAAA,EACN,UAAA,EAAY,gBAAA;AAAA,EACZ,SAAA,EAAW,eAAA;AAAA,EACX,OAAA,EAAS,aAAA;AAAA,EACT,IAAA,EAAM;AACR;AAGO,IAAM,mBAAA,GAA8C;AAAA,EACzD,WAAA,EAAa,SAAA;AAAA,EACb,mBAAA,EAAqB,WAAA;AAAA,EACrB,eAAA,EAAiB,SAAA;AAAA,EACjB,UAAA,EAAY;AACd;AAEA,IAAM,aAAA,GAAsB,oBAAsC,mBAAmB,CAAA;AAa9E,SAAS,cAAA,CAAe,EAAE,MAAA,EAAQ,QAAA,EAAS,EAAwB;AACxE,EAAA,MAAM,KAAA,GAAc,KAAA,CAAA,OAAA,CAAQ,OAAO,EAAE,GAAG,mBAAA,EAAqB,GAAG,MAAA,EAAO,CAAA,EAAI,CAAC,MAAM,CAAC,CAAA;AACnF,EAAA,uBAAO,GAAA,CAAC,aAAA,CAAc,QAAA,EAAd,EAAuB,OAAe,QAAA,EAAS,CAAA;AACzD;AACA,cAAA,CAAe,WAAA,GAAc,gBAAA;AAGtB,SAAS,WAAW,IAAA,EAAqD;AAC9E,EAAA,MAAM,MAAA,GAAe,iBAAW,aAAa,CAAA;AAC7C,EAAA,OAAO,QAAA,CAAS,MAAA,CAAO,IAAI,CAAC,CAAA;AAC9B;AAmBA,IAAM,WAAA,GAA0C;AAAA,EAC9C,WAAA,EAAa,oCAAA;AAAA,EACb,eAAA,EAAiB,oCAAA;AAAA,EACjB,UAAA,EAAY,uBAAA;AAAA,EACZ,mBAAA,EACE;AACJ,CAAA;AASO,IAAM,MAAA,GAAe,KAAA,CAAA,UAAA;AAAA,EAC1B,CAAC,EAAE,IAAA,EAAM,KAAA,EAAO,SAAA,GAAY,MAAM,SAAA,EAAW,GAAG,KAAA,EAAM,EAAG,GAAA,KAAQ;AAC/D,IAAA,MAAM,KAAA,GAAQ,WAAW,IAAI,CAAA;AAC7B,IAAA,uBACE,IAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,cAAA,EAAc,IAAA;AAAA,QACd,IAAA,EAAM,IAAA,KAAS,eAAA,GAAkB,QAAA,GAAW,MAAA;AAAA,QAC5C,WAAA,EAAW,IAAA,KAAS,eAAA,GAAkB,QAAA,GAAW,MAAA;AAAA,QACjD,WAAW,EAAA,CAAG,0CAAA,EAA4C,WAAA,CAAY,IAAI,GAAG,SAAS,CAAA;AAAA,QACrF,GAAG,KAAA;AAAA,QAEJ,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,KAAA,EAAA,EAAM,CAAA;AAAA,8BACN,MAAA,EAAA,EAAK,SAAA,EAAW,SAAA,GAAY,MAAA,GAAY,WAAY,QAAA,EAAA,KAAA,EAAM;AAAA;AAAA;AAAA,KAC7D;AAAA,EAEJ;AACF;AACA,MAAA,CAAO,WAAA,GAAc,QAAA;AAUrB,IAAM,WAAA,GAA2C;AAAA,EAC/C,EAAA,EAAI,iCAAA;AAAA,EACJ,EAAA,EAAI,+BAAA;AAAA,EACJ,EAAA,EAAI;AACN,CAAA;AA0BO,IAAM,OAAA,GAAgB,KAAA,CAAA,UAAA;AAAA,EAC3B,CAAC,EAAE,OAAA,GAAU,SAAA,EAAW,OAAO,IAAA,EAAM,IAAA,GAAO,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,SAAA,EAAW,GAAG,KAAA,IAAS,GAAA,KAAQ;AAChG,IAAA,MAAM,OAAA,GAAU,WAAW,WAAW,CAAA;AACtC,IAAA,MAAM,IAAA,GAAO,KAAA,GAAQ,EAAE,IAAA,EAAM,KAAA,EAAgB,cAAc,KAAA,EAAM,GAAI,EAAE,aAAA,EAAe,IAAA,EAAc;AACpG,IAAA,MAAM,IAAA,GAAO,uDAAA;AAEb,IAAA,IAAI,YAAY,cAAA,EAAgB;AAC9B,MAAA,uBACE,GAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,GAAA;AAAA,UACA,cAAA,EAAc,OAAA;AAAA,UACd,SAAA,EAAW,EAAA;AAAA,YACT,IAAA;AAAA,YACA,gEAAA;AAAA,YACA,cAAA,CAAe,OAAA;AAAA,YACf,YAAY,IAAI,CAAA;AAAA,YAChB;AAAA,WACF;AAAA,UACC,GAAG,IAAA;AAAA,UACH,GAAG;AAAA;AAAA,OACN;AAAA,IAEJ;AAEA,IAAA,MAAM,WAAA,GACJ,IAAA,KAAS,OAAA,GACL,oCAAA,GACA,oDAAA;AAEN,IAAA,IAAI,YAAY,cAAA,EAAgB;AAC9B,MAAA,MAAM,OAAA,GAAU,KAAA,KAAU,KAAA,GAAQ,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,CAAE,WAAA,EAAY,mBAAI,GAAA,CAAC,OAAA,EAAA,EAAQ,CAAA,CAAA;AAC3E,MAAA,uBACE,GAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,GAAA;AAAA,UACA,cAAA,EAAc,OAAA;AAAA,UACd,SAAA,EAAW,EAAA;AAAA,YACT,IAAA;AAAA,YACA,iCAAA;AAAA,YACA,IAAA,KAAS,UAAU,sEAAA,GAAyE,WAAA;AAAA,YAC5F,YAAY,IAAI,CAAA;AAAA,YAChB;AAAA,WACF;AAAA,UACC,GAAG,IAAA;AAAA,UACH,GAAG,KAAA;AAAA,UAEH,QAAA,EAAA;AAAA;AAAA,OACH;AAAA,IAEJ;AAEA,IAAA,uBACE,GAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,cAAA,EAAc,OAAA;AAAA,QACd,SAAA,EAAW,GAAG,IAAA,EAAM,eAAA,EAAiB,aAAa,WAAA,CAAY,IAAI,GAAG,SAAS,CAAA;AAAA,QAC7E,GAAG,IAAA;AAAA,QACH,GAAG,KAAA;AAAA,QAEJ,8BAAC,OAAA,EAAA,EAAQ;AAAA;AAAA,KACX;AAAA,EAEJ;AACF;AACA,OAAA,CAAQ,WAAA,GAAc,SAAA","file":"index.js","sourcesContent":["import * as React from \"react\";\nimport { RefreshCw, WandSparkles, Wrench } from \"lucide-react\";\nimport { cn } from \"@nucleux/utils\";\nimport { aiColorClasses } from \"@nucleux/color\";\n\n/* -------------------------------------------------------------------------- */\n/* Glyphs */\n/* -------------------------------------------------------------------------- */\n\nexport type AiGlyphProps = React.SVGProps<SVGSVGElement>;\n\n/** Decorative unless the caller names it. */\nfunction glyphA11y(props: AiGlyphProps) {\n const named = props[\"aria-label\"] != null || props[\"aria-labelledby\"] != null;\n return named ? { role: \"img\" as const } : { \"aria-hidden\": true as const };\n}\n\n/**\n * The four-point AI sparkle — the reserved mark for \"this runs AI\" (generate).\n * The same drawing appears on the agent avatar and the disclosure chip.\n * Decorative (`aria-hidden`) unless given an `aria-label`.\n */\nexport const AiSparkleIcon = React.forwardRef<SVGSVGElement, AiGlyphProps>(({ className, ...props }, ref) => (\n <svg\n ref={ref}\n viewBox=\"0 0 24 24\"\n width={16}\n height={16}\n fill=\"currentColor\"\n focusable=\"false\"\n data-ai-glyph=\"sparkle\"\n className={cn(\"size-4 shrink-0\", className)}\n {...glyphA11y(props)}\n {...props}\n >\n <path d=\"M12 3c.6 4.8 3.2 7.4 9 9-5.8 1.6-8.4 4.2-9 9-.6-4.8-3.2-7.4-9-9 5.8-1.6 8.4-4.2 9-9z\" />\n </svg>\n));\nAiSparkleIcon.displayName = \"AiSparkleIcon\";\n\n/**\n * The \"generated with AI\" mark: a content outline carrying the sparkle. Used\n * only on content AI wrote or changed, never on controls.\n */\nexport const AiGeneratedIcon = React.forwardRef<SVGSVGElement, AiGlyphProps>(({ className, ...props }, ref) => (\n <svg\n ref={ref}\n viewBox=\"0 0 24 24\"\n width={16}\n height={16}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={1.8}\n strokeLinejoin=\"round\"\n focusable=\"false\"\n data-ai-glyph=\"generated\"\n className={cn(\"size-4 shrink-0\", className)}\n {...glyphA11y(props)}\n {...props}\n >\n <path d=\"M5 4h14a1 1 0 0 1 1 1v11a1 1 0 0 1-1 1h-7l-4 3v-3H5a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1z\" />\n <path\n d=\"M12 6.5c.3 2.2 1.3 3.2 3.5 3.5-2.2.3-3.2 1.3-3.5 3.5-.3-2.2-1.3-3.2-3.5-3.5 2.2-.3 3.2-1.3 3.5-3.5z\"\n fill=\"currentColor\"\n stroke=\"none\"\n />\n </svg>\n));\nAiGeneratedIcon.displayName = \"AiGeneratedIcon\";\n\nexport interface AiWorkingIconProps extends AiGlyphProps {\n /** Hold the mark still (it only turns while work is happening). */\n still?: boolean;\n}\n\n/**\n * The \"agent working\" mark: a turning arc. The only AI mark that moves, and\n * only while work is happening; it holds still under reduced motion.\n */\nexport const AiWorkingIcon = React.forwardRef<SVGSVGElement, AiWorkingIconProps>(\n ({ still = false, className, ...props }, ref) => (\n <svg\n ref={ref}\n viewBox=\"0 0 24 24\"\n width={16}\n height={16}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2.2}\n strokeLinecap=\"round\"\n focusable=\"false\"\n data-ai-glyph=\"working\"\n className={cn(\"size-4 shrink-0\", !still && \"animate-spin motion-reduce:animate-none\", className)}\n {...glyphA11y(props)}\n {...props}\n >\n <circle cx=\"12\" cy=\"12\" r=\"8.5\" opacity={0.25} />\n <path d=\"M12 3.5a8.5 8.5 0 0 1 8.5 8.5\" />\n </svg>\n ),\n);\nAiWorkingIcon.displayName = \"AiWorkingIcon\";\n\nfunction lucideGlyph(Icon: React.ComponentType<AiGlyphProps>, name: string, displayName: string) {\n const Glyph = React.forwardRef<SVGSVGElement, AiGlyphProps>(({ className, ...props }, ref) => (\n <Icon\n ref={ref}\n focusable=\"false\"\n data-ai-glyph={name}\n className={cn(\"size-4 shrink-0\", className)}\n {...glyphA11y(props)}\n {...props}\n />\n ));\n Glyph.displayName = displayName;\n return Glyph;\n}\n\n/** The \"transform\" mark (wand): for AI actions that change something the user already has — rewrite, enhance, restyle. */\nexport const AiWandIcon = lucideGlyph(\n WandSparkles as unknown as React.ComponentType<AiGlyphProps>,\n \"wand\",\n \"AiWandIcon\",\n);\n/** The \"regenerate\" mark: run the same AI action again. */\nexport const AiRegenerateIcon = lucideGlyph(\n RefreshCw as unknown as React.ComponentType<AiGlyphProps>,\n \"regenerate\",\n \"AiRegenerateIcon\",\n);\n/** The \"tool use\" mark: on the lines that say which tool the agent used. */\nexport const AiToolIcon = lucideGlyph(Wrench as unknown as React.ComponentType<AiGlyphProps>, \"tool\", \"AiToolIcon\");\n\n/* -------------------------------------------------------------------------- */\n/* Roles and the approved glyph lists */\n/* -------------------------------------------------------------------------- */\n\n/** The four AI meanings. Each has its own mark, used for that meaning only. */\nexport type AiIconRole = \"ai-action\" | \"generated-content\" | \"agent-working\" | \"tool-use\";\n\n/** Every reserved glyph by name. */\nexport type AiGlyphName = \"sparkle\" | \"wand\" | \"regenerate\" | \"generated\" | \"working\" | \"tool\";\n\n/**\n * Approved glyphs per role. The lists do not overlap, so two meanings can\n * never share a mark.\n */\nexport interface AiIconGlyphs {\n \"ai-action\"?: \"sparkle\" | \"wand\";\n \"generated-content\"?: \"generated\";\n \"agent-working\"?: \"working\";\n \"tool-use\"?: \"tool\";\n}\n\n/** The reserved glyph components, by name. */\nexport const aiGlyphs: Record<AiGlyphName, React.ComponentType<AiGlyphProps>> = {\n sparkle: AiSparkleIcon,\n wand: AiWandIcon,\n regenerate: AiRegenerateIcon,\n generated: AiGeneratedIcon,\n working: AiWorkingIcon,\n tool: AiToolIcon,\n};\n\n/** The default glyph for each role. */\nexport const defaultAiIconGlyphs: Required<AiIconGlyphs> = {\n \"ai-action\": \"sparkle\",\n \"generated-content\": \"generated\",\n \"agent-working\": \"working\",\n \"tool-use\": \"tool\",\n};\n\nconst AiIconContext = React.createContext<Required<AiIconGlyphs>>(defaultAiIconGlyphs);\n\nexport interface AiIconProviderProps {\n /** Product-wide choice of approved glyph per role. Set once; unset roles keep the default. */\n glyphs?: AiIconGlyphs;\n children?: React.ReactNode;\n}\n\n/**\n * Sets the approved glyph for each AI role once for the whole product.\n * Every `AiIcon`, `AiIcons`, `Iconography` and `Disclosure` under it uses\n * the same choice, so a meaning keeps one mark everywhere.\n */\nexport function AiIconProvider({ glyphs, children }: AiIconProviderProps) {\n const value = React.useMemo(() => ({ ...defaultAiIconGlyphs, ...glyphs }), [glyphs]);\n return <AiIconContext.Provider value={value}>{children}</AiIconContext.Provider>;\n}\nAiIconProvider.displayName = \"AiIconProvider\";\n\n/** The glyph component the nearest `AiIconProvider` approved for a role. */\nexport function useAiGlyph(role: AiIconRole): React.ComponentType<AiGlyphProps> {\n const glyphs = React.useContext(AiIconContext);\n return aiGlyphs[glyphs[role]];\n}\n\n/* -------------------------------------------------------------------------- */\n/* AiIcon — a meaning, with its mark and its words */\n/* -------------------------------------------------------------------------- */\n\nexport interface AiIconProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, \"role\"> {\n /**\n * Which AI meaning this is: `ai-action` (a control runs AI),\n * `generated-content` (AI wrote this), `agent-working` (the agent is\n * working now — announced politely) or `tool-use` (the agent used a tool).\n */\n role: AiIconRole;\n /** The words that travel with the mark (\"Rewrite\", \"Generated with AI\", \"Rewriting release note…\"). Required: a mark is never alone. */\n label: React.ReactNode;\n /** Show the words visibly (default) or keep them for assistive tech only. */\n showLabel?: boolean;\n}\n\nconst roleClasses: Record<AiIconRole, string> = {\n \"ai-action\": \"text-foreground [&>svg]:text-brand\",\n \"agent-working\": \"text-foreground [&>svg]:text-brand\",\n \"tool-use\": \"text-muted-foreground\",\n \"generated-content\":\n \"rounded-full border border-brand/30 bg-background px-2 py-0.5 text-xs font-medium text-foreground [&>svg]:size-3.5 [&>svg]:text-brand\",\n};\n\n/**\n * One AI meaning drawn with its reserved mark and its words. The product\n * names the meaning; the component maps it to the approved glyph (see\n * `AiIconProvider`). `agent-working` turns its mark and announces its words\n * in a polite live region; the rest are static. For a control that runs\n * AI, use `Iconography`, which puts the `ai-action` mark on a Button.\n */\nexport const AiIcon = React.forwardRef<HTMLSpanElement, AiIconProps>(\n ({ role, label, showLabel = true, className, ...props }, ref) => {\n const Glyph = useAiGlyph(role);\n return (\n <span\n ref={ref}\n data-ai-role={role}\n role={role === \"agent-working\" ? \"status\" : undefined}\n aria-live={role === \"agent-working\" ? \"polite\" : undefined}\n className={cn(\"inline-flex items-center gap-1.5 text-sm\", roleClasses[role], className)}\n {...props}\n >\n <Glyph />\n <span className={showLabel ? undefined : \"sr-only\"}>{label}</span>\n </span>\n );\n },\n);\nAiIcon.displayName = \"AiIcon\";\n\n/* -------------------------------------------------------------------------- */\n/* AiIcons — the AI presence mark */\n/* -------------------------------------------------------------------------- */\n\nexport type AiIconsVariant = \"sparkle\" | \"thinking-orb\" | \"branded-mark\";\nexport type AiIconsSize = \"sm\" | \"md\" | \"lg\";\nexport type AiIconsTone = \"solid\" | \"outline\";\n\nconst sizeClasses: Record<AiIconsSize, string> = {\n sm: \"size-6 text-xs [&>svg]:size-3.5\",\n md: \"size-8 text-sm [&>svg]:size-4\",\n lg: \"size-10 text-lg [&>svg]:size-5\",\n};\n\nexport interface AiIconsProps extends React.HTMLAttributes<HTMLSpanElement> {\n /**\n * `sparkle` (the universal \"AI\" mark in a tile), `thinking-orb` (an\n * animated orb for active, listening or generating states) or\n * `branded-mark` (your product's own shape or letter).\n */\n variant?: AiIconsVariant;\n /** 24 / 32 / 40 px. */\n size?: AiIconsSize;\n /** `solid` (filled tile) or `outline` (bordered tile). Sparkle and branded mark only. */\n tone?: AiIconsTone;\n /** Accessible name. Omit when words sit beside the mark — it is then decorative. */\n label?: string;\n /** Content of the branded mark (a letter or your SVG). Defaults to the first letter of `label`, else the sparkle. */\n glyph?: React.ReactNode;\n}\n\n/**\n * The AI presence mark: one stable symbol that tells people the AI is here.\n * `sparkle` is the default; `thinking-orb` is the active state and pulses\n * (still under reduced motion — pair it with words such as an `AiIcon`\n * `agent-working` line); `branded-mark` carries your product's own shape.\n * Never a photo or a human face.\n */\nexport const AiIcons = React.forwardRef<HTMLSpanElement, AiIconsProps>(\n ({ variant = \"sparkle\", size = \"md\", tone = \"solid\", label, glyph, className, ...props }, ref) => {\n const Sparkle = useAiGlyph(\"ai-action\");\n const a11y = label ? { role: \"img\" as const, \"aria-label\": label } : { \"aria-hidden\": true as const };\n const base = \"inline-grid shrink-0 place-items-center font-semibold\";\n\n if (variant === \"thinking-orb\") {\n return (\n <span\n ref={ref}\n data-variant={variant}\n className={cn(\n base,\n \"rounded-full bg-gradient-to-br from-brand to-primary shadow-sm\",\n aiColorClasses.working,\n sizeClasses[size],\n className,\n )}\n {...a11y}\n {...props}\n />\n );\n }\n\n const toneClasses =\n tone === \"solid\"\n ? \"bg-primary text-primary-foreground\"\n : \"border border-border bg-background text-foreground\";\n\n if (variant === \"branded-mark\") {\n const content = glyph ?? (label ? label.charAt(0).toLowerCase() : <Sparkle />);\n return (\n <span\n ref={ref}\n data-variant={variant}\n className={cn(\n base,\n \"rounded-[28%] font-serif italic\",\n tone === \"solid\" ? \"bg-gradient-to-br from-primary to-primary/70 text-primary-foreground\" : toneClasses,\n sizeClasses[size],\n className,\n )}\n {...a11y}\n {...props}\n >\n {content}\n </span>\n );\n }\n\n return (\n <span\n ref={ref}\n data-variant={variant}\n className={cn(base, \"rounded-[22%]\", toneClasses, sizeClasses[size], className)}\n {...a11y}\n {...props}\n >\n <Sparkle />\n </span>\n );\n },\n);\nAiIcons.displayName = \"AiIcons\";\n"]}
package/package.json CHANGED
@@ -1,6 +1,59 @@
1
1
  {
2
2
  "name": "@nucleux/ai-icons",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.6.0",
4
+ "type": "module",
5
+ "sideEffects": false,
6
+ "description": "Icons — a small, stable AI mark vocabulary: action, generated, working and tool use — Nucleux agentic UI for React.",
7
+ "keywords": [
8
+ "nucleux",
9
+ "react",
10
+ "ui",
11
+ "components",
12
+ "agentic",
13
+ "ai",
14
+ "tailwind",
15
+ "ai-icons"
16
+ ],
17
+ "main": "./dist/index.cjs",
18
+ "module": "./dist/index.js",
19
+ "types": "./dist/index.d.ts",
20
+ "exports": {
21
+ ".": {
22
+ "types": "./dist/index.d.ts",
23
+ "import": "./dist/index.js",
24
+ "require": "./dist/index.cjs"
25
+ }
26
+ },
27
+ "files": [
28
+ "dist",
29
+ "README.md"
30
+ ],
31
+ "peerDependencies": {
32
+ "react": ">=18",
33
+ "react-dom": ">=18"
34
+ },
35
+ "dependencies": {
36
+ "@nucleux/color": "0.6.0",
37
+ "@nucleux/utils": "0.6.0",
38
+ "lucide-react": "^0.469.0"
39
+ },
40
+ "devDependencies": {
41
+ "tsup": "^8.3.5",
42
+ "typescript": "^5.7.2",
43
+ "@types/react": "^18.3.18",
44
+ "react": "^18.3.1"
45
+ },
46
+ "publishConfig": {
47
+ "access": "public"
48
+ },
49
+ "license": "MIT",
50
+ "repository": {
51
+ "type": "git",
52
+ "url": "git+https://github.com/intelligaia-open-labs/nucleux.git",
53
+ "directory": "packages/ai-icons"
54
+ },
55
+ "homepage": "https://github.com/intelligaia-open-labs/nucleux#readme",
56
+ "scripts": {
57
+ "build": "tsup"
58
+ }
6
59
  }