@iyulab/u-widgets 0.5.0 → 0.6.1

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/README.md CHANGED
@@ -88,6 +88,46 @@ AI assistants can use u-widgets via [MCP server](docs/mcp-server.md):
88
88
  npx @iyulab/u-widgets-mcp
89
89
  ```
90
90
 
91
+ ## Framework Integration
92
+
93
+ u-widgets is a browser-only Web Component library — it requires DOM APIs (`customElements`, `HTMLElement`) and cannot run in Node.js or server-side environments.
94
+
95
+ ### Next.js (App Router)
96
+
97
+ Create a client-side wrapper component:
98
+
99
+ ```tsx
100
+ // components/widget.tsx
101
+ "use client";
102
+ import "@iyulab/u-widgets";
103
+
104
+ export function Widget({ spec }: { spec: object }) {
105
+ return <u-widget spec={JSON.stringify(spec)} />;
106
+ }
107
+ ```
108
+
109
+ Use the wrapper from Server Components:
110
+
111
+ ```tsx
112
+ // app/dashboard/page.tsx
113
+ import { Widget } from "@/components/widget";
114
+
115
+ export default async function Page() {
116
+ const data = await fetchData();
117
+ return <Widget spec={{ widget: "stat-group", data }} />;
118
+ }
119
+ ```
120
+
121
+ For pages where SSR hydration mismatch is a concern, use dynamic import:
122
+
123
+ ```tsx
124
+ import dynamic from "next/dynamic";
125
+ const Widget = dynamic(
126
+ () => import("@/components/widget").then((m) => m.Widget),
127
+ { ssr: false }
128
+ );
129
+ ```
130
+
91
131
  ## Documentation
92
132
 
93
133
  - [Widget Reference](docs/widgets.md) — Schema, mapping, options, theming
@@ -1,7 +1,7 @@
1
1
  import { css as V, LitElement as I, nothing as P, html as E } from "lit";
2
2
  import { property as R, customElement as T } from "lit/decorators.js";
3
3
  import { a as D, t as $ } from "./tokens-x1kDxgG8.js";
4
- import * as z from "echarts/core";
4
+ import * as N from "echarts/core";
5
5
  import { BarChart as B, LineChart as q, PieChart as G, ScatterChart as H, RadarChart as K, HeatmapChart as U, BoxplotChart as W, FunnelChart as J, TreemapChart as Q } from "echarts/charts";
6
6
  import { GridComponent as X, TooltipComponent as Y, LegendComponent as Z, RadarComponent as ee, MarkLineComponent as te, VisualMapComponent as re } from "echarts/components";
7
7
  import { CanvasRenderer as se } from "echarts/renderers";
@@ -54,103 +54,109 @@ function F(e, t, i, r) {
54
54
  if (!Array.isArray(e)) return {};
55
55
  const n = t?.x ?? C(e), s = t?.y ?? [k(e)].filter(Boolean);
56
56
  if (!n || s.length === 0) return {};
57
- const c = e.map((a) => String(a[n] ?? "")), u = !!r.horizontal, l = s.map((a) => {
58
- const d = {
59
- name: a,
57
+ const c = e.map((l) => String(l[n] ?? "")), u = !!r.horizontal, f = Array.isArray(r.series) ? r.series : [], y = s.map((l, x) => {
58
+ const o = {
59
+ name: l,
60
60
  type: i,
61
- data: e.map((v) => v[a] ?? null)
61
+ data: e.map((h) => h[l] ?? null)
62
62
  };
63
- return r._area && (d.areaStyle = {}), r.smooth && (d.smooth = !0), r.step && (d.step = r.step === !0 ? "end" : r.step), d;
64
- }), m = { type: "category", data: c }, g = { type: "value" };
65
- r.histogram && (m.axisTick = { alignWithLabel: !0 }, l.forEach((a) => {
66
- a.barCategoryGap = "0%";
63
+ r._area && (o.areaStyle = {}), r.smooth && (o.smooth = !0), r.step && (o.step = r.step === !0 ? "end" : r.step);
64
+ const a = f[x];
65
+ return a && (a.color && (o.itemStyle = { color: a.color }, o.lineStyle = { ...o.lineStyle ?? {}, color: a.color }), a.lineStyle && (o.lineStyle = { ...o.lineStyle ?? {}, ...a.lineStyle }), a.symbol !== void 0 && (o.symbol = a.symbol), a.label && (o.name = a.label)), o;
66
+ }), b = { type: "category", data: c }, p = { type: "value" };
67
+ r.histogram && (b.axisTick = { alignWithLabel: !0 }, y.forEach((l) => {
68
+ l.barCategoryGap = "0%";
67
69
  }));
68
- const y = {
69
- xAxis: u ? g : m,
70
- yAxis: u ? m : g,
71
- series: l,
70
+ const g = {
71
+ xAxis: u ? p : b,
72
+ yAxis: u ? b : p,
73
+ series: y,
72
74
  tooltip: { trigger: "axis" }
73
75
  };
74
- s.length > 1 && (y.legend = { data: s }), r.stack && y.series.forEach((a) => {
75
- a.stack = "total";
76
+ if (s.length > 1) {
77
+ const l = y.map((x) => x.name);
78
+ g.legend = { data: l };
79
+ }
80
+ r.stack && g.series.forEach((l) => {
81
+ l.stack = "total";
76
82
  });
77
- const b = r.referenceLines;
78
- return Array.isArray(b) && b.length > 0 && l.length > 0 && (l[0].markLine = {
83
+ const m = r.referenceLines;
84
+ return Array.isArray(m) && m.length > 0 && y.length > 0 && (y[0].markLine = {
79
85
  silent: !0,
80
86
  symbol: "none",
81
- data: b.map((a) => {
82
- const d = {};
83
- a.axis === "x" ? d.xAxis = a.value : d.yAxis = a.value, a.label && (d.name = a.label);
84
- const v = {};
85
- return a.color && (v.color = a.color), a.style && (v.type = a.style), Object.keys(v).length > 0 && (d.lineStyle = v), a.label && (d.label = { formatter: a.label, position: "end" }), d;
87
+ data: m.map((l) => {
88
+ const x = {};
89
+ l.axis === "x" ? x.xAxis = l.value : x.yAxis = l.value, l.label && (x.name = l.label);
90
+ const o = {};
91
+ return l.color && (o.color = l.color), l.style && (o.type = l.style), Object.keys(o).length > 0 && (x.lineStyle = o), l.label && (x.label = { formatter: l.label, position: "end" }), x;
86
92
  })
87
- }), y;
93
+ }), g;
88
94
  }
89
95
  function ne(e, t, i) {
90
96
  if (!Array.isArray(e)) return {};
91
- const r = j(e), n = t?.x ?? r[0], s = (t?.y ?? [r[1]])[0], c = t?.color, u = t?.size, l = t?.opacity;
97
+ const r = j(e), n = t?.x ?? r[0], s = (t?.y ?? [r[1]])[0], c = t?.color, u = t?.size, f = t?.opacity;
92
98
  if (!n || !s) return {};
93
- const m = {
99
+ const y = {
94
100
  xAxis: { type: "value" },
95
101
  yAxis: { type: "value" },
96
102
  tooltip: { trigger: "item" }
97
103
  };
98
- let g = 1 / 0, y = -1 / 0;
99
- if (l)
100
- for (const f of e) {
101
- const o = Number(f[l] ?? 0);
102
- o < g && (g = o), o > y && (y = o);
104
+ let b = 1 / 0, p = -1 / 0;
105
+ if (f)
106
+ for (const o of e) {
107
+ const a = Number(o[f] ?? 0);
108
+ a < b && (b = a), a > p && (p = a);
103
109
  }
104
- const b = y - g || 1, a = (f) => {
105
- const o = [Number(f[n] ?? 0), Number(f[s] ?? 0)];
106
- if (u && o.push(Number(f[u] ?? 0)), l) {
107
- const A = 0.1 + 0.9 * ((Number(f[l] ?? 0) - g) / b);
108
- return { value: o, itemStyle: { opacity: Math.round(A * 100) / 100 } };
110
+ const g = p - b || 1, m = (o) => {
111
+ const a = [Number(o[n] ?? 0), Number(o[s] ?? 0)];
112
+ if (u && a.push(Number(o[u] ?? 0)), f) {
113
+ const S = 0.1 + 0.9 * ((Number(o[f] ?? 0) - b) / g);
114
+ return { value: a, itemStyle: { opacity: Math.round(S * 100) / 100 } };
109
115
  }
110
- return o;
111
- }, d = u ? (f) => {
112
- const p = (Array.isArray(f) ? f : f.value)[2] ?? 0;
113
- return Math.max(4, Math.min(60, Math.sqrt(p) * 4));
116
+ return a;
117
+ }, l = u ? (o) => {
118
+ const h = (Array.isArray(o) ? o : o.value)[2] ?? 0;
119
+ return Math.max(4, Math.min(60, Math.sqrt(h) * 4));
114
120
  } : void 0;
115
121
  if (c) {
116
- const f = /* @__PURE__ */ new Map();
117
- for (const p of e) {
118
- const A = String(p[c] ?? "unknown");
119
- f.has(A) || f.set(A, []), f.get(A).push(a(p));
122
+ const o = /* @__PURE__ */ new Map();
123
+ for (const h of e) {
124
+ const S = String(h[c] ?? "unknown");
125
+ o.has(S) || o.set(S, []), o.get(S).push(m(h));
120
126
  }
121
- const o = [];
122
- for (const [p, A] of f) {
123
- const h = { name: p, type: "scatter", data: A };
124
- d && (h.symbolSize = d), o.push(h);
127
+ const a = [];
128
+ for (const [h, S] of o) {
129
+ const d = { name: h, type: "scatter", data: S };
130
+ l && (d.symbolSize = l), a.push(d);
125
131
  }
126
- m.series = o, m.legend = { data: Array.from(f.keys()) };
132
+ y.series = a, y.legend = { data: Array.from(o.keys()) };
127
133
  } else {
128
- const o = { type: "scatter", data: e.map((p) => a(p)) };
129
- d && (o.symbolSize = d), m.series = [o];
134
+ const a = { type: "scatter", data: e.map((h) => m(h)) };
135
+ l && (a.symbolSize = l), y.series = [a];
130
136
  }
131
- const v = i.referenceLines;
132
- if (Array.isArray(v) && v.length > 0) {
133
- const f = m.series[0];
134
- f.markLine = {
137
+ const x = i.referenceLines;
138
+ if (Array.isArray(x) && x.length > 0) {
139
+ const o = y.series[0];
140
+ o.markLine = {
135
141
  silent: !0,
136
142
  symbol: "none",
137
- data: v.map((o) => {
138
- const p = {};
139
- o.axis === "x" ? p.xAxis = o.value : p.yAxis = o.value, o.label && (p.name = o.label);
140
- const A = {};
141
- return o.color && (A.color = o.color), o.style && (A.type = o.style), Object.keys(A).length > 0 && (p.lineStyle = A), o.label && (p.label = { formatter: o.label, position: "end" }), p;
143
+ data: x.map((a) => {
144
+ const h = {};
145
+ a.axis === "x" ? h.xAxis = a.value : h.yAxis = a.value, a.label && (h.name = a.label);
146
+ const S = {};
147
+ return a.color && (S.color = a.color), a.style && (S.type = a.style), Object.keys(S).length > 0 && (h.lineStyle = S), a.label && (h.label = { formatter: a.label, position: "end" }), h;
142
148
  })
143
149
  };
144
150
  }
145
- return m;
151
+ return y;
146
152
  }
147
153
  function ae(e, t, i) {
148
154
  if (!Array.isArray(e)) return {};
149
155
  const r = t?.label ?? C(e), n = t?.value ?? k(e);
150
156
  if (!r || !n) return {};
151
- const s = e.map((l) => ({
152
- name: String(l[r] ?? ""),
153
- value: Number(l[n] ?? 0)
157
+ const s = e.map((f) => ({
158
+ name: String(f[r] ?? ""),
159
+ value: Number(f[n] ?? 0)
154
160
  })), u = {
155
161
  type: "pie",
156
162
  radius: i.donut ? ["40%", "70%"] : "50%",
@@ -171,7 +177,7 @@ function oe(e, t, i) {
171
177
  name: String(u[r] ?? "")
172
178
  })), c = n.map((u) => ({
173
179
  name: u,
174
- value: e.map((l) => Number(l[u] ?? 0))
180
+ value: e.map((f) => Number(f[u] ?? 0))
175
181
  }));
176
182
  return {
177
183
  tooltip: {},
@@ -187,73 +193,73 @@ function oe(e, t, i) {
187
193
  }
188
194
  function le(e, t, i) {
189
195
  if (!Array.isArray(e)) return {};
190
- const r = e[0] ?? {}, n = Object.keys(r), s = n.filter((h) => typeof r[h] == "string"), c = n.filter((h) => typeof r[h] == "number"), u = t?.x ?? s[0], l = t?.y?.[0] ?? s.find((h) => h !== u), m = t?.value ?? c[0];
191
- if (!u || !l || !m) return {};
192
- const g = [], y = [], b = /* @__PURE__ */ new Set(), a = /* @__PURE__ */ new Set();
193
- for (const h of e) {
194
- const x = String(h[u] ?? ""), w = String(h[l] ?? "");
195
- b.has(x) || (b.add(x), g.push(x)), a.has(w) || (a.add(w), y.push(w));
196
+ const r = e[0] ?? {}, n = Object.keys(r), s = n.filter((d) => typeof r[d] == "string"), c = n.filter((d) => typeof r[d] == "number"), u = t?.x ?? s[0], f = t?.y?.[0] ?? s.find((d) => d !== u), y = t?.value ?? c[0];
197
+ if (!u || !f || !y) return {};
198
+ const b = [], p = [], g = /* @__PURE__ */ new Set(), m = /* @__PURE__ */ new Set();
199
+ for (const d of e) {
200
+ const A = String(d[u] ?? ""), w = String(d[f] ?? "");
201
+ g.has(A) || (g.add(A), b.push(A)), m.has(w) || (m.add(w), p.push(w));
196
202
  }
197
- const d = /* @__PURE__ */ new Map();
198
- g.forEach((h, x) => d.set(h, x));
199
- const v = /* @__PURE__ */ new Map();
200
- y.forEach((h, x) => v.set(h, x));
201
- const f = [];
202
- let o = 1 / 0, p = -1 / 0;
203
- for (const h of e) {
204
- const x = d.get(String(h[u] ?? "")) ?? 0, w = v.get(String(h[l] ?? "")) ?? 0, S = h[m] != null ? Number(h[m]) : null;
205
- f.push([x, w, S]), S != null && (S < o && (o = S), S > p && (p = S));
203
+ const l = /* @__PURE__ */ new Map();
204
+ b.forEach((d, A) => l.set(d, A));
205
+ const x = /* @__PURE__ */ new Map();
206
+ p.forEach((d, A) => x.set(d, A));
207
+ const o = [];
208
+ let a = 1 / 0, h = -1 / 0;
209
+ for (const d of e) {
210
+ const A = l.get(String(d[u] ?? "")) ?? 0, w = x.get(String(d[f] ?? "")) ?? 0, v = d[y] != null ? Number(d[y]) : null;
211
+ o.push([A, w, v]), v != null && (v < a && (a = v), v > h && (h = v));
206
212
  }
207
- isFinite(o) || (o = 0, p = 1);
208
- const A = i.colorRange ?? ["#313695", "#4575b4", "#74add1", "#abd9e9", "#fee090", "#fdae61", "#f46d43", "#d73027"];
213
+ isFinite(a) || (a = 0, h = 1);
214
+ const S = i.colorRange ?? ["#313695", "#4575b4", "#74add1", "#abd9e9", "#fee090", "#fdae61", "#f46d43", "#d73027"];
209
215
  return {
210
- xAxis: { type: "category", data: g, splitArea: { show: !0 } },
211
- yAxis: { type: "category", data: y, splitArea: { show: !0 } },
216
+ xAxis: { type: "category", data: b, splitArea: { show: !0 } },
217
+ yAxis: { type: "category", data: p, splitArea: { show: !0 } },
212
218
  visualMap: {
213
- min: i.min != null ? Number(i.min) : o,
214
- max: i.max != null ? Number(i.max) : p,
219
+ min: i.min != null ? Number(i.min) : a,
220
+ max: i.max != null ? Number(i.max) : h,
215
221
  calculable: !0,
216
222
  orient: "horizontal",
217
223
  left: "center",
218
224
  bottom: 0,
219
- inRange: { color: A }
225
+ inRange: { color: S }
220
226
  },
221
227
  tooltip: {
222
228
  trigger: "item",
223
- formatter: (h) => {
224
- const x = h.data;
225
- return x ? `${g[x[0]]} × ${y[x[1]]}: ${x[2] != null ? x[2] : "-"}` : "";
229
+ formatter: (d) => {
230
+ const A = d.data;
231
+ return A ? `${b[A[0]]} × ${p[A[1]]}: ${A[2] != null ? A[2] : "-"}` : "";
226
232
  }
227
233
  },
228
234
  grid: { bottom: 60 },
229
235
  series: [{
230
236
  type: "heatmap",
231
- data: f,
237
+ data: o,
232
238
  label: { show: i.showLabel !== !1 }
233
239
  }]
234
240
  };
235
241
  }
236
242
  function ce(e, t, i) {
237
243
  if (!Array.isArray(e) || e.length === 0) return {};
238
- const r = e[0] ?? {}, n = Object.keys(r), s = n.filter((b) => typeof r[b] == "string"), c = n.filter((b) => typeof r[b] == "number"), u = t?.x ?? s[0];
239
- let l;
244
+ const r = e[0] ?? {}, n = Object.keys(r), s = n.filter((g) => typeof r[g] == "string"), c = n.filter((g) => typeof r[g] == "number"), u = t?.x ?? s[0];
245
+ let f;
240
246
  if (t?.y && t.y.length >= 5)
241
- l = t.y.slice(0, 5);
247
+ f = t.y.slice(0, 5);
242
248
  else {
243
- const a = ["min", "q1", "median", "q3", "max"].filter((d) => c.includes(d));
244
- l = a.length === 5 ? a : c.slice(0, 5);
249
+ const m = ["min", "q1", "median", "q3", "max"].filter((l) => c.includes(l));
250
+ f = m.length === 5 ? m : c.slice(0, 5);
245
251
  }
246
- if (l.length < 5) return {};
247
- const m = u ? e.map((b) => String(b[u] ?? "")) : void 0, g = e.map(
248
- (b) => l.map((a) => Number(b[a] ?? 0))
249
- ), y = {
252
+ if (f.length < 5) return {};
253
+ const y = u ? e.map((g) => String(g[u] ?? "")) : void 0, b = e.map(
254
+ (g) => f.map((m) => Number(g[m] ?? 0))
255
+ ), p = {
250
256
  tooltip: { trigger: "item" },
251
257
  series: [{
252
258
  type: "boxplot",
253
- data: g
259
+ data: b
254
260
  }]
255
261
  };
256
- return m ? (y.xAxis = { type: "category", data: m }, y.yAxis = { type: "value" }) : (y.xAxis = { type: "category" }, y.yAxis = { type: "value" }), y;
262
+ return y ? (p.xAxis = { type: "category", data: y }, p.yAxis = { type: "value" }) : (p.xAxis = { type: "category" }, p.yAxis = { type: "value" }), p;
257
263
  }
258
264
  function C(e) {
259
265
  if (e.length === 0) return;
@@ -289,11 +295,11 @@ function fe(e, t, i) {
289
295
  if (!Array.isArray(e)) return {};
290
296
  const r = e, n = t?.x ?? C(r), s = (t?.y ?? [k(r)])[0];
291
297
  if (!n || !s) return {};
292
- const c = [], u = [], l = [], m = [];
293
- let g = 0;
294
- for (const y of r) {
295
- const b = String(y[n] ?? ""), a = Number(y[s] ?? 0);
296
- c.push(b), a >= 0 ? (u.push(g), l.push(a), m.push(null)) : (u.push(g + a), l.push(null), m.push(Math.abs(a))), g += a;
298
+ const c = [], u = [], f = [], y = [];
299
+ let b = 0;
300
+ for (const p of r) {
301
+ const g = String(p[n] ?? ""), m = Number(p[s] ?? 0);
302
+ c.push(g), m >= 0 ? (u.push(b), f.push(m), y.push(null)) : (u.push(b + m), f.push(null), y.push(Math.abs(m))), b += m;
297
303
  }
298
304
  return {
299
305
  tooltip: { trigger: "axis", axisPointer: { type: "shadow" } },
@@ -312,20 +318,20 @@ function fe(e, t, i) {
312
318
  name: "Positive",
313
319
  type: "bar",
314
320
  stack: "waterfall",
315
- data: l
321
+ data: f
316
322
  },
317
323
  {
318
324
  name: "Negative",
319
325
  type: "bar",
320
326
  stack: "waterfall",
321
- data: m
327
+ data: y
322
328
  }
323
329
  ]
324
330
  };
325
331
  }
326
332
  function he(e, t) {
327
333
  if (!Array.isArray(e)) return {};
328
- const i = e.map((r) => N(r));
334
+ const i = e.map((r) => z(r));
329
335
  return {
330
336
  tooltip: { trigger: "item" },
331
337
  series: [{
@@ -337,12 +343,12 @@ function he(e, t) {
337
343
  }]
338
344
  };
339
345
  }
340
- function N(e) {
346
+ function z(e) {
341
347
  const t = {
342
348
  name: String(e.name ?? ""),
343
349
  value: Number(e.value ?? 0)
344
350
  };
345
- return Array.isArray(e.children) && (t.children = e.children.map((i) => N(i))), t;
351
+ return Array.isArray(e.children) && (t.children = e.children.map((i) => z(i))), t;
346
352
  }
347
353
  function j(e) {
348
354
  if (e.length === 0) return [];
@@ -365,7 +371,7 @@ var ye = Object.defineProperty, de = Object.getOwnPropertyDescriptor, M = (e, t,
365
371
  (c = e[s]) && (n = (r ? c(t, i, n) : c(n)) || n);
366
372
  return r && n && ye(t, i, n), n;
367
373
  };
368
- z.use([
374
+ N.use([
369
375
  B,
370
376
  q,
371
377
  G,
@@ -401,7 +407,7 @@ let _ = class extends I {
401
407
  _initChart() {
402
408
  if (!(!this._container || !this.spec))
403
409
  try {
404
- this._chart = z.init(this._container), this._chart.on("click", (e) => {
410
+ this._chart = N.init(this._container), this._chart.on("click", (e) => {
405
411
  this._onChartClick(e);
406
412
  }), this._updateChart();
407
413
  } catch (e) {