@nivaro/react 0.3.34 → 0.3.35

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,31 +1,33 @@
1
- import { jsx as s, jsxs as y, Fragment as z } from "react/jsx-runtime";
2
- import { Copy as Y, History as Q, Eye as Z, Sigma as ee, ExternalLink as te, UserRound as ne, UserRoundX as re, Lock as oe, X } from "lucide-react";
3
- import { useContext as ae, createContext as se, useState as M, useCallback as F, useRef as j, useEffect as _, useLayoutEffect as le } from "react";
4
- import { createPortal as ie } from "react-dom";
5
- import { toast as h } from "sonner";
6
- import { htmlToText as ce } from "../../lib/sanitize-html.js";
7
- import { cn as q, formatRelative as I } from "../../lib/utils.js";
8
- import { PERSONAL_DEFAULT_GHOST_BUTTON as de } from "./PersonalDefaultPill.js";
9
- import { usePersonalDefaultsApi as ue } from "./usePersonalDefaults.js";
10
- const me = se(null), Ce = () => ae(me), V = (t) => {
11
- if (t == null || t === "") return "empty";
12
- if (typeof t == "boolean") return t ? "Yes" : "No";
13
- if (typeof t == "object")
1
+ import { jsx as s, jsxs as h, Fragment as fe } from "react/jsx-runtime";
2
+ import { Copy as Q, History as me, Eye as be, Sigma as pe, ExternalLink as xe, UserRound as ye, UserRoundPen as he, UserRoundX as ge, Lock as ke, X as ne } from "lucide-react";
3
+ import { useContext as we, createContext as ve, useState as C, useCallback as N, useRef as M, useEffect as B, useLayoutEffect as Ne } from "react";
4
+ import { createPortal as Ce } from "react-dom";
5
+ import { toast as v } from "sonner";
6
+ import { htmlToText as Se } from "../../lib/sanitize-html.js";
7
+ import { cn as re, formatRelative as Z } from "../../lib/utils.js";
8
+ import { useOverflowTip as Ee } from "../TipLayer.js";
9
+ import { clearPersonalDefault as Te, usePersonalDefaultCss as Ue, refusalText as ee } from "./PersonalDefaultControl.js";
10
+ import { PERSONAL_DEFAULT_GHOST_BUTTON as Le } from "./PersonalDefaultPill.js";
11
+ import { usePersonalDefaultsApi as Fe } from "./usePersonalDefaults.js";
12
+ const Me = ve(null), Ve = () => we(Me), te = (n) => {
13
+ if (n == null || n === "") return "empty";
14
+ if (typeof n == "boolean") return n ? "Yes" : "No";
15
+ if (typeof n == "object")
14
16
  try {
15
- const a = JSON.stringify(t);
16
- return a.length > 80 ? `${a.slice(0, 80)}…` : a;
17
+ const l = JSON.stringify(n);
18
+ return l.length > 80 ? `${l.slice(0, 80)}…` : l;
17
19
  } catch {
18
- return String(t);
20
+ return String(n);
19
21
  }
20
- const n = String(t), e = /[<&]/.test(n) ? ce(n).trim() : n;
21
- return e.length > 80 ? `${e.slice(0, 80)}…` : e;
22
+ const t = String(n), o = /[<&]/.test(t) ? Se(t).trim() : t;
23
+ return o.length > 80 ? `${o.slice(0, 80)}…` : o;
22
24
  };
23
- function Se({
24
- change: t,
25
- onDismiss: n,
26
- onTakeTheirs: e
25
+ function Xe({
26
+ change: n,
27
+ onDismiss: t,
28
+ onTakeTheirs: o
27
29
  }) {
28
- return t.conflict && e ? /* @__PURE__ */ y(
30
+ return n.conflict && o ? /* @__PURE__ */ h(
29
31
  "div",
30
32
  {
31
33
  "data-remote-change-ghost": !0,
@@ -33,23 +35,23 @@ function Se({
33
35
  className: "nvr-expand-in flex flex-wrap items-center gap-1.5 rounded-md border border-amber-300 bg-amber-50 px-2 py-1 text-[11.5px] text-amber-900 dark:border-amber-500/40 dark:bg-amber-500/10 dark:text-amber-100",
34
36
  children: [
35
37
  /* @__PURE__ */ s("span", { className: "h-1.5 w-1.5 shrink-0 animate-pulse rounded-full bg-amber-500" }),
36
- /* @__PURE__ */ y("span", { className: "min-w-0 flex-1", children: [
37
- t.by ?? "Someone",
38
+ /* @__PURE__ */ h("span", { className: "min-w-0 flex-1", children: [
39
+ n.by ?? "Someone",
38
40
  " changed this to",
39
41
  " ",
40
- /* @__PURE__ */ s("span", { className: "font-medium", children: V(t.theirs) }),
42
+ /* @__PURE__ */ s("span", { className: "font-medium", children: te(n.theirs) }),
41
43
  " while you were editing",
42
- /* @__PURE__ */ y("span", { className: "text-amber-700/80 dark:text-amber-200/70", children: [
44
+ /* @__PURE__ */ h("span", { className: "text-amber-700/80 dark:text-amber-200/70", children: [
43
45
  " ",
44
46
  "· ",
45
- I(t.at)
47
+ Z(n.at)
46
48
  ] })
47
49
  ] }),
48
50
  /* @__PURE__ */ s(
49
51
  "button",
50
52
  {
51
53
  type: "button",
52
- onClick: e,
54
+ onClick: o,
53
55
  "data-remote-take-theirs": !0,
54
56
  className: "shrink-0 rounded border border-amber-400 bg-white px-1.5 py-0.5 text-[10.5px] font-medium text-amber-900 hover:bg-amber-100 dark:bg-transparent dark:text-amber-100 dark:hover:bg-amber-500/20",
55
57
  children: "Take theirs"
@@ -59,7 +61,7 @@ function Se({
59
61
  "button",
60
62
  {
61
63
  type: "button",
62
- onClick: n,
64
+ onClick: t,
63
65
  "data-remote-keep-mine": !0,
64
66
  className: "shrink-0 rounded px-1.5 py-0.5 text-[10.5px] font-medium text-amber-800 hover:bg-amber-100 dark:text-amber-200 dark:hover:bg-amber-500/20",
65
67
  children: "Keep mine"
@@ -67,353 +69,395 @@ function Se({
67
69
  )
68
70
  ]
69
71
  }
70
- ) : /* @__PURE__ */ y(
72
+ ) : /* @__PURE__ */ h(
71
73
  "div",
72
74
  {
73
75
  "data-remote-change-ghost": !0,
74
76
  className: "nvr-expand-in flex items-start gap-1.5 rounded-md border border-sky-200 bg-sky-50 px-2 py-1 text-[11.5px] text-sky-900 dark:border-sky-500/30 dark:bg-sky-500/10 dark:text-sky-200",
75
77
  children: [
76
78
  /* @__PURE__ */ s("span", { className: "mt-0.5 h-1.5 w-1.5 shrink-0 animate-pulse rounded-full bg-sky-500" }),
77
- /* @__PURE__ */ y("span", { className: "min-w-0 flex-1", children: [
79
+ /* @__PURE__ */ h("span", { className: "min-w-0 flex-1", children: [
78
80
  "was",
79
81
  " ",
80
- /* @__PURE__ */ s("span", { className: "font-medium line-through decoration-sky-400/70", children: V(t.was) }),
81
- /* @__PURE__ */ y("span", { className: "text-sky-700/80 dark:text-sky-300/80", children: [
82
+ /* @__PURE__ */ s("span", { className: "font-medium line-through decoration-sky-400/70", children: te(n.was) }),
83
+ /* @__PURE__ */ h("span", { className: "text-sky-700/80 dark:text-sky-300/80", children: [
82
84
  " ",
83
85
  "· ",
84
- t.by ?? "someone",
86
+ n.by ?? "someone",
85
87
  ", ",
86
- I(t.at)
88
+ Z(n.at)
87
89
  ] })
88
90
  ] }),
89
91
  /* @__PURE__ */ s(
90
92
  "button",
91
93
  {
92
94
  type: "button",
93
- onClick: n,
95
+ onClick: t,
94
96
  "aria-label": "Dismiss",
95
97
  className: "shrink-0 rounded p-0.5 text-sky-500 hover:bg-sky-100 hover:text-sky-800 dark:hover:bg-sky-500/20",
96
- children: /* @__PURE__ */ s(X, { className: "h-3 w-3" })
98
+ children: /* @__PURE__ */ s(ne, { className: "h-3 w-3" })
97
99
  }
98
100
  )
99
101
  ]
100
102
  }
101
103
  );
102
104
  }
103
- function Ee({ reason: t, onHover: n }) {
105
+ function Ye({ reason: n, onHover: t }) {
104
106
  return /* @__PURE__ */ s(
105
107
  "span",
106
108
  {
107
- onPointerEnter: n,
109
+ onPointerEnter: t,
108
110
  className: "inline-flex cursor-help items-center gap-1 text-amber-500 dark:text-amber-400",
109
- "data-tip": t,
111
+ "data-tip": n,
110
112
  "data-lock-reason": !0,
111
- "aria-label": t,
113
+ "aria-label": n,
112
114
  role: "img",
113
- children: /* @__PURE__ */ s(oe, { className: "h-3 w-3" })
115
+ children: /* @__PURE__ */ s(ke, { className: "h-3 w-3" })
114
116
  }
115
117
  );
116
118
  }
117
- function P(t, n) {
118
- var a, c, d;
119
- const e = t;
120
- return ((c = (a = e == null ? void 0 : e.response) == null ? void 0 : a.data) == null ? void 0 : c.error) ?? ((d = e == null ? void 0 : e.data) == null ? void 0 : d.error) ?? (e == null ? void 0 : e.error) ?? (e == null ? void 0 : e.message) ?? n;
121
- }
122
- function fe(t, n) {
123
- if (!t || !(n != null && n.contains(t))) return null;
124
- const e = t.closest(
119
+ function Re(n, t) {
120
+ if (!n || !(t != null && t.contains(n))) return null;
121
+ const o = n.closest(
125
122
  "input, textarea, select"
126
123
  );
127
- if (e && n.contains(e) && !(e instanceof HTMLInputElement && e.type === "checkbox"))
128
- return e.value;
129
- const a = t.closest("td, th");
130
- return a && n.contains(a) ? a.innerText.replace(/\s+/g, " ").trim() : null;
124
+ if (o && t.contains(o) && !(o instanceof HTMLInputElement && o.type === "checkbox"))
125
+ return o.value;
126
+ const l = n.closest("td, th");
127
+ return l && t.contains(l) ? l.innerText.replace(/\s+/g, " ").trim() : null;
131
128
  }
132
- function Te({
133
- wrapperRef: t,
134
- field: n,
135
- value: e,
136
- relations: a,
137
- collection: c,
138
- itemId: d,
139
- openRelated: g,
140
- editable: D = !1
129
+ function qe({
130
+ wrapperRef: n,
131
+ field: t,
132
+ value: o,
133
+ relations: l,
134
+ collection: m,
135
+ itemId: x,
136
+ openRelated: w,
137
+ editable: R = !1
141
138
  }) {
142
- var B, H;
143
- const [p, S] = M(null), l = ue(), [k, E] = M(!1), [f, O] = M(null), [U, A] = M(!1), v = F((r, u) => S({ x: r, y: u }), []), w = j(null), T = F(() => {
144
- S(null), E(!1), O(null), A(!1);
145
- const r = w.current;
146
- w.current = null, r && window.setTimeout(() => {
147
- r.isConnected && (!document.activeElement || document.activeElement === document.body) && r.focus();
139
+ var J, z;
140
+ const [g, T] = C(null), r = Fe(), [k, S] = C(!1), [y, O] = C(null), [U, A] = C(null), [$, j] = C(!1), b = N((e, c) => T({ x: e, y: c }), []), [D, a] = C(null), f = M(null), L = M(null), i = N(() => {
141
+ T(null), a(null), S(!1), O(null), A(null), j(!1);
142
+ const e = f.current, c = L.current;
143
+ f.current = null, L.current = null, (e || c) && window.setTimeout(() => {
144
+ var u;
145
+ document.activeElement && document.activeElement !== document.body || (e != null && e.isConnected ? e.focus() : (u = c == null ? void 0 : c()) == null || u.focus());
148
146
  }, 0);
149
- }, []), o = p !== null, b = F(
150
- (r) => {
151
- if (o) {
152
- T();
147
+ }, []), p = g !== null, d = N(
148
+ (e) => {
149
+ if (p) {
150
+ i();
153
151
  return;
154
152
  }
155
- const u = r.getBoundingClientRect();
156
- N.current = null, w.current = r, v(u.left, u.bottom + 4);
153
+ const c = e.getBoundingClientRect();
154
+ _.current = null, f.current = e, a("menu"), b(c.left, c.bottom + 4);
157
155
  },
158
- [o, T, v]
159
- ), N = j(null), m = F(
160
- (r) => {
161
- var K;
162
- const u = r.target;
163
- (K = window.getSelection()) != null && K.toString() && u.closest("input, textarea, [contenteditable]") || (r.preventDefault(), N.current = u, v(r.clientX, r.clientY));
156
+ [p, i, b]
157
+ ), E = N(() => {
158
+ r && (O(null), S("save"), r.describeSave(t.field).then(
159
+ (e) => O(e),
160
+ () => O([])
161
+ ));
162
+ }, [r, t.field]), P = N(() => {
163
+ r && (A(null), S("update"), r.describeUpdate(t.field).then(
164
+ (e) => A(e),
165
+ () => A({ value: "", context: [] })
166
+ ));
167
+ }, [r, t.field]), H = N(
168
+ (e, c, u = "make") => {
169
+ if (p && D === u) {
170
+ i();
171
+ return;
172
+ }
173
+ const F = e.getBoundingClientRect();
174
+ _.current = null, f.current = e, L.current = c ?? null, a(u), u === "update" ? P() : E(), b(F.right - ae, F.bottom + 4);
164
175
  },
165
- [v]
166
- ), x = F(
167
- (r) => {
168
- var u;
169
- if (r.key === "ContextMenu" || r.shiftKey && r.key === "F10") {
170
- r.preventDefault();
171
- const L = (u = t.current) == null ? void 0 : u.getBoundingClientRect();
172
- N.current = document.activeElement, v(L ? L.left + 16 : 16, L ? L.top + 28 : 16);
176
+ [p, D, i, b, E, P]
177
+ ), _ = M(null), oe = N(
178
+ (e) => {
179
+ var F;
180
+ const c = e.target;
181
+ (F = window.getSelection()) != null && F.toString() && c.closest("input, textarea, [contenteditable]") || (e.preventDefault(), _.current = c, a("menu"), b(e.clientX, e.clientY));
182
+ },
183
+ [b]
184
+ ), le = N(
185
+ (e) => {
186
+ var c;
187
+ if (e.key === "ContextMenu" || e.shiftKey && e.key === "F10") {
188
+ e.preventDefault();
189
+ const u = (c = n.current) == null ? void 0 : c.getBoundingClientRect();
190
+ _.current = document.activeElement, a("menu"), b(u ? u.left + 16 : 16, u ? u.top + 28 : 16);
173
191
  }
174
192
  },
175
- [v, t]
176
- ), i = a.find(
177
- (r) => r.many_collection === c && r.many_field === n.field && r.one_collection
178
- ), C = d && d !== "new", R = (r) => {
179
- var L;
180
- const u = (L = t.current) == null ? void 0 : L.querySelector(r);
181
- return u ? (u.click(), !0) : !1;
182
- }, $ = [
193
+ [b, n]
194
+ ), I = l.find(
195
+ (e) => e.many_collection === m && e.many_field === t.field && e.one_collection
196
+ ), K = x && x !== "new", W = (e) => {
197
+ var u;
198
+ const c = (u = n.current) == null ? void 0 : u.querySelector(e);
199
+ return c ? (c.click(), !0) : !1;
200
+ }, V = !!(r != null && r.allowed(t.field)), X = V && R && !!(r != null && r.hasValue(t.field)), G = V ? (r == null ? void 0 : r.defaultFor(t.field)) ?? null : null, se = X && !G, ie = X && !!G && !(r != null && r.isDefault(t.field)), Y = [
183
201
  {
184
202
  key: "copy",
185
203
  label: "Copy value",
186
- icon: /* @__PURE__ */ s(Y, { className: "h-3.5 w-3.5" }),
204
+ icon: /* @__PURE__ */ s(Q, { className: "h-3.5 w-3.5" }),
187
205
  run: () => {
188
- const u = fe(N.current, t.current) ?? (e == null ? "" : typeof e == "object" ? JSON.stringify(e) : String(e));
189
- if (!u) {
190
- h.info("Nothing to copy");
206
+ const c = Re(_.current, n.current) ?? (o == null ? "" : typeof o == "object" ? JSON.stringify(o) : String(o));
207
+ if (!c) {
208
+ v.info("Nothing to copy");
191
209
  return;
192
210
  }
193
- navigator.clipboard.writeText(u).then(
194
- () => h.success("Value copied"),
195
- () => h.error("Could not copy")
211
+ navigator.clipboard.writeText(c).then(
212
+ () => v.success("Value copied"),
213
+ () => v.error("Could not copy")
196
214
  );
197
215
  }
198
216
  },
199
217
  {
200
218
  key: "copy-key",
201
219
  label: "Copy field key",
202
- icon: /* @__PURE__ */ s(Y, { className: "h-3.5 w-3.5" }),
203
- hint: n.field,
220
+ icon: /* @__PURE__ */ s(Q, { className: "h-3.5 w-3.5" }),
221
+ hint: t.field,
204
222
  run: () => {
205
- navigator.clipboard.writeText(n.field).then(
206
- () => h.success(`Copied “${n.field}”`),
207
- () => h.error("Could not copy")
223
+ navigator.clipboard.writeText(t.field).then(
224
+ () => v.success(`Copied “${t.field}”`),
225
+ () => v.error("Could not copy")
208
226
  );
209
227
  }
210
228
  },
211
229
  {
212
230
  key: "history",
213
231
  label: "Value history",
214
- icon: /* @__PURE__ */ s(Q, { className: "h-3.5 w-3.5" }),
215
- disabled: !C,
232
+ icon: /* @__PURE__ */ s(me, { className: "h-3.5 w-3.5" }),
233
+ disabled: !K,
216
234
  run: () => {
217
- R("[data-field-history]") || h.info("No history for this field yet");
235
+ W("[data-field-history]") || v.info("No history for this field yet");
218
236
  }
219
237
  },
220
238
  {
221
239
  key: "watch",
222
240
  label: "Watch this field",
223
- icon: /* @__PURE__ */ s(Z, { className: "h-3.5 w-3.5" }),
224
- disabled: !C,
241
+ icon: /* @__PURE__ */ s(be, { className: "h-3.5 w-3.5" }),
242
+ disabled: !K,
225
243
  run: () => {
226
- R("[data-field-watch]") || h.info("Field watching is off — an admin can enable it in Settings → Content");
244
+ W("[data-field-watch]") || v.info("Field watching is off — an admin can enable it in Settings → Content");
227
245
  }
228
246
  },
229
247
  {
230
248
  key: "explain",
231
249
  label: "Explain value",
232
- icon: /* @__PURE__ */ s(ee, { className: "h-3.5 w-3.5" }),
233
- disabled: !C || !((B = t.current) != null && B.querySelector("[data-field-lineage]")),
250
+ icon: /* @__PURE__ */ s(pe, { className: "h-3.5 w-3.5" }),
251
+ disabled: !K || !((J = n.current) != null && J.querySelector("[data-field-lineage]")),
234
252
  run: () => {
235
- R("[data-field-lineage]");
253
+ W("[data-field-lineage]");
236
254
  }
237
255
  },
238
- ...i && g ? [
256
+ ...I && w ? [
239
257
  {
240
258
  key: "open",
241
- label: `Open related ${(H = i.one_collection) == null ? void 0 : H.replace(/_/g, " ")}`,
242
- icon: /* @__PURE__ */ s(te, { className: "h-3.5 w-3.5" }),
243
- disabled: e == null || e === "",
259
+ label: `Open related ${(z = I.one_collection) == null ? void 0 : z.replace(/_/g, " ")}`,
260
+ icon: /* @__PURE__ */ s(xe, { className: "h-3.5 w-3.5" }),
261
+ disabled: o == null || o === "",
244
262
  run: () => {
245
- const r = typeof e == "object" && e && "id" in e ? String(e.id) : String(e);
246
- g(String(i.one_collection), r);
263
+ const e = typeof o == "object" && o && "id" in o ? String(o.id) : String(o);
264
+ w(String(I.one_collection), e);
247
265
  }
248
266
  }
249
267
  ] : [],
250
- ...l != null && l.allowed(n.field) && D && l.hasValue(n.field) ? [
268
+ // Same states as the visible control: no default here → Save; a default holding another
269
+ // value → Update (that default, in place); the value IS the default → only Clear.
270
+ ...se ? [
251
271
  {
252
272
  key: "save-default",
253
273
  label: "Save as my default",
254
- icon: /* @__PURE__ */ s(ne, { className: "h-3.5 w-3.5" }),
274
+ icon: /* @__PURE__ */ s(ye, { className: "h-3.5 w-3.5" }),
255
275
  stay: !0,
256
- run: () => {
257
- O(null), E(!0), l.describeSave(n.field).then(
258
- (r) => O(r),
259
- () => O([])
260
- );
261
- }
276
+ run: E
262
277
  }
263
278
  ] : [],
264
- ...l != null && l.allowed(n.field) && l.defaultFor(n.field) ? [
279
+ ...ie ? [
280
+ {
281
+ key: "update-default",
282
+ label: "Update my default",
283
+ icon: /* @__PURE__ */ s(he, { className: "h-3.5 w-3.5" }),
284
+ stay: !0,
285
+ run: P
286
+ }
287
+ ] : [],
288
+ ...G && r ? [
265
289
  {
266
290
  key: "clear-default",
267
291
  label: "Clear my default",
268
- icon: /* @__PURE__ */ s(re, { className: "h-3.5 w-3.5" }),
292
+ icon: /* @__PURE__ */ s(ge, { className: "h-3.5 w-3.5" }),
269
293
  // Runs at once (a menu pick is deliberate); the toast's Undo saves it back.
270
294
  run: () => {
271
- l.clear(n.field).then(
272
- (r) => h.success(
273
- "Your default was cleared",
274
- r ? {
275
- action: {
276
- label: "Undo",
277
- onClick: () => {
278
- l.restore(r).then(
279
- () => h.success("Your default is back"),
280
- (u) => h.error(P(u, "Could not put your default back"))
281
- );
282
- }
283
- }
284
- } : void 0
285
- ),
286
- (r) => h.error(P(r, "Could not clear your default"))
287
- );
295
+ Te(r, t.field);
288
296
  }
289
297
  }
290
298
  ] : []
291
- ], G = k && l ? {
292
- text: f != null && f.length ? `Save ${f.join(" · ")} as your ${f.length > 1 ? "defaults" : "default"}?` : "Save as your default?",
293
- ready: f !== null && !U,
294
- saving: U,
295
- onCancel: T,
299
+ ], q = (e, c) => {
300
+ const u = e.value ? ` to ${e.value}` : "", F = e.context.length ? ` for ${e.context.join(" · ")}` : "";
301
+ return c ? `Updated your default${F}${u}` : `Update your default${F}${u}?`;
302
+ }, ce = k === "update" && r ? {
303
+ label: "Update my default",
304
+ action: "Update",
305
+ text: U ? q(U, !1) : "Update your default?",
306
+ ready: U !== null && !$,
307
+ saving: $,
308
+ onCancel: i,
296
309
  onSave: () => {
297
- A(!0), l.save(n.field).then(
310
+ j(!0), r.update(t.field).then(
298
311
  () => {
299
- h.success(
300
- f != null && f.length ? `Saved ${f.join(" · ")} as your default${f.length > 1 ? "s" : ""}` : "Your default was saved"
301
- ), T();
312
+ v.success(U ? q(U, !0) : "Updated your default"), i();
302
313
  },
303
- (r) => {
304
- h.error(P(r, "Could not save your default")), T();
314
+ (e) => {
315
+ v.error(ee(e, "Could not update your default")), i();
305
316
  }
306
317
  );
307
318
  }
308
- } : null, J = p ? /* @__PURE__ */ s(
309
- be,
319
+ } : k && r ? {
320
+ label: "Save as my default",
321
+ action: "Save",
322
+ text: y != null && y.length ? `Save ${y.join(" · ")} as your ${y.length > 1 ? "defaults" : "default"}?` : "Save as your default?",
323
+ ready: y !== null && !$,
324
+ saving: $,
325
+ onCancel: i,
326
+ onSave: () => {
327
+ j(!0), r.save(t.field).then(
328
+ () => {
329
+ v.success(
330
+ y != null && y.length ? `Saved ${y.join(" · ")} as your default${y.length > 1 ? "s" : ""}` : "Your default was saved"
331
+ ), i();
332
+ },
333
+ (e) => {
334
+ v.error(ee(e, "Could not save your default")), i();
335
+ }
336
+ );
337
+ }
338
+ } : null, de = g ? /* @__PURE__ */ s(
339
+ Oe,
310
340
  {
311
- at: p,
312
- items: $,
313
- onClose: T,
314
- confirm: G,
315
- anchor: t.current
341
+ at: g,
342
+ items: Y,
343
+ onClose: i,
344
+ confirm: ce,
345
+ anchor: n.current
316
346
  }
317
- ) : null, W = $.some((r) => r.key === "save-default" || r.key === "clear-default");
318
- return { onContextMenu: m, onKeyDown: x, menu: J, openFrom: b, isOpen: o, hasFieldItems: W };
347
+ ) : null, ue = Y.some(
348
+ (e) => e.key === "save-default" || e.key === "update-default" || e.key === "clear-default"
349
+ );
350
+ return {
351
+ onContextMenu: oe,
352
+ onKeyDown: le,
353
+ menu: de,
354
+ openFrom: d,
355
+ isOpen: p,
356
+ hasFieldItems: ue,
357
+ confirmSaveFrom: H,
358
+ openedBy: D
359
+ };
319
360
  }
320
- function be({
321
- at: t,
322
- items: n,
323
- onClose: e,
324
- confirm: a,
325
- anchor: c
361
+ const ae = 240, $e = "[data-field-menu-trigger], [data-personal-default-make], [data-personal-default-update]";
362
+ function Oe({
363
+ at: n,
364
+ items: t,
365
+ onClose: o,
366
+ confirm: l,
367
+ anchor: m
326
368
  }) {
327
- const d = j(null), [g, D] = M(0), p = n.filter((o) => !o.disabled);
328
- _(() => {
329
- var N;
330
- const o = (m) => {
331
- var i, C;
332
- const x = m.target;
333
- (i = d.current) != null && i.contains(x) || (C = x == null ? void 0 : x.closest) != null && C.call(x, "[data-field-menu-trigger]") && (c != null && c.contains(x)) || e();
334
- }, b = (m) => {
335
- var x;
336
- if (m.key === "Escape")
337
- m.preventDefault(), e();
338
- else if (a) {
339
- if (m.key === "Tab") {
340
- m.preventDefault();
341
- const i = [l.current, S.current].filter(
342
- ($) => !!$ && !$.disabled
369
+ Ue();
370
+ const x = M(null), [w, R] = C(0), g = t.filter((a) => !a.disabled);
371
+ B(() => {
372
+ var L;
373
+ const a = (i) => {
374
+ var d, E;
375
+ const p = i.target;
376
+ (d = x.current) != null && d.contains(p) || (E = p == null ? void 0 : p.closest) != null && E.call(p, $e) && (m != null && m.contains(p)) || o();
377
+ }, f = (i) => {
378
+ var p;
379
+ if (i.key === "Escape")
380
+ i.preventDefault(), o();
381
+ else if (l) {
382
+ if (i.key === "Tab") {
383
+ i.preventDefault();
384
+ const d = [r.current, T.current].filter(
385
+ (H) => !!H && !H.disabled
343
386
  );
344
- if (i.length === 0) return;
345
- const C = i.indexOf(document.activeElement), R = m.shiftKey ? C - 1 : C + 1;
346
- (x = i[(R % i.length + i.length) % i.length]) == null || x.focus();
387
+ if (d.length === 0) return;
388
+ const E = d.indexOf(document.activeElement), P = i.shiftKey ? E - 1 : E + 1;
389
+ (p = d[(P % d.length + d.length) % d.length]) == null || p.focus();
347
390
  }
348
391
  return;
349
- } else if (m.key === "ArrowDown")
350
- m.preventDefault(), D((i) => (i + 1) % Math.max(1, p.length));
351
- else if (m.key === "ArrowUp")
352
- m.preventDefault(), D((i) => (i - 1 + Math.max(1, p.length)) % Math.max(1, p.length));
353
- else if (m.key === "Enter" || m.key === " ") {
354
- m.preventDefault();
355
- const i = p[g];
356
- i && (i.run(), i.stay || e());
392
+ } else if (i.key === "ArrowDown")
393
+ i.preventDefault(), R((d) => (d + 1) % Math.max(1, g.length));
394
+ else if (i.key === "ArrowUp")
395
+ i.preventDefault(), R((d) => (d - 1 + Math.max(1, g.length)) % Math.max(1, g.length));
396
+ else if (i.key === "Enter" || i.key === " ") {
397
+ i.preventDefault();
398
+ const d = g[w];
399
+ d && (d.run(), d.stay || o());
357
400
  }
358
401
  };
359
- return window.addEventListener("mousedown", o, !0), window.addEventListener("keydown", b, !0), (N = d.current) == null || N.focus(), () => {
360
- window.removeEventListener("mousedown", o, !0), window.removeEventListener("keydown", b, !0);
402
+ return window.addEventListener("mousedown", a, !0), window.addEventListener("keydown", f, !0), (L = x.current) == null || L.focus(), () => {
403
+ window.removeEventListener("mousedown", a, !0), window.removeEventListener("keydown", f, !0);
361
404
  };
362
- }, [e, p, g, a, c]);
363
- const S = j(null), l = j(null), k = !!a, E = !!(a != null && a.ready);
364
- _(() => {
365
- var o;
366
- k && ((o = l.current) == null || o.focus());
367
- }, [k]), _(() => {
368
- var b;
369
- if (!E) return;
370
- const o = document.activeElement;
371
- (o === l.current || o === d.current || o === document.body) && ((b = S.current) == null || b.focus());
372
- }, [E]);
373
- const f = 240, [O, U] = M(() => a ? 96 : n.length * 30 + 12);
374
- le(() => {
375
- var b;
376
- const o = (b = d.current) == null ? void 0 : b.offsetHeight;
377
- o && o !== O && U(o);
405
+ }, [o, g, w, l, m]);
406
+ const T = M(null), r = M(null), k = !!l, S = !!(l != null && l.ready);
407
+ B(() => {
408
+ var a;
409
+ k && ((a = r.current) == null || a.focus());
410
+ }, [k]), B(() => {
411
+ var f;
412
+ if (!S) return;
413
+ const a = document.activeElement;
414
+ (a === r.current || a === x.current || a === document.body) && ((f = T.current) == null || f.focus());
415
+ }, [S]);
416
+ const y = Math.min(ae, window.innerWidth - 16), O = Ee(l == null ? void 0 : l.text), [U, A] = C(() => l ? 96 : t.length * 30 + 12);
417
+ Ne(() => {
418
+ var f;
419
+ const a = (f = x.current) == null ? void 0 : f.offsetHeight;
420
+ a && a !== U && A(a);
378
421
  });
379
- const A = Math.max(8, Math.min(t.x, window.innerWidth - f - 8)), v = Math.max(8, Math.min(t.y, window.innerHeight - O - 8)), w = (c == null ? void 0 : c.closest('[role="dialog"]')) ?? document.body, T = w === document.body ? { position: "fixed", left: A, top: v } : (() => {
380
- const o = w.getBoundingClientRect();
422
+ const $ = Math.max(8, Math.min(n.x, window.innerWidth - y - 8)), j = Math.max(8, Math.min(n.y, window.innerHeight - U - 8)), b = (m == null ? void 0 : m.closest('[role="dialog"]')) ?? document.body, D = b === document.body ? { position: "fixed", left: $, top: j } : (() => {
423
+ const a = b.getBoundingClientRect();
381
424
  return {
382
425
  position: "absolute",
383
- left: A - o.left + w.scrollLeft - w.clientLeft,
384
- top: v - o.top + w.scrollTop - w.clientTop
426
+ left: $ - a.left + b.scrollLeft - b.clientLeft,
427
+ top: j - a.top + b.scrollTop - b.clientTop
385
428
  };
386
429
  })();
387
- return ie(
388
- /* @__PURE__ */ y(
430
+ return Ce(
431
+ /* @__PURE__ */ h(
389
432
  "div",
390
433
  {
391
- ref: d,
392
- ...a ? { role: "dialog", "aria-modal": !1, "aria-label": "Save as my default" } : { role: "menu", "aria-label": "Field options" },
434
+ ref: x,
435
+ ...l ? { role: "dialog", "aria-modal": !1, "aria-label": l.label } : { role: "menu", "aria-label": "Field options" },
393
436
  tabIndex: -1,
394
437
  "data-field-context-menu": !0,
395
- style: { ...T, width: f, zIndex: 110 },
438
+ style: { ...D, width: y, maxWidth: "calc(100vw - 16px)", zIndex: 110 },
396
439
  className: "rounded-lg border border-slate-200 bg-white p-1 shadow-xl outline-none dark:border-border dark:bg-card",
397
440
  children: [
398
- a ? /* @__PURE__ */ y("div", { "data-personal-default-confirm": !0, className: "space-y-2 px-2 py-1.5", children: [
441
+ l ? /* @__PURE__ */ h("div", { "data-personal-default-confirm": !0, className: "space-y-2 px-2 py-1.5", children: [
399
442
  /* @__PURE__ */ s(
400
443
  "p",
401
444
  {
445
+ ref: O,
402
446
  "aria-live": "polite",
403
- className: "text-[12.5px] leading-snug text-slate-700 dark:text-slate-200",
404
- children: a.text
447
+ className: "line-clamp-4 text-[12.5px] leading-snug text-slate-700 [overflow-wrap:anywhere] dark:text-slate-200",
448
+ children: l.text
405
449
  }
406
450
  ),
407
- /* @__PURE__ */ y("div", { className: "flex justify-end gap-1.5", children: [
408
- /* @__PURE__ */ y(
451
+ /* @__PURE__ */ h("div", { className: "flex justify-end gap-1.5", children: [
452
+ /* @__PURE__ */ h(
409
453
  "button",
410
454
  {
411
- ref: l,
455
+ ref: r,
412
456
  type: "button",
413
- onClick: a.onCancel,
414
- className: de,
457
+ onClick: l.onCancel,
458
+ className: Le,
415
459
  children: [
416
- /* @__PURE__ */ s(X, { className: "h-3 w-3", "aria-hidden": !0 }),
460
+ /* @__PURE__ */ s(ne, { className: "h-3 w-3", "aria-hidden": !0 }),
417
461
  " Cancel"
418
462
  ]
419
463
  }
@@ -421,102 +465,102 @@ function be({
421
465
  /* @__PURE__ */ s(
422
466
  "button",
423
467
  {
424
- ref: S,
468
+ ref: T,
425
469
  type: "button",
426
- disabled: !a.ready,
427
- onClick: a.onSave,
470
+ disabled: !l.ready,
471
+ onClick: l.onSave,
428
472
  className: "h-7 rounded-md bg-nvr-cyan px-2.5 text-[11.5px] font-semibold text-white hover:bg-nvr-cyan/90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-nvr-cyan/40 focus-visible:ring-offset-1 disabled:cursor-not-allowed disabled:opacity-50",
429
- children: a.saving ? "Saving…" : "Save"
473
+ children: l.saving ? "Saving…" : l.action
430
474
  }
431
475
  )
432
476
  ] })
433
477
  ] }) : null,
434
- a ? null : n.map((o) => {
435
- const b = p.indexOf(o), N = b === g && !o.disabled;
436
- return /* @__PURE__ */ y(
478
+ l ? null : t.map((a) => {
479
+ const f = g.indexOf(a), L = f === w && !a.disabled;
480
+ return /* @__PURE__ */ h(
437
481
  "button",
438
482
  {
439
483
  type: "button",
440
484
  role: "menuitem",
441
- disabled: o.disabled,
442
- onMouseEnter: () => b >= 0 && D(b),
485
+ disabled: a.disabled,
486
+ onMouseEnter: () => f >= 0 && R(f),
443
487
  onClick: () => {
444
- o.run(), o.stay || e();
488
+ a.run(), a.stay || o();
445
489
  },
446
- className: q(
490
+ className: re(
447
491
  "flex h-[30px] w-full items-center gap-2 rounded-sm px-2 text-left text-[12.5px] font-medium text-slate-700 dark:text-slate-200",
448
- N && "bg-accent text-accent-foreground",
449
- o.disabled && "cursor-not-allowed opacity-40"
492
+ L && "bg-accent text-accent-foreground",
493
+ a.disabled && "cursor-not-allowed opacity-40"
450
494
  ),
451
495
  children: [
452
- /* @__PURE__ */ s("span", { className: "shrink-0 text-slate-500", children: o.icon }),
453
- /* @__PURE__ */ s("span", { className: "min-w-0 flex-1 truncate", children: o.label }),
454
- o.hint && /* @__PURE__ */ s("span", { className: "max-w-[90px] truncate font-mono text-[10.5px] text-slate-400", children: o.hint })
496
+ /* @__PURE__ */ s("span", { className: "shrink-0 text-slate-500", children: a.icon }),
497
+ /* @__PURE__ */ s("span", { className: "min-w-0 flex-1 truncate", children: a.label }),
498
+ a.hint && /* @__PURE__ */ s("span", { className: "max-w-[90px] truncate font-mono text-[10.5px] text-slate-400", children: a.hint })
455
499
  ]
456
500
  },
457
- o.key
501
+ a.key
458
502
  );
459
503
  })
460
504
  ]
461
505
  }
462
506
  ),
463
- w
507
+ b
464
508
  );
465
509
  }
466
- function Le(t) {
467
- const [n, e] = M(null), [a, c] = M(!1), d = j(!1), g = j(null);
468
- _(() => {
469
- const l = t.current;
470
- if (!l) return;
471
- const k = () => e(l.getAttribute("data-remote-editor"));
510
+ function Je(n) {
511
+ const [t, o] = C(null), [l, m] = C(!1), x = M(!1), w = M(null);
512
+ B(() => {
513
+ const r = n.current;
514
+ if (!r) return;
515
+ const k = () => o(r.getAttribute("data-remote-editor"));
472
516
  k();
473
- const E = new MutationObserver(k);
474
- return E.observe(l, { attributes: !0, attributeFilter: ["data-remote-editor"] }), () => E.disconnect();
475
- }, [t]), _(() => {
476
- n || (c(!1), d.current = !1);
477
- }, [n]);
478
- const D = F(
479
- (l) => {
480
- if (!n || d.current) return;
481
- const k = l.target;
482
- k.matches('input, textarea, select, [contenteditable="true"], [role="combobox"]') && (g.current = k, setTimeout(() => {
483
- d.current || k.blur();
484
- }, 0), c(!0));
517
+ const S = new MutationObserver(k);
518
+ return S.observe(r, { attributes: !0, attributeFilter: ["data-remote-editor"] }), () => S.disconnect();
519
+ }, [n]), B(() => {
520
+ t || (m(!1), x.current = !1);
521
+ }, [t]);
522
+ const R = N(
523
+ (r) => {
524
+ if (!t || x.current) return;
525
+ const k = r.target;
526
+ k.matches('input, textarea, select, [contenteditable="true"], [role="combobox"]') && (w.current = k, setTimeout(() => {
527
+ x.current || k.blur();
528
+ }, 0), m(!0));
485
529
  },
486
- [n]
487
- ), p = F(() => {
488
- d.current = !0, c(!1);
489
- const l = g.current;
490
- g.current = null, l && setTimeout(() => l.focus(), 0);
491
- }, []), S = F(() => {
492
- c(!1), g.current = null;
530
+ [t]
531
+ ), g = N(() => {
532
+ x.current = !0, m(!1);
533
+ const r = w.current;
534
+ w.current = null, r && setTimeout(() => r.focus(), 0);
535
+ }, []), T = N(() => {
536
+ m(!1), w.current = null;
493
537
  }, []);
494
- return { editor: n, confirming: a, onFocusCapture: D, confirm: p, cancel: S };
538
+ return { editor: t, confirming: l, onFocusCapture: R, confirm: g, cancel: T };
495
539
  }
496
- function Fe({
497
- editor: t,
498
- confirming: n,
499
- onConfirm: e,
500
- onCancel: a
540
+ function ze({
541
+ editor: n,
542
+ confirming: t,
543
+ onConfirm: o,
544
+ onCancel: l
501
545
  }) {
502
- const c = t.split(/\s+/).map((d) => d[0]).filter(Boolean).slice(0, 2).join("").toUpperCase();
503
- return /* @__PURE__ */ y(
546
+ const m = n.split(/\s+/).map((x) => x[0]).filter(Boolean).slice(0, 2).join("").toUpperCase();
547
+ return /* @__PURE__ */ h(
504
548
  "div",
505
549
  {
506
550
  "data-presence-soft-lock": !0,
507
- className: q(
551
+ className: re(
508
552
  "flex flex-wrap items-center gap-2 rounded-md px-2 py-1 text-[11.5px]",
509
- n ? "border border-amber-300 bg-amber-50 text-amber-900 dark:border-amber-500/40 dark:bg-amber-500/10 dark:text-amber-100" : "text-amber-700 dark:text-amber-300"
553
+ t ? "border border-amber-300 bg-amber-50 text-amber-900 dark:border-amber-500/40 dark:bg-amber-500/10 dark:text-amber-100" : "text-amber-700 dark:text-amber-300"
510
554
  ),
511
555
  children: [
512
- /* @__PURE__ */ s("span", { className: "inline-flex h-4 w-4 shrink-0 items-center justify-center rounded-full bg-amber-200 text-[9px] font-semibold text-amber-900 dark:bg-amber-500/40 dark:text-amber-50", children: c || "?" }),
513
- /* @__PURE__ */ s("span", { className: "min-w-0 flex-1", children: n ? `${t} is typing here — edit anyway?` : `${t} is editing this field` }),
514
- n && /* @__PURE__ */ y(z, { children: [
556
+ /* @__PURE__ */ s("span", { className: "inline-flex h-4 w-4 shrink-0 items-center justify-center rounded-full bg-amber-200 text-[9px] font-semibold text-amber-900 dark:bg-amber-500/40 dark:text-amber-50", children: m || "?" }),
557
+ /* @__PURE__ */ s("span", { className: "min-w-0 flex-1", children: t ? `${n} is typing here — edit anyway?` : `${n} is editing this field` }),
558
+ t && /* @__PURE__ */ h(fe, { children: [
515
559
  /* @__PURE__ */ s(
516
560
  "button",
517
561
  {
518
562
  type: "button",
519
- onClick: e,
563
+ onClick: o,
520
564
  className: "rounded-md bg-amber-600 px-2 py-0.5 text-[11px] font-semibold text-white hover:bg-amber-700",
521
565
  children: "Edit anyway"
522
566
  }
@@ -525,7 +569,7 @@ function Fe({
525
569
  "button",
526
570
  {
527
571
  type: "button",
528
- onClick: a,
572
+ onClick: l,
529
573
  className: "rounded-md border border-amber-300 px-2 py-0.5 text-[11px] font-medium hover:bg-amber-100 dark:border-amber-500/40 dark:hover:bg-amber-500/15",
530
574
  children: "Leave it"
531
575
  }
@@ -536,12 +580,12 @@ function Fe({
536
580
  );
537
581
  }
538
582
  export {
539
- me as FieldAffordancesContext,
540
- Ee as LockReasonBadge,
541
- Fe as PresenceSoftLockStrip,
542
- Se as RemoteChangeGhost,
543
- V as ghostText,
544
- Ce as useFieldAffordances,
545
- Te as useFieldContextMenu,
546
- Le as usePresenceSoftLock
583
+ Me as FieldAffordancesContext,
584
+ Ye as LockReasonBadge,
585
+ ze as PresenceSoftLockStrip,
586
+ Xe as RemoteChangeGhost,
587
+ te as ghostText,
588
+ Ve as useFieldAffordances,
589
+ qe as useFieldContextMenu,
590
+ Je as usePresenceSoftLock
547
591
  };