@alfadocs/ui-kit 0.83.0 → 0.84.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.
Files changed (72) hide show
  1. package/dist/_chunks/dashboard-grid-D2dm0IRN.js +691 -0
  2. package/dist/_chunks/widget-picker-DEmTVuFL.js +193 -0
  3. package/dist/agent-catalog.json +182 -1
  4. package/dist/agent-i18n/en.json +20 -0
  5. package/dist/components/dashboard-grid/dashboard-grid-engine.d.ts +37 -0
  6. package/dist/components/dashboard-grid/dashboard-grid.agent.d.ts +4 -0
  7. package/dist/components/dashboard-grid/dashboard-grid.d.ts +74 -0
  8. package/dist/components/dashboard-grid/index.d.ts +3 -0
  9. package/dist/components/dashboard-grid/index.js +6 -0
  10. package/dist/components/index.d.ts +2 -0
  11. package/dist/components/select/select.d.ts +8 -5
  12. package/dist/components/widget-picker/index.d.ts +3 -0
  13. package/dist/components/widget-picker/index.js +6 -0
  14. package/dist/components/widget-picker/widget-picker.agent.d.ts +4 -0
  15. package/dist/components/widget-picker/widget-picker.d.ts +49 -0
  16. package/dist/i18n/locales/ar.d.ts +21 -0
  17. package/dist/i18n/locales/ar.js +21 -0
  18. package/dist/i18n/locales/de.d.ts +21 -0
  19. package/dist/i18n/locales/de.js +21 -0
  20. package/dist/i18n/locales/el.d.ts +21 -0
  21. package/dist/i18n/locales/el.js +21 -0
  22. package/dist/i18n/locales/en.d.ts +21 -0
  23. package/dist/i18n/locales/en.js +21 -0
  24. package/dist/i18n/locales/es.d.ts +21 -0
  25. package/dist/i18n/locales/es.js +21 -0
  26. package/dist/i18n/locales/fr.d.ts +21 -0
  27. package/dist/i18n/locales/fr.js +21 -0
  28. package/dist/i18n/locales/hi.d.ts +21 -0
  29. package/dist/i18n/locales/hi.js +21 -0
  30. package/dist/i18n/locales/it.d.ts +21 -0
  31. package/dist/i18n/locales/it.js +21 -0
  32. package/dist/i18n/locales/ja.d.ts +21 -0
  33. package/dist/i18n/locales/ja.js +21 -0
  34. package/dist/i18n/locales/nl.d.ts +21 -0
  35. package/dist/i18n/locales/nl.js +21 -0
  36. package/dist/i18n/locales/pl.d.ts +21 -0
  37. package/dist/i18n/locales/pl.js +21 -0
  38. package/dist/i18n/locales/pt.d.ts +21 -0
  39. package/dist/i18n/locales/pt.js +21 -0
  40. package/dist/i18n/locales/ro.d.ts +21 -0
  41. package/dist/i18n/locales/ro.js +21 -0
  42. package/dist/i18n/locales/ru.d.ts +21 -0
  43. package/dist/i18n/locales/ru.js +21 -0
  44. package/dist/i18n/locales/sq.d.ts +21 -0
  45. package/dist/i18n/locales/sq.js +21 -0
  46. package/dist/i18n/locales/sv.d.ts +21 -0
  47. package/dist/i18n/locales/sv.js +21 -0
  48. package/dist/i18n/locales/tr.d.ts +21 -0
  49. package/dist/i18n/locales/tr.js +21 -0
  50. package/dist/i18n/locales/zh.d.ts +21 -0
  51. package/dist/i18n/locales/zh.js +21 -0
  52. package/dist/index.js +74 -68
  53. package/dist/locales/ar.json +21 -0
  54. package/dist/locales/de.json +21 -0
  55. package/dist/locales/el.json +21 -0
  56. package/dist/locales/en.json +21 -0
  57. package/dist/locales/es.json +21 -0
  58. package/dist/locales/fr.json +21 -0
  59. package/dist/locales/hi.json +21 -0
  60. package/dist/locales/it.json +21 -0
  61. package/dist/locales/ja.json +21 -0
  62. package/dist/locales/nl.json +21 -0
  63. package/dist/locales/pl.json +21 -0
  64. package/dist/locales/pt.json +21 -0
  65. package/dist/locales/ro.json +21 -0
  66. package/dist/locales/ru.json +21 -0
  67. package/dist/locales/sq.json +21 -0
  68. package/dist/locales/sv.json +21 -0
  69. package/dist/locales/tr.json +21 -0
  70. package/dist/locales/zh.json +21 -0
  71. package/dist/tokens.css +1 -1
  72. package/package.json +9 -1
@@ -0,0 +1,691 @@
1
+ import { jsxs as _, jsx as w } from "react/jsx-runtime";
2
+ import { forwardRef as Te, useRef as S, useMemo as L, useState as O, useCallback as D, useEffect as X, useImperativeHandle as We, useContext as $e, Children as Ie, isValidElement as Ae, Fragment as je, createContext as Fe } from "react";
3
+ import { c as Ge } from "./index-D2ZczOXr.js";
4
+ import { useTranslation as ke } from "react-i18next";
5
+ import { I as re } from "./icon-button-C_kbcd7I.js";
6
+ import { u as U } from "./use-isomorphic-layout-effect-BGfaCOP1.js";
7
+ import { u as Ke } from "./registry-DvAUVLHh.js";
8
+ import { P as _e } from "./plus-DzMQ_c6b.js";
9
+ import { G as Ve } from "./grip-vertical-onSb1JXO.js";
10
+ import { X as Be } from "./x-B5YnXwCz.js";
11
+ import { c as He } from "./createLucideIcon-DhHxpK9K.js";
12
+ /**
13
+ * @license lucide-react v1.22.0 - ISC
14
+ *
15
+ * This source code is licensed under the ISC license.
16
+ * See the LICENSE file in the root directory of this source tree.
17
+ */
18
+ const Ye = [
19
+ ["path", { d: "M19 13v6h-6", key: "1hxl6d" }],
20
+ ["path", { d: "M5 11V5h6", key: "12e2xe" }],
21
+ ["path", { d: "m5 5 14 14", key: "11anup" }]
22
+ ], qe = He("move-diagonal-2", Ye), Oe = {
23
+ id: "dashboard-grid",
24
+ // The board's whole purpose is in-place rearrangement of its widgets.
25
+ capabilities: ["edit_inline"],
26
+ state: {
27
+ layout: {
28
+ type: "{ id: string, x: number, y: number, w: number, h: number }[]",
29
+ descriptionKey: "ui.agent.dashboardGrid.state.layout",
30
+ description: "Current widget geometry in cell units — ids and rectangles only, no widget content.",
31
+ read: (t) => t.getGridState().layout
32
+ },
33
+ cols: {
34
+ type: "number",
35
+ descriptionKey: "ui.agent.dashboardGrid.state.cols",
36
+ description: "Logical column count of the board.",
37
+ read: (t) => t.getGridState().cols
38
+ },
39
+ editing: {
40
+ type: "boolean",
41
+ descriptionKey: "ui.agent.dashboardGrid.state.editing",
42
+ description: "Whether edit mode is on. Move/resize actions are refused while it is off — the host app owns the toggle.",
43
+ read: (t) => t.getGridState().editing
44
+ }
45
+ },
46
+ actions: {
47
+ move_widget: {
48
+ // Rearranging the board mutates user configuration — a write,
49
+ // reversible by moving back.
50
+ safety: "write",
51
+ argsType: "id, x, y",
52
+ argsSchema: {
53
+ type: "object",
54
+ properties: {
55
+ id: { type: "string", description: "Widget id (see layout state)." },
56
+ x: {
57
+ type: "integer",
58
+ minimum: 0,
59
+ description: "0-based logical column."
60
+ },
61
+ y: { type: "integer", minimum: 0, description: "0-based row." }
62
+ },
63
+ required: ["id", "x", "y"]
64
+ },
65
+ returns: "boolean (accepted)",
66
+ returnsSchema: {
67
+ type: "boolean",
68
+ description: "True when applied; false when edit mode is off or the id is unknown."
69
+ },
70
+ idempotent: !0,
71
+ descriptionKey: "ui.agent.dashboardGrid.actions.moveWidget",
72
+ description: "Move a widget to a cell. Out-of-bounds targets are clamped; colliding widgets are pushed down and the layout re-compacts. Refused while edit mode is off.",
73
+ invoke: (t, s) => t.moveWidgetTo(s.id, s.x, s.y)
74
+ },
75
+ resize_widget: {
76
+ safety: "write",
77
+ argsType: "id, w, h",
78
+ argsSchema: {
79
+ type: "object",
80
+ properties: {
81
+ id: { type: "string", description: "Widget id (see layout state)." },
82
+ w: {
83
+ type: "integer",
84
+ minimum: 1,
85
+ description: "Column span (≥ 1)."
86
+ },
87
+ h: { type: "integer", minimum: 1, description: "Row span (≥ 1)." }
88
+ },
89
+ required: ["id", "w", "h"]
90
+ },
91
+ returns: "boolean (accepted)",
92
+ returnsSchema: {
93
+ type: "boolean",
94
+ description: "True when applied; false when edit mode is off or the id is unknown."
95
+ },
96
+ idempotent: !0,
97
+ descriptionKey: "ui.agent.dashboardGrid.actions.resizeWidget",
98
+ description: "Resize a widget to a span. Clamped to the grid and the widget’s min/max; colliding widgets are pushed down. Refused while edit mode is off.",
99
+ invoke: (t, s) => t.resizeWidgetTo(s.id, s.w, s.h)
100
+ }
101
+ },
102
+ domHooks: {
103
+ root: { attr: "data-component", value: "dashboard-grid" },
104
+ instanceId: {
105
+ attr: "data-component-id",
106
+ sourceProp: "id",
107
+ description: "Sourced from the id prop."
108
+ },
109
+ item: {
110
+ attr: "data-widget-id",
111
+ description: "Each widget wrapper carries its layout id."
112
+ }
113
+ }
114
+ };
115
+ function A(t, s) {
116
+ return t.x < s.x + s.w && s.x < t.x + t.w && t.y < s.y + s.h && s.y < t.y + t.h;
117
+ }
118
+ function J(t, s) {
119
+ const n = Math.max(1, t.minW ?? 1), g = Math.max(1, t.minH ?? 1), f = Math.min(s, t.maxW ?? s), c = t.maxH ?? Number.POSITIVE_INFINITY, l = Math.min(Math.max(t.w, n), f), a = Math.min(Math.max(t.h, g), c), i = Math.min(Math.max(0, t.x), s - l), m = Math.max(0, t.y);
120
+ return { ...t, x: i, y: m, w: l, h: a };
121
+ }
122
+ function T(t, s, n) {
123
+ const g = t.map((i) => J(i, s)), f = [...g].sort((i, m) => i.id === n ? -1 : m.id === n ? 1 : i.y - m.y || i.x - m.x), c = [], l = n ? g.find((i) => i.id === n) : void 0;
124
+ for (const i of f) {
125
+ if (i.id !== n) {
126
+ if (l && A(l, i)) {
127
+ const m = { ...i, y: Math.max(0, l.y - i.h) };
128
+ !A(l, m) && !c.some((y) => y.id !== n && A(y, m)) && (i.y = m.y);
129
+ }
130
+ for (; c.some((m) => A(m, i)); )
131
+ i.y += 1;
132
+ for (; i.y > 0; ) {
133
+ const m = { ...i, y: i.y - 1 };
134
+ if (c.some((y) => A(y, m))) break;
135
+ i.y -= 1;
136
+ }
137
+ }
138
+ c.push(i);
139
+ }
140
+ const a = new Map(c.map((i) => [i.id, i]));
141
+ return t.map((i) => a.get(i.id));
142
+ }
143
+ function te(t, s, n, g, f) {
144
+ const c = t.map(
145
+ (l) => l.id === s ? J({ ...l, x: n, y: g }, f) : l
146
+ );
147
+ return T(c, f, s);
148
+ }
149
+ function ne(t, s, n, g, f) {
150
+ const c = t.map(
151
+ (l) => l.id === s ? (
152
+ // Resizing never moves the widget: the width clamps to the space
153
+ // between its position and the grid edge (clampRect would slide it).
154
+ // minW wins over the edge clamp so clampRect cannot re-raise w and
155
+ // slide x as a side effect.
156
+ J(
157
+ {
158
+ ...l,
159
+ w: Math.max(l.minW ?? 1, Math.min(n, f - l.x)),
160
+ h: g
161
+ },
162
+ f
163
+ )
164
+ ) : l
165
+ );
166
+ return T(c, f, s);
167
+ }
168
+ function xe(t, s, n, g) {
169
+ const f = Math.min(Math.max(1, n), s), c = t.reduce((l, a) => Math.max(l, a.y + a.h), 0);
170
+ for (let l = 0; l <= c; l += 1)
171
+ for (let a = 0; a <= s - f; a += 1) {
172
+ const i = {
173
+ x: a,
174
+ y: l,
175
+ w: f,
176
+ h: g
177
+ };
178
+ if (!t.some((m) => A(m, i)))
179
+ return { x: a, y: l };
180
+ }
181
+ return { x: 0, y: c };
182
+ }
183
+ function Xe(t) {
184
+ return t.reduce((s, n) => Math.max(s, n.y + n.h), 0);
185
+ }
186
+ const Ue = Ge(
187
+ [
188
+ "ds:grid ds:w-full",
189
+ "ds:gap-[var(--spacing-md)]",
190
+ "ds:[grid-template-columns:repeat(var(--dg-cols),minmax(0,1fr))]",
191
+ "ds:[grid-auto-rows:var(--dg-row)]",
192
+ // Edit-mode surface: tint the whole plane, draw faint cell lines, and
193
+ // reserve spare rows (--dg-min-block) so the AVAILABLE space reads at
194
+ // a glance instead of the board ending at the last occupied row.
195
+ "ds:data-[editing=true]:rounded-[var(--radius-lg)] ds:data-[editing=true]:bg-muted/10",
196
+ "ds:data-[editing=true]:[background-image:var(--dg-grid-lines)]",
197
+ "ds:data-[editing=true]:min-h-[var(--dg-min-block)]"
198
+ ].join(" "),
199
+ { variants: {}, defaultVariants: {} }
200
+ ), Je = Ge(
201
+ [
202
+ "ds:relative ds:flex ds:min-h-0 ds:min-w-0 ds:flex-col ds:overflow-hidden",
203
+ // Mirror of Card variant="elevated" so widgets read as kit cards.
204
+ "ds:rounded-[var(--radius-lg)] ds:bg-[var(--card)] ds:text-[var(--card-foreground)]",
205
+ "ds:border ds:border-[color:var(--card-border)] ds:shadow-[var(--shadow-card)] ds:[.theme-accessible_&]:border-2",
206
+ "ds:[grid-column-start:var(--dg-x)] ds:[grid-column-end:span_var(--dg-w)]",
207
+ "ds:[grid-row-start:var(--dg-y)] ds:[grid-row-end:span_var(--dg-h)]",
208
+ // Grabbed feedback (keyboard or pointer drag in flight).
209
+ "ds:data-[grabbed=true]:ring-[length:var(--focus-ring-width)] ds:data-[grabbed=true]:ring-ring ds:data-[grabbed=true]:z-10"
210
+ ].join(" "),
211
+ { variants: {}, defaultVariants: {} }
212
+ ), Me = Fe(
213
+ null
214
+ );
215
+ function oe(t, s) {
216
+ Ie.forEach(t, (n) => {
217
+ if (Ae(n)) {
218
+ if (n.type === je) {
219
+ oe(
220
+ n.props.children,
221
+ s
222
+ );
223
+ return;
224
+ }
225
+ s(n);
226
+ }
227
+ });
228
+ }
229
+ function Se({
230
+ id: t,
231
+ title: s,
232
+ actionsSlot: n,
233
+ children: g
234
+ }) {
235
+ var y, V, B;
236
+ const { t: f } = ke(), c = $e(Me), l = S(null), a = c == null ? void 0 : c.layoutById.get(t);
237
+ if (U(() => {
238
+ const p = l.current;
239
+ !p || !a || (p.style.setProperty("--dg-x", String(a.x + 1)), p.style.setProperty("--dg-y", String(a.y + 1)), p.style.setProperty("--dg-w", String(a.w)), p.style.setProperty("--dg-h", String(a.h)));
240
+ }, [a == null ? void 0 : a.x, a == null ? void 0 : a.y, a == null ? void 0 : a.w, a == null ? void 0 : a.h, a]), !c || !a) return null;
241
+ const i = ((y = c.grab) == null ? void 0 : y.id) === t, m = c.editing;
242
+ return /* @__PURE__ */ _(
243
+ "div",
244
+ {
245
+ ref: l,
246
+ role: "listitem",
247
+ "aria-label": s,
248
+ "data-component": "dashboard-grid-widget",
249
+ "data-widget-id": t,
250
+ "data-grabbed": i || void 0,
251
+ className: Je(),
252
+ children: [
253
+ /* @__PURE__ */ _("div", { className: "ds:flex ds:items-center ds:gap-[var(--spacing-xs)] ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)] ds:pt-[var(--spacing-sm)]", children: [
254
+ m ? /* @__PURE__ */ w(
255
+ re,
256
+ {
257
+ size: "sm",
258
+ intent: "outline",
259
+ type: "button",
260
+ icon: /* @__PURE__ */ w(Ve, {}),
261
+ "aria-label": f("dashboardGrid.move", { title: s }),
262
+ "aria-pressed": i && ((V = c.grab) == null ? void 0 : V.kind) === "move",
263
+ className: "ds:cursor-grab ds:touch-none ds:bg-[var(--card)]",
264
+ onPointerDown: (p) => c.startPointerGrab("move", t, p),
265
+ onKeyDown: (p) => c.keyboardStep(p, t),
266
+ onClick: () => c.startKeyboardGrab("move", t)
267
+ }
268
+ ) : null,
269
+ /* @__PURE__ */ w("span", { className: "ds:min-w-0 ds:flex-1 ds:truncate ds:text-sm ds:font-medium", children: s }),
270
+ n,
271
+ m && c.canRemove ? /* @__PURE__ */ w(
272
+ re,
273
+ {
274
+ size: "sm",
275
+ intent: "outline",
276
+ type: "button",
277
+ icon: /* @__PURE__ */ w(Be, {}),
278
+ className: "ds:bg-[var(--card)]",
279
+ "aria-label": f("dashboardGrid.remove", { title: s }),
280
+ onClick: () => c.requestRemove(t)
281
+ }
282
+ ) : null
283
+ ] }),
284
+ /* @__PURE__ */ w("div", { className: "ds:min-h-0 ds:flex-1 ds:overflow-hidden ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)] ds:pb-[var(--spacing-md)] ds:pt-[var(--spacing-xs)]", children: g }),
285
+ m ? /* @__PURE__ */ w("span", { className: "ds:absolute ds:bottom-[var(--spacing-sm)] ds:end-[var(--spacing-sm)]", children: /* @__PURE__ */ w(
286
+ re,
287
+ {
288
+ size: "sm",
289
+ intent: "outline",
290
+ type: "button",
291
+ icon: /* @__PURE__ */ w(qe, {}),
292
+ flipIconInRtl: !0,
293
+ "aria-label": f("dashboardGrid.resize", { title: s }),
294
+ "aria-pressed": i && ((B = c.grab) == null ? void 0 : B.kind) === "resize",
295
+ className: "ds:touch-none ds:bg-[var(--card)]",
296
+ onPointerDown: (p) => c.startPointerGrab("resize", t, p),
297
+ onKeyDown: (p) => c.keyboardStep(p, t),
298
+ onClick: () => c.startKeyboardGrab("resize", t)
299
+ }
300
+ ) }) : null
301
+ ]
302
+ }
303
+ );
304
+ }
305
+ Se.displayName = "DashboardGrid.Widget";
306
+ const Ne = Te(
307
+ ({
308
+ "aria-label": t,
309
+ id: s,
310
+ cols: n = 12,
311
+ rowHeight: g = 96,
312
+ layout: f,
313
+ defaultLayout: c,
314
+ onLayoutChange: l,
315
+ editing: a = !1,
316
+ onRemoveWidget: i,
317
+ onRequestAdd: m,
318
+ children: y,
319
+ className: V
320
+ }, B) => {
321
+ const { t: p } = ke(), N = S(null), ae = L(() => {
322
+ const e = [];
323
+ return oe(y, (r) => {
324
+ r.props.id && e.push(r.props.id);
325
+ }), e;
326
+ }, [y]), se = L(() => {
327
+ const e = /* @__PURE__ */ new Map();
328
+ return oe(y, (r) => {
329
+ r.props.id && e.set(r.props.id, {
330
+ defaultW: r.props.defaultW ?? 4,
331
+ defaultH: r.props.defaultH ?? 2
332
+ });
333
+ }), e;
334
+ }, [y]), [Pe, De] = O(() => c ?? []), ie = f ?? Pe, P = D(
335
+ (e) => {
336
+ f === void 0 && De(e), l == null || l(e);
337
+ },
338
+ [f, l]
339
+ ), { resolved: v, autoPlaced: de } = L(() => {
340
+ const e = ie.map((u) => J(u, n)), r = ae.filter(
341
+ (u) => !e.some((d) => d.id === u)
342
+ );
343
+ if (r.length === 0)
344
+ return { resolved: e, autoPlaced: !1 };
345
+ const o = [...e];
346
+ for (const u of r) {
347
+ const d = se.get(u) ?? { defaultW: 4, defaultH: 2 }, b = Math.min(d.defaultW, n), h = xe(o, n, b, d.defaultH);
348
+ o.push({ id: u, x: h.x, y: h.y, w: b, h: d.defaultH });
349
+ }
350
+ return { resolved: T(o, n), autoPlaced: !0 };
351
+ }, [ie, ae, se, n]), ce = S("");
352
+ X(() => {
353
+ if (!de) return;
354
+ const e = v.map(
355
+ (r) => `${r.id}:${r.x},${r.y},${r.w},${r.h}`
356
+ ).join("|");
357
+ ce.current !== e && (ce.current = e, P(v));
358
+ }, [de, v, P]);
359
+ const [Re, Ce] = O(null), [k, ue] = O(null), [Ee, W] = O(""), Q = S(null), C = S(null), j = S(null), H = S(!1), F = S(n);
360
+ F.current = n;
361
+ const $ = S(v);
362
+ $.current = v;
363
+ const R = D((e) => {
364
+ Q.current = e, Ce(e);
365
+ }, []), Y = D(
366
+ (e, r, o) => {
367
+ const u = { kind: e, id: r, via: o };
368
+ C.current = { ...u, baseLayout: $.current }, ue(u), R($.current);
369
+ },
370
+ [R]
371
+ ), K = Re ?? v, le = L(
372
+ () => new Map(K.map((e) => [e.id, e])),
373
+ [K]
374
+ ), pe = D(
375
+ (e, r) => {
376
+ W(
377
+ e === "move" ? p("dashboardGrid.movedTo", { col: r.x + 1, row: r.y + 1 }) : p("dashboardGrid.resizedTo", { cols: r.w, rows: r.h })
378
+ );
379
+ },
380
+ [p]
381
+ ), x = D(
382
+ (e) => {
383
+ const r = Q.current, o = C.current;
384
+ if (C.current = null, j.current = null, ue(null), R(null), !e || !r || !o) {
385
+ W(p("dashboardGrid.cancelled"));
386
+ return;
387
+ }
388
+ const u = T(r, F.current), d = (h) => h.map((G) => `${G.id}:${G.x},${G.y},${G.w},${G.h}`).join("|");
389
+ if (d(u) === d($.current)) {
390
+ W(p("dashboardGrid.cancelled"));
391
+ return;
392
+ }
393
+ P(u);
394
+ const b = u.find((h) => h.id === o.id);
395
+ W(
396
+ b ? p("dashboardGrid.droppedAt", {
397
+ col: b.x + 1,
398
+ row: b.y + 1
399
+ }) : p("dashboardGrid.cancelled")
400
+ );
401
+ },
402
+ [R, P, p]
403
+ ), me = D(
404
+ (e, r) => {
405
+ if (!a) return;
406
+ if (H.current) {
407
+ H.current = !1;
408
+ return;
409
+ }
410
+ const o = C.current;
411
+ if ((o == null ? void 0 : o.via) !== "pointer") {
412
+ if (o && o.id === r && o.kind === e) {
413
+ x(!0);
414
+ return;
415
+ }
416
+ Y(e, r, "keyboard"), W(
417
+ p(e === "move" ? "dashboardGrid.grabbed" : "dashboardGrid.resizeGrabbed")
418
+ );
419
+ }
420
+ },
421
+ [a, Y, x, p]
422
+ ), fe = D(
423
+ (e, r) => {
424
+ const o = C.current;
425
+ if (!o || o.id !== r || o.via !== "keyboard")
426
+ return;
427
+ if (e.key === "Escape") {
428
+ e.preventDefault(), x(!1);
429
+ return;
430
+ }
431
+ if (!["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown"].includes(e.key)) return;
432
+ e.preventDefault();
433
+ const d = typeof window < "u" && N.current ? window.getComputedStyle(N.current).direction === "rtl" : !1, b = e.key === "ArrowRight" ? d ? -1 : 1 : e.key === "ArrowLeft" ? d ? 1 : -1 : 0, h = e.key === "ArrowDown" ? 1 : e.key === "ArrowUp" ? -1 : 0, M = (Q.current ?? o.baseLayout).find((I) => I.id === r);
434
+ if (!M) return;
435
+ const E = o.kind === "move" ? te(
436
+ o.baseLayout,
437
+ r,
438
+ M.x + b,
439
+ M.y + h,
440
+ n
441
+ ) : ne(
442
+ o.baseLayout,
443
+ r,
444
+ M.w + b,
445
+ M.h + h,
446
+ n
447
+ );
448
+ R(E);
449
+ const z = E.find((I) => I.id === r);
450
+ z && pe(o.kind, z);
451
+ },
452
+ [n, x, R, pe]
453
+ ), ge = D(
454
+ (e, r, o) => {
455
+ var z, I, we, ve;
456
+ if (!a || C.current) return;
457
+ const u = N.current, d = $.current.find((Le) => Le.id === r);
458
+ if (!u || !d) return;
459
+ o.preventDefault(), (I = (z = o.currentTarget).focus) == null || I.call(z);
460
+ const b = u.getBoundingClientRect();
461
+ if (b.width <= 0) return;
462
+ const h = window.getComputedStyle(u), G = Number.parseFloat(h.columnGap) || 0, M = Number.parseFloat(h.rowGap) || 0, E = (b.width - G * (n - 1)) / n;
463
+ j.current = {
464
+ kind: e,
465
+ id: r,
466
+ pointerId: o.pointerId,
467
+ startClientX: o.clientX,
468
+ startClientY: o.clientY,
469
+ origin: d,
470
+ colStride: E + G,
471
+ rowStride: g + M,
472
+ isRtl: h.direction === "rtl"
473
+ };
474
+ try {
475
+ (ve = (we = o.currentTarget).setPointerCapture) == null || ve.call(we, o.pointerId);
476
+ } catch {
477
+ }
478
+ Y(e, r, "pointer");
479
+ },
480
+ [a, n, g, Y]
481
+ );
482
+ X(() => {
483
+ if (!k || k.via !== "pointer") return;
484
+ const e = (u) => {
485
+ const d = j.current, b = C.current;
486
+ if (!d || !b || u.pointerId !== d.pointerId)
487
+ return;
488
+ const h = u.clientX - d.startClientX, G = u.clientY - d.startClientY, M = Math.round(h / d.colStride) * (d.isRtl ? -1 : 1), E = Math.round(G / d.rowStride), z = d.kind === "move" ? te(
489
+ b.baseLayout,
490
+ d.id,
491
+ d.origin.x + M,
492
+ d.origin.y + E,
493
+ F.current
494
+ ) : ne(
495
+ b.baseLayout,
496
+ d.id,
497
+ d.origin.w + M,
498
+ d.origin.h + E,
499
+ F.current
500
+ );
501
+ R(z);
502
+ }, r = (u) => {
503
+ const d = j.current;
504
+ !d || u.pointerId !== d.pointerId || (H.current = !0, x(!0));
505
+ }, o = (u) => {
506
+ const d = j.current;
507
+ !d || u.pointerId !== d.pointerId || (H.current = !0, x(!1));
508
+ };
509
+ return window.addEventListener("pointermove", e), window.addEventListener("pointerup", r), window.addEventListener("pointercancel", o), () => {
510
+ window.removeEventListener("pointermove", e), window.removeEventListener("pointerup", r), window.removeEventListener("pointercancel", o);
511
+ };
512
+ }, [k, x, R]), X(() => {
513
+ if (!k) return;
514
+ const e = (r) => {
515
+ r.key === "Escape" && x(!1);
516
+ };
517
+ return window.addEventListener("keydown", e), () => window.removeEventListener("keydown", e);
518
+ }, [k, x]), X(() => {
519
+ if (!k || k.via !== "keyboard") return;
520
+ const e = (o) => {
521
+ var d;
522
+ const u = o.relatedTarget;
523
+ (!u || !((d = N.current) != null && d.contains(u))) && x(!1);
524
+ }, r = N.current;
525
+ return r == null || r.addEventListener("focusout", e), () => r == null ? void 0 : r.removeEventListener("focusout", e);
526
+ }, [k, x]), U(() => {
527
+ const e = N.current;
528
+ e && (e.style.setProperty("--dg-cols", String(n)), e.style.setProperty("--dg-row", `${g}px`));
529
+ }, [n, g]);
530
+ const be = Xe(K);
531
+ U(() => {
532
+ const e = N.current;
533
+ e && (e.style.setProperty(
534
+ "--dg-grid-lines",
535
+ `repeating-linear-gradient(to right, color-mix(in srgb, var(--border) 50%, transparent) 0 1px, transparent 1px calc((100% + var(--spacing-md)) / ${n})), repeating-linear-gradient(to bottom, color-mix(in srgb, var(--border) 50%, transparent) 0 1px, transparent 1px calc(${g}px + var(--spacing-md)))`
536
+ ), e.style.setProperty(
537
+ "--dg-min-block",
538
+ `calc(${be + 2} * (${g}px + var(--spacing-md)) - var(--spacing-md))`
539
+ ));
540
+ }, [n, g, be]);
541
+ const he = S(null), Z = a && !!m, q = L(
542
+ () => Z ? xe(K, n, 2, 2) : null,
543
+ [Z, K, n]
544
+ );
545
+ U(() => {
546
+ const e = he.current;
547
+ !e || !q || (e.style.setProperty("--dg-x", String(q.x + 1)), e.style.setProperty("--dg-y", String(q.y + 1)), e.style.setProperty("--dg-w", "2"), e.style.setProperty("--dg-h", "2"));
548
+ }, [q]);
549
+ const ye = D(
550
+ (e) => {
551
+ P(
552
+ T(
553
+ $.current.filter((r) => r.id !== e),
554
+ F.current
555
+ )
556
+ ), W(p("dashboardGrid.removed")), i == null || i(e), requestAnimationFrame(() => {
557
+ const r = N.current;
558
+ if (!r) return;
559
+ const o = r.querySelector("button");
560
+ o ? o.focus() : r.focus();
561
+ });
562
+ },
563
+ [P, i, p]
564
+ ), ee = L(
565
+ () => ({
566
+ moveWidgetTo(e, r, o) {
567
+ return !a || !Number.isFinite(r) || !Number.isFinite(o) || !v.some((u) => u.id === e) ? !1 : (P(
568
+ T(
569
+ te(v, e, Math.round(r), Math.round(o), n),
570
+ n
571
+ )
572
+ ), !0);
573
+ },
574
+ resizeWidgetTo(e, r, o) {
575
+ return !a || !Number.isFinite(r) || !Number.isFinite(o) || !v.some((u) => u.id === e) ? !1 : (P(
576
+ T(
577
+ ne(
578
+ v,
579
+ e,
580
+ Math.round(r),
581
+ Math.round(o),
582
+ n
583
+ ),
584
+ n
585
+ )
586
+ ), !0);
587
+ },
588
+ getGridState() {
589
+ return {
590
+ cols: n,
591
+ editing: a,
592
+ layout: v.map((e) => ({ ...e }))
593
+ };
594
+ }
595
+ }),
596
+ [a, v, n, P]
597
+ );
598
+ We(B, () => ee, [ee]), Ke(Oe, ee, s);
599
+ const ze = L(
600
+ () => ({
601
+ editing: a,
602
+ layoutById: le,
603
+ grab: k,
604
+ canRemove: !!i,
605
+ requestRemove: ye,
606
+ startKeyboardGrab: me,
607
+ keyboardStep: fe,
608
+ startPointerGrab: ge
609
+ }),
610
+ [
611
+ a,
612
+ le,
613
+ k,
614
+ i,
615
+ ye,
616
+ me,
617
+ fe,
618
+ ge
619
+ ]
620
+ );
621
+ return /* @__PURE__ */ _(
622
+ "div",
623
+ {
624
+ "data-component": "dashboard-grid",
625
+ "data-component-id": s,
626
+ "data-editing": a || void 0,
627
+ className: `ds:block ds:w-full ${V ?? ""}`.trim(),
628
+ children: [
629
+ /* @__PURE__ */ w("div", { role: "status", "aria-live": "polite", className: "ds:sr-only", children: Ee }),
630
+ /* @__PURE__ */ _(
631
+ "div",
632
+ {
633
+ ref: N,
634
+ role: "list",
635
+ "aria-label": t,
636
+ tabIndex: -1,
637
+ "data-editing": a || void 0,
638
+ className: Ue(),
639
+ children: [
640
+ /* @__PURE__ */ w(Me.Provider, { value: ze, children: y }),
641
+ Z ? (
642
+ // role="list" allows only listitem children — the tile wrapper
643
+ // carries the grid placement, the button fills it.
644
+ /* @__PURE__ */ w(
645
+ "div",
646
+ {
647
+ ref: he,
648
+ role: "listitem",
649
+ className: [
650
+ "ds:flex",
651
+ "ds:[grid-column-start:var(--dg-x)] ds:[grid-column-end:span_var(--dg-w)]",
652
+ "ds:[grid-row-start:var(--dg-y)] ds:[grid-row-end:span_var(--dg-h)]"
653
+ ].join(" "),
654
+ children: /* @__PURE__ */ _(
655
+ "button",
656
+ {
657
+ type: "button",
658
+ onClick: m,
659
+ className: [
660
+ "ds:flex ds:flex-1 ds:items-center ds:justify-center ds:gap-[var(--spacing-xs)]",
661
+ "ds:rounded-[var(--radius-lg)] ds:border ds:border-dashed ds:border-border",
662
+ "ds:text-sm ds:text-muted-foreground ds:transition-colors",
663
+ "ds:hover:bg-muted/10 ds:hover:text-foreground",
664
+ "ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid ds:focus-visible:outline-ring"
665
+ ].join(" "),
666
+ children: [
667
+ /* @__PURE__ */ w(_e, { "aria-hidden": "true", className: "ds:size-4" }),
668
+ p("dashboardGrid.add")
669
+ ]
670
+ }
671
+ )
672
+ }
673
+ )
674
+ ) : null
675
+ ]
676
+ }
677
+ )
678
+ ]
679
+ }
680
+ );
681
+ }
682
+ );
683
+ Ne.displayName = "DashboardGrid";
684
+ const cr = Object.assign(Ne, {
685
+ Widget: Se
686
+ });
687
+ export {
688
+ cr as D,
689
+ Oe as d
690
+ };
691
+ //# sourceMappingURL=dashboard-grid-D2dm0IRN.js.map