impact-nova 3.0.0-alpha.7 → 3.0.0-alpha.9

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.
Files changed (103) hide show
  1. package/README.md +1 -1
  2. package/dist/components/data/expandable-list-item/sku-picker-chrome.d.ts +4 -0
  3. package/dist/components/data/expandable-list-item/sku-picker-chrome.js +37 -42
  4. package/dist/components/data-display/stereo-scatter/index.d.ts +2 -0
  5. package/dist/components/data-display/stereo-scatter/index.js +10 -0
  6. package/dist/components/data-display/stereo-scatter/internals/stereo-engine-frame.d.ts +41 -0
  7. package/dist/components/data-display/stereo-scatter/internals/stereo-engine-frame.js +178 -0
  8. package/dist/components/data-display/stereo-scatter/internals/stereo-engine-theme.d.ts +14 -0
  9. package/dist/components/data-display/stereo-scatter/internals/stereo-engine-theme.js +29 -0
  10. package/dist/components/data-display/stereo-scatter/internals/stereo-engine-wedges.d.ts +23 -0
  11. package/dist/components/data-display/stereo-scatter/internals/stereo-engine-wedges.js +80 -0
  12. package/dist/components/data-display/stereo-scatter/internals/stereo-engine.d.ts +120 -0
  13. package/dist/components/data-display/stereo-scatter/internals/stereo-engine.js +519 -0
  14. package/dist/components/data-display/stereo-scatter/internals/stereo-math.d.ts +64 -0
  15. package/dist/components/data-display/stereo-scatter/internals/stereo-math.js +129 -0
  16. package/dist/components/data-display/stereo-scatter/internals/stereo-model.d.ts +37 -0
  17. package/dist/components/data-display/stereo-scatter/internals/stereo-model.js +71 -0
  18. package/dist/components/data-display/stereo-scatter/internals/stereo-scatter-context.d.ts +33 -0
  19. package/dist/components/data-display/stereo-scatter/internals/stereo-scatter-context.js +19 -0
  20. package/dist/components/data-display/stereo-scatter/internals/stereo-scatter-key.d.ts +4 -0
  21. package/dist/components/data-display/stereo-scatter/internals/stereo-scatter-key.js +19 -0
  22. package/dist/components/data-display/stereo-scatter/internals/stereo-scatter-legend.d.ts +2 -0
  23. package/dist/components/data-display/stereo-scatter/internals/stereo-scatter-legend.js +75 -0
  24. package/dist/components/data-display/stereo-scatter/internals/stereo-scatter-scene.d.ts +2 -0
  25. package/dist/components/data-display/stereo-scatter/internals/stereo-scatter-scene.js +149 -0
  26. package/dist/components/data-display/stereo-scatter/internals/stereo-scatter-toolbar.d.ts +13 -0
  27. package/dist/components/data-display/stereo-scatter/internals/stereo-scatter-toolbar.js +93 -0
  28. package/dist/components/data-display/stereo-scatter/internals/stereo-scatter-tooltip.d.ts +2 -0
  29. package/dist/components/data-display/stereo-scatter/internals/stereo-scatter-tooltip.js +62 -0
  30. package/dist/components/data-display/stereo-scatter/internals/stereo-scatter-viewport.d.ts +3 -0
  31. package/dist/components/data-display/stereo-scatter/internals/stereo-scatter-viewport.js +41 -0
  32. package/dist/components/data-display/stereo-scatter/stereo-scatter.d.ts +12 -0
  33. package/dist/components/data-display/stereo-scatter/stereo-scatter.js +107 -0
  34. package/dist/components/data-display/stereo-scatter/stereo-scatter.stories-data.d.ts +11 -0
  35. package/dist/components/data-display/stereo-scatter/stereo-scatter.types.d.ts +69 -0
  36. package/dist/components/data-display/stereo-scatter/stereo-scatter.variants.d.ts +13 -0
  37. package/dist/components/data-display/stereo-scatter/stereo-scatter.variants.js +42 -0
  38. package/dist/components/feedback/tooltip/button-icon-tooltip.d.ts +3 -1
  39. package/dist/components/feedback/tooltip/button-icon-tooltip.js +22 -19
  40. package/dist/components/flows/iris-chat/IrisChatComposerVoiceCapture.d.ts +5 -0
  41. package/dist/components/flows/iris-chat/IrisChatComposerVoiceCapture.js +73 -0
  42. package/dist/components/flows/iris-chat/IrisChatVoiceWaveform.d.ts +3 -0
  43. package/dist/components/flows/iris-chat/IrisChatVoiceWaveform.js +25 -0
  44. package/dist/components/flows/iris-chat/index.d.ts +3 -1
  45. package/dist/components/flows/iris-chat/index.js +58 -53
  46. package/dist/components/flows/iris-chat/iris-chat-chrome.d.ts +39 -0
  47. package/dist/components/flows/iris-chat/iris-chat-chrome.js +325 -0
  48. package/dist/components/flows/iris-chat/iris-chat-close-animation.d.ts +12 -0
  49. package/dist/components/flows/iris-chat/iris-chat-close-animation.js +21 -0
  50. package/dist/components/flows/iris-chat/iris-chat-composer.js +266 -238
  51. package/dist/components/flows/iris-chat/iris-chat-context.d.ts +13 -0
  52. package/dist/components/flows/iris-chat/iris-chat-context.js +14 -10
  53. package/dist/components/flows/iris-chat/iris-chat-copy-feedback.d.ts +4 -0
  54. package/dist/components/flows/iris-chat/iris-chat-copy-feedback.js +16 -0
  55. package/dist/components/flows/iris-chat/iris-chat-frame.d.ts +31 -0
  56. package/dist/components/flows/iris-chat/iris-chat-frame.js +79 -0
  57. package/dist/components/flows/iris-chat/iris-chat-icons.d.ts +1 -0
  58. package/dist/components/flows/iris-chat/iris-chat-icons.js +28 -15
  59. package/dist/components/flows/iris-chat/iris-chat-launch-animation.d.ts +11 -0
  60. package/dist/components/flows/iris-chat/iris-chat-launch-animation.js +35 -0
  61. package/dist/components/flows/iris-chat/iris-chat-markdown.js +70 -50
  62. package/dist/components/flows/iris-chat/iris-chat-menu.js +91 -86
  63. package/dist/components/flows/iris-chat/iris-chat-speech.d.ts +52 -0
  64. package/dist/components/flows/iris-chat/iris-chat-speech.js +121 -0
  65. package/dist/components/flows/iris-chat/iris-chat-thread.d.ts +3 -0
  66. package/dist/components/flows/iris-chat/iris-chat-thread.js +241 -190
  67. package/dist/components/flows/iris-chat/iris-chat-window-chrome.d.ts +30 -0
  68. package/dist/components/flows/iris-chat/iris-chat-window-chrome.js +34 -0
  69. package/dist/components/flows/iris-chat/iris-chat-window-geometry-context.d.ts +14 -0
  70. package/dist/components/flows/iris-chat/iris-chat-window-geometry-context.js +15 -0
  71. package/dist/components/flows/iris-chat/iris-chat-window-geometry.d.ts +12 -0
  72. package/dist/components/flows/iris-chat/iris-chat-window-geometry.js +113 -0
  73. package/dist/components/flows/iris-chat/iris-chat-window-handles.d.ts +6 -0
  74. package/dist/components/flows/iris-chat/iris-chat-window-handles.js +50 -0
  75. package/dist/components/flows/iris-chat/iris-chat-window-shell.d.ts +8 -0
  76. package/dist/components/flows/iris-chat/iris-chat-window-shell.js +37 -0
  77. package/dist/components/flows/iris-chat/iris-chat.d.ts +3 -39
  78. package/dist/components/flows/iris-chat/iris-chat.js +22 -330
  79. package/dist/components/flows/iris-chat/iris-chat.types.d.ts +18 -0
  80. package/dist/components/flows/iris-chat/iris-chat.variants.d.ts +3 -3
  81. package/dist/components/flows/iris-chat/iris-chat.variants.js +21 -16
  82. package/dist/components/flows/iris-chat/use-iris-chat-root.d.ts +26 -0
  83. package/dist/components/flows/iris-chat/use-iris-chat-root.js +140 -0
  84. package/dist/components/forms/choice-card/choice-card.d.ts +1 -0
  85. package/dist/components/forms/choice-card/choice-card.js +183 -186
  86. package/dist/components/layout/header/header.js +1 -0
  87. package/dist/form-react/Fields/SelectField.js +66 -57
  88. package/dist/form-react/Fields/VirtualizedListField.js +140 -96
  89. package/dist/form-react/index.d.ts +1 -1
  90. package/dist/form-react/types/fields.types.d.ts +27 -0
  91. package/dist/form-react/types/reactHookForm.types.d.ts +18 -1
  92. package/dist/i18n/defaultMessages.d.ts +37 -0
  93. package/dist/i18n/defaultMessages.js +54 -18
  94. package/dist/i18n/index.d.ts +1 -1
  95. package/dist/i18n/locales/de.js +36 -0
  96. package/dist/i18n/locales/es.js +36 -0
  97. package/dist/i18n/locales/hi.js +36 -0
  98. package/dist/i18n/locales/kn.js +36 -0
  99. package/dist/impact-nova-components.css +19 -0
  100. package/dist/impact-nova.css +1 -1
  101. package/dist/llms/rules/installation.js +1 -1
  102. package/dist/llms/rules/requirements.js +1 -1
  103. package/package.json +5 -1
@@ -0,0 +1,129 @@
1
+ const p = Math.PI / 2 - 0.02, g = 0.06, I = {
2
+ iso: { azimuth: 0.62, elevation: 0.42 },
3
+ front: { azimuth: 0, elevation: 0 },
4
+ top: { azimuth: 0, elevation: p },
5
+ side: { azimuth: -Math.PI / 2, elevation: 0 }
6
+ };
7
+ function S(t, n, e) {
8
+ return Math.min(e, Math.max(n, t));
9
+ }
10
+ function z(t, n, e) {
11
+ return t + (n - t) * e;
12
+ }
13
+ function L(t) {
14
+ return 1 - (1 - t) ** 3;
15
+ }
16
+ function P(t) {
17
+ return t < 0.5 ? 4 * t ** 3 : 1 - (-2 * t + 2) ** 3 / 2;
18
+ }
19
+ function b(t, n) {
20
+ const e = Math.PI * 2;
21
+ let i = (n - t) % e;
22
+ return i > Math.PI && (i -= e), i < -Math.PI && (i += e), i;
23
+ }
24
+ function w(t, n) {
25
+ const e = Math.cos(t.elevation) * n;
26
+ return {
27
+ x: Math.sin(t.azimuth) * e,
28
+ y: Math.sin(t.elevation) * n,
29
+ z: Math.cos(t.azimuth) * e
30
+ };
31
+ }
32
+ function $(t, n) {
33
+ const e = t / Math.max(1, n), i = 10 ** Math.floor(Math.log10(e)), o = e / i;
34
+ return o < 1.5 ? i : o < 3 ? 2 * i : o < 7 ? 5 * i : 10 * i;
35
+ }
36
+ function O(t, n = 4) {
37
+ const e = t.filter(Number.isFinite);
38
+ let i = e.length ? Math.min(...e) : 0, o = e.length ? Math.max(...e) : 1;
39
+ if (i === o) {
40
+ const u = Math.abs(i) * 0.1 || 1;
41
+ i -= u, o += u;
42
+ }
43
+ const r = $(o - i, n), c = Math.floor(i / r) * r, h = Math.ceil(o / r) * r, s = [];
44
+ for (let u = c; u <= h + r / 2; u += r)
45
+ s.push(Number(u.toPrecision(12)));
46
+ return { min: c, max: h, ticks: s };
47
+ }
48
+ function T(t, n) {
49
+ const e = n.max - n.min || 1;
50
+ return (t - n.min) / e * 2 - 1;
51
+ }
52
+ function v(t, n = g) {
53
+ return t > n ? "solid" : t < -n ? "hashed" : "plain";
54
+ }
55
+ function F(t) {
56
+ return Math.min(1, Math.abs(t) / 0.5);
57
+ }
58
+ function d(t, n) {
59
+ const e = n.x - t.x, i = n.y - t.y, o = Math.hypot(e, i) || 1;
60
+ return { dx: e, dy: i, length: o, nx: -i / o, ny: e / o };
61
+ }
62
+ function a(t) {
63
+ return t.toFixed(2);
64
+ }
65
+ function N(t, n, e) {
66
+ const { nx: i, ny: o } = d(t, n), r = 0.45;
67
+ return [
68
+ `M${a(t.x + i * r)} ${a(t.y + o * r)}`,
69
+ `L${a(n.x + i * e)} ${a(n.y + o * e)}`,
70
+ `L${a(n.x - i * e)} ${a(n.y - o * e)}`,
71
+ `L${a(t.x - i * r)} ${a(t.y - o * r)}`,
72
+ "Z"
73
+ ].join("");
74
+ }
75
+ function _(t, n, e, i = 3) {
76
+ const { dx: o, dy: r, length: c, nx: h, ny: s } = d(t, n), u = Math.max(3, Math.floor(c / i)), m = [];
77
+ for (let x = 1; x <= u; x += 1) {
78
+ const f = x / u, M = t.x + o * f, y = t.y + r * f, l = Math.max(0.7, e * f);
79
+ m.push(
80
+ `M${a(M + h * l)} ${a(y + s * l)}L${a(M - h * l)} ${a(y - s * l)}`
81
+ );
82
+ }
83
+ return m.join("");
84
+ }
85
+ function R(t, n) {
86
+ return `M${a(t.x)} ${a(t.y)}L${a(n.x)} ${a(n.y)}`;
87
+ }
88
+ function C(t, n, e = 4) {
89
+ const i = [], o = /* @__PURE__ */ new Set(), r = [...t].sort((c, h) => h.priority - c.priority);
90
+ for (const c of r) {
91
+ if (c.x < 0 || c.y < 0 || c.x + c.width > n.width || c.y + c.height > n.height)
92
+ continue;
93
+ i.some(
94
+ (s) => c.x < s.x + s.width + e && c.x + c.width + e > s.x && c.y < s.y + s.height + e && c.y + c.height + e > s.y
95
+ ) || (i.push(c), o.add(c.id));
96
+ }
97
+ return o;
98
+ }
99
+ function D(t, n = 11) {
100
+ return t.length * n * 0.6;
101
+ }
102
+ const E = new Intl.NumberFormat("en-US", {
103
+ notation: "compact",
104
+ maximumFractionDigits: 1
105
+ });
106
+ function j(t) {
107
+ return E.format(t);
108
+ }
109
+ export {
110
+ p as STEREO_ELEVATION_LIMIT,
111
+ I as STEREO_VIEW_PRESETS,
112
+ g as STEREO_WEDGE_THRESHOLD,
113
+ S as clamp,
114
+ P as easeInOutCubic,
115
+ L as easeOutCubic,
116
+ D as estimateLabelWidth,
117
+ j as formatCompactNumber,
118
+ _ as hashedWedgePath,
119
+ z as lerp,
120
+ R as linePath,
121
+ O as niceDomain,
122
+ T as normalizeToCube,
123
+ w as orbitOffset,
124
+ C as placeLabels,
125
+ b as shortestAngle,
126
+ N as solidWedgePath,
127
+ F as wedgeStrength,
128
+ v as wedgeStyleForDepth
129
+ };
@@ -0,0 +1,37 @@
1
+ import { StereoScatterCluster, StereoScatterPoint } from '../stereo-scatter.types';
2
+ import { NiceDomain, Vec3 } from './stereo-math';
3
+ export interface StereoNode {
4
+ point: StereoScatterPoint;
5
+ position: Vec3;
6
+ }
7
+ export interface StereoClusterModel {
8
+ cluster: StereoScatterCluster;
9
+ index: number;
10
+ color: string;
11
+ nodes: StereoNode[];
12
+ centroid: Vec3;
13
+ /** Mean of the raw metric values. */
14
+ mean: {
15
+ x: number;
16
+ y: number;
17
+ z: number;
18
+ };
19
+ /** RMS distance of members from the centroid in scene units. */
20
+ spread: number;
21
+ }
22
+ export interface StereoModel {
23
+ domains: {
24
+ x: NiceDomain;
25
+ y: NiceDomain;
26
+ z: NiceDomain;
27
+ };
28
+ clusters: StereoClusterModel[];
29
+ clusterById: Map<string, StereoClusterModel>;
30
+ nodeById: Map<string, StereoNode>;
31
+ }
32
+ /**
33
+ * `nice` rounds domains to tick boundaries for variants that draw axes.
34
+ * `tight` fits the data extent so tick-less variants fill the scene cube.
35
+ */
36
+ export type StereoDomainMode = "nice" | "tight";
37
+ export declare function buildStereoModel(points: readonly StereoScatterPoint[], clusters: readonly StereoScatterCluster[], domainMode?: StereoDomainMode): StereoModel;
@@ -0,0 +1,71 @@
1
+ import { chartPaletteCssVar as I } from "../../chart/chart-palette.js";
2
+ import { normalizeToCube as l, niceDomain as h } from "./stereo-math.js";
3
+ function a(o) {
4
+ return o.length === 0 ? 0 : o.reduce((e, r) => e + r, 0) / o.length;
5
+ }
6
+ function M(o) {
7
+ const e = h(o), r = o.filter(Number.isFinite);
8
+ if (r.length === 0) return e;
9
+ const c = Math.min(...r), s = Math.max(...r);
10
+ if (c === s) return e;
11
+ const p = (s - c) * 0.04;
12
+ return { min: c - p, max: s + p, ticks: e.ticks };
13
+ }
14
+ function b(o, e, r = "nice") {
15
+ const c = r === "tight" ? M : h, s = {
16
+ x: c(o.map((t) => t.x)),
17
+ y: c(o.map((t) => t.y)),
18
+ z: c(o.map((t) => t.z))
19
+ }, p = [...e], f = new Set(e.map((t) => t.id));
20
+ for (const t of o)
21
+ f.has(t.clusterId) || (f.add(t.clusterId), p.push({ id: t.clusterId, label: t.clusterId }));
22
+ const u = /* @__PURE__ */ new Map(), x = /* @__PURE__ */ new Map();
23
+ for (const t of o) {
24
+ const m = {
25
+ point: t,
26
+ position: {
27
+ x: l(t.x, s.x),
28
+ y: l(t.y, s.y),
29
+ z: l(t.z, s.z)
30
+ }
31
+ };
32
+ x.set(t.id, m);
33
+ const i = u.get(t.clusterId) ?? [];
34
+ i.push(m), u.set(t.clusterId, i);
35
+ }
36
+ const y = p.map((t, m) => {
37
+ const i = u.get(t.id) ?? [], d = {
38
+ x: a(i.map((n) => n.position.x)),
39
+ y: a(i.map((n) => n.position.y)),
40
+ z: a(i.map((n) => n.position.z))
41
+ }, z = Math.sqrt(
42
+ a(
43
+ i.map(
44
+ (n) => (n.position.x - d.x) ** 2 + (n.position.y - d.y) ** 2 + (n.position.z - d.z) ** 2
45
+ )
46
+ )
47
+ );
48
+ return {
49
+ cluster: t,
50
+ index: m,
51
+ color: t.color ?? I(m),
52
+ nodes: i,
53
+ centroid: d,
54
+ mean: {
55
+ x: a(i.map((n) => n.point.x)),
56
+ y: a(i.map((n) => n.point.y)),
57
+ z: a(i.map((n) => n.point.z))
58
+ },
59
+ spread: z
60
+ };
61
+ });
62
+ return {
63
+ domains: s,
64
+ clusters: y,
65
+ clusterById: new Map(y.map((t) => [t.cluster.id, t])),
66
+ nodeById: x
67
+ };
68
+ }
69
+ export {
70
+ b as buildStereoModel
71
+ };
@@ -0,0 +1,33 @@
1
+ import { StereoScatterHover, StereoScatterPoint, StereoScatterVariant, StereoScatterView } from '../stereo-scatter.types';
2
+ import { StereoModel } from './stereo-model';
3
+ import * as React from "react";
4
+ export interface StereoResolvedAxis {
5
+ label: string;
6
+ format: (value: number) => string;
7
+ }
8
+ export interface StereoScatterContextValue {
9
+ variant: StereoScatterVariant;
10
+ model: StereoModel;
11
+ axes: {
12
+ x: StereoResolvedAxis;
13
+ y: StereoResolvedAxis;
14
+ z: StereoResolvedAxis;
15
+ };
16
+ hiddenClusterIds: string[];
17
+ toggleCluster: (clusterId: string) => void;
18
+ focusedClusterId: string | null;
19
+ setFocusedClusterId: (clusterId: string | null) => void;
20
+ legendHoverClusterId: string | null;
21
+ setLegendHoverClusterId: (clusterId: string | null) => void;
22
+ hover: StereoScatterHover | null;
23
+ setHover: (hover: StereoScatterHover | null) => void;
24
+ autoRotate: boolean;
25
+ defaultView: StereoScatterView;
26
+ onPointClick?: (point: StereoScatterPoint) => void;
27
+ chartLabel: string;
28
+ }
29
+ export declare function StereoScatterProvider({ value, children, }: {
30
+ value: StereoScatterContextValue;
31
+ children: React.ReactNode;
32
+ }): import("react/jsx-runtime").JSX.Element;
33
+ export declare function useStereoScatterContext(): StereoScatterContextValue;
@@ -0,0 +1,19 @@
1
+ import { jsx as n } from "react/jsx-runtime";
2
+ import * as e from "react";
3
+ const r = e.createContext(null);
4
+ function S({
5
+ value: t,
6
+ children: o
7
+ }) {
8
+ return /* @__PURE__ */ n(r.Provider, { value: t, children: o });
9
+ }
10
+ function i() {
11
+ const t = e.useContext(r);
12
+ if (!t)
13
+ throw new Error("StereoScatter components must be used within StereoScatter");
14
+ return t;
15
+ }
16
+ export {
17
+ S as StereoScatterProvider,
18
+ i as useStereoScatterContext
19
+ };
@@ -0,0 +1,4 @@
1
+ /** Explains the wedge-dash notation; axis names live on the axis rods in the scene. */
2
+ export declare function StereoScatterKey({ className }: {
3
+ className?: string;
4
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,19 @@
1
+ import { jsx as e, jsxs as i } from "react/jsx-runtime";
2
+ import { useImpactNovaI18n as c } from "../../../../i18n/use-impact-nova-i18n.js";
3
+ import { cn as d } from "../../../../lib/utils.js";
4
+ import { stereoScatterKeyVariants as l } from "../stereo-scatter.variants.js";
5
+ import { solidWedgePath as m, hashedWedgePath as h } from "./stereo-math.js";
6
+ const a = { x: 2, y: 5 }, o = { x: 20, y: 5 };
7
+ function y({ className: s }) {
8
+ const { t: r } = c(), n = [
9
+ { kind: "solid", label: r("stereoScatter.towardViewer") },
10
+ { kind: "hashed", label: r("stereoScatter.awayFromViewer") }
11
+ ];
12
+ return /* @__PURE__ */ e("div", { "data-component": "stereo-scatter-key", className: d(l(), s), children: n.map((t) => /* @__PURE__ */ i("span", { className: "flex items-center gap-2", children: [
13
+ /* @__PURE__ */ e("svg", { width: "22", height: "10", viewBox: "0 0 22 10", "aria-hidden": !0, className: "shrink-0 text-content", children: t.kind === "solid" ? /* @__PURE__ */ e("path", { d: m(a, o, 3.6), fill: "currentColor" }) : /* @__PURE__ */ e("path", { d: h(a, o, 3.6, 2.6), stroke: "currentColor", strokeWidth: "1", fill: "none" }) }),
14
+ /* @__PURE__ */ e("span", { className: "truncate", children: t.label })
15
+ ] }, t.kind)) });
16
+ }
17
+ export {
18
+ y as StereoScatterKey
19
+ };
@@ -0,0 +1,2 @@
1
+ import { StereoScatterLegendProps } from '../stereo-scatter.types';
2
+ export declare const StereoScatterLegend: import('react').ForwardRefExoticComponent<StereoScatterLegendProps & import('react').RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,75 @@
1
+ import { jsxs as a, jsx as s } from "react/jsx-runtime";
2
+ import { Cross as C } from "impact-nova-icons";
3
+ import { createComponent as h } from "../../../../lib/primitives/create-component.js";
4
+ import { cn as S } from "../../../../lib/utils.js";
5
+ import { useImpactNovaI18n as x } from "../../../../i18n/use-impact-nova-i18n.js";
6
+ import { stereoScatterLegendItemVariants as I, stereoScatterLegendVariants as N } from "../stereo-scatter.variants.js";
7
+ import { useStereoScatterContext as L } from "./stereo-scatter-context.js";
8
+ const P = h(
9
+ "StereoScatterLegend",
10
+ ({ className: i, ...u }, m) => {
11
+ const { t: o } = x(), {
12
+ model: c,
13
+ hiddenClusterIds: p,
14
+ toggleCluster: b,
15
+ focusedClusterId: l,
16
+ setFocusedClusterId: g,
17
+ legendHoverClusterId: f,
18
+ setLegendHoverClusterId: n
19
+ } = L(), d = f ?? l, v = l ? c.clusterById.get(l) : void 0;
20
+ return /* @__PURE__ */ a(
21
+ "div",
22
+ {
23
+ ref: m,
24
+ "data-component": "stereo-scatter-legend",
25
+ role: "group",
26
+ "aria-label": o("stereoScatter.legend"),
27
+ className: S(N(), i),
28
+ onPointerLeave: () => n(null),
29
+ ...u,
30
+ children: [
31
+ c.clusters.map((e) => {
32
+ const t = e.cluster.id, r = p.includes(t);
33
+ return /* @__PURE__ */ a(
34
+ "button",
35
+ {
36
+ type: "button",
37
+ "aria-pressed": !r,
38
+ "aria-label": r ? o("stereoScatter.showCluster", { label: e.cluster.label }) : o("stereoScatter.hideCluster", { label: e.cluster.label }),
39
+ className: I({
40
+ hidden: r,
41
+ dimmed: !r && d !== null && d !== t
42
+ }),
43
+ onClick: () => b(t),
44
+ onPointerEnter: () => n(r ? null : t),
45
+ onFocus: () => n(r ? null : t),
46
+ onBlur: () => n(null),
47
+ children: [
48
+ /* @__PURE__ */ s("span", { className: "size-2.5 shrink-0 rounded-full", style: { backgroundColor: e.color }, "aria-hidden": !0 }),
49
+ /* @__PURE__ */ s("span", { children: e.cluster.label }),
50
+ /* @__PURE__ */ s("span", { className: "tabular-nums text-content-muted", children: e.nodes.length })
51
+ ]
52
+ },
53
+ t
54
+ );
55
+ }),
56
+ v ? /* @__PURE__ */ a(
57
+ "button",
58
+ {
59
+ type: "button",
60
+ className: "inline-flex items-center gap-1 rounded-full border border-stroke bg-canvas-elevated py-0.5 pe-1.5 ps-2 text-xs font-semibold leading-4 text-brand hover:bg-canvas-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring",
61
+ onClick: () => g(null),
62
+ children: [
63
+ o("stereoScatter.clearFocus"),
64
+ /* @__PURE__ */ s(C, { className: "size-3.5" })
65
+ ]
66
+ }
67
+ ) : null
68
+ ]
69
+ }
70
+ );
71
+ }
72
+ );
73
+ export {
74
+ P as StereoScatterLegend
75
+ };
@@ -0,0 +1,2 @@
1
+ /** Hosts the WebGL engine, the orientation gizmo, and the camera toolbar. */
2
+ export declare function StereoScatterScene(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,149 @@
1
+ import { jsxs as k, Fragment as F, jsx as R } from "react/jsx-runtime";
2
+ import * as t from "react";
3
+ import { useImpactNovaI18n as H } from "../../../../i18n/use-impact-nova-i18n.js";
4
+ import { createStereoEngine as L } from "./stereo-engine.js";
5
+ import { useStereoScatterContext as N } from "./stereo-scatter-context.js";
6
+ import { StereoScatterToolbar as O } from "./stereo-scatter-toolbar.js";
7
+ const y = Math.PI / 15, h = 1.25;
8
+ function j() {
9
+ const [l, n] = t.useState(
10
+ () => typeof window < "u" && window.matchMedia?.("(prefers-reduced-motion: reduce)").matches === !0
11
+ );
12
+ return t.useEffect(() => {
13
+ const a = window.matchMedia?.("(prefers-reduced-motion: reduce)");
14
+ if (!a) return;
15
+ const u = () => n(a.matches);
16
+ return a.addEventListener("change", u), () => a.removeEventListener("change", u);
17
+ }, []), l;
18
+ }
19
+ function q() {
20
+ const { t: l } = H(), n = N(), {
21
+ variant: a,
22
+ model: u,
23
+ axes: i,
24
+ hiddenClusterIds: g,
25
+ focusedClusterId: v,
26
+ legendHoverClusterId: S,
27
+ defaultView: b,
28
+ chartLabel: V
29
+ } = n, C = t.useRef(null), I = t.useRef(null), s = t.useRef(null), c = t.useRef(n);
30
+ c.current = n;
31
+ const d = j(), [M, z] = t.useState(!1), [x, E] = t.useState(n.autoRotate), [D, p] = t.useState(b), w = t.useMemo(
32
+ () => ({
33
+ hiddenClusterIds: new Set(g),
34
+ activeClusterId: S ?? v,
35
+ focusedClusterId: v
36
+ }),
37
+ [v, g, S]
38
+ ), A = t.useRef(w);
39
+ A.current = w, t.useEffect(() => {
40
+ E(n.autoRotate);
41
+ }, [n.autoRotate]), t.useEffect(() => {
42
+ const o = C.current;
43
+ if (!o) return;
44
+ const r = (e) => {
45
+ const m = c.current;
46
+ if (!e) {
47
+ m.setFocusedClusterId(null);
48
+ return;
49
+ }
50
+ if (e.type === "cluster") {
51
+ m.setFocusedClusterId(m.focusedClusterId === e.id ? null : e.id);
52
+ return;
53
+ }
54
+ const B = m.model.nodeById.get(e.id);
55
+ B && m.onPointClick?.(B.point);
56
+ }, f = L({
57
+ container: o,
58
+ gizmo: I.current,
59
+ variant: a,
60
+ model: u,
61
+ axes: {
62
+ x: { label: i.x.label, format: (e) => c.current.axes.x.format(e) },
63
+ y: { label: i.y.label, format: (e) => c.current.axes.y.format(e) },
64
+ z: { label: i.z.label, format: (e) => c.current.axes.z.format(e) }
65
+ },
66
+ defaultView: b,
67
+ autoRotate: !1,
68
+ reducedMotion: d,
69
+ formatStoreCount: (e) => l("stereoScatter.storeCount", { count: e }),
70
+ onHover: (e) => c.current.setHover(e),
71
+ onClick: r
72
+ });
73
+ if (!f) {
74
+ z(!0);
75
+ return;
76
+ }
77
+ return z(!1), f.setEmphasis(A.current), s.current = f, () => {
78
+ s.current = null, c.current.setHover(null), f.dispose();
79
+ };
80
+ }, [a, u, i.x.label, i.y.label, i.z.label, b, d]), t.useEffect(() => {
81
+ s.current?.setEmphasis(w);
82
+ }, [w]), t.useEffect(() => {
83
+ s.current?.setAutoRotate(x && !d);
84
+ }, [x, d, a, u]);
85
+ const P = (o) => {
86
+ p(o), s.current?.setView(o);
87
+ }, T = (o) => {
88
+ const r = s.current;
89
+ if (!r) return;
90
+ const e = {
91
+ ArrowLeft: () => r.rotateBy(-y, 0),
92
+ ArrowRight: () => r.rotateBy(y, 0),
93
+ ArrowUp: () => r.rotateBy(0, y / 2),
94
+ ArrowDown: () => r.rotateBy(0, -y / 2),
95
+ "+": () => r.zoomBy(h),
96
+ "=": () => r.zoomBy(h),
97
+ "-": () => r.zoomBy(1 / h),
98
+ 0: () => r.resetView(),
99
+ Escape: () => n.setFocusedClusterId(null)
100
+ }[o.key];
101
+ e && (o.preventDefault(), o.key.startsWith("Arrow") && p(null), e());
102
+ };
103
+ return /* @__PURE__ */ k(F, { children: [
104
+ /* @__PURE__ */ R(
105
+ "div",
106
+ {
107
+ ref: C,
108
+ "data-slot": "stereo-scatter-stage",
109
+ role: "img",
110
+ tabIndex: 0,
111
+ "aria-label": `${V}. ${l("stereoScatter.interactionHint")}`,
112
+ "aria-roledescription": "3D chart",
113
+ className: "absolute inset-0 rounded-[inherit] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-focus-ring",
114
+ onKeyDown: T,
115
+ onPointerDown: () => {
116
+ p(null);
117
+ }
118
+ }
119
+ ),
120
+ /* @__PURE__ */ R(
121
+ "svg",
122
+ {
123
+ ref: I,
124
+ viewBox: "0 0 56 56",
125
+ "aria-hidden": !0,
126
+ className: "pointer-events-none absolute bottom-3 start-3 z-[2] size-14 text-content-secondary"
127
+ }
128
+ ),
129
+ M ? /* @__PURE__ */ R("div", { className: "absolute inset-0 z-[3] flex items-center justify-center p-6 text-center text-sm text-content-muted", children: l("stereoScatter.webglUnavailable") }) : null,
130
+ /* @__PURE__ */ R(
131
+ O,
132
+ {
133
+ activeView: D,
134
+ autoRotating: x,
135
+ canAutoRotate: !d,
136
+ onView: P,
137
+ onZoomIn: () => s.current?.zoomBy(h),
138
+ onZoomOut: () => s.current?.zoomBy(1 / h),
139
+ onToggleAutoRotate: () => E((o) => !o),
140
+ onReset: () => {
141
+ p(b), s.current?.resetView(), n.setFocusedClusterId(null);
142
+ }
143
+ }
144
+ )
145
+ ] });
146
+ }
147
+ export {
148
+ q as StereoScatterScene
149
+ };
@@ -0,0 +1,13 @@
1
+ import { StereoScatterView } from '../stereo-scatter.types';
2
+ export interface StereoScatterToolbarProps {
3
+ className?: string;
4
+ activeView: StereoScatterView | null;
5
+ autoRotating: boolean;
6
+ canAutoRotate: boolean;
7
+ onView: (view: StereoScatterView) => void;
8
+ onZoomIn: () => void;
9
+ onZoomOut: () => void;
10
+ onToggleAutoRotate: () => void;
11
+ onReset: () => void;
12
+ }
13
+ export declare function StereoScatterToolbar({ className, activeView, autoRotating, canAutoRotate, onView, onZoomIn, onZoomOut, onToggleAutoRotate, onReset, }: StereoScatterToolbarProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,93 @@
1
+ import { jsxs as d, jsx as e } from "react/jsx-runtime";
2
+ import { RemoveMinimize as h, Plus as N, Pause as S, Play as w, Reset as v } from "impact-nova-icons";
3
+ import { useImpactNovaI18n as x } from "../../../../i18n/use-impact-nova-i18n.js";
4
+ import { cn as z } from "../../../../lib/utils.js";
5
+ import { stereoScatterToolbarButtonVariants as o, stereoScatterToolbarVariants as f } from "../stereo-scatter.variants.js";
6
+ const k = [
7
+ { view: "iso", short: "viewIso" },
8
+ { view: "front", short: "viewFront" },
9
+ { view: "top", short: "viewTop" },
10
+ { view: "side", short: "viewSide" }
11
+ ];
12
+ function V({
13
+ className: s,
14
+ activeView: i,
15
+ autoRotating: r,
16
+ canAutoRotate: l,
17
+ onView: n,
18
+ onZoomIn: c,
19
+ onZoomOut: m,
20
+ onToggleAutoRotate: p,
21
+ onReset: b
22
+ }) {
23
+ const { t } = x();
24
+ return /* @__PURE__ */ d(
25
+ "div",
26
+ {
27
+ role: "toolbar",
28
+ "aria-label": t("stereoScatter.toolbar"),
29
+ "data-component": "stereo-scatter-toolbar",
30
+ className: z(f(), s),
31
+ onPointerDown: (a) => a.stopPropagation(),
32
+ children: [
33
+ k.map(({ view: a, short: u }) => /* @__PURE__ */ e(
34
+ "button",
35
+ {
36
+ type: "button",
37
+ className: o(),
38
+ "aria-pressed": i === a,
39
+ onClick: () => n(a),
40
+ children: t(`stereoScatter.${u}`)
41
+ },
42
+ a
43
+ )),
44
+ /* @__PURE__ */ e("span", { className: "mx-1 h-[18px] w-px bg-stroke", "aria-hidden": !0 }),
45
+ /* @__PURE__ */ e(
46
+ "button",
47
+ {
48
+ type: "button",
49
+ className: o(),
50
+ "aria-label": t("stereoScatter.zoomOut"),
51
+ onClick: m,
52
+ children: /* @__PURE__ */ e(h, { className: "size-4" })
53
+ }
54
+ ),
55
+ /* @__PURE__ */ e(
56
+ "button",
57
+ {
58
+ type: "button",
59
+ className: o(),
60
+ "aria-label": t("stereoScatter.zoomIn"),
61
+ onClick: c,
62
+ children: /* @__PURE__ */ e(N, { className: "size-4" })
63
+ }
64
+ ),
65
+ /* @__PURE__ */ e("span", { className: "mx-1 h-[18px] w-px bg-stroke", "aria-hidden": !0 }),
66
+ l ? /* @__PURE__ */ e(
67
+ "button",
68
+ {
69
+ type: "button",
70
+ className: o(),
71
+ "aria-label": t("stereoScatter.autoRotate"),
72
+ "aria-pressed": r,
73
+ onClick: p,
74
+ children: r ? /* @__PURE__ */ e(S, { className: "size-4" }) : /* @__PURE__ */ e(w, { className: "size-4" })
75
+ }
76
+ ) : null,
77
+ /* @__PURE__ */ e(
78
+ "button",
79
+ {
80
+ type: "button",
81
+ className: o(),
82
+ "aria-label": t("stereoScatter.resetView"),
83
+ onClick: b,
84
+ children: /* @__PURE__ */ e(v, { className: "size-4" })
85
+ }
86
+ )
87
+ ]
88
+ }
89
+ );
90
+ }
91
+ export {
92
+ V as StereoScatterToolbar
93
+ };
@@ -0,0 +1,2 @@
1
+ import { StereoScatterTooltipProps } from '../stereo-scatter.types';
2
+ export declare const StereoScatterTooltip: import('react').ForwardRefExoticComponent<StereoScatterTooltipProps & import('react').RefAttributes<HTMLDivElement>>;