@illuma-ai/icons 2.2.0 → 2.4.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,25 @@
1
+ import { SVGProps } from 'react';
2
+ export interface TerminalIconProps extends Omit<SVGProps<SVGSVGElement>, 'children'> {
3
+ /** Pixel size for width and height. Defaults to 24. */
4
+ size?: number;
5
+ }
6
+ /**
7
+ * Static terminal glyph — a rounded window with a prompt chevron and a cursor
8
+ * line. `currentColor` for strokes so it inherits the surrounding text color
9
+ * (works on light and dark); the cursor is brand yellow.
10
+ */
11
+ export declare const TerminalIcon: import('react').ForwardRefExoticComponent<Omit<TerminalIconProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
12
+ export interface AnimatedTerminalIconProps extends TerminalIconProps {
13
+ /** When false, renders the static icon (no animation). Defaults to true. */
14
+ running?: boolean;
15
+ /** Cursor/typing color. Defaults to brand yellow (#facc15). */
16
+ accent?: string;
17
+ }
18
+ /**
19
+ * Animated terminal logo for an in-progress terminal/code step: a prompt chevron
20
+ * with a blinking yellow cursor and a subtle "typing" line that grows and resets,
21
+ * evoking a command being typed. Subtle enough to suit light and dark themes;
22
+ * honors `prefers-reduced-motion` (framer-motion disables transform/opacity
23
+ * tweens automatically). When `running` is false it settles to the static icon.
24
+ */
25
+ export declare const AnimatedTerminalIcon: import('react').ForwardRefExoticComponent<Omit<AnimatedTerminalIconProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
@@ -0,0 +1,16 @@
1
+ export interface ThinkingOrbProps {
2
+ /** Pixel diameter. Defaults to 20 (inline with text). */
3
+ size?: number;
4
+ /** Animation speed multiplier. Defaults to 1. */
5
+ speed?: number;
6
+ className?: string;
7
+ }
8
+ /**
9
+ * A premium, AI-"thinking" fluid orb rendered with raw WebGL (no three.js). A
10
+ * simplex-noise–deformed sphere with a shifting cyan→violet→magenta→amber
11
+ * gradient and fresnel rim — the kind of organic, alive blob shown in modern
12
+ * assistant UIs. Self-contained (~3KB), 60fps on a tiny canvas, transparent
13
+ * background so it sits inline beside "Thinking" text on any theme. Falls back
14
+ * gracefully (renders nothing) where WebGL is unavailable.
15
+ */
16
+ export declare function ThinkingOrb({ size, speed, className }: ThinkingOrbProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,4 @@
1
+ export { TerminalIcon, AnimatedTerminalIcon } from './Terminal';
2
+ export type { TerminalIconProps, AnimatedTerminalIconProps } from './Terminal';
3
+ export { ThinkingOrb } from './ThinkingOrb';
4
+ export type { ThinkingOrbProps } from './ThinkingOrb';
package/dist/brand.cjs ADDED
@@ -0,0 +1,53 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("react/jsx-runtime"),l=require("react"),u=require("framer-motion"),p=l.forwardRef(function({size:o=24,className:a,...r},n){return i.jsxs("svg",{ref:n,width:o,height:o,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",className:a,role:"img","aria-label":"Terminal",...r,children:[i.jsx("rect",{x:"2.5",y:"4",width:"19",height:"16",rx:"2.5"}),i.jsx("path",{d:"m6.5 9 3 3-3 3"}),i.jsx("path",{d:"M12.5 15h4",stroke:"#facc15"})]})}),b=l.forwardRef(function({size:o=24,running:a=!0,accent:r="#facc15",className:n,...s},e){return a?i.jsxs("svg",{ref:e,width:o,height:o,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",className:n,role:"img","aria-label":"Terminal running",...s,children:[i.jsx("rect",{x:"2.5",y:"4",width:"19",height:"16",rx:"2.5"}),i.jsx("path",{d:"m6.5 9 3 3-3 3"}),i.jsx(u.motion.path,{d:"M12.5 15h5",stroke:r,initial:{pathLength:0,opacity:.9},animate:{pathLength:[0,1,1,0]},transition:{duration:1.6,times:[0,.5,.8,1],repeat:1/0,ease:"easeInOut"}}),i.jsx(u.motion.rect,{x:"18.5",y:"13.4",width:"1.6",height:"3.2",rx:"0.3",fill:r,stroke:"none",animate:{opacity:[1,1,0,0,1]},transition:{duration:1.1,times:[0,.4,.5,.9,1],repeat:1/0}})]}):i.jsx(p,{ref:e,size:o,className:n,...s})}),R=`
2
+ attribute vec2 p;
3
+ varying vec2 uv;
4
+ void main() { uv = p; gl_Position = vec4(p, 0.0, 1.0); }
5
+ `,T=`
6
+ precision highp float;
7
+ varying vec2 uv;
8
+ uniform float t;
9
+
10
+ // Classic 2D simplex noise (Ashima Arts, MIT) — compact.
11
+ vec3 permute(vec3 x){return mod(((x*34.0)+1.0)*x,289.0);}
12
+ float snoise(vec2 v){
13
+ const vec4 C=vec4(0.211324865,0.366025404,-0.577350269,0.024390244);
14
+ vec2 i=floor(v+dot(v,C.yy));vec2 x0=v-i+dot(i,C.xx);
15
+ vec2 i1=(x0.x>x0.y)?vec2(1.0,0.0):vec2(0.0,1.0);
16
+ vec4 x12=x0.xyxy+C.xxzz;x12.xy-=i1;
17
+ i=mod(i,289.0);
18
+ vec3 p=permute(permute(i.y+vec3(0.0,i1.y,1.0))+i.x+vec3(0.0,i1.x,1.0));
19
+ vec3 m=max(0.5-vec3(dot(x0,x0),dot(x12.xy,x12.xy),dot(x12.zw,x12.zw)),0.0);
20
+ m=m*m;m=m*m;
21
+ vec3 x=2.0*fract(p*C.www)-1.0;vec3 h=abs(x)-0.5;vec3 ox=floor(x+0.5);vec3 a0=x-ox;
22
+ m*=1.79284291-0.85373472*(a0*a0+h*h);
23
+ vec3 g;g.x=a0.x*x0.x+h.x*x0.y;g.yz=a0.yz*x12.xz+h.yz*x12.yw;
24
+ return 130.0*dot(m,g);
25
+ }
26
+
27
+ void main(){
28
+ vec2 p=uv;
29
+ float r=length(p);
30
+ // Noise-deform the radius so the silhouette wobbles organically.
31
+ float n=snoise(p*2.2+vec2(t*0.25,t*0.18))*0.5+snoise(p*4.0-vec2(t*0.2))*0.25;
32
+ float edge=0.78+n*0.16;
33
+ float orb=smoothstep(edge,edge-0.18,r);
34
+ if(orb<0.01){ gl_FragColor=vec4(0.0); return; }
35
+ // Shifting gradient palette.
36
+ float a=atan(p.y,p.x);
37
+ float f=0.5+0.5*sin(a*1.0+t*0.6+n*2.0);
38
+ vec3 cyan=vec3(0.20,0.85,0.95);
39
+ vec3 violet=vec3(0.55,0.35,0.95);
40
+ vec3 magenta=vec3(0.95,0.30,0.70);
41
+ vec3 amber=vec3(1.0,0.75,0.30);
42
+ vec3 col=mix(cyan,violet,smoothstep(0.0,0.4,f));
43
+ col=mix(col,magenta,smoothstep(0.35,0.7,f));
44
+ col=mix(col,amber,smoothstep(0.7,1.0,f));
45
+ // Inner glow + fresnel rim.
46
+ float glow=smoothstep(0.0,0.6,1.0-r);
47
+ col+=glow*0.25;
48
+ float rim=smoothstep(edge-0.02,edge-0.16,r);
49
+ col=mix(col,vec3(1.0),(1.0-rim)*0.35*orb);
50
+ gl_FragColor=vec4(col,orb);
51
+ }
52
+ `;function g(t,o,a){const r=t.createShader(o);return t.shaderSource(r,a),t.compileShader(r),r}function k({size:t=20,speed:o=1,className:a}){const r=l.useRef(null);return l.useEffect(()=>{const n=r.current;if(!n)return;const s=Math.min(window.devicePixelRatio||1,2);n.width=t*s,n.height=t*s;const e=n.getContext("webgl",{premultipliedAlpha:!1,alpha:!0});if(!e)return;const c=e.createProgram();e.attachShader(c,g(e,e.VERTEX_SHADER,R)),e.attachShader(c,g(e,e.FRAGMENT_SHADER,T)),e.linkProgram(c),e.useProgram(c);const y=e.createBuffer();e.bindBuffer(e.ARRAY_BUFFER,y),e.bufferData(e.ARRAY_BUFFER,new Float32Array([-1,-1,3,-1,-1,3]),e.STATIC_DRAW);const d=e.getAttribLocation(c,"p");e.enableVertexAttribArray(d),e.vertexAttribPointer(d,2,e.FLOAT,!1,0,0);const w=e.getUniformLocation(c,"t");e.viewport(0,0,n.width,n.height),e.enable(e.BLEND),e.blendFunc(e.SRC_ALPHA,e.ONE_MINUS_SRC_ALPHA);const f=typeof window.matchMedia=="function"&&window.matchMedia("(prefers-reduced-motion: reduce)").matches;let m=0,x=0;const v=h=>{x||(x=h);const A=(h-x)/1e3*o;e.uniform1f(w,f?.4:A),e.drawArrays(e.TRIANGLES,0,3),f||(m=requestAnimationFrame(v))};return m=requestAnimationFrame(v),()=>{cancelAnimationFrame(m),e.getExtension("WEBGL_lose_context")?.loseContext()}},[t,o]),i.jsx("canvas",{ref:r,className:a,style:{width:t,height:t,display:"inline-block"},role:"img","aria-label":"Thinking"})}exports.AnimatedTerminalIcon=b;exports.TerminalIcon=p;exports.ThinkingOrb=k;
53
+ //# sourceMappingURL=brand.cjs.map
@@ -0,0 +1,178 @@
1
+ import { jsxs as p, jsx as n } from "react/jsx-runtime";
2
+ import { forwardRef as g, useRef as b, useEffect as R } from "react";
3
+ import { motion as v } from "framer-motion";
4
+ const T = g(function({ size: o = 24, className: a, ...r }, i) {
5
+ return /* @__PURE__ */ p(
6
+ "svg",
7
+ {
8
+ ref: i,
9
+ width: o,
10
+ height: o,
11
+ viewBox: "0 0 24 24",
12
+ fill: "none",
13
+ stroke: "currentColor",
14
+ strokeWidth: 2,
15
+ strokeLinecap: "round",
16
+ strokeLinejoin: "round",
17
+ className: a,
18
+ role: "img",
19
+ "aria-label": "Terminal",
20
+ ...r,
21
+ children: [
22
+ /* @__PURE__ */ n("rect", { x: "2.5", y: "4", width: "19", height: "16", rx: "2.5" }),
23
+ /* @__PURE__ */ n("path", { d: "m6.5 9 3 3-3 3" }),
24
+ /* @__PURE__ */ n("path", { d: "M12.5 15h4", stroke: "#facc15" })
25
+ ]
26
+ }
27
+ );
28
+ }), _ = g(
29
+ function({ size: o = 24, running: a = !0, accent: r = "#facc15", className: i, ...l }, e) {
30
+ return a ? /* @__PURE__ */ p(
31
+ "svg",
32
+ {
33
+ ref: e,
34
+ width: o,
35
+ height: o,
36
+ viewBox: "0 0 24 24",
37
+ fill: "none",
38
+ stroke: "currentColor",
39
+ strokeWidth: 2,
40
+ strokeLinecap: "round",
41
+ strokeLinejoin: "round",
42
+ className: i,
43
+ role: "img",
44
+ "aria-label": "Terminal running",
45
+ ...l,
46
+ children: [
47
+ /* @__PURE__ */ n("rect", { x: "2.5", y: "4", width: "19", height: "16", rx: "2.5" }),
48
+ /* @__PURE__ */ n("path", { d: "m6.5 9 3 3-3 3" }),
49
+ /* @__PURE__ */ n(
50
+ v.path,
51
+ {
52
+ d: "M12.5 15h5",
53
+ stroke: r,
54
+ initial: { pathLength: 0, opacity: 0.9 },
55
+ animate: { pathLength: [0, 1, 1, 0] },
56
+ transition: { duration: 1.6, times: [0, 0.5, 0.8, 1], repeat: 1 / 0, ease: "easeInOut" }
57
+ }
58
+ ),
59
+ /* @__PURE__ */ n(
60
+ v.rect,
61
+ {
62
+ x: "18.5",
63
+ y: "13.4",
64
+ width: "1.6",
65
+ height: "3.2",
66
+ rx: "0.3",
67
+ fill: r,
68
+ stroke: "none",
69
+ animate: { opacity: [1, 1, 0, 0, 1] },
70
+ transition: { duration: 1.1, times: [0, 0.4, 0.5, 0.9, 1], repeat: 1 / 0 }
71
+ }
72
+ )
73
+ ]
74
+ }
75
+ ) : /* @__PURE__ */ n(T, { ref: e, size: o, className: i, ...l });
76
+ }
77
+ ), k = `
78
+ attribute vec2 p;
79
+ varying vec2 uv;
80
+ void main() { uv = p; gl_Position = vec4(p, 0.0, 1.0); }
81
+ `, C = `
82
+ precision highp float;
83
+ varying vec2 uv;
84
+ uniform float t;
85
+
86
+ // Classic 2D simplex noise (Ashima Arts, MIT) — compact.
87
+ vec3 permute(vec3 x){return mod(((x*34.0)+1.0)*x,289.0);}
88
+ float snoise(vec2 v){
89
+ const vec4 C=vec4(0.211324865,0.366025404,-0.577350269,0.024390244);
90
+ vec2 i=floor(v+dot(v,C.yy));vec2 x0=v-i+dot(i,C.xx);
91
+ vec2 i1=(x0.x>x0.y)?vec2(1.0,0.0):vec2(0.0,1.0);
92
+ vec4 x12=x0.xyxy+C.xxzz;x12.xy-=i1;
93
+ i=mod(i,289.0);
94
+ vec3 p=permute(permute(i.y+vec3(0.0,i1.y,1.0))+i.x+vec3(0.0,i1.x,1.0));
95
+ vec3 m=max(0.5-vec3(dot(x0,x0),dot(x12.xy,x12.xy),dot(x12.zw,x12.zw)),0.0);
96
+ m=m*m;m=m*m;
97
+ vec3 x=2.0*fract(p*C.www)-1.0;vec3 h=abs(x)-0.5;vec3 ox=floor(x+0.5);vec3 a0=x-ox;
98
+ m*=1.79284291-0.85373472*(a0*a0+h*h);
99
+ vec3 g;g.x=a0.x*x0.x+h.x*x0.y;g.yz=a0.yz*x12.xz+h.yz*x12.yw;
100
+ return 130.0*dot(m,g);
101
+ }
102
+
103
+ void main(){
104
+ vec2 p=uv;
105
+ float r=length(p);
106
+ // Noise-deform the radius so the silhouette wobbles organically.
107
+ float n=snoise(p*2.2+vec2(t*0.25,t*0.18))*0.5+snoise(p*4.0-vec2(t*0.2))*0.25;
108
+ float edge=0.78+n*0.16;
109
+ float orb=smoothstep(edge,edge-0.18,r);
110
+ if(orb<0.01){ gl_FragColor=vec4(0.0); return; }
111
+ // Shifting gradient palette.
112
+ float a=atan(p.y,p.x);
113
+ float f=0.5+0.5*sin(a*1.0+t*0.6+n*2.0);
114
+ vec3 cyan=vec3(0.20,0.85,0.95);
115
+ vec3 violet=vec3(0.55,0.35,0.95);
116
+ vec3 magenta=vec3(0.95,0.30,0.70);
117
+ vec3 amber=vec3(1.0,0.75,0.30);
118
+ vec3 col=mix(cyan,violet,smoothstep(0.0,0.4,f));
119
+ col=mix(col,magenta,smoothstep(0.35,0.7,f));
120
+ col=mix(col,amber,smoothstep(0.7,1.0,f));
121
+ // Inner glow + fresnel rim.
122
+ float glow=smoothstep(0.0,0.6,1.0-r);
123
+ col+=glow*0.25;
124
+ float rim=smoothstep(edge-0.02,edge-0.16,r);
125
+ col=mix(col,vec3(1.0),(1.0-rim)*0.35*orb);
126
+ gl_FragColor=vec4(col,orb);
127
+ }
128
+ `;
129
+ function u(t, o, a) {
130
+ const r = t.createShader(o);
131
+ return t.shaderSource(r, a), t.compileShader(r), r;
132
+ }
133
+ function S({ size: t = 20, speed: o = 1, className: a }) {
134
+ const r = b(null);
135
+ return R(() => {
136
+ const i = r.current;
137
+ if (!i)
138
+ return;
139
+ const l = Math.min(window.devicePixelRatio || 1, 2);
140
+ i.width = t * l, i.height = t * l;
141
+ const e = i.getContext("webgl", { premultipliedAlpha: !1, alpha: !0 });
142
+ if (!e)
143
+ return;
144
+ const c = e.createProgram();
145
+ e.attachShader(c, u(e, e.VERTEX_SHADER, k)), e.attachShader(c, u(e, e.FRAGMENT_SHADER, C)), e.linkProgram(c), e.useProgram(c);
146
+ const y = e.createBuffer();
147
+ e.bindBuffer(e.ARRAY_BUFFER, y), e.bufferData(e.ARRAY_BUFFER, new Float32Array([-1, -1, 3, -1, -1, 3]), e.STATIC_DRAW);
148
+ const x = e.getAttribLocation(c, "p");
149
+ e.enableVertexAttribArray(x), e.vertexAttribPointer(x, 2, e.FLOAT, !1, 0, 0);
150
+ const w = e.getUniformLocation(c, "t");
151
+ e.viewport(0, 0, i.width, i.height), e.enable(e.BLEND), e.blendFunc(e.SRC_ALPHA, e.ONE_MINUS_SRC_ALPHA);
152
+ const d = typeof window.matchMedia == "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
153
+ let s = 0, m = 0;
154
+ const f = (h) => {
155
+ m || (m = h);
156
+ const A = (h - m) / 1e3 * o;
157
+ e.uniform1f(w, d ? 0.4 : A), e.drawArrays(e.TRIANGLES, 0, 3), d || (s = requestAnimationFrame(f));
158
+ };
159
+ return s = requestAnimationFrame(f), () => {
160
+ cancelAnimationFrame(s), e.getExtension("WEBGL_lose_context")?.loseContext();
161
+ };
162
+ }, [t, o]), /* @__PURE__ */ n(
163
+ "canvas",
164
+ {
165
+ ref: r,
166
+ className: a,
167
+ style: { width: t, height: t, display: "inline-block" },
168
+ role: "img",
169
+ "aria-label": "Thinking"
170
+ }
171
+ );
172
+ }
173
+ export {
174
+ _ as AnimatedTerminalIcon,
175
+ T as TerminalIcon,
176
+ S as ThinkingOrb
177
+ };
178
+ //# sourceMappingURL=brand.es.js.map
@@ -23,12 +23,19 @@ export interface ArtifactIconProps extends Omit<SVGProps<SVGSVGElement>, 'childr
23
23
  type?: string;
24
24
  /** Artifact language (e.g. `react`, `html`, `python`) — fallback when no type. */
25
25
  language?: string;
26
+ /**
27
+ * The artifact's real filename. Takes precedence over `type`/`language` so a
28
+ * `.docx` shows the Word icon even though its preview is rendered to PDF.
29
+ */
30
+ filename?: string;
26
31
  /** Pixel size for width and height. Defaults to 24. */
27
32
  size?: number;
28
33
  }
29
34
  /**
30
- * Icon for a side-panel code/document artifact, resolved from its type/language
31
- * rather than a filename (a React artifact react icon, HTML html, etc.).
35
+ * Icon for a side-panel code/document artifact. Resolved from the real filename
36
+ * first (source of truth), then artifact type/language so a React artifact
37
+ * react icon, an HTML artifact → html, and a `.docx` → Word (not PDF, even
38
+ * though its preview is rendered to PDF).
32
39
  */
33
40
  export declare const ArtifactIcon: import('react').ForwardRefExoticComponent<Omit<ArtifactIconProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
34
41
  export interface AnimatedFileIconProps {
@@ -1,14 +1,22 @@
1
1
  import { FILE_ICONS, FileIconName, FileIconData } from './icons.generated';
2
2
  /** Generic fallback for unknown/other file types (Office 365 mark). */
3
3
  export declare const DEFAULT_FILE_ICON: FileIconName;
4
- /**
5
- * Resolve an artifact's icon from its `type` and/or `language`. Resolution
6
- * order: artifact type → language → {@link DEFAULT_FILE_ICON}.
7
- */
8
- export declare function resolveArtifactIcon(type?: string, language?: string): ResolvedFileIcon;
9
4
  export interface ResolvedFileIcon extends FileIconData {
10
5
  readonly name: FileIconName;
11
6
  }
7
+ /**
8
+ * Resolve an artifact's icon. The real file is the source of truth, so a
9
+ * `filename` (when present) wins — a `.docx` shows the Word icon even though its
10
+ * side-panel PREVIEW is rendered to PDF. Resolution order:
11
+ * filename extension → artifact type → language → {@link DEFAULT_FILE_ICON}.
12
+ *
13
+ * @param type artifact type identifier (e.g. `application/vnd.react`); note that
14
+ * office docs carry a `*-pdf-preview`/`*-preview` type reflecting how they're
15
+ * rendered, NOT the source format — which is why `filename` is checked first.
16
+ * @param language artifact language (e.g. `react`, `python`)
17
+ * @param filename the artifact's real filename, when known
18
+ */
19
+ export declare function resolveArtifactIcon(type?: string, language?: string, filename?: string): ResolvedFileIcon;
12
20
  /**
13
21
  * Resolve a file's icon from its filename and/or MIME type. Resolution order:
14
22
  * exact extension → exact MIME → {@link DEFAULT_FILE_ICON}.