@illuma-ai/icons 2.3.0 → 2.5.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.
@@ -1,16 +1,22 @@
1
+ /** Built-in color palettes for the orb. A palette is four RGB stops blended
2
+ * around the orb as the noise field shifts. */
3
+ export type ThinkingOrbPalette = 'aurora' | 'ai';
1
4
  export interface ThinkingOrbProps {
2
5
  /** Pixel diameter. Defaults to 20 (inline with text). */
3
6
  size?: number;
4
7
  /** Animation speed multiplier. Defaults to 1. */
5
8
  speed?: number;
9
+ /** Color palette. Defaults to `'ai'` (pink/purple). */
10
+ palette?: ThinkingOrbPalette;
6
11
  className?: string;
7
12
  }
8
13
  /**
9
14
  * 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
15
+ * simplex-noise–deformed sphere with a shifting four-stop gradient and fresnel
16
+ * rim — the kind of organic, alive blob shown in modern assistant UIs. Defaults
17
+ * to the `'ai'` pink/purple palette; pass `palette="aurora"` for the original
18
+ * cyan→amber. Self-contained (~3KB), 60fps on a tiny canvas, transparent
13
19
  * background so it sits inline beside "Thinking" text on any theme. Falls back
14
20
  * gracefully (renders nothing) where WebGL is unavailable.
15
21
  */
16
- export declare function ThinkingOrb({ size, speed, className }: ThinkingOrbProps): import("react/jsx-runtime").JSX.Element;
22
+ export declare function ThinkingOrb({ size, speed, palette, className }: ThinkingOrbProps): import("react/jsx-runtime").JSX.Element;
@@ -1,4 +1,4 @@
1
1
  export { TerminalIcon, AnimatedTerminalIcon } from './Terminal';
2
2
  export type { TerminalIconProps, AnimatedTerminalIconProps } from './Terminal';
3
3
  export { ThinkingOrb } from './ThinkingOrb';
4
- export type { ThinkingOrbProps } from './ThinkingOrb';
4
+ export type { ThinkingOrbProps, ThinkingOrbPalette } from './ThinkingOrb';
package/dist/brand.cjs CHANGED
@@ -1,8 +1,8 @@
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=`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),m=require("react"),g=require("framer-motion"),w=m.forwardRef(function({size:o=24,className:a,...i},c){return r.jsxs("svg",{ref:c,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",...i,children:[r.jsx("rect",{x:"2.5",y:"4",width:"19",height:"16",rx:"2.5"}),r.jsx("path",{d:"m6.5 9 3 3-3 3"}),r.jsx("path",{d:"M12.5 15h4",stroke:"#facc15"})]})}),R=m.forwardRef(function({size:o=24,running:a=!0,accent:i="#facc15",className:c,...n},s){return a?r.jsxs("svg",{ref:s,width:o,height:o,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",className:c,role:"img","aria-label":"Terminal running",...n,children:[r.jsx("rect",{x:"2.5",y:"4",width:"19",height:"16",rx:"2.5"}),r.jsx("path",{d:"m6.5 9 3 3-3 3"}),r.jsx(g.motion.path,{d:"M12.5 15h5",stroke:i,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"}}),r.jsx(g.motion.rect,{x:"18.5",y:"13.4",width:"1.6",height:"3.2",rx:"0.3",fill:i,stroke:"none",animate:{opacity:[1,1,0,0,1]},transition:{duration:1.1,times:[0,.4,.5,.9,1],repeat:1/0}})]}):r.jsx(w,{ref:s,size:o,className:c,...n})}),p={aurora:["vec3(0.20,0.85,0.95)","vec3(0.55,0.35,0.95)","vec3(0.95,0.30,0.70)","vec3(1.0,0.75,0.30)"],ai:["vec3(0.55,0.36,0.98)","vec3(0.74,0.34,0.96)","vec3(0.96,0.36,0.82)","vec3(1.0,0.62,0.86)"]},k=`
2
2
  attribute vec2 p;
3
3
  varying vec2 uv;
4
4
  void main() { uv = p; gl_Position = vec4(p, 0.0, 1.0); }
5
- `,T=`
5
+ `,E=t=>`
6
6
  precision highp float;
7
7
  varying vec2 uv;
8
8
  uniform float t;
@@ -35,13 +35,13 @@ void main(){
35
35
  // Shifting gradient palette.
36
36
  float a=atan(p.y,p.x);
37
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));
38
+ vec3 c0=${t[0]};
39
+ vec3 c1=${t[1]};
40
+ vec3 c2=${t[2]};
41
+ vec3 c3=${t[3]};
42
+ vec3 col=mix(c0,c1,smoothstep(0.0,0.4,f));
43
+ col=mix(col,c2,smoothstep(0.35,0.7,f));
44
+ col=mix(col,c3,smoothstep(0.7,1.0,f));
45
45
  // Inner glow + fresnel rim.
46
46
  float glow=smoothstep(0.0,0.6,1.0-r);
47
47
  col+=glow*0.25;
@@ -49,5 +49,5 @@ void main(){
49
49
  col=mix(col,vec3(1.0),(1.0-rim)*0.35*orb);
50
50
  gl_FragColor=vec4(col,orb);
51
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;
52
+ `;function y(t,o,a){const i=t.createShader(o);return t.shaderSource(i,a),t.compileShader(i),i}function L({size:t=20,speed:o=1,palette:a="ai",className:i}){const c=m.useRef(null);return m.useEffect(()=>{const n=c.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 l=e.createProgram();e.attachShader(l,y(e,e.VERTEX_SHADER,k)),e.attachShader(l,y(e,e.FRAGMENT_SHADER,E(p[a]??p.ai))),e.linkProgram(l),e.useProgram(l);const A=e.createBuffer();e.bindBuffer(e.ARRAY_BUFFER,A),e.bufferData(e.ARRAY_BUFFER,new Float32Array([-1,-1,3,-1,-1,3]),e.STATIC_DRAW);const v=e.getAttribLocation(l,"p");e.enableVertexAttribArray(v),e.vertexAttribPointer(v,2,e.FLOAT,!1,0,0);const b=e.getUniformLocation(l,"t");e.viewport(0,0,n.width,n.height),e.enable(e.BLEND),e.blendFunc(e.SRC_ALPHA,e.ONE_MINUS_SRC_ALPHA);const u=typeof window.matchMedia=="function"&&window.matchMedia("(prefers-reduced-motion: reduce)").matches;let x=0,h=0;const f=d=>{h||(h=d);const T=(d-h)/1e3*o;e.uniform1f(b,u?.4:T),e.drawArrays(e.TRIANGLES,0,3),u||(x=requestAnimationFrame(f))};return x=requestAnimationFrame(f),()=>{cancelAnimationFrame(x),e.getExtension("WEBGL_lose_context")?.loseContext()}},[t,o,a]),r.jsx("canvas",{ref:c,className:i,style:{width:t,height:t,display:"inline-block"},role:"img","aria-label":"Thinking"})}exports.AnimatedTerminalIcon=R;exports.TerminalIcon=w;exports.ThinkingOrb=L;
53
53
  //# sourceMappingURL=brand.cjs.map
package/dist/brand.es.js CHANGED
@@ -1,11 +1,11 @@
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(
1
+ import { jsxs as y, jsx as n } from "react/jsx-runtime";
2
+ import { forwardRef as w, useRef as T, useEffect as E } from "react";
3
+ import { motion as u } from "framer-motion";
4
+ const L = w(function({ size: o = 24, className: a, ...r }, c) {
5
+ return /* @__PURE__ */ y(
6
6
  "svg",
7
7
  {
8
- ref: i,
8
+ ref: c,
9
9
  width: o,
10
10
  height: o,
11
11
  viewBox: "0 0 24 24",
@@ -25,12 +25,12 @@ const T = g(function({ size: o = 24, className: a, ...r }, i) {
25
25
  ]
26
26
  }
27
27
  );
28
- }), _ = g(
29
- function({ size: o = 24, running: a = !0, accent: r = "#facc15", className: i, ...l }, e) {
30
- return a ? /* @__PURE__ */ p(
28
+ }), I = w(
29
+ function({ size: o = 24, running: a = !0, accent: r = "#facc15", className: c, ...i }, s) {
30
+ return a ? /* @__PURE__ */ y(
31
31
  "svg",
32
32
  {
33
- ref: e,
33
+ ref: s,
34
34
  width: o,
35
35
  height: o,
36
36
  viewBox: "0 0 24 24",
@@ -39,15 +39,15 @@ const T = g(function({ size: o = 24, className: a, ...r }, i) {
39
39
  strokeWidth: 2,
40
40
  strokeLinecap: "round",
41
41
  strokeLinejoin: "round",
42
- className: i,
42
+ className: c,
43
43
  role: "img",
44
44
  "aria-label": "Terminal running",
45
- ...l,
45
+ ...i,
46
46
  children: [
47
47
  /* @__PURE__ */ n("rect", { x: "2.5", y: "4", width: "19", height: "16", rx: "2.5" }),
48
48
  /* @__PURE__ */ n("path", { d: "m6.5 9 3 3-3 3" }),
49
49
  /* @__PURE__ */ n(
50
- v.path,
50
+ u.path,
51
51
  {
52
52
  d: "M12.5 15h5",
53
53
  stroke: r,
@@ -57,7 +57,7 @@ const T = g(function({ size: o = 24, className: a, ...r }, i) {
57
57
  }
58
58
  ),
59
59
  /* @__PURE__ */ n(
60
- v.rect,
60
+ u.rect,
61
61
  {
62
62
  x: "18.5",
63
63
  y: "13.4",
@@ -72,13 +72,19 @@ const T = g(function({ size: o = 24, className: a, ...r }, i) {
72
72
  )
73
73
  ]
74
74
  }
75
- ) : /* @__PURE__ */ n(T, { ref: e, size: o, className: i, ...l });
75
+ ) : /* @__PURE__ */ n(L, { ref: s, size: o, className: c, ...i });
76
76
  }
77
- ), k = `
77
+ ), g = {
78
+ // Original: cyan → violet → magenta → amber.
79
+ aurora: ["vec3(0.20,0.85,0.95)", "vec3(0.55,0.35,0.95)", "vec3(0.95,0.30,0.70)", "vec3(1.0,0.75,0.30)"],
80
+ // AI pink/purple: violet → purple → magenta-pink → soft rose. Vivid on light
81
+ // and dark, no cyan/amber — the "AI" gradient.
82
+ ai: ["vec3(0.55,0.36,0.98)", "vec3(0.74,0.34,0.96)", "vec3(0.96,0.36,0.82)", "vec3(1.0,0.62,0.86)"]
83
+ }, k = `
78
84
  attribute vec2 p;
79
85
  varying vec2 uv;
80
86
  void main() { uv = p; gl_Position = vec4(p, 0.0, 1.0); }
81
- `, C = `
87
+ `, C = (t) => `
82
88
  precision highp float;
83
89
  varying vec2 uv;
84
90
  uniform float t;
@@ -111,13 +117,13 @@ void main(){
111
117
  // Shifting gradient palette.
112
118
  float a=atan(p.y,p.x);
113
119
  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));
120
+ vec3 c0=${t[0]};
121
+ vec3 c1=${t[1]};
122
+ vec3 c2=${t[2]};
123
+ vec3 c3=${t[3]};
124
+ vec3 col=mix(c0,c1,smoothstep(0.0,0.4,f));
125
+ col=mix(col,c2,smoothstep(0.35,0.7,f));
126
+ col=mix(col,c3,smoothstep(0.7,1.0,f));
121
127
  // Inner glow + fresnel rim.
122
128
  float glow=smoothstep(0.0,0.6,1.0-r);
123
129
  col+=glow*0.25;
@@ -126,44 +132,44 @@ void main(){
126
132
  gl_FragColor=vec4(col,orb);
127
133
  }
128
134
  `;
129
- function u(t, o, a) {
135
+ function p(t, o, a) {
130
136
  const r = t.createShader(o);
131
137
  return t.shaderSource(r, a), t.compileShader(r), r;
132
138
  }
133
- function S({ size: t = 20, speed: o = 1, className: a }) {
134
- const r = b(null);
135
- return R(() => {
136
- const i = r.current;
139
+ function P({ size: t = 20, speed: o = 1, palette: a = "ai", className: r }) {
140
+ const c = T(null);
141
+ return E(() => {
142
+ const i = c.current;
137
143
  if (!i)
138
144
  return;
139
- const l = Math.min(window.devicePixelRatio || 1, 2);
140
- i.width = t * l, i.height = t * l;
145
+ const s = Math.min(window.devicePixelRatio || 1, 2);
146
+ i.width = t * s, i.height = t * s;
141
147
  const e = i.getContext("webgl", { premultipliedAlpha: !1, alpha: !0 });
142
148
  if (!e)
143
149
  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");
150
+ const l = e.createProgram();
151
+ e.attachShader(l, p(e, e.VERTEX_SHADER, k)), e.attachShader(l, p(e, e.FRAGMENT_SHADER, C(g[a] ?? g.ai))), e.linkProgram(l), e.useProgram(l);
152
+ const A = e.createBuffer();
153
+ e.bindBuffer(e.ARRAY_BUFFER, A), e.bufferData(e.ARRAY_BUFFER, new Float32Array([-1, -1, 3, -1, -1, 3]), e.STATIC_DRAW);
154
+ const d = e.getAttribLocation(l, "p");
155
+ e.enableVertexAttribArray(d), e.vertexAttribPointer(d, 2, e.FLOAT, !1, 0, 0);
156
+ const b = e.getUniformLocation(l, "t");
151
157
  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
+ const v = typeof window.matchMedia == "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
159
+ let m = 0, h = 0;
160
+ const f = (x) => {
161
+ h || (h = x);
162
+ const R = (x - h) / 1e3 * o;
163
+ e.uniform1f(b, v ? 0.4 : R), e.drawArrays(e.TRIANGLES, 0, 3), v || (m = requestAnimationFrame(f));
158
164
  };
159
- return s = requestAnimationFrame(f), () => {
160
- cancelAnimationFrame(s), e.getExtension("WEBGL_lose_context")?.loseContext();
165
+ return m = requestAnimationFrame(f), () => {
166
+ cancelAnimationFrame(m), e.getExtension("WEBGL_lose_context")?.loseContext();
161
167
  };
162
- }, [t, o]), /* @__PURE__ */ n(
168
+ }, [t, o, a]), /* @__PURE__ */ n(
163
169
  "canvas",
164
170
  {
165
- ref: r,
166
- className: a,
171
+ ref: c,
172
+ className: r,
167
173
  style: { width: t, height: t, display: "inline-block" },
168
174
  role: "img",
169
175
  "aria-label": "Thinking"
@@ -171,8 +177,8 @@ function S({ size: t = 20, speed: o = 1, className: a }) {
171
177
  );
172
178
  }
173
179
  export {
174
- _ as AnimatedTerminalIcon,
175
- T as TerminalIcon,
176
- S as ThinkingOrb
180
+ I as AnimatedTerminalIcon,
181
+ L as TerminalIcon,
182
+ P as ThinkingOrb
177
183
  };
178
184
  //# 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}.