@haklex/rich-editor-ui 0.58.0 → 0.59.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/dist/components/action-button/index.d.ts +9 -1
  2. package/dist/components/action-button/index.d.ts.map +1 -1
  3. package/dist/components/action-button/styles.css.d.ts +15 -0
  4. package/dist/components/action-button/styles.css.d.ts.map +1 -1
  5. package/dist/components/color-picker/index.d.ts +5 -1
  6. package/dist/components/color-picker/index.d.ts.map +1 -1
  7. package/dist/components/color-picker/preset-view.d.ts +12 -0
  8. package/dist/components/color-picker/preset-view.d.ts.map +1 -0
  9. package/dist/components/color-picker/presets.d.ts +12 -0
  10. package/dist/components/color-picker/presets.d.ts.map +1 -0
  11. package/dist/components/color-picker/recent.d.ts +5 -0
  12. package/dist/components/color-picker/recent.d.ts.map +1 -0
  13. package/dist/components/color-picker/styles.css.d.ts +8 -2
  14. package/dist/components/color-picker/styles.css.d.ts.map +1 -1
  15. package/dist/components/dialog/confirm.d.ts +10 -0
  16. package/dist/components/dialog/confirm.d.ts.map +1 -0
  17. package/dist/components/dialog/sheet.d.ts.map +1 -1
  18. package/dist/components/dialog/stack.d.ts.map +1 -1
  19. package/dist/components/dialog/store.d.ts +9 -1
  20. package/dist/components/dialog/store.d.ts.map +1 -1
  21. package/dist/components/dialog/styles.css.d.ts.map +1 -1
  22. package/dist/components/dropdown-menu/index.d.ts +8 -1
  23. package/dist/components/dropdown-menu/index.d.ts.map +1 -1
  24. package/dist/components/dropdown-menu/styles.css.d.ts +2 -0
  25. package/dist/components/dropdown-menu/styles.css.d.ts.map +1 -1
  26. package/dist/components/field/index.d.ts +12 -0
  27. package/dist/components/field/index.d.ts.map +1 -0
  28. package/dist/components/field/styles.css.d.ts +5 -0
  29. package/dist/components/field/styles.css.d.ts.map +1 -0
  30. package/dist/components/modal-shell/index.d.ts +35 -0
  31. package/dist/components/modal-shell/index.d.ts.map +1 -0
  32. package/dist/components/modal-shell/styles.css.d.ts +13 -0
  33. package/dist/components/modal-shell/styles.css.d.ts.map +1 -0
  34. package/dist/components/popover/index.d.ts +22 -2
  35. package/dist/components/popover/index.d.ts.map +1 -1
  36. package/dist/components/popover/styles.css.d.ts +9 -0
  37. package/dist/components/popover/styles.css.d.ts.map +1 -1
  38. package/dist/components/quote-attribution/QuoteAttributionPlugin.d.ts.map +1 -1
  39. package/dist/components/quote-attribution/styles.css.d.ts +4 -7
  40. package/dist/components/quote-attribution/styles.css.d.ts.map +1 -1
  41. package/dist/components/segmented-control/styles.css.d.ts.map +1 -1
  42. package/dist/components/select/styles.css.d.ts.map +1 -1
  43. package/dist/components/text-input/index.d.ts +10 -0
  44. package/dist/components/text-input/index.d.ts.map +1 -0
  45. package/dist/components/text-input/styles.css.d.ts +3 -0
  46. package/dist/components/text-input/styles.css.d.ts.map +1 -0
  47. package/dist/components/toast/index.d.ts +4 -0
  48. package/dist/components/toast/index.d.ts.map +1 -0
  49. package/dist/components/toast/store.d.ts +21 -0
  50. package/dist/components/toast/store.d.ts.map +1 -0
  51. package/dist/components/toast/styles.css.d.ts +8 -0
  52. package/dist/components/toast/styles.css.d.ts.map +1 -0
  53. package/dist/hooks/use-live-edit.d.ts +6 -0
  54. package/dist/hooks/use-live-edit.d.ts.map +1 -0
  55. package/dist/index.d.ts +18 -6
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.mjs +1334 -758
  58. package/dist/rich-editor-ui.css +1 -1
  59. package/dist/styles/menu.css.d.ts +11 -0
  60. package/dist/styles/menu.css.d.ts.map +1 -1
  61. package/package.json +2 -2
package/dist/index.mjs CHANGED
@@ -1,17 +1,18 @@
1
1
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
- import { AlertCircle, AlertTriangle, ArrowDown, ArrowLeft, ArrowRight, ArrowUp, Check, CheckCircle2, ChevronDown, ChevronRight, ChevronUp, Copy, CornerDownLeft, Delete, Info, Pipette, Plus, X } from "lucide-react";
2
+ import { AlertCircle, AlertTriangle, ArrowDown, ArrowLeft, ArrowRight, ArrowUp, Check, CheckCircle2, ChevronDown, ChevronRight, ChevronUp, CircleAlert, CircleCheck, Copy, CornerDownLeft, Delete, Info, LoaderCircle, Pipette, Plus, X } from "lucide-react";
3
3
  import { createContext, createElement, forwardRef, use, useCallback, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
4
4
  import { Collapsible as Collapsible$1 } from "@base-ui/react/collapsible";
5
5
  import { Popover as Popover$1 } from "@base-ui/react/popover";
6
- import { PortalThemeProvider, PortalThemeProvider as PortalThemeProvider$1, PortalThemeWrapper, PortalThemeWrapper as PortalThemeWrapper$1, usePortalContainer, usePortalTheme } from "@haklex/rich-style-token";
6
+ import { PortalThemeProvider, PortalThemeProvider as PortalThemeProvider$1, PortalThemeWrapper, PortalThemeWrapper as PortalThemeWrapper$1, usePortalTheme } from "@haklex/rich-style-token";
7
+ import { Tooltip } from "@base-ui/react/tooltip";
7
8
  import { Combobox as Combobox$1 } from "@base-ui/react/combobox";
8
9
  import { Dialog as Dialog$1 } from "@base-ui/react/dialog";
10
+ import { chromeWidth } from "@haklex/rich-style-token/styles";
11
+ import { createPortal } from "react-dom";
9
12
  import { Menu } from "@base-ui/react/menu";
10
13
  import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
11
- import { $getNodeByKey, $getRoot } from "lexical";
12
- import { createPortal } from "react-dom";
14
+ import { $getNodeByKey, $getRoot, $getSelection, $isRangeSelection } from "lexical";
13
15
  import { Select as Select$1 } from "@base-ui/react/select";
14
- import { Tooltip } from "@base-ui/react/tooltip";
15
16
  //#region ../../node_modules/.pnpm/@vanilla-extract+recipes@0.5.7_@vanilla-extract+css@1.21.3/node_modules/@vanilla-extract/recipes/dist/createRuntimeFn-62c9670f.esm.js
16
17
  function toPrimitive(t, r) {
17
18
  if ("object" != typeof t || !t) return t;
@@ -101,43 +102,49 @@ var createRuntimeFn = (config) => {
101
102
  };
102
103
  //#endregion
103
104
  //#region src/components/action-button/styles.css.ts
104
- var semanticClassNames$1 = {
105
+ var levelTone = {
106
+ "1": "_73ej2i1",
107
+ "2": "_73ej2i2",
108
+ "3": "_73ej2i3",
109
+ "4": "_73ej2i4"
110
+ };
111
+ var semanticClassNames = {
105
112
  actionBar: "re-ui-action-bar",
106
113
  actionButton: "re-ui-action-btn",
107
114
  actionButtonEnd: "re-ui-action-btn--end",
108
115
  actionButtonDanger: "re-ui-action-btn--danger",
109
116
  actionButtonIcon: "re-ui-action-btn--icon"
110
117
  };
111
- var actionBar = "_73ej2i0";
118
+ var actionBar = "_73ej2i5";
112
119
  var actionButton$1 = createRuntimeFn({
113
- defaultClassName: "_73ej2i1",
120
+ defaultClassName: "_73ej2i6",
114
121
  variantClassNames: {
115
122
  variant: {
116
- ghost: "_73ej2i2",
117
- solid: "_73ej2i3",
118
- outline: "_73ej2i4",
119
- accent: "_73ej2i5"
123
+ ghost: "_73ej2i7",
124
+ solid: "_73ej2i8",
125
+ outline: "_73ej2i9",
126
+ accent: "_73ej2ia"
120
127
  },
121
128
  size: {
122
- sm: "_73ej2i6",
123
- md: "_73ej2i7",
124
- lg: "_73ej2i8"
129
+ sm: "_73ej2ib",
130
+ md: "_73ej2ic",
131
+ lg: "_73ej2id"
125
132
  },
126
133
  icon: {
127
- true: "_73ej2i9",
128
- false: "_73ej2ia"
134
+ true: "_73ej2ie",
135
+ false: "_73ej2if"
129
136
  },
130
137
  end: {
131
- true: "_73ej2ib",
132
- false: "_73ej2ic"
138
+ true: "_73ej2ig",
139
+ false: "_73ej2ih"
133
140
  },
134
141
  danger: {
135
- true: "_73ej2id",
136
- false: "_73ej2ie"
142
+ true: "_73ej2ii",
143
+ false: "_73ej2ij"
137
144
  },
138
145
  rounded: {
139
- true: "_73ej2if",
140
- false: "_73ej2ig"
146
+ true: "_73ej2ik",
147
+ false: "_73ej2il"
141
148
  }
142
149
  },
143
150
  defaultVariants: {
@@ -152,31 +159,39 @@ var actionButton$1 = createRuntimeFn({
152
159
  [{
153
160
  icon: true,
154
161
  size: "sm"
155
- }, "_73ej2ih"],
162
+ }, "_73ej2im"],
156
163
  [{
157
164
  icon: true,
158
165
  size: "md"
159
- }, "_73ej2ii"],
166
+ }, "_73ej2in"],
160
167
  [{
161
168
  icon: true,
162
169
  size: "lg"
163
- }, "_73ej2ij"],
170
+ }, "_73ej2io"],
171
+ [{
172
+ icon: true,
173
+ variant: "outline"
174
+ }, "_73ej2ip"],
164
175
  [{
165
176
  icon: true,
166
177
  variant: "ghost"
167
- }, "_73ej2ik"],
178
+ }, "_73ej2iq"],
168
179
  [{
169
180
  rounded: true,
170
181
  icon: true
171
- }, "_73ej2il"],
172
- [{ danger: true }, "_73ej2im"]
182
+ }, "_73ej2ir"],
183
+ [{
184
+ danger: true,
185
+ variant: "solid"
186
+ }, "_73ej2is"],
187
+ [{ danger: true }, "_73ej2it"]
173
188
  ]
174
189
  });
175
190
  //#endregion
176
191
  //#region src/components/action-button/index.tsx
177
192
  function ActionBar({ className, gap, style, ...props }) {
178
193
  return /* @__PURE__ */ jsx("div", {
179
- className: `${actionBar} ${semanticClassNames$1.actionBar}${className ? ` ${className}` : ""}`,
194
+ className: `${actionBar} ${semanticClassNames.actionBar}${className ? ` ${className}` : ""}`,
180
195
  style: gap != null ? {
181
196
  ...style,
182
197
  gap
@@ -184,11 +199,12 @@ function ActionBar({ className, gap, style, ...props }) {
184
199
  ...props
185
200
  });
186
201
  }
187
- function ActionButton({ variant, size, end = false, danger = false, icon = false, rounded = false, className, type = "button", ...props }) {
188
- const semanticParts = [semanticClassNames$1.actionButton];
189
- if (end) semanticParts.push(semanticClassNames$1.actionButtonEnd);
190
- if (danger) semanticParts.push(semanticClassNames$1.actionButtonDanger);
191
- if (icon) semanticParts.push(semanticClassNames$1.actionButtonIcon);
202
+ function ActionButton({ variant, size, end = false, danger = false, icon = false, rounded = false, level, className, type = "button", ...props }) {
203
+ const semanticParts = [semanticClassNames.actionButton];
204
+ if (end) semanticParts.push(semanticClassNames.actionButtonEnd);
205
+ if (danger) semanticParts.push(semanticClassNames.actionButtonDanger);
206
+ if (icon) semanticParts.push(semanticClassNames.actionButtonIcon);
207
+ if (level && !icon) semanticParts.push(levelTone[level]);
192
208
  const recipeClass = actionButton$1({
193
209
  variant,
194
210
  size,
@@ -204,7 +220,9 @@ function ActionButton({ variant, size, end = false, danger = false, icon = false
204
220
  });
205
221
  }
206
222
  function getActionButtonClassName(options) {
207
- return `${actionButton$1(options)} ${semanticClassNames$1.actionButton}`;
223
+ const { level, ...recipe } = options ?? {};
224
+ const levelClass = level ? ` ${levelTone[level]}` : "";
225
+ return `${actionButton$1(recipe)} ${semanticClassNames.actionButton}${levelClass}`;
208
226
  }
209
227
  //#endregion
210
228
  //#region src/components/alert/styles.css.ts
@@ -1117,7 +1135,7 @@ function CodeBlock({ chrome, className, collapsible = true, code, language, show
1117
1135
  //#endregion
1118
1136
  //#region src/components/collapsible/styles.css.ts
1119
1137
  var trigger$1 = "_1hdi6a90";
1120
- var panel$2 = "_1hdi6a92";
1138
+ var panel$1 = "_1hdi6a92";
1121
1139
  var panelContent = "_1hdi6a93";
1122
1140
  //#endregion
1123
1141
  //#region src/components/collapsible/index.tsx
@@ -1135,7 +1153,7 @@ function CollapsibleTrigger({ children, className, hideChevron, ...props }) {
1135
1153
  function CollapsiblePanel({ children, className, ...props }) {
1136
1154
  return /* @__PURE__ */ jsx(Collapsible$1.Panel, {
1137
1155
  ...props,
1138
- className: `${panel$2}${className ? ` ${className}` : ""}`,
1156
+ className: `${panel$1}${className ? ` ${className}` : ""}`,
1139
1157
  children: /* @__PURE__ */ jsx("div", {
1140
1158
  className: panelContent,
1141
1159
  children
@@ -1161,8 +1179,18 @@ function getStrictContext(name) {
1161
1179
  //#region src/components/popover/styles.css.ts
1162
1180
  var popup$5 = "f2q44l0";
1163
1181
  var arrow = "f2q44l1";
1164
- var title$1 = "f2q44l2";
1182
+ var title$2 = "f2q44l2";
1165
1183
  var description$1 = "f2q44l3";
1184
+ var size$1 = {
1185
+ sm: "f2q44l4",
1186
+ md: "f2q44l5",
1187
+ lg: "f2q44l6"
1188
+ };
1189
+ var flush = "f2q44l7";
1190
+ var header$2 = "f2q44l8";
1191
+ var headerTitle$1 = "f2q44la";
1192
+ var body$1 = "f2q44lc";
1193
+ var footer$3 = "f2q44ld";
1166
1194
  //#endregion
1167
1195
  //#region src/components/popover/index.tsx
1168
1196
  var [PopoverProvider, usePopover] = getStrictContext("PopoverContext");
@@ -1195,14 +1223,18 @@ function PopoverPortal({ children, ...props }) {
1195
1223
  function PopoverPositioner(props) {
1196
1224
  return /* @__PURE__ */ jsx(Popover$1.Positioner, { ...props });
1197
1225
  }
1198
- function PopoverPopup({ className, children, ...props }) {
1226
+ function PopoverPopup({ className, children, flush: flush$1, size, ...props }) {
1227
+ const classes = [popup$5];
1228
+ if (size) classes.push(size$1[size]);
1229
+ if (flush$1) classes.push(flush);
1230
+ if (className) classes.push(className);
1199
1231
  return /* @__PURE__ */ jsx(Popover$1.Popup, {
1200
- className: `${popup$5}${className ? ` ${className}` : ""}`,
1232
+ className: classes.join(" "),
1201
1233
  ...props,
1202
1234
  children
1203
1235
  });
1204
1236
  }
1205
- function PopoverPanel({ align = "center", side, sideOffset = 4, className, children, ...popupProps }) {
1237
+ function PopoverPanel({ align = "center", side, sideOffset = 8, className, children, ...popupProps }) {
1206
1238
  return /* @__PURE__ */ jsx(PopoverPortal, { children: /* @__PURE__ */ jsx(PopoverPositioner, {
1207
1239
  align,
1208
1240
  side,
@@ -1225,7 +1257,7 @@ function PopoverClose(props) {
1225
1257
  }
1226
1258
  function PopoverTitle({ className, ...props }) {
1227
1259
  return /* @__PURE__ */ jsx(Popover$1.Title, {
1228
- className: `${title$1}${className ? ` ${className}` : ""}`,
1260
+ className: `${title$2}${className ? ` ${className}` : ""}`,
1229
1261
  ...props
1230
1262
  });
1231
1263
  }
@@ -1235,6 +1267,268 @@ function PopoverDescription({ className, ...props }) {
1235
1267
  ...props
1236
1268
  });
1237
1269
  }
1270
+ function PopoverHeader({ actions, className, icon, title }) {
1271
+ return /* @__PURE__ */ jsxs("div", {
1272
+ className: `${header$2}${className ? ` ${className}` : ""}`,
1273
+ children: [
1274
+ icon && /* @__PURE__ */ jsx("span", {
1275
+ className: "f2q44l9",
1276
+ children: icon
1277
+ }),
1278
+ /* @__PURE__ */ jsx("span", {
1279
+ className: headerTitle$1,
1280
+ children: title
1281
+ }),
1282
+ actions && /* @__PURE__ */ jsx("span", {
1283
+ className: "f2q44lb",
1284
+ children: actions
1285
+ })
1286
+ ]
1287
+ });
1288
+ }
1289
+ function PopoverBody({ children, className }) {
1290
+ return /* @__PURE__ */ jsx("div", {
1291
+ className: `${body$1}${className ? ` ${className}` : ""}`,
1292
+ children
1293
+ });
1294
+ }
1295
+ function PopoverFooter({ children, className, hint }) {
1296
+ return /* @__PURE__ */ jsxs("div", {
1297
+ className: `${footer$3}${className ? ` ${className}` : ""}`,
1298
+ children: [hint && /* @__PURE__ */ jsx("span", {
1299
+ className: "f2q44le",
1300
+ children: hint
1301
+ }), children]
1302
+ });
1303
+ }
1304
+ //#endregion
1305
+ //#region src/components/kbd/keys.ts
1306
+ var aliases = {
1307
+ "ctrl": "mod",
1308
+ "control": "mod",
1309
+ "cmd": "mod",
1310
+ "command": "mod",
1311
+ "meta": "mod",
1312
+ "mod": "mod",
1313
+ "option": "alt",
1314
+ "opt": "alt",
1315
+ "alt": "alt",
1316
+ "shift": "shift",
1317
+ "return": "enter",
1318
+ "enter": "enter",
1319
+ "esc": "escape",
1320
+ "escape": "escape",
1321
+ "backspace": "backspace",
1322
+ "del": "delete",
1323
+ "delete": "delete",
1324
+ "arrowup": "up",
1325
+ "up": "up",
1326
+ "arrowdown": "down",
1327
+ "down": "down",
1328
+ "arrowleft": "left",
1329
+ "left": "left",
1330
+ "arrowright": "right",
1331
+ "right": "right",
1332
+ "⌘": "mod",
1333
+ "⌃": "mod",
1334
+ "⇧": "shift",
1335
+ "⌥": "alt",
1336
+ "↵": "enter",
1337
+ "⏎": "enter",
1338
+ "⌫": "backspace",
1339
+ "⌦": "delete",
1340
+ "↑": "up",
1341
+ "↓": "down",
1342
+ "←": "left",
1343
+ "→": "right"
1344
+ };
1345
+ var glyphs = /[←↑→↓↵⇧⌃⌘⌥⌦⌫⏎]/g;
1346
+ function normalize(token) {
1347
+ const lower = token.trim().toLowerCase();
1348
+ return aliases[lower] ?? lower;
1349
+ }
1350
+ function parseShortcut(shortcut) {
1351
+ return (shortcut.includes("+") ? shortcut.split("+") : shortcut.replaceAll(glyphs, (g) => `+${g}+`).split("+")).filter((p) => p.trim() !== "").map(normalize);
1352
+ }
1353
+ var macModifiers = {
1354
+ mod: {
1355
+ label: "⌘",
1356
+ name: "Command"
1357
+ },
1358
+ shift: {
1359
+ label: "⇧",
1360
+ name: "Shift"
1361
+ },
1362
+ alt: {
1363
+ label: "⌥",
1364
+ name: "Option"
1365
+ }
1366
+ };
1367
+ var otherModifiers = {
1368
+ mod: {
1369
+ label: "Ctrl",
1370
+ name: "Control"
1371
+ },
1372
+ shift: {
1373
+ label: "Shift",
1374
+ name: "Shift"
1375
+ },
1376
+ alt: {
1377
+ label: "Alt",
1378
+ name: "Alt"
1379
+ }
1380
+ };
1381
+ var iconKeys = {
1382
+ enter: "Enter",
1383
+ backspace: "Backspace",
1384
+ delete: "Delete",
1385
+ up: "Up",
1386
+ down: "Down",
1387
+ left: "Left",
1388
+ right: "Right"
1389
+ };
1390
+ var namedKeys = {
1391
+ escape: {
1392
+ label: "Esc",
1393
+ name: "Escape"
1394
+ },
1395
+ tab: {
1396
+ label: "Tab",
1397
+ name: "Tab"
1398
+ },
1399
+ space: {
1400
+ label: "Space",
1401
+ name: "Space"
1402
+ }
1403
+ };
1404
+ function keyDisplay(key, platform) {
1405
+ const modifiers = platform === "mac" ? macModifiers : otherModifiers;
1406
+ if (modifiers[key]) return modifiers[key];
1407
+ if (key in iconKeys) return {
1408
+ icon: key,
1409
+ name: iconKeys[key]
1410
+ };
1411
+ if (namedKeys[key]) return namedKeys[key];
1412
+ const label = key.length === 1 ? key.toUpperCase() : key[0].toUpperCase() + key.slice(1);
1413
+ return {
1414
+ label,
1415
+ name: label
1416
+ };
1417
+ }
1418
+ function detectPlatform(nav) {
1419
+ if (!nav) return "other";
1420
+ const source = `${nav.platform ?? ""} ${nav.userAgent ?? ""}`;
1421
+ return /mac|iphone|ipad|ipod/i.test(source) ? "mac" : "other";
1422
+ }
1423
+ //#endregion
1424
+ //#region src/components/kbd/styles.css.ts
1425
+ var group$1 = "lhlko40";
1426
+ var cap = "lhlko41";
1427
+ var size = {
1428
+ sm: "lhlko42",
1429
+ md: "lhlko43"
1430
+ };
1431
+ var tone = {
1432
+ "default": "lhlko44",
1433
+ muted: "lhlko45",
1434
+ inverted: "lhlko46"
1435
+ };
1436
+ var icon$2 = "lhlko47";
1437
+ var mirrored = "lhlko48";
1438
+ var visuallyHidden = "lhlko49";
1439
+ //#endregion
1440
+ //#region src/components/kbd/index.tsx
1441
+ var icons = {
1442
+ enter: CornerDownLeft,
1443
+ backspace: Delete,
1444
+ delete: Delete,
1445
+ up: ArrowUp,
1446
+ down: ArrowDown,
1447
+ left: ArrowLeft,
1448
+ right: ArrowRight
1449
+ };
1450
+ var subscribe$2 = () => () => {};
1451
+ var clientPlatform = () => detectPlatform(typeof navigator === "undefined" ? void 0 : navigator);
1452
+ var serverPlatform = () => "other";
1453
+ function useKbdPlatform() {
1454
+ return useSyncExternalStore(subscribe$2, clientPlatform, serverPlatform);
1455
+ }
1456
+ function Kbd({ className, keys, platform, size: size$2 = "md", tone: tone$1 = "default" }) {
1457
+ const detected = useKbdPlatform();
1458
+ const resolved = platform ?? detected;
1459
+ const displays = (typeof keys === "string" ? parseShortcut(keys) : keys).map((key) => keyDisplay(key, resolved));
1460
+ const iconSize = size$2 === "sm" ? 11 : 12;
1461
+ const capClass = `${cap} ${size[size$2]} ${tone[tone$1]}`;
1462
+ return /* @__PURE__ */ jsxs("kbd", {
1463
+ className: `${group$1}${className ? ` ${className}` : ""}`,
1464
+ children: [/* @__PURE__ */ jsx("span", {
1465
+ className: visuallyHidden,
1466
+ "data-slot": "kbd-label",
1467
+ children: displays.map((d) => d.name).join(" ")
1468
+ }), displays.map((d, i) => {
1469
+ const Icon = d.icon ? icons[d.icon] : void 0;
1470
+ return /* @__PURE__ */ jsx("kbd", {
1471
+ "aria-hidden": "true",
1472
+ className: capClass,
1473
+ children: Icon ? /* @__PURE__ */ jsx(Icon, {
1474
+ className: d.icon === "delete" ? `${icon$2} ${mirrored}` : icon$2,
1475
+ size: iconSize,
1476
+ strokeWidth: 2
1477
+ }) : d.label
1478
+ }, `${d.name}-${i}`);
1479
+ })]
1480
+ });
1481
+ }
1482
+ //#endregion
1483
+ //#region src/components/tooltip/styles.css.ts
1484
+ var positioner$2 = "_1cspf2m0";
1485
+ var popup$4 = "_1cspf2m1";
1486
+ //#endregion
1487
+ //#region src/components/tooltip/index.tsx
1488
+ function TooltipProvider(props) {
1489
+ return /* @__PURE__ */ jsx(Tooltip.Provider, { ...props });
1490
+ }
1491
+ function TooltipRoot(props) {
1492
+ return /* @__PURE__ */ jsx(Tooltip.Root, { ...props });
1493
+ }
1494
+ function TooltipTrigger(props) {
1495
+ return /* @__PURE__ */ jsx(Tooltip.Trigger, { ...props });
1496
+ }
1497
+ function TooltipPortal({ children, ...props }) {
1498
+ return /* @__PURE__ */ jsx(Tooltip.Portal, {
1499
+ ...props,
1500
+ children: /* @__PURE__ */ jsx(PortalThemeWrapper$1, { children })
1501
+ });
1502
+ }
1503
+ function TooltipPositioner(props) {
1504
+ return /* @__PURE__ */ jsx(Tooltip.Positioner, { ...props });
1505
+ }
1506
+ function TooltipPopup({ className, children, shortcut, ...props }) {
1507
+ return /* @__PURE__ */ jsxs(Tooltip.Popup, {
1508
+ className: `${popup$4}${className ? ` ${className}` : ""}`,
1509
+ ...props,
1510
+ children: [children, shortcut && /* @__PURE__ */ jsx(Kbd, {
1511
+ className: "_1cspf2m2",
1512
+ keys: shortcut,
1513
+ size: "sm",
1514
+ tone: "inverted"
1515
+ })]
1516
+ });
1517
+ }
1518
+ function TooltipContent({ side = "top", sideOffset = 6, align = "center", className, children, ...popupProps }) {
1519
+ return /* @__PURE__ */ jsx(TooltipPortal, { children: /* @__PURE__ */ jsx(TooltipPositioner, {
1520
+ align,
1521
+ className: positioner$2,
1522
+ side,
1523
+ sideOffset,
1524
+ children: /* @__PURE__ */ jsx(TooltipPopup, {
1525
+ className,
1526
+ ...popupProps,
1527
+ children
1528
+ })
1529
+ }) });
1530
+ }
1531
+ var createTooltipHandle = Tooltip.createHandle;
1238
1532
  //#endregion
1239
1533
  //#region src/components/color-picker/color-math.ts
1240
1534
  var clamp = (n, min, max) => n < min ? min : n > max ? max : n;
@@ -1348,30 +1642,36 @@ var triggerLabel = "_17r50hf1";
1348
1642
  var triggerLetter = "_17r50hf2";
1349
1643
  var triggerBar = "_17r50hf3";
1350
1644
  var triggerChevron = "_17r50hf4";
1351
- var panel$1 = "_17r50hf5";
1352
- var grid = "_17r50hf6";
1353
- var swatch = "_17r50hf7";
1354
- var swatchDot = "_17r50hf8";
1355
- var addSwatchDot = "_17r50hf9";
1356
- var addSwatchIcon = "_17r50hfa";
1357
- var pickerView = "_17r50hfb";
1358
- var backButton = "_17r50hfc";
1359
- var backIcon = "_17r50hfd";
1360
- var satSquare = "_17r50hfe";
1361
- var satOverlayX = "_17r50hff";
1362
- var satOverlayY = "_17r50hfg";
1363
- var satThumb = "_17r50hfh";
1364
- var hueTrack = "_17r50hfi";
1365
- var alphaTrack = "_17r50hfj";
1366
- var alphaGradient = "_17r50hfk";
1367
- var sliderThumb = "_17r50hfl";
1368
- var hexRow = "_17r50hfm";
1369
- var hexInput = "_17r50hfn";
1370
- var hexInputInvalid = "_17r50hfo";
1371
- var previewPair = "_17r50hfr";
1372
- var previewCell = "_17r50hfs";
1373
- var actionRow = "_17r50hft";
1374
- var actionButton = "_17r50hfu";
1645
+ var panel = "_17r50hf5";
1646
+ var presetView = "_17r50hf6";
1647
+ var section = "_17r50hf7";
1648
+ var sectionLabel = "_17r50hf8";
1649
+ var grid = "_17r50hf9";
1650
+ var swatch = "_17r50hfa";
1651
+ var swatchDot = "_17r50hfb";
1652
+ var defaultDot = "_17r50hfc";
1653
+ var backgroundChip = "_17r50hfd";
1654
+ var footer$2 = "_17r50hfe";
1655
+ var footerButton = "_17r50hff";
1656
+ var footerIcon = "_17r50hfg";
1657
+ var pickerView = "_17r50hfh";
1658
+ var backButton = "_17r50hfi";
1659
+ var backIcon = "_17r50hfj";
1660
+ var satSquare = "_17r50hfk";
1661
+ var satOverlayX = "_17r50hfl";
1662
+ var satOverlayY = "_17r50hfm";
1663
+ var satThumb = "_17r50hfn";
1664
+ var hueTrack = "_17r50hfo";
1665
+ var alphaTrack = "_17r50hfp";
1666
+ var alphaGradient = "_17r50hfq";
1667
+ var sliderThumb = "_17r50hfr";
1668
+ var hexRow = "_17r50hfs";
1669
+ var hexInput = "_17r50hft";
1670
+ var hexInputInvalid = "_17r50hfu";
1671
+ var previewPair = "_17r50hfx";
1672
+ var previewCell = "_17r50hfy";
1673
+ var actionRow = "_17r50hfz";
1674
+ var actionButton = "_17r50hf10";
1375
1675
  //#endregion
1376
1676
  //#region src/components/color-picker/picker-view.tsx
1377
1677
  var FALLBACK = {
@@ -1555,11 +1855,11 @@ function PickerView({ initialColor, onApply, onCancel, onBack }) {
1555
1855
  }),
1556
1856
  hasEyeDropper && /* @__PURE__ */ jsx("button", {
1557
1857
  "aria-label": "Pick color from screen",
1558
- className: "_17r50hfp",
1858
+ className: "_17r50hfv",
1559
1859
  type: "button",
1560
1860
  onClick: openEyeDropper,
1561
1861
  onMouseDown: (e) => e.preventDefault(),
1562
- children: /* @__PURE__ */ jsx(Pipette, { className: "_17r50hfq" })
1862
+ children: /* @__PURE__ */ jsx(Pipette, { className: "_17r50hfw" })
1563
1863
  }),
1564
1864
  /* @__PURE__ */ jsxs("div", {
1565
1865
  "aria-hidden": true,
@@ -1596,129 +1896,442 @@ function PickerView({ initialColor, onApply, onCancel, onBack }) {
1596
1896
  });
1597
1897
  }
1598
1898
  //#endregion
1599
- //#region src/components/color-picker/index.tsx
1600
- var TEXT_COLORS = [
1601
- {
1602
- name: "Default",
1603
- value: "inherit"
1604
- },
1605
- {
1606
- name: "Gray",
1607
- value: "#6b7280"
1608
- },
1609
- {
1610
- name: "Red",
1611
- value: "#ef4444"
1612
- },
1613
- {
1614
- name: "Orange",
1615
- value: "#f97316"
1616
- },
1617
- {
1618
- name: "Amber",
1619
- value: "#f59e0b"
1620
- },
1621
- {
1622
- name: "Green",
1623
- value: "#22c55e"
1624
- },
1625
- {
1626
- name: "Teal",
1627
- value: "#14b8a6"
1899
+ //#region src/components/segmented-control/styles.css.ts
1900
+ var container = createRuntimeFn({
1901
+ defaultClassName: "_6d8tz20",
1902
+ variantClassNames: {
1903
+ size: {
1904
+ sm: "_6d8tz21",
1905
+ md: "_6d8tz22"
1906
+ },
1907
+ fullWidth: {
1908
+ true: "_6d8tz23",
1909
+ false: "_6d8tz24"
1910
+ }
1628
1911
  },
1629
- {
1630
- name: "Blue",
1631
- value: "#3b82f6"
1912
+ defaultVariants: {
1913
+ size: "sm",
1914
+ fullWidth: false
1632
1915
  },
1633
- {
1634
- name: "Indigo",
1635
- value: "#6366f1"
1916
+ compoundVariants: []
1917
+ });
1918
+ var indicator = createRuntimeFn({
1919
+ defaultClassName: "_6d8tz25",
1920
+ variantClassNames: { ready: {
1921
+ true: "_6d8tz26",
1922
+ false: "_6d8tz27"
1923
+ } },
1924
+ defaultVariants: { ready: true },
1925
+ compoundVariants: []
1926
+ });
1927
+ var item$3 = createRuntimeFn({
1928
+ defaultClassName: "_6d8tz28",
1929
+ variantClassNames: {
1930
+ size: {
1931
+ sm: "_6d8tz29",
1932
+ md: "_6d8tz2a"
1933
+ },
1934
+ active: {
1935
+ true: "_6d8tz2b",
1936
+ false: "_6d8tz2c"
1937
+ },
1938
+ disabled: {
1939
+ true: "_6d8tz2d",
1940
+ false: "_6d8tz2e"
1941
+ },
1942
+ fullWidth: {
1943
+ true: "_6d8tz2f",
1944
+ false: "_6d8tz2g"
1945
+ }
1636
1946
  },
1637
- {
1638
- name: "Purple",
1639
- value: "#a855f7"
1947
+ defaultVariants: {
1948
+ size: "sm",
1949
+ active: false,
1950
+ disabled: false,
1951
+ fullWidth: false
1640
1952
  },
1641
- {
1642
- name: "Pink",
1643
- value: "#ec4899"
1644
- }
1953
+ compoundVariants: []
1954
+ });
1955
+ //#endregion
1956
+ //#region src/components/segmented-control/index.tsx
1957
+ function SegmentedControl({ items, value, onChange, size = "sm", fullWidth = false, className }) {
1958
+ const containerRef = useRef(null);
1959
+ const itemElementsRef = useRef(/* @__PURE__ */ new Map());
1960
+ const [indicator$2, setIndicator] = useState({
1961
+ left: 0,
1962
+ width: 0
1963
+ });
1964
+ const [isReady, setIsReady] = useState(false);
1965
+ const updateIndicator = useCallback(() => {
1966
+ const container = containerRef.current;
1967
+ const activeEl = itemElementsRef.current.get(value);
1968
+ if (!container || !activeEl) return;
1969
+ const containerRect = container.getBoundingClientRect();
1970
+ const activeRect = activeEl.getBoundingClientRect();
1971
+ setIndicator({
1972
+ left: activeRect.left - containerRect.left,
1973
+ width: activeRect.width
1974
+ });
1975
+ setIsReady(true);
1976
+ }, [value]);
1977
+ useEffect(() => {
1978
+ updateIndicator();
1979
+ }, [updateIndicator]);
1980
+ useEffect(() => {
1981
+ const container = containerRef.current;
1982
+ if (!container) return;
1983
+ const observer = new ResizeObserver(() => {
1984
+ updateIndicator();
1985
+ });
1986
+ observer.observe(container);
1987
+ return () => observer.disconnect();
1988
+ }, [updateIndicator]);
1989
+ const handleKeyDown = (e) => {
1990
+ const enabledItems = items.filter((item) => !item.disabled);
1991
+ const currentIndex = enabledItems.findIndex((item) => item.value === value);
1992
+ let nextIndex = currentIndex;
1993
+ switch (e.key) {
1994
+ case "ArrowRight":
1995
+ case "ArrowDown":
1996
+ e.preventDefault();
1997
+ nextIndex = (currentIndex + 1) % enabledItems.length;
1998
+ break;
1999
+ case "ArrowLeft":
2000
+ case "ArrowUp":
2001
+ e.preventDefault();
2002
+ nextIndex = (currentIndex - 1 + enabledItems.length) % enabledItems.length;
2003
+ break;
2004
+ case "Home":
2005
+ e.preventDefault();
2006
+ nextIndex = 0;
2007
+ break;
2008
+ case "End":
2009
+ e.preventDefault();
2010
+ nextIndex = enabledItems.length - 1;
2011
+ }
2012
+ if (nextIndex !== currentIndex) {
2013
+ const nextItem = enabledItems[nextIndex];
2014
+ onChange(nextItem.value);
2015
+ itemElementsRef.current.get(nextItem.value)?.focus();
2016
+ }
2017
+ };
2018
+ return /* @__PURE__ */ jsxs("div", {
2019
+ "aria-orientation": "horizontal",
2020
+ className: `${container({
2021
+ size,
2022
+ fullWidth
2023
+ })} ${className || ""}`.trim(),
2024
+ ref: containerRef,
2025
+ role: "tablist",
2026
+ onKeyDown: handleKeyDown,
2027
+ children: [/* @__PURE__ */ jsx("div", {
2028
+ "aria-hidden": "true",
2029
+ className: indicator({ ready: isReady }),
2030
+ style: {
2031
+ left: indicator$2.left,
2032
+ width: indicator$2.width
2033
+ }
2034
+ }), items.map((item) => {
2035
+ const isActive = item.value === value;
2036
+ return /* @__PURE__ */ jsx("button", {
2037
+ "aria-selected": isActive,
2038
+ "data-active": isActive || void 0,
2039
+ disabled: item.disabled,
2040
+ role: "tab",
2041
+ tabIndex: isActive ? 0 : -1,
2042
+ type: "button",
2043
+ className: item$3({
2044
+ size,
2045
+ active: isActive,
2046
+ disabled: Boolean(item.disabled),
2047
+ fullWidth
2048
+ }),
2049
+ ref: (el) => {
2050
+ if (el) itemElementsRef.current.set(item.value, el);
2051
+ else itemElementsRef.current.delete(item.value);
2052
+ },
2053
+ onClick: () => onChange(item.value),
2054
+ children: item.label
2055
+ }, item.value);
2056
+ })]
2057
+ });
2058
+ }
2059
+ //#endregion
2060
+ //#region src/components/color-picker/presets.ts
2061
+ var DEFAULT_COLOR = "inherit";
2062
+ var HUES = [
2063
+ ["Gray", "#737373"],
2064
+ ["Red", "#ef4444"],
2065
+ ["Orange", "#f97316"],
2066
+ ["Amber", "#f59e0b"],
2067
+ ["Green", "#22c55e"],
2068
+ ["Teal", "#14b8a6"],
2069
+ ["Blue", "#3b82f6"],
2070
+ ["Indigo", "#6366f1"],
2071
+ ["Purple", "#a855f7"],
2072
+ ["Pink", "#ec4899"]
1645
2073
  ];
1646
- function ColorPicker({ currentColor, onSelect, className }) {
2074
+ var textValue = (base) => `color-mix(in oklab, ${base} 75%, var(--rc-text, #171717))`;
2075
+ var backgroundValue = (base) => `color-mix(in oklab, ${base} 18%, transparent)`;
2076
+ var PRESETS = {
2077
+ text: HUES.map(([name, base]) => ({
2078
+ name,
2079
+ value: textValue(base)
2080
+ })),
2081
+ background: HUES.map(([name, base]) => ({
2082
+ name,
2083
+ value: backgroundValue(base)
2084
+ }))
2085
+ };
2086
+ function isDefaultColor(value) {
2087
+ return !value || value === "inherit" || value === "transparent";
2088
+ }
2089
+ function presetName(target, value) {
2090
+ return PRESETS[target].find((p) => p.value === value)?.name ?? value;
2091
+ }
2092
+ //#endregion
2093
+ //#region src/components/color-picker/preset-view.tsx
2094
+ var GRID_COLUMNS = 8;
2095
+ var TARGET_ITEMS = [{
2096
+ label: "Text",
2097
+ value: "text"
2098
+ }, {
2099
+ label: "Background",
2100
+ value: "background"
2101
+ }];
2102
+ function moveFocus(e) {
2103
+ const step = e.key === "ArrowRight" ? 1 : e.key === "ArrowLeft" ? -1 : e.key === "ArrowDown" ? GRID_COLUMNS : e.key === "ArrowUp" ? -8 : 0;
2104
+ if (!step) return;
2105
+ const buttons = Array.from(e.currentTarget.querySelectorAll("button"));
2106
+ const index = buttons.indexOf(document.activeElement);
2107
+ if (index === -1) return;
2108
+ const next = buttons[Math.max(0, Math.min(buttons.length - 1, index + step))];
2109
+ e.preventDefault();
2110
+ next?.focus();
2111
+ }
2112
+ function Swatch({ current, onPick, preset, target }) {
2113
+ const isDefault = preset.value === DEFAULT_COLOR;
2114
+ const pressed = isDefault ? isDefaultColor(current) : current === preset.value;
2115
+ return /* @__PURE__ */ jsx("button", {
2116
+ "aria-label": preset.name,
2117
+ "aria-pressed": pressed,
2118
+ className: swatch,
2119
+ title: preset.name,
2120
+ type: "button",
2121
+ onClick: () => onPick(preset.value),
2122
+ onMouseDown: (e) => e.preventDefault(),
2123
+ children: isDefault ? /* @__PURE__ */ jsx("span", {
2124
+ "data-default-swatch": true,
2125
+ className: `${swatchDot} ${defaultDot}`
2126
+ }) : target === "background" ? /* @__PURE__ */ jsx("span", {
2127
+ className: backgroundChip,
2128
+ style: { backgroundColor: preset.value },
2129
+ children: "A"
2130
+ }) : /* @__PURE__ */ jsx("span", {
2131
+ className: swatchDot,
2132
+ style: { backgroundColor: preset.value }
2133
+ })
2134
+ });
2135
+ }
2136
+ function PresetView({ current, onCustom, onPick, onTargetChange, recent, target }) {
2137
+ const presets = [{
2138
+ name: "Default",
2139
+ value: DEFAULT_COLOR
2140
+ }, ...PRESETS[target]];
2141
+ return /* @__PURE__ */ jsxs("div", {
2142
+ className: presetView,
2143
+ children: [
2144
+ onTargetChange && /* @__PURE__ */ jsx(SegmentedControl, {
2145
+ fullWidth: true,
2146
+ items: TARGET_ITEMS,
2147
+ value: target,
2148
+ onChange: onTargetChange
2149
+ }),
2150
+ /* @__PURE__ */ jsxs("div", {
2151
+ className: section,
2152
+ children: [/* @__PURE__ */ jsx("div", {
2153
+ className: sectionLabel,
2154
+ children: "Theme colors"
2155
+ }), /* @__PURE__ */ jsx("div", {
2156
+ "aria-label": "Theme colors",
2157
+ className: grid,
2158
+ role: "group",
2159
+ onKeyDown: moveFocus,
2160
+ children: presets.map((preset) => /* @__PURE__ */ jsx(Swatch, {
2161
+ current,
2162
+ preset,
2163
+ target,
2164
+ onPick
2165
+ }, preset.value))
2166
+ })]
2167
+ }),
2168
+ recent.length > 0 && /* @__PURE__ */ jsxs("div", {
2169
+ className: "_17r50hf7",
2170
+ children: [/* @__PURE__ */ jsx("div", {
2171
+ className: "_17r50hf8",
2172
+ children: "Recent"
2173
+ }), /* @__PURE__ */ jsx("div", {
2174
+ "aria-label": "Recent colors",
2175
+ className: "_17r50hf9",
2176
+ role: "group",
2177
+ onKeyDown: moveFocus,
2178
+ children: recent.map((value) => /* @__PURE__ */ jsx(Swatch, {
2179
+ current,
2180
+ preset: {
2181
+ name: presetName(target, value),
2182
+ value
2183
+ },
2184
+ target,
2185
+ onPick
2186
+ }, value))
2187
+ })]
2188
+ }),
2189
+ /* @__PURE__ */ jsx("div", {
2190
+ className: footer$2,
2191
+ children: /* @__PURE__ */ jsxs("button", {
2192
+ "aria-label": "Custom color",
2193
+ className: footerButton,
2194
+ type: "button",
2195
+ onClick: onCustom,
2196
+ onMouseDown: (e) => e.preventDefault(),
2197
+ children: [/* @__PURE__ */ jsx(Plus, { className: footerIcon }), "Custom…"]
2198
+ })
2199
+ })
2200
+ ]
2201
+ });
2202
+ }
2203
+ //#endregion
2204
+ //#region src/components/color-picker/recent.ts
2205
+ var MAX_RECENT = 5;
2206
+ var STORAGE_KEY = "haklex:color-picker:recent";
2207
+ var EMPTY$1 = {
2208
+ text: [],
2209
+ background: []
2210
+ };
2211
+ var state = null;
2212
+ var listeners$2 = /* @__PURE__ */ new Set();
2213
+ function sanitize(value) {
2214
+ if (!Array.isArray(value)) return [];
2215
+ return value.filter((v) => typeof v === "string").slice(0, MAX_RECENT);
2216
+ }
2217
+ function load() {
2218
+ if (state) return state;
2219
+ state = EMPTY$1;
2220
+ try {
2221
+ const raw = localStorage.getItem(STORAGE_KEY);
2222
+ if (raw) {
2223
+ const parsed = JSON.parse(raw);
2224
+ state = {
2225
+ text: sanitize(parsed.text),
2226
+ background: sanitize(parsed.background)
2227
+ };
2228
+ }
2229
+ } catch {
2230
+ state = EMPTY$1;
2231
+ }
2232
+ return state;
2233
+ }
2234
+ function persist(next) {
2235
+ try {
2236
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(next));
2237
+ return true;
2238
+ } catch {
2239
+ return false;
2240
+ }
2241
+ }
2242
+ function pushRecentColor(target, color) {
2243
+ const current = load();
2244
+ const list = [color, ...current[target].filter((c) => c !== color)].slice(0, MAX_RECENT);
2245
+ state = {
2246
+ ...current,
2247
+ [target]: list
2248
+ };
2249
+ persist(state);
2250
+ for (const listener of listeners$2) listener();
2251
+ }
2252
+ function subscribe$1(listener) {
2253
+ listeners$2.add(listener);
2254
+ return () => {
2255
+ listeners$2.delete(listener);
2256
+ };
2257
+ }
2258
+ var getServerSnapshot = () => EMPTY$1;
2259
+ function useRecentColors(target) {
2260
+ return useSyncExternalStore(subscribe$1, load, getServerSnapshot)[target];
2261
+ }
2262
+ //#endregion
2263
+ //#region src/components/color-picker/index.tsx
2264
+ function ColorPicker({ currentColor, currentBackground, onSelect, onSelectBackground, className, tooltip }) {
1647
2265
  const [open, setOpen] = useState(false);
1648
2266
  const [view, setView] = useState("preset");
1649
- const displayColor = currentColor === "inherit" || !currentColor ? "currentColor" : currentColor;
2267
+ const [target, setTarget] = useState("text");
2268
+ const recent = useRecentColors(target);
2269
+ const activeTarget = onSelectBackground ? target : "text";
2270
+ const current = activeTarget === "text" ? currentColor : currentBackground ?? "";
2271
+ const textColor = isDefaultColor(currentColor) ? "currentColor" : currentColor;
2272
+ const background = isDefaultColor(currentBackground) ? void 0 : currentBackground;
1650
2273
  const handleOpenChange = (next) => {
1651
2274
  setOpen(next);
1652
2275
  if (!next) setView("preset");
1653
2276
  };
1654
- const handlePreset = (value) => {
1655
- onSelect(value);
1656
- handleOpenChange(false);
1657
- };
1658
- const handleApply = (hex) => {
1659
- onSelect(hex);
2277
+ const pick = (value) => {
2278
+ if (value !== "inherit") pushRecentColor(activeTarget, value);
2279
+ if (activeTarget === "background") onSelectBackground?.(value);
2280
+ else onSelect(value);
1660
2281
  handleOpenChange(false);
1661
2282
  };
1662
- const handleCancel = () => handleOpenChange(false);
2283
+ const triggerButton = /* @__PURE__ */ jsx("button", {
2284
+ "aria-label": "Text color",
2285
+ "data-tooltip": tooltip,
2286
+ type: "button",
2287
+ onMouseDown: (e) => e.preventDefault()
2288
+ });
2289
+ const trigger$2 = /* @__PURE__ */ jsxs(PopoverTrigger, {
2290
+ className: `${trigger}${className ? ` ${className}` : ""}`,
2291
+ render: triggerButton,
2292
+ children: [/* @__PURE__ */ jsxs("span", {
2293
+ className: triggerLabel,
2294
+ children: [/* @__PURE__ */ jsx("span", {
2295
+ className: triggerLetter,
2296
+ style: {
2297
+ color: textColor,
2298
+ backgroundColor: background
2299
+ },
2300
+ children: "A"
2301
+ }), /* @__PURE__ */ jsx("span", {
2302
+ className: triggerBar,
2303
+ style: { backgroundColor: textColor }
2304
+ })]
2305
+ }), /* @__PURE__ */ jsx(ChevronDown, { className: triggerChevron })]
2306
+ });
1663
2307
  return /* @__PURE__ */ jsxs(Popover, {
1664
2308
  open,
1665
2309
  onOpenChange: handleOpenChange,
1666
- children: [/* @__PURE__ */ jsxs(PopoverTrigger, {
1667
- className: `${trigger}${className ? ` ${className}` : ""}`,
1668
- render: /* @__PURE__ */ jsx("button", {
1669
- type: "button",
1670
- onMouseDown: (e) => e.preventDefault()
1671
- }),
1672
- children: [/* @__PURE__ */ jsxs("span", {
1673
- className: triggerLabel,
1674
- children: [/* @__PURE__ */ jsx("span", {
1675
- className: triggerLetter,
1676
- style: { color: displayColor },
1677
- children: "A"
1678
- }), /* @__PURE__ */ jsx("span", {
1679
- className: triggerBar,
1680
- style: { backgroundColor: displayColor }
1681
- })]
1682
- }), /* @__PURE__ */ jsx(ChevronDown, { className: triggerChevron })]
1683
- }), /* @__PURE__ */ jsx(PopoverPanel, {
1684
- className: panel$1,
2310
+ children: [tooltip ? /* @__PURE__ */ jsxs(TooltipRoot, { children: [/* @__PURE__ */ jsx(TooltipTrigger, { render: trigger$2 }), /* @__PURE__ */ jsx(TooltipContent, {
1685
2311
  side: "bottom",
1686
- sideOffset: 6,
1687
- children: view === "preset" ? /* @__PURE__ */ jsxs("div", {
1688
- className: grid,
1689
- children: [TEXT_COLORS.map((color) => /* @__PURE__ */ jsx("button", {
1690
- "aria-label": color.name,
1691
- "aria-pressed": currentColor === color.value,
1692
- className: swatch,
1693
- type: "button",
1694
- onClick: () => handlePreset(color.value),
1695
- onMouseDown: (e) => e.preventDefault(),
1696
- children: /* @__PURE__ */ jsx("span", {
1697
- className: swatchDot,
1698
- style: { backgroundColor: color.value === "inherit" ? "currentColor" : color.value }
1699
- })
1700
- }, color.value)), /* @__PURE__ */ jsx("button", {
1701
- "aria-label": "Custom color",
1702
- className: swatch,
1703
- type: "button",
1704
- onClick: () => setView("picker"),
1705
- onMouseDown: (e) => e.preventDefault(),
1706
- children: /* @__PURE__ */ jsx("span", {
1707
- className: addSwatchDot,
1708
- children: /* @__PURE__ */ jsx(Plus, { className: addSwatchIcon })
1709
- })
1710
- })]
2312
+ children: tooltip
2313
+ })] }) : trigger$2, /* @__PURE__ */ jsx(PopoverPanel, {
2314
+ className: panel,
2315
+ side: "bottom",
2316
+ size: "md",
2317
+ children: view === "preset" ? /* @__PURE__ */ jsx(PresetView, {
2318
+ current,
2319
+ recent,
2320
+ target: activeTarget,
2321
+ onCustom: () => setView("picker"),
2322
+ onPick: pick,
2323
+ onTargetChange: onSelectBackground ? setTarget : void 0
1711
2324
  }) : /* @__PURE__ */ jsx(PickerView, {
1712
- initialColor: currentColor,
1713
- onApply: handleApply,
2325
+ initialColor: current,
2326
+ onApply: pick,
1714
2327
  onBack: () => setView("preset"),
1715
- onCancel: handleCancel
2328
+ onCancel: () => handleOpenChange(false)
1716
2329
  })
1717
2330
  })]
1718
2331
  });
1719
2332
  }
1720
- var popup$4 = "_2buwsh1";
1721
- var item$3 = "_2buwsh2";
2333
+ var popup$3 = "_2buwsh1";
2334
+ var item$2 = "_2buwsh2";
1722
2335
  var empty = "_2buwsh3";
1723
2336
  //#endregion
1724
2337
  //#region src/components/combobox/index.tsx
@@ -1749,7 +2362,7 @@ function ComboboxContent({ align = "start", alignOffset = 0, side = "bottom", si
1749
2362
  sideOffset,
1750
2363
  style: { zIndex: 50 },
1751
2364
  children: /* @__PURE__ */ jsx(Combobox$1.Popup, {
1752
- className: `${popup$4}${className ? ` ${className}` : ""}`,
2365
+ className: `${popup$3}${className ? ` ${className}` : ""}`,
1753
2366
  ...popupProps,
1754
2367
  children
1755
2368
  })
@@ -1760,7 +2373,7 @@ function ComboboxList(props) {
1760
2373
  }
1761
2374
  function ComboboxItem({ className, ...props }) {
1762
2375
  return /* @__PURE__ */ jsx(Combobox$1.Item, {
1763
- className: `${item$3}${className ? ` ${className}` : ""}`,
2376
+ className: `${item$2}${className ? ` ${className}` : ""}`,
1764
2377
  ...props
1765
2378
  });
1766
2379
  }
@@ -1782,11 +2395,11 @@ function ComboboxGroupLabel(props) {
1782
2395
  //#endregion
1783
2396
  //#region src/components/dialog/styles.css.ts
1784
2397
  var backdrop = "vwlngv0";
1785
- var popup$3 = "vwlngv1";
1786
- var header = "vwlngv3";
2398
+ var popup$2 = "vwlngv1";
2399
+ var header$1 = "vwlngv3";
1787
2400
  var headerContent = "vwlngv4";
1788
- var footer = "vwlngv5";
1789
- var title = "vwlngv6";
2401
+ var footer$1 = "vwlngv5";
2402
+ var title$1 = "vwlngv6";
1790
2403
  var description = "vwlngv7";
1791
2404
  var sheetBackdrop = "vwlngva";
1792
2405
  var sheetContainer = "vwlngvb";
@@ -1815,7 +2428,7 @@ function DialogBackdrop({ className, ...props }) {
1815
2428
  }
1816
2429
  function DialogPopup({ showCloseButton = true, className, children, ...props }) {
1817
2430
  return /* @__PURE__ */ jsxs(DialogPortal, { children: [/* @__PURE__ */ jsx(DialogBackdrop, {}), /* @__PURE__ */ jsxs(Dialog$1.Popup, {
1818
- className: `${popup$3}${className ? ` ${className}` : ""}`,
2431
+ className: `${popup$2}${className ? ` ${className}` : ""}`,
1819
2432
  ...props,
1820
2433
  children: [children, showCloseButton && /* @__PURE__ */ jsx(Dialog$1.Close, {
1821
2434
  className: "vwlngv2",
@@ -1828,7 +2441,7 @@ function DialogClose(props) {
1828
2441
  }
1829
2442
  function DialogHeader({ className, children, ...props }) {
1830
2443
  return /* @__PURE__ */ jsx("div", {
1831
- className: `${header}${className ? ` ${className}` : ""}`,
2444
+ className: `${header$1}${className ? ` ${className}` : ""}`,
1832
2445
  ...props,
1833
2446
  children: /* @__PURE__ */ jsx("div", {
1834
2447
  className: headerContent,
@@ -1838,13 +2451,13 @@ function DialogHeader({ className, children, ...props }) {
1838
2451
  }
1839
2452
  function DialogFooter({ className, ...props }) {
1840
2453
  return /* @__PURE__ */ jsx("div", {
1841
- className: `${footer}${className ? ` ${className}` : ""}`,
2454
+ className: `${footer$1}${className ? ` ${className}` : ""}`,
1842
2455
  ...props
1843
2456
  });
1844
2457
  }
1845
2458
  function DialogTitle({ className, ...props }) {
1846
2459
  return /* @__PURE__ */ jsx(Dialog$1.Title, {
1847
- className: `${title}${className ? ` ${className}` : ""}`,
2460
+ className: `${title$1}${className ? ` ${className}` : ""}`,
1848
2461
  ...props
1849
2462
  });
1850
2463
  }
@@ -1857,33 +2470,33 @@ function DialogDescription({ className, ...props }) {
1857
2470
  //#endregion
1858
2471
  //#region src/components/dialog/store.ts
1859
2472
  var stack = [];
1860
- var idCounter = 0;
1861
- var listeners = /* @__PURE__ */ new Set();
1862
- function emit() {
1863
- for (const fn of listeners) fn();
2473
+ var idCounter$1 = 0;
2474
+ var listeners$1 = /* @__PURE__ */ new Set();
2475
+ function emit$1() {
2476
+ for (const fn of listeners$1) fn();
1864
2477
  }
1865
- function subscribe$1(fn) {
1866
- listeners.add(fn);
2478
+ function subscribe(fn) {
2479
+ listeners$1.add(fn);
1867
2480
  return () => {
1868
- listeners.delete(fn);
2481
+ listeners$1.delete(fn);
1869
2482
  };
1870
2483
  }
1871
2484
  function getSnapshot() {
1872
2485
  return stack;
1873
2486
  }
1874
2487
  function presentDialog(props) {
1875
- const id = `dialog-${++idCounter}`;
2488
+ const id = `dialog-${++idCounter$1}`;
1876
2489
  stack = [...stack, {
1877
2490
  ...props,
1878
2491
  id,
1879
2492
  open: true
1880
2493
  }];
1881
- emit();
2494
+ emit$1();
1882
2495
  return () => dismissDialog(id);
1883
2496
  }
1884
2497
  function removeDialog(id) {
1885
2498
  stack = stack.filter((item) => item.id !== id);
1886
- emit();
2499
+ emit$1();
1887
2500
  }
1888
2501
  function dismissDialog(id) {
1889
2502
  const target = stack.find((item) => item.id === id);
@@ -1892,29 +2505,193 @@ function dismissDialog(id) {
1892
2505
  ...item,
1893
2506
  open: false
1894
2507
  } : item);
1895
- emit();
2508
+ emit$1();
1896
2509
  target.onClose?.();
1897
2510
  }
1898
- function dismissTopDialog() {
1899
- for (let i = stack.length - 1; i >= 0; i--) if (stack[i].open) {
1900
- dismissDialog(stack[i].id);
1901
- return;
1902
- }
2511
+ async function requestDismissDialog(id) {
2512
+ const target = stack.find((item) => item.id === id);
2513
+ if (!target || !target.open) return;
2514
+ if (target.confirmDismiss && !await target.confirmDismiss()) return;
2515
+ dismissDialog(id);
2516
+ }
2517
+ function dialogWidthStyle(width) {
2518
+ if (width === void 0) return {};
2519
+ return { "--rc-dialog-width": typeof width === "number" ? `${width}px` : chromeWidth[width] };
2520
+ }
2521
+ function dismissTopDialog() {
2522
+ for (let i = stack.length - 1; i >= 0; i--) if (stack[i].open) {
2523
+ dismissDialog(stack[i].id);
2524
+ return;
2525
+ }
2526
+ }
2527
+ function dismissAllDialogs() {
2528
+ const closing = stack.filter((item) => item.open);
2529
+ stack = stack.map((item) => ({
2530
+ ...item,
2531
+ open: false
2532
+ }));
2533
+ emit$1();
2534
+ for (const item of closing) item.onClose?.();
2535
+ }
2536
+ //#endregion
2537
+ //#region src/components/dialog/confirm.tsx
2538
+ function confirmDiscardChanges({ cancelLabel = "Keep editing", confirmLabel = "Discard", description = "Your edits haven’t been saved.", title = "Discard changes?" } = {}) {
2539
+ return new Promise((resolve) => {
2540
+ let settled = false;
2541
+ const settle = (value) => {
2542
+ if (settled) return;
2543
+ settled = true;
2544
+ resolve(value);
2545
+ };
2546
+ presentDialog({
2547
+ title,
2548
+ description,
2549
+ showCloseButton: false,
2550
+ width: 360,
2551
+ onClose: () => settle(false),
2552
+ content: ({ dismiss }) => /* @__PURE__ */ jsxs("div", {
2553
+ className: footer$1,
2554
+ children: [/* @__PURE__ */ jsx(ActionButton, {
2555
+ size: "md",
2556
+ variant: "outline",
2557
+ onClick: () => {
2558
+ settle(false);
2559
+ dismiss();
2560
+ },
2561
+ children: cancelLabel
2562
+ }), /* @__PURE__ */ jsx(ActionButton, {
2563
+ autoFocus: true,
2564
+ danger: true,
2565
+ size: "md",
2566
+ variant: "solid",
2567
+ onClick: () => {
2568
+ settle(true);
2569
+ dismiss();
2570
+ },
2571
+ children: confirmLabel
2572
+ })]
2573
+ })
2574
+ });
2575
+ });
2576
+ }
2577
+ //#endregion
2578
+ //#region src/components/toast/store.ts
2579
+ var DEFAULT_DURATION = 2400;
2580
+ var toasts = [];
2581
+ var idCounter = 0;
2582
+ var timers = /* @__PURE__ */ new Map();
2583
+ var listeners = /* @__PURE__ */ new Set();
2584
+ function emit() {
2585
+ for (const fn of listeners) fn();
2586
+ }
2587
+ function schedule(item) {
2588
+ const existing = timers.get(item.id);
2589
+ if (existing) clearTimeout(existing);
2590
+ timers.delete(item.id);
2591
+ if (item.tone === "loading" && item.duration === void 0) return;
2592
+ timers.set(item.id, setTimeout(() => dismissToast(item.id), item.duration ?? DEFAULT_DURATION));
2593
+ }
2594
+ function subscribeToasts(fn) {
2595
+ listeners.add(fn);
2596
+ return () => {
2597
+ listeners.delete(fn);
2598
+ };
2599
+ }
2600
+ function getToasts() {
2601
+ return toasts;
1903
2602
  }
1904
- function dismissAllDialogs() {
1905
- const closing = stack.filter((item) => item.open);
1906
- stack = stack.map((item) => ({
1907
- ...item,
1908
- open: false
1909
- }));
2603
+ function toast(options) {
2604
+ const item = {
2605
+ ...options,
2606
+ id: `toast-${++idCounter}`
2607
+ };
2608
+ toasts = [...toasts, item];
2609
+ schedule(item);
1910
2610
  emit();
1911
- for (const item of closing) item.onClose?.();
2611
+ return item.id;
2612
+ }
2613
+ function updateToast(id, patch) {
2614
+ let updated;
2615
+ toasts = toasts.map((item) => {
2616
+ if (item.id !== id) return item;
2617
+ updated = {
2618
+ ...item,
2619
+ ...patch
2620
+ };
2621
+ return updated;
2622
+ });
2623
+ if (!updated) return;
2624
+ schedule(updated);
2625
+ emit();
2626
+ }
2627
+ function dismissToast(id) {
2628
+ const timer = timers.get(id);
2629
+ if (timer) clearTimeout(timer);
2630
+ timers.delete(id);
2631
+ if (!toasts.some((item) => item.id === id)) return;
2632
+ toasts = toasts.filter((item) => item.id !== id);
2633
+ emit();
2634
+ }
2635
+ //#endregion
2636
+ //#region src/components/toast/styles.css.ts
2637
+ var viewport = "xom7f32";
2638
+ var toast$1 = "xom7f33";
2639
+ var title = "xom7f34";
2640
+ var icon = "xom7f35";
2641
+ var spin = "xom7f36";
2642
+ var success = "xom7f37";
2643
+ var error$1 = "xom7f38";
2644
+ //#endregion
2645
+ //#region src/components/toast/index.tsx
2646
+ var EMPTY = [];
2647
+ function ToastIcon({ tone }) {
2648
+ if (tone === "loading") return /* @__PURE__ */ jsx(LoaderCircle, { className: `${icon} ${spin}` });
2649
+ if (tone === "success") return /* @__PURE__ */ jsx(CircleCheck, { className: `${icon} ${success}` });
2650
+ if (tone === "error") return /* @__PURE__ */ jsx(CircleAlert, { className: `${icon} ${error$1}` });
2651
+ return null;
2652
+ }
2653
+ function ToastViewport() {
2654
+ const items = useSyncExternalStore(subscribeToasts, getToasts, () => EMPTY);
2655
+ if (typeof document === "undefined") return null;
2656
+ return createPortal(/* @__PURE__ */ jsx(PortalThemeWrapper$1, { children: /* @__PURE__ */ jsx("div", {
2657
+ "aria-live": "polite",
2658
+ className: viewport,
2659
+ role: "status",
2660
+ children: items.map((item) => /* @__PURE__ */ jsxs("div", {
2661
+ className: toast$1,
2662
+ children: [
2663
+ /* @__PURE__ */ jsx(ToastIcon, { tone: item.tone }),
2664
+ /* @__PURE__ */ jsx("span", {
2665
+ className: title,
2666
+ children: item.title
2667
+ }),
2668
+ item.action && /* @__PURE__ */ jsx(ActionButton, {
2669
+ size: "sm",
2670
+ onClick: () => {
2671
+ item.action?.onClick();
2672
+ dismissToast(item.id);
2673
+ },
2674
+ children: item.action.label
2675
+ })
2676
+ ]
2677
+ }, item.id))
2678
+ }) }), document.body);
1912
2679
  }
1913
2680
  //#endregion
1914
2681
  //#region src/components/dialog/sheet.tsx
2682
+ function isScrollRegion(el) {
2683
+ if (el.isContentEditable || el.classList.contains("cm-editor")) return true;
2684
+ const { overflowY } = getComputedStyle(el);
2685
+ return (overflowY === "auto" || overflowY === "scroll") && el.scrollHeight > el.clientHeight;
2686
+ }
2687
+ function isInsideScrolledRegion(target, boundary) {
2688
+ for (let el = target; el && el !== boundary; el = el.parentElement) if (el.scrollTop > 0 && isScrollRegion(el)) return true;
2689
+ return false;
2690
+ }
1915
2691
  var SheetStackEntry = ({ item, index }) => {
1916
- const { id, open, title: title$3, description: description$4, content, className, portalClassName, theme = "light", clickOutsideToDismiss = true } = item;
2692
+ const { id, open, title, description: description$4, content, className, portalClassName, theme = "light", clickOutsideToDismiss = true } = item;
1917
2693
  const dismiss = useCallback(() => dismissDialog(id), [id]);
2694
+ const requestDismiss = useCallback(() => requestDismissDialog(id), [id]);
1918
2695
  useEffect(() => {
1919
2696
  if (!open) {
1920
2697
  const timer = setTimeout(() => removeDialog(id), 200);
@@ -1929,16 +2706,13 @@ var SheetStackEntry = ({ item, index }) => {
1929
2706
  };
1930
2707
  }, []);
1931
2708
  const sheetRef = useRef(null);
1932
- const contentRef = useRef(null);
1933
2709
  const dragState = useRef(null);
1934
2710
  const [translateY, setTranslateY] = useState(0);
1935
2711
  const [isDragging, setIsDragging] = useState(false);
1936
2712
  const handleTouchStart = useCallback((e) => {
1937
2713
  const touch = e.touches[0];
1938
- const isHandle = e.target.closest(`.${sheetDragHandle}`) !== null;
1939
- const contentEl = contentRef.current;
1940
- const isContentAtTop = !contentEl || contentEl.scrollTop <= 0;
1941
- if (!isHandle && !isContentAtTop) return;
2714
+ const target = e.target;
2715
+ if (!(target.closest(`.vwlngvc, .vwlngvf`) !== null) && isInsideScrolledRegion(target, sheetRef.current)) return;
1942
2716
  dragState.current = {
1943
2717
  startY: touch.clientY,
1944
2718
  startTime: Date.now(),
@@ -1978,11 +2752,12 @@ var SheetStackEntry = ({ item, index }) => {
1978
2752
  const deltaY = state.currentY - state.startY;
1979
2753
  const elapsed = Date.now() - state.startTime;
1980
2754
  const velocity = deltaY / Math.max(elapsed, 1) * 1e3;
1981
- if (deltaY > (sheetRef.current?.offsetHeight ?? 0) * .25 || velocity > 500) dismiss();
1982
- else setTranslateY(0);
2755
+ const threshold = (sheetRef.current?.offsetHeight ?? 0) * .25;
2756
+ setTranslateY(0);
2757
+ if (deltaY > threshold || velocity > 500) requestDismiss();
1983
2758
  setIsDragging(false);
1984
2759
  dragState.current = null;
1985
- }, [dismiss]);
2760
+ }, [requestDismiss]);
1986
2761
  const zIndex = 50 + index;
1987
2762
  const sheetHeight = sheetRef.current?.offsetHeight || 1;
1988
2763
  const backdropOpacity = isDragging ? Math.max(0, 1 - translateY / sheetHeight) : 1;
@@ -1996,7 +2771,7 @@ var SheetStackEntry = ({ item, index }) => {
1996
2771
  opacity: open ? backdropOpacity : 0,
1997
2772
  pointerEvents: open ? "auto" : "none"
1998
2773
  },
1999
- onClick: clickOutsideToDismiss ? dismiss : void 0
2774
+ onClick: clickOutsideToDismiss ? requestDismiss : void 0
2000
2775
  }), /* @__PURE__ */ jsxs("div", {
2001
2776
  className: `${sheetContainer}${className ? ` ${className}` : ""}`,
2002
2777
  "data-closed": !open ? "" : void 0,
@@ -2015,11 +2790,11 @@ var SheetStackEntry = ({ item, index }) => {
2015
2790
  className: sheetDragHandle,
2016
2791
  children: /* @__PURE__ */ jsx("div", { className: sheetDragPill })
2017
2792
  }),
2018
- (title$3 || description$4) && /* @__PURE__ */ jsxs("div", {
2793
+ (title || description$4) && /* @__PURE__ */ jsxs("div", {
2019
2794
  className: "vwlngvf",
2020
- children: [title$3 && /* @__PURE__ */ jsx("div", {
2795
+ children: [title && /* @__PURE__ */ jsx("div", {
2021
2796
  className: "vwlngv6",
2022
- children: title$3
2797
+ children: title
2023
2798
  }), description$4 && /* @__PURE__ */ jsx("div", {
2024
2799
  className: "vwlngv7",
2025
2800
  children: description$4
@@ -2027,8 +2802,10 @@ var SheetStackEntry = ({ item, index }) => {
2027
2802
  }),
2028
2803
  /* @__PURE__ */ jsx("div", {
2029
2804
  className: sheetContent,
2030
- ref: contentRef,
2031
- children: createElement(content, { dismiss })
2805
+ children: createElement(content, {
2806
+ dismiss,
2807
+ requestDismiss
2808
+ })
2032
2809
  })
2033
2810
  ]
2034
2811
  })] })
@@ -2051,8 +2828,9 @@ function shouldUseSheet(sheet, isMobile) {
2051
2828
  }
2052
2829
  var CloseIcon = () => /* @__PURE__ */ jsx(X, {});
2053
2830
  var DialogStackEntry = ({ item, index }) => {
2054
- const { id, open, title: title$2, description: description$3, content, className, portalClassName, theme = "light", showCloseButton = true, clickOutsideToDismiss = true } = item;
2831
+ const { id, open, title, description: description$3, content, className, portalClassName, theme = "light", showCloseButton = true, clickOutsideToDismiss = true, width } = item;
2055
2832
  const dismiss = useCallback(() => dismissDialog(id), [id]);
2833
+ const requestDismiss = useCallback(() => requestDismissDialog(id), [id]);
2056
2834
  useEffect(() => {
2057
2835
  if (!open) {
2058
2836
  const timer = setTimeout(() => {
@@ -2066,7 +2844,7 @@ var DialogStackEntry = ({ item, index }) => {
2066
2844
  disablePointerDismissal: !clickOutsideToDismiss,
2067
2845
  open,
2068
2846
  onOpenChange: (open) => {
2069
- if (!open) dismiss();
2847
+ if (!open) requestDismiss();
2070
2848
  },
2071
2849
  children: /* @__PURE__ */ jsx(Dialog$1.Portal, { children: /* @__PURE__ */ jsx(PortalThemeProvider$1, {
2072
2850
  className: portalClassName ?? "",
@@ -2076,16 +2854,19 @@ var DialogStackEntry = ({ item, index }) => {
2076
2854
  style: { zIndex }
2077
2855
  }), /* @__PURE__ */ jsxs(Dialog$1.Popup, {
2078
2856
  suppressHydrationWarning: true,
2079
- className: `${popup$3}${className ? ` ${className}` : ""}`,
2857
+ className: `${popup$2}${className ? ` ${className}` : ""}`,
2080
2858
  "data-theme": theme,
2081
- style: { zIndex: zIndex + 1 },
2082
- children: [(title$2 || description$3 || showCloseButton) && /* @__PURE__ */ jsxs("div", {
2859
+ style: {
2860
+ zIndex: zIndex + 1,
2861
+ ...dialogWidthStyle(width)
2862
+ },
2863
+ children: [(title || description$3 || showCloseButton) && /* @__PURE__ */ jsxs("div", {
2083
2864
  className: "vwlngv3",
2084
- children: [(title$2 || description$3) && /* @__PURE__ */ jsxs("div", {
2865
+ children: [(title || description$3) && /* @__PURE__ */ jsxs("div", {
2085
2866
  className: "vwlngv4",
2086
- children: [title$2 && /* @__PURE__ */ jsx(Dialog$1.Title, {
2867
+ children: [title && /* @__PURE__ */ jsx(Dialog$1.Title, {
2087
2868
  className: "vwlngv6",
2088
- children: title$2
2869
+ children: title
2089
2870
  }), description$3 && /* @__PURE__ */ jsx(Dialog$1.Description, {
2090
2871
  className: "vwlngv7",
2091
2872
  children: description$3
@@ -2094,211 +2875,42 @@ var DialogStackEntry = ({ item, index }) => {
2094
2875
  className: "vwlngv2",
2095
2876
  children: /* @__PURE__ */ jsx(CloseIcon, {})
2096
2877
  })]
2097
- }), createElement(content, { dismiss })]
2878
+ }), createElement(content, {
2879
+ dismiss,
2880
+ requestDismiss
2881
+ })]
2098
2882
  })] })
2099
2883
  }) })
2100
2884
  });
2101
2885
  };
2102
2886
  var DialogStackProvider = ({ children }) => {
2103
- const stack = useSyncExternalStore(subscribe$1, getSnapshot, getSnapshot);
2887
+ const stack = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
2104
2888
  const isMobile = useIsMobile();
2105
- return /* @__PURE__ */ jsxs(Fragment, { children: [children, stack.map((item, index) => shouldUseSheet(item.sheet, isMobile) ? /* @__PURE__ */ jsx(SheetStackEntry, {
2106
- index,
2107
- item
2108
- }, item.id) : /* @__PURE__ */ jsx(DialogStackEntry, {
2109
- index,
2110
- item
2111
- }, item.id))] });
2112
- };
2113
- //#endregion
2114
- //#region src/components/kbd/keys.ts
2115
- var aliases = {
2116
- "ctrl": "mod",
2117
- "control": "mod",
2118
- "cmd": "mod",
2119
- "command": "mod",
2120
- "meta": "mod",
2121
- "mod": "mod",
2122
- "option": "alt",
2123
- "opt": "alt",
2124
- "alt": "alt",
2125
- "shift": "shift",
2126
- "return": "enter",
2127
- "enter": "enter",
2128
- "esc": "escape",
2129
- "escape": "escape",
2130
- "backspace": "backspace",
2131
- "del": "delete",
2132
- "delete": "delete",
2133
- "arrowup": "up",
2134
- "up": "up",
2135
- "arrowdown": "down",
2136
- "down": "down",
2137
- "arrowleft": "left",
2138
- "left": "left",
2139
- "arrowright": "right",
2140
- "right": "right",
2141
- "⌘": "mod",
2142
- "⌃": "mod",
2143
- "⇧": "shift",
2144
- "⌥": "alt",
2145
- "↵": "enter",
2146
- "⏎": "enter",
2147
- "⌫": "backspace",
2148
- "⌦": "delete",
2149
- "↑": "up",
2150
- "↓": "down",
2151
- "←": "left",
2152
- "→": "right"
2153
- };
2154
- var glyphs = /[←↑→↓↵⇧⌃⌘⌥⌦⌫⏎]/g;
2155
- function normalize(token) {
2156
- const lower = token.trim().toLowerCase();
2157
- return aliases[lower] ?? lower;
2158
- }
2159
- function parseShortcut(shortcut) {
2160
- return (shortcut.includes("+") ? shortcut.split("+") : shortcut.replaceAll(glyphs, (g) => `+${g}+`).split("+")).filter((p) => p.trim() !== "").map(normalize);
2161
- }
2162
- var macModifiers = {
2163
- mod: {
2164
- label: "⌘",
2165
- name: "Command"
2166
- },
2167
- shift: {
2168
- label: "⇧",
2169
- name: "Shift"
2170
- },
2171
- alt: {
2172
- label: "⌥",
2173
- name: "Option"
2174
- }
2175
- };
2176
- var otherModifiers = {
2177
- mod: {
2178
- label: "Ctrl",
2179
- name: "Control"
2180
- },
2181
- shift: {
2182
- label: "Shift",
2183
- name: "Shift"
2184
- },
2185
- alt: {
2186
- label: "Alt",
2187
- name: "Alt"
2188
- }
2189
- };
2190
- var iconKeys = {
2191
- enter: "Enter",
2192
- backspace: "Backspace",
2193
- delete: "Delete",
2194
- up: "Up",
2195
- down: "Down",
2196
- left: "Left",
2197
- right: "Right"
2198
- };
2199
- var namedKeys = {
2200
- escape: {
2201
- label: "Esc",
2202
- name: "Escape"
2203
- },
2204
- tab: {
2205
- label: "Tab",
2206
- name: "Tab"
2207
- },
2208
- space: {
2209
- label: "Space",
2210
- name: "Space"
2211
- }
2212
- };
2213
- function keyDisplay(key, platform) {
2214
- const modifiers = platform === "mac" ? macModifiers : otherModifiers;
2215
- if (modifiers[key]) return modifiers[key];
2216
- if (key in iconKeys) return {
2217
- icon: key,
2218
- name: iconKeys[key]
2219
- };
2220
- if (namedKeys[key]) return namedKeys[key];
2221
- const label = key.length === 1 ? key.toUpperCase() : key[0].toUpperCase() + key.slice(1);
2222
- return {
2223
- label,
2224
- name: label
2225
- };
2226
- }
2227
- function detectPlatform(nav) {
2228
- if (!nav) return "other";
2229
- const source = `${nav.platform ?? ""} ${nav.userAgent ?? ""}`;
2230
- return /mac|iphone|ipad|ipod/i.test(source) ? "mac" : "other";
2231
- }
2232
- //#endregion
2233
- //#region src/components/kbd/styles.css.ts
2234
- var group$1 = "lhlko40";
2235
- var cap = "lhlko41";
2236
- var size = {
2237
- sm: "lhlko42",
2238
- md: "lhlko43"
2239
- };
2240
- var tone = {
2241
- "default": "lhlko44",
2242
- muted: "lhlko45",
2243
- inverted: "lhlko46"
2244
- };
2245
- var icon = "lhlko47";
2246
- var mirrored = "lhlko48";
2247
- var visuallyHidden = "lhlko49";
2248
- //#endregion
2249
- //#region src/components/kbd/index.tsx
2250
- var icons = {
2251
- enter: CornerDownLeft,
2252
- backspace: Delete,
2253
- delete: Delete,
2254
- up: ArrowUp,
2255
- down: ArrowDown,
2256
- left: ArrowLeft,
2257
- right: ArrowRight
2889
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
2890
+ children,
2891
+ /* @__PURE__ */ jsx(ToastViewport, {}),
2892
+ stack.map((item, index) => shouldUseSheet(item.sheet, isMobile) ? /* @__PURE__ */ jsx(SheetStackEntry, {
2893
+ index,
2894
+ item
2895
+ }, item.id) : /* @__PURE__ */ jsx(DialogStackEntry, {
2896
+ index,
2897
+ item
2898
+ }, item.id))
2899
+ ] });
2258
2900
  };
2259
- var subscribe = () => () => {};
2260
- var clientPlatform = () => detectPlatform(typeof navigator === "undefined" ? void 0 : navigator);
2261
- var serverPlatform = () => "other";
2262
- function useKbdPlatform() {
2263
- return useSyncExternalStore(subscribe, clientPlatform, serverPlatform);
2264
- }
2265
- function Kbd({ className, keys, platform, size: size$1 = "md", tone: tone$1 = "default" }) {
2266
- const detected = useKbdPlatform();
2267
- const resolved = platform ?? detected;
2268
- const displays = (typeof keys === "string" ? parseShortcut(keys) : keys).map((key) => keyDisplay(key, resolved));
2269
- const iconSize = size$1 === "sm" ? 11 : 12;
2270
- const capClass = `${cap} ${size[size$1]} ${tone[tone$1]}`;
2271
- return /* @__PURE__ */ jsxs("kbd", {
2272
- className: `${group$1}${className ? ` ${className}` : ""}`,
2273
- children: [/* @__PURE__ */ jsx("span", {
2274
- className: visuallyHidden,
2275
- "data-slot": "kbd-label",
2276
- children: displays.map((d) => d.name).join(" ")
2277
- }), displays.map((d, i) => {
2278
- const Icon = d.icon ? icons[d.icon] : void 0;
2279
- return /* @__PURE__ */ jsx("kbd", {
2280
- "aria-hidden": "true",
2281
- className: capClass,
2282
- children: Icon ? /* @__PURE__ */ jsx(Icon, {
2283
- className: d.icon === "delete" ? `${icon} ${mirrored}` : icon,
2284
- size: iconSize,
2285
- strokeWidth: 2
2286
- }) : d.label
2287
- }, `${d.name}-${i}`);
2288
- })]
2289
- });
2290
- }
2291
2901
  //#endregion
2292
2902
  //#region src/components/dropdown-menu/styles.css.ts
2293
- var popup$2 = "oih0op0";
2294
- var positioner$2 = "oih0op1";
2295
- var item$2 = "oih0op2";
2296
- var separator$1 = "_1sxaacb2";
2297
- var label = "_1sxaacb3";
2903
+ var popup$1 = "oih0op0";
2904
+ var positioner$1 = "oih0op1";
2905
+ var item$1 = "oih0op2";
2906
+ var separator$1 = "_1sxaacb3";
2907
+ var label$1 = "_1sxaacb4";
2298
2908
  var checkboxItem = "oih0op3";
2299
2909
  var radioItem = "oih0op3";
2300
2910
  var checkboxIndicator = "oih0op4";
2301
2911
  var radioIndicator = "oih0op4";
2912
+ var subTrigger = "oih0op5";
2913
+ var subTriggerValue = "oih0op6";
2302
2914
  //#endregion
2303
2915
  //#region src/components/dropdown-menu/index.tsx
2304
2916
  function DropdownMenu(props) {
@@ -2320,14 +2932,14 @@ function DropdownMenuContent({ align = "start", alignOffset = 0, side = "bottom"
2320
2932
  return /* @__PURE__ */ jsx(DropdownMenuPortal, { children: /* @__PURE__ */ jsx(Menu.Positioner, {
2321
2933
  align,
2322
2934
  alignOffset,
2323
- className: positioner$2,
2935
+ className: positioner$1,
2324
2936
  "data-slot": "dropdown-menu-positioner",
2325
2937
  positionMethod,
2326
2938
  side,
2327
2939
  sideOffset,
2328
2940
  style: { zIndex: 50 },
2329
2941
  children: /* @__PURE__ */ jsx(Menu.Popup, {
2330
- className: `${popup$2}${className ? ` ${className}` : ""}`,
2942
+ className: `${popup$1}${className ? ` ${className}` : ""}`,
2331
2943
  "data-slot": "dropdown-menu-content",
2332
2944
  ...popupProps,
2333
2945
  children
@@ -2342,29 +2954,43 @@ function DropdownMenuGroup(props) {
2342
2954
  }
2343
2955
  function DropdownMenuLabel({ className, ...props }) {
2344
2956
  return /* @__PURE__ */ jsx(Menu.GroupLabel, {
2345
- className: `${label}${className ? ` ${className}` : ""}`,
2957
+ className: `${label$1}${className ? ` ${className}` : ""}`,
2346
2958
  "data-slot": "dropdown-menu-label",
2347
2959
  ...props
2348
2960
  });
2349
2961
  }
2350
- function DropdownMenuItem({ className, children, shortcut, variant = "default", ...props }) {
2962
+ function DropdownMenuItem({ className, children, shortcut: shortcut$2, variant = "default", ...props }) {
2351
2963
  const classes = [
2352
- item$2,
2353
- variant === "destructive" && "_1sxaacb0",
2964
+ item$1,
2965
+ variant === "destructive" && "_1sxaacb1",
2354
2966
  className
2355
2967
  ].filter(Boolean).join(" ");
2356
2968
  return /* @__PURE__ */ jsxs(Menu.Item, {
2357
2969
  className: classes,
2358
2970
  "data-slot": "dropdown-menu-item",
2359
2971
  ...props,
2360
- children: [children, shortcut && /* @__PURE__ */ jsx(Kbd, {
2361
- className: "_1sxaacb1",
2362
- keys: shortcut,
2972
+ children: [children, shortcut$2 && /* @__PURE__ */ jsx(Kbd, {
2973
+ className: "_1sxaacb2",
2974
+ keys: shortcut$2,
2363
2975
  size: "sm",
2364
2976
  tone: "muted"
2365
2977
  })]
2366
2978
  });
2367
2979
  }
2980
+ function DropdownMenuSub(props) {
2981
+ return /* @__PURE__ */ jsx(Menu.SubmenuRoot, { ...props });
2982
+ }
2983
+ function DropdownMenuSubTrigger({ className, children, value, ...props }) {
2984
+ return /* @__PURE__ */ jsxs(Menu.SubmenuTrigger, {
2985
+ className: `${item$1} ${subTrigger}${className ? ` ${className}` : ""}`,
2986
+ "data-slot": "dropdown-menu-sub-trigger",
2987
+ ...props,
2988
+ children: [children, /* @__PURE__ */ jsxs("span", {
2989
+ className: subTriggerValue,
2990
+ children: [value, /* @__PURE__ */ jsx(ChevronRight, {})]
2991
+ })]
2992
+ });
2993
+ }
2368
2994
  function DropdownMenuSeparator({ className, ...props }) {
2369
2995
  return /* @__PURE__ */ jsx(Menu.Separator, {
2370
2996
  className: `${separator$1}${className ? ` ${className}` : ""}`,
@@ -2380,7 +3006,7 @@ function DropdownMenuRadioGroup(props) {
2380
3006
  }
2381
3007
  function DropdownMenuRadioItem({ className, children, ...props }) {
2382
3008
  return /* @__PURE__ */ jsxs(Menu.RadioItem, {
2383
- className: `${item$2} ${radioItem}${className ? ` ${className}` : ""}`,
3009
+ className: `${item$1} ${radioItem}${className ? ` ${className}` : ""}`,
2384
3010
  "data-slot": "dropdown-menu-radio-item",
2385
3011
  ...props,
2386
3012
  children: [children, /* @__PURE__ */ jsx(Menu.RadioItemIndicator, {
@@ -2392,7 +3018,7 @@ function DropdownMenuRadioItem({ className, children, ...props }) {
2392
3018
  }
2393
3019
  function DropdownMenuCheckboxItem({ className, children, ...props }) {
2394
3020
  return /* @__PURE__ */ jsxs(Menu.CheckboxItem, {
2395
- className: `${item$2} ${checkboxItem}${className ? ` ${className}` : ""}`,
3021
+ className: `${item$1} ${checkboxItem}${className ? ` ${className}` : ""}`,
2396
3022
  "data-slot": "dropdown-menu-checkbox-item",
2397
3023
  ...props,
2398
3024
  children: [children, /* @__PURE__ */ jsx(Menu.CheckboxItemIndicator, {
@@ -2402,22 +3028,148 @@ function DropdownMenuCheckboxItem({ className, children, ...props }) {
2402
3028
  })]
2403
3029
  });
2404
3030
  }
2405
- function CheckIcon() {
2406
- return /* @__PURE__ */ jsx(Check, { size: 16 });
3031
+ function CheckIcon() {
3032
+ return /* @__PURE__ */ jsx(Check, { size: 16 });
3033
+ }
3034
+ //#endregion
3035
+ //#region src/components/field/styles.css.ts
3036
+ var field$1 = "_1i1no470";
3037
+ var label = "_1i1no471";
3038
+ var hint = "_1i1no472";
3039
+ var error = "_1i1no473";
3040
+ //#endregion
3041
+ //#region src/components/field/index.tsx
3042
+ function Field({ children, className, error: error$2, hint: hint$1, id, label: label$3 }) {
3043
+ return /* @__PURE__ */ jsxs("div", {
3044
+ className: `${field$1}${className ? ` ${className}` : ""}`,
3045
+ children: [
3046
+ /* @__PURE__ */ jsx("label", {
3047
+ className: label,
3048
+ htmlFor: id,
3049
+ children: label$3
3050
+ }),
3051
+ children,
3052
+ error$2 ? /* @__PURE__ */ jsx("p", {
3053
+ className: error,
3054
+ id: `${id}-error`,
3055
+ role: "alert",
3056
+ children: error$2
3057
+ }) : hint$1 ? /* @__PURE__ */ jsx("p", {
3058
+ className: hint,
3059
+ id: `${id}-hint`,
3060
+ children: hint$1
3061
+ }) : null
3062
+ ]
3063
+ });
3064
+ }
3065
+ //#endregion
3066
+ //#region src/components/modal-shell/styles.css.ts
3067
+ var shell = "_1q3gqvh0";
3068
+ var header = "_1q3gqvh1";
3069
+ var headerLead = "_1q3gqvh2";
3070
+ var headerTitle = "_1q3gqvh4";
3071
+ var headerCenter = "_1q3gqvh5";
3072
+ var headerActions = "_1q3gqvh6";
3073
+ var body = "_1q3gqvh8";
3074
+ var footer = "_1q3gqvh9";
3075
+ var footerStatus = "_1q3gqvha";
3076
+ //#endregion
3077
+ //#region src/components/modal-shell/index.tsx
3078
+ function ModalShell({ children, className, onSave }) {
3079
+ const handleKeyDown = (event) => {
3080
+ if (!onSave || event.defaultPrevented || !(event.metaKey || event.ctrlKey)) return;
3081
+ if (event.key === "s" || event.key === "Enter") {
3082
+ event.preventDefault();
3083
+ onSave();
3084
+ }
3085
+ };
3086
+ return /* @__PURE__ */ jsx("div", {
3087
+ className: `${shell}${className ? ` ${className}` : ""}`,
3088
+ onKeyDown: handleKeyDown,
3089
+ children
3090
+ });
3091
+ }
3092
+ function ModalShellHeader({ actions, center, closeLabel = "Close", icon, onClose, title }) {
3093
+ return /* @__PURE__ */ jsxs("div", {
3094
+ className: header,
3095
+ children: [
3096
+ /* @__PURE__ */ jsxs("div", {
3097
+ className: headerLead,
3098
+ children: [icon && /* @__PURE__ */ jsx("span", {
3099
+ className: "_1q3gqvh3",
3100
+ children: icon
3101
+ }), /* @__PURE__ */ jsx("span", {
3102
+ className: headerTitle,
3103
+ children: title
3104
+ })]
3105
+ }),
3106
+ /* @__PURE__ */ jsx("div", {
3107
+ className: headerCenter,
3108
+ children: center
3109
+ }),
3110
+ /* @__PURE__ */ jsxs("div", {
3111
+ className: headerActions,
3112
+ children: [actions, onClose && /* @__PURE__ */ jsxs(Fragment, { children: [actions && /* @__PURE__ */ jsx("span", { className: "_1q3gqvh7" }), /* @__PURE__ */ jsx(ActionButton, {
3113
+ icon: true,
3114
+ "aria-label": closeLabel,
3115
+ size: "md",
3116
+ title: closeLabel,
3117
+ onClick: onClose,
3118
+ children: /* @__PURE__ */ jsx(X, {})
3119
+ })] })]
3120
+ })
3121
+ ]
3122
+ });
3123
+ }
3124
+ function ModalShellBody({ children, className }) {
3125
+ return /* @__PURE__ */ jsx("div", {
3126
+ className: `${body}${className ? ` ${className}` : ""}`,
3127
+ children
3128
+ });
3129
+ }
3130
+ function ModalShellFooter({ cancelLabel = "Cancel", children, dirty, onCancel, onSave, saveDisabled, saveLabel = "Save", status }) {
3131
+ return /* @__PURE__ */ jsxs("div", {
3132
+ className: footer,
3133
+ children: [
3134
+ /* @__PURE__ */ jsxs("div", {
3135
+ className: footerStatus,
3136
+ children: [dirty && /* @__PURE__ */ jsx("span", {
3137
+ "aria-hidden": true,
3138
+ className: "_1q3gqvhb"
3139
+ }), status]
3140
+ }),
3141
+ children,
3142
+ onCancel && /* @__PURE__ */ jsx(ActionButton, {
3143
+ size: "md",
3144
+ variant: "outline",
3145
+ onClick: onCancel,
3146
+ children: cancelLabel
3147
+ }),
3148
+ onSave && /* @__PURE__ */ jsxs(ActionButton, {
3149
+ disabled: saveDisabled,
3150
+ size: "md",
3151
+ variant: "solid",
3152
+ onClick: onSave,
3153
+ children: [saveLabel, /* @__PURE__ */ jsx(Kbd, {
3154
+ keys: ["mod", "s"],
3155
+ size: "sm",
3156
+ tone: "inverted"
3157
+ })]
3158
+ })
3159
+ ]
3160
+ });
2407
3161
  }
2408
3162
  //#endregion
2409
3163
  //#region src/components/quote-attribution/styles.css.ts
2410
- var semanticClassNames = {
2411
- overlay: "rich-quote-attribution-overlay",
2412
- panel: "rich-quote-attribution-panel",
2413
- input: "rich-quote-attribution-input"
2414
- };
2415
- var overlay = "_1dj5lvb0";
2416
- var panel = "_1dj5lvb1";
2417
- var input = "_1dj5lvb2";
3164
+ var slot = "_1dj5lvb0";
3165
+ var text = "_1dj5lvb1";
3166
+ var field = "_1dj5lvb2";
3167
+ var dash = "_1dj5lvb3";
3168
+ var input$1 = "_1dj5lvb4";
2418
3169
  //#endregion
2419
3170
  //#region src/components/quote-attribution/QuoteAttributionPlugin.tsx
2420
3171
  var RICH_QUOTE_TYPE = "rich-quote";
3172
+ var SLOT_ATTR = "data-quote-attribution-slot";
2421
3173
  function $isRichQuoteLike(node) {
2422
3174
  if (!node) return false;
2423
3175
  const ctor = node.constructor;
@@ -2432,98 +3184,104 @@ function $collectQuotes() {
2432
3184
  for (const child of $getRoot().getChildren()) visit(child);
2433
3185
  return out;
2434
3186
  }
2435
- function readRect(dom) {
2436
- const r = dom.getBoundingClientRect();
2437
- return {
2438
- top: r.top,
2439
- left: r.left,
2440
- width: r.width,
2441
- height: r.height
2442
- };
3187
+ function $activeQuoteKey() {
3188
+ const selection = $getSelection();
3189
+ if (!$isRangeSelection(selection)) return null;
3190
+ let node = selection.anchor.getNode();
3191
+ while (node) {
3192
+ if ($isRichQuoteLike(node)) return node.getKey();
3193
+ node = node.getParent();
3194
+ }
3195
+ return null;
2443
3196
  }
2444
- function rectsEqual(a, b) {
2445
- if (a === b) return true;
2446
- if (!a || !b) return false;
2447
- return a.top === b.top && a.left === b.left && a.width === b.width && a.height === b.height;
3197
+ function findSlot(quote) {
3198
+ if (!quote) return null;
3199
+ for (const child of quote.children) if (child.hasAttribute(SLOT_ATTR)) return child;
3200
+ return null;
2448
3201
  }
2449
3202
  function QuoteAttributionPlugin() {
2450
3203
  const [editor] = useLexicalComposerContext();
2451
- const portalContainer = usePortalContainer();
2452
3204
  const [quotes, setQuotes] = useState([]);
3205
+ const [activeKey, setActiveKey] = useState(null);
3206
+ const [editable, setEditable] = useState(() => editor.isEditable());
3207
+ useEffect(() => editor.registerEditableListener(setEditable), [editor]);
2453
3208
  useEffect(() => {
2454
3209
  const collect = () => {
2455
3210
  editor.getEditorState().read(() => {
2456
3211
  const list = [];
2457
3212
  for (const node of $collectQuotes()) {
2458
- const dom = editor.getElementByKey(node.getKey());
2459
- if (dom) list.push({
3213
+ const slot = findSlot(editor.getElementByKey(node.getKey()));
3214
+ if (slot) list.push({
2460
3215
  key: node.getKey(),
2461
3216
  attribution: node.getAttribution() ?? "",
2462
- dom
3217
+ slot
2463
3218
  });
2464
3219
  }
2465
3220
  setQuotes(list);
3221
+ setActiveKey($activeQuoteKey());
2466
3222
  });
2467
3223
  };
2468
- collect();
2469
- return editor.registerUpdateListener(() => collect());
3224
+ const removeRoot = editor.registerRootListener(() => queueMicrotask(collect));
3225
+ const removeUpdate = editor.registerUpdateListener(collect);
3226
+ return () => {
3227
+ removeRoot();
3228
+ removeUpdate();
3229
+ };
2470
3230
  }, [editor]);
2471
- if (!editor.isEditable()) return null;
2472
- if (quotes.length === 0) return null;
2473
- return createPortal(/* @__PURE__ */ jsx(PortalThemeWrapper$1, { children: quotes.map((q) => /* @__PURE__ */ jsx(QuotePanel, {
2474
- attribution: q.attribution,
3231
+ return /* @__PURE__ */ jsx(Fragment, { children: quotes.map((quote) => createPortal(/* @__PURE__ */ jsx(QuoteAttribution, {
3232
+ active: quote.key === activeKey,
3233
+ attribution: quote.attribution,
3234
+ editable,
2475
3235
  editor,
2476
- quoteDom: q.dom,
2477
- quoteKey: q.key
2478
- }, q.key)) }), portalContainer);
3236
+ quoteKey: quote.key,
3237
+ slot: quote.slot
3238
+ }), quote.slot, quote.key)) });
2479
3239
  }
2480
- function QuotePanel({ attribution, editor, quoteDom, quoteKey }) {
2481
- const [rect, setRect] = useState(null);
3240
+ var stop = (event) => event.stopPropagation();
3241
+ function QuoteAttribution({ active, attribution, editable, editor, quoteKey, slot: slot$1 }) {
2482
3242
  const [value, setValue] = useState(attribution);
2483
3243
  const [focused, setFocused] = useState(false);
2484
3244
  useEffect(() => {
2485
3245
  if (!focused) setValue(attribution);
2486
3246
  }, [attribution, focused]);
2487
3247
  useLayoutEffect(() => {
2488
- quoteDom.setAttribute("data-attribution-panel", "");
2489
- let next = null;
2490
- const sync = () => {
2491
- const r = readRect(quoteDom);
2492
- if (!rectsEqual(next, r)) {
2493
- next = r;
2494
- setRect(r);
2495
- }
2496
- };
2497
- sync();
2498
- const ro = new ResizeObserver(sync);
2499
- ro.observe(quoteDom);
2500
- window.addEventListener("scroll", sync, true);
2501
- window.addEventListener("resize", sync);
2502
- return () => {
2503
- quoteDom.removeAttribute("data-attribution-panel");
2504
- ro.disconnect();
2505
- window.removeEventListener("scroll", sync, true);
2506
- window.removeEventListener("resize", sync);
2507
- };
2508
- }, [quoteDom]);
3248
+ slot$1.classList.add(slot);
3249
+ slot$1.toggleAttribute("data-empty", !attribution);
3250
+ slot$1.toggleAttribute("data-active", active || focused);
3251
+ }, [
3252
+ active,
3253
+ attribution,
3254
+ focused,
3255
+ slot$1
3256
+ ]);
3257
+ useLayoutEffect(() => () => {
3258
+ slot$1.classList.remove(slot);
3259
+ slot$1.removeAttribute("data-empty");
3260
+ slot$1.removeAttribute("data-active");
3261
+ }, [slot$1]);
2509
3262
  const commit = useCallback((raw) => {
2510
- const trimmed = raw.trim();
3263
+ const next = raw.trim() || null;
3264
+ if (next === (attribution || null)) return;
2511
3265
  editor.update(() => {
2512
3266
  const node = $getNodeByKey(quoteKey);
2513
- if ($isRichQuoteLike(node)) node.setAttribution(trimmed || null);
3267
+ if ($isRichQuoteLike(node)) node.setAttribution(next);
2514
3268
  });
2515
- }, [editor, quoteKey]);
2516
- const handleKeyDown = useCallback((e) => {
2517
- e.stopPropagation();
2518
- if (e.key === "Enter") {
2519
- e.preventDefault();
3269
+ }, [
3270
+ attribution,
3271
+ editor,
3272
+ quoteKey
3273
+ ]);
3274
+ const handleKeyDown = useCallback((event) => {
3275
+ event.stopPropagation();
3276
+ if (event.key === "Enter") {
3277
+ event.preventDefault();
2520
3278
  commit(value);
2521
- e.currentTarget.blur();
3279
+ event.currentTarget.blur();
2522
3280
  editor.focus();
2523
- } else if (e.key === "Escape") {
2524
- e.preventDefault();
3281
+ } else if (event.key === "Escape") {
3282
+ event.preventDefault();
2525
3283
  setValue(attribution);
2526
- e.currentTarget.blur();
3284
+ event.currentTarget.blur();
2527
3285
  editor.focus();
2528
3286
  }
2529
3287
  }, [
@@ -2532,53 +3290,44 @@ function QuotePanel({ attribution, editor, quoteDom, quoteKey }) {
2532
3290
  editor,
2533
3291
  value
2534
3292
  ]);
2535
- const stop = useCallback((e) => {
2536
- e.stopPropagation();
2537
- }, []);
2538
- if (!rect) return null;
2539
- return /* @__PURE__ */ jsx("div", {
2540
- className: overlay,
2541
- style: {
2542
- top: `${rect.top}px`,
2543
- left: `${rect.left}px`,
2544
- width: `${rect.width}px`,
2545
- height: `${rect.height}px`
2546
- },
2547
- children: /* @__PURE__ */ jsx("div", {
2548
- className: `${panel} ${semanticClassNames.panel}`,
2549
- contentEditable: false,
2550
- "data-lexical-editor": "false",
2551
- children: /* @__PURE__ */ jsx("input", {
2552
- className: `${input} ${semanticClassNames.input}`,
2553
- placeholder: "— Author, Work",
2554
- type: "text",
2555
- value,
2556
- onBeforeInput: stop,
2557
- onClick: stop,
2558
- onCompositionEnd: stop,
2559
- onCompositionStart: stop,
2560
- onCompositionUpdate: stop,
2561
- onCopy: stop,
2562
- onCut: stop,
2563
- onDragStart: stop,
2564
- onDrop: stop,
2565
- onFocus: () => setFocused(true),
2566
- onInput: stop,
2567
- onKeyDown: handleKeyDown,
2568
- onKeyUp: stop,
2569
- onMouseDown: stop,
2570
- onPaste: stop,
2571
- onPointerDown: stop,
2572
- onBlur: (e) => {
2573
- setFocused(false);
2574
- commit(e.currentTarget.value);
2575
- },
2576
- onChange: (e) => {
2577
- e.stopPropagation();
2578
- setValue(e.target.value);
2579
- }
2580
- })
2581
- })
3293
+ if (!editable) return attribution ? /* @__PURE__ */ jsxs("span", {
3294
+ className: text,
3295
+ children: ["— ", attribution]
3296
+ }) : null;
3297
+ return /* @__PURE__ */ jsxs("label", {
3298
+ className: field,
3299
+ children: [/* @__PURE__ */ jsx("span", {
3300
+ "aria-hidden": true,
3301
+ className: dash,
3302
+ children: "—"
3303
+ }), /* @__PURE__ */ jsx("input", {
3304
+ "aria-label": "Quote attribution",
3305
+ className: input$1,
3306
+ placeholder: "Author, Work",
3307
+ type: "text",
3308
+ value,
3309
+ onBeforeInput: stop,
3310
+ onChange: (event) => setValue(event.target.value),
3311
+ onClick: stop,
3312
+ onCompositionEnd: stop,
3313
+ onCompositionStart: stop,
3314
+ onCompositionUpdate: stop,
3315
+ onCopy: stop,
3316
+ onCut: stop,
3317
+ onDragStart: stop,
3318
+ onDrop: stop,
3319
+ onFocus: () => setFocused(true),
3320
+ onInput: stop,
3321
+ onKeyDown: handleKeyDown,
3322
+ onKeyUp: stop,
3323
+ onMouseDown: stop,
3324
+ onPaste: stop,
3325
+ onPointerDown: stop,
3326
+ onBlur: (event) => {
3327
+ setFocused(false);
3328
+ commit(event.currentTarget.value);
3329
+ }
3330
+ })]
2582
3331
  });
2583
3332
  }
2584
3333
  //#endregion
@@ -2612,177 +3361,16 @@ function ScrollArea({ children, className, autoScrollToBottom = false, scrollRef
2612
3361
  });
2613
3362
  }
2614
3363
  //#endregion
2615
- //#region src/components/segmented-control/styles.css.ts
2616
- var container = createRuntimeFn({
2617
- defaultClassName: "_6d8tz20",
2618
- variantClassNames: {
2619
- size: {
2620
- sm: "_6d8tz21",
2621
- md: "_6d8tz22"
2622
- },
2623
- fullWidth: {
2624
- true: "_6d8tz23",
2625
- false: "_6d8tz24"
2626
- }
2627
- },
2628
- defaultVariants: {
2629
- size: "sm",
2630
- fullWidth: false
2631
- },
2632
- compoundVariants: []
2633
- });
2634
- var indicator = createRuntimeFn({
2635
- defaultClassName: "_6d8tz25",
2636
- variantClassNames: { ready: {
2637
- true: "_6d8tz26",
2638
- false: "_6d8tz27"
2639
- } },
2640
- defaultVariants: { ready: true },
2641
- compoundVariants: []
2642
- });
2643
- var item$1 = createRuntimeFn({
2644
- defaultClassName: "_6d8tz28",
2645
- variantClassNames: {
2646
- size: {
2647
- sm: "_6d8tz29",
2648
- md: "_6d8tz2a"
2649
- },
2650
- active: {
2651
- true: "_6d8tz2b",
2652
- false: "_6d8tz2c"
2653
- },
2654
- disabled: {
2655
- true: "_6d8tz2d",
2656
- false: "_6d8tz2e"
2657
- },
2658
- fullWidth: {
2659
- true: "_6d8tz2f",
2660
- false: "_6d8tz2g"
2661
- }
2662
- },
2663
- defaultVariants: {
2664
- size: "sm",
2665
- active: false,
2666
- disabled: false,
2667
- fullWidth: false
2668
- },
2669
- compoundVariants: []
2670
- });
2671
- //#endregion
2672
- //#region src/components/segmented-control/index.tsx
2673
- function SegmentedControl({ items, value, onChange, size = "sm", fullWidth = false, className }) {
2674
- const containerRef = useRef(null);
2675
- const itemElementsRef = useRef(/* @__PURE__ */ new Map());
2676
- const [indicator$2, setIndicator] = useState({
2677
- left: 0,
2678
- width: 0
2679
- });
2680
- const [isReady, setIsReady] = useState(false);
2681
- const updateIndicator = useCallback(() => {
2682
- const container = containerRef.current;
2683
- const activeEl = itemElementsRef.current.get(value);
2684
- if (!container || !activeEl) return;
2685
- const containerRect = container.getBoundingClientRect();
2686
- const activeRect = activeEl.getBoundingClientRect();
2687
- setIndicator({
2688
- left: activeRect.left - containerRect.left,
2689
- width: activeRect.width
2690
- });
2691
- setIsReady(true);
2692
- }, [value]);
2693
- useEffect(() => {
2694
- updateIndicator();
2695
- }, [updateIndicator]);
2696
- useEffect(() => {
2697
- const container = containerRef.current;
2698
- if (!container) return;
2699
- const observer = new ResizeObserver(() => {
2700
- updateIndicator();
2701
- });
2702
- observer.observe(container);
2703
- return () => observer.disconnect();
2704
- }, [updateIndicator]);
2705
- const handleKeyDown = (e) => {
2706
- const enabledItems = items.filter((item) => !item.disabled);
2707
- const currentIndex = enabledItems.findIndex((item) => item.value === value);
2708
- let nextIndex = currentIndex;
2709
- switch (e.key) {
2710
- case "ArrowRight":
2711
- case "ArrowDown":
2712
- e.preventDefault();
2713
- nextIndex = (currentIndex + 1) % enabledItems.length;
2714
- break;
2715
- case "ArrowLeft":
2716
- case "ArrowUp":
2717
- e.preventDefault();
2718
- nextIndex = (currentIndex - 1 + enabledItems.length) % enabledItems.length;
2719
- break;
2720
- case "Home":
2721
- e.preventDefault();
2722
- nextIndex = 0;
2723
- break;
2724
- case "End":
2725
- e.preventDefault();
2726
- nextIndex = enabledItems.length - 1;
2727
- }
2728
- if (nextIndex !== currentIndex) {
2729
- const nextItem = enabledItems[nextIndex];
2730
- onChange(nextItem.value);
2731
- itemElementsRef.current.get(nextItem.value)?.focus();
2732
- }
2733
- };
2734
- return /* @__PURE__ */ jsxs("div", {
2735
- "aria-orientation": "horizontal",
2736
- className: `${container({
2737
- size,
2738
- fullWidth
2739
- })} ${className || ""}`.trim(),
2740
- ref: containerRef,
2741
- role: "tablist",
2742
- onKeyDown: handleKeyDown,
2743
- children: [/* @__PURE__ */ jsx("div", {
2744
- "aria-hidden": "true",
2745
- className: indicator({ ready: isReady }),
2746
- style: {
2747
- left: indicator$2.left,
2748
- width: indicator$2.width
2749
- }
2750
- }), items.map((item) => {
2751
- const isActive = item.value === value;
2752
- return /* @__PURE__ */ jsx("button", {
2753
- "aria-selected": isActive,
2754
- "data-active": isActive || void 0,
2755
- disabled: item.disabled,
2756
- role: "tab",
2757
- tabIndex: isActive ? 0 : -1,
2758
- type: "button",
2759
- className: item$1({
2760
- size,
2761
- active: isActive,
2762
- disabled: Boolean(item.disabled),
2763
- fullWidth
2764
- }),
2765
- ref: (el) => {
2766
- if (el) itemElementsRef.current.set(item.value, el);
2767
- else itemElementsRef.current.delete(item.value);
2768
- },
2769
- onClick: () => onChange(item.value),
2770
- children: item.label
2771
- }, item.value);
2772
- })]
2773
- });
2774
- }
2775
- //#endregion
2776
3364
  //#region src/components/select/styles.css.ts
2777
3365
  var triggerButton = "p74a620";
2778
3366
  var triggerIcon = "p74a621";
2779
- var positioner$1 = "p74a622";
2780
- var popup$1 = "p74a623";
3367
+ var positioner = "p74a622";
3368
+ var popup = "p74a623";
2781
3369
  var group = "p74a624";
2782
3370
  var item = "p74a625";
2783
3371
  var itemIndicator = "p74a626";
2784
- var groupLabel = "_1sxaacb3";
2785
- var separator = "_1sxaacb2";
3372
+ var groupLabel = "_1sxaacb4";
3373
+ var separator = "_1sxaacb3";
2786
3374
  var scrollButton = "p74a627";
2787
3375
  //#endregion
2788
3376
  //#region src/components/select/index.tsx
@@ -2806,12 +3394,12 @@ function SelectContent({ children, className, align = "center", alignItemWithTri
2806
3394
  return /* @__PURE__ */ jsx(Select$1.Portal, { children: /* @__PURE__ */ jsx(PortalThemeWrapper, { children: /* @__PURE__ */ jsx(Select$1.Positioner, {
2807
3395
  align,
2808
3396
  alignItemWithTrigger,
2809
- className: positioner$1,
3397
+ className: positioner,
2810
3398
  side,
2811
3399
  sideOffset,
2812
3400
  children: /* @__PURE__ */ jsxs(Select$1.Popup, {
2813
3401
  ...props,
2814
- className: `${popup$1}${className ? ` ${className}` : ""}`,
3402
+ className: `${popup}${className ? ` ${className}` : ""}`,
2815
3403
  children: [
2816
3404
  /* @__PURE__ */ jsx(Select$1.ScrollUpArrow, {
2817
3405
  className: scrollButton,
@@ -2932,55 +3520,20 @@ function StatusDot({ status, pulse: showPulse, size, className }) {
2932
3520
  });
2933
3521
  }
2934
3522
  //#endregion
2935
- //#region src/components/tooltip/styles.css.ts
2936
- var positioner = "_1cspf2m0";
2937
- var popup = "_1cspf2m1";
3523
+ //#region src/components/text-input/styles.css.ts
3524
+ var input = "i56btd0";
3525
+ var mono = "i56btd1";
2938
3526
  //#endregion
2939
- //#region src/components/tooltip/index.tsx
2940
- function TooltipProvider(props) {
2941
- return /* @__PURE__ */ jsx(Tooltip.Provider, { ...props });
2942
- }
2943
- function TooltipRoot(props) {
2944
- return /* @__PURE__ */ jsx(Tooltip.Root, { ...props });
2945
- }
2946
- function TooltipTrigger(props) {
2947
- return /* @__PURE__ */ jsx(Tooltip.Trigger, { ...props });
2948
- }
2949
- function TooltipPortal({ children, ...props }) {
2950
- return /* @__PURE__ */ jsx(Tooltip.Portal, {
2951
- ...props,
2952
- children: /* @__PURE__ */ jsx(PortalThemeWrapper$1, { children })
2953
- });
2954
- }
2955
- function TooltipPositioner(props) {
2956
- return /* @__PURE__ */ jsx(Tooltip.Positioner, { ...props });
2957
- }
2958
- function TooltipPopup({ className, children, shortcut: shortcut$2, ...props }) {
2959
- return /* @__PURE__ */ jsxs(Tooltip.Popup, {
2960
- className: `${popup}${className ? ` ${className}` : ""}`,
2961
- ...props,
2962
- children: [children, shortcut$2 && /* @__PURE__ */ jsx(Kbd, {
2963
- className: "_1cspf2m2",
2964
- keys: shortcut$2,
2965
- size: "sm",
2966
- tone: "inverted"
2967
- })]
3527
+ //#region src/components/text-input/index.tsx
3528
+ function TextInput({ invalid, mono: mono$1, className, type = "text", ...props }) {
3529
+ return /* @__PURE__ */ jsx("input", {
3530
+ "aria-invalid": invalid || void 0,
3531
+ className: `${input}${mono$1 ? ` ${mono}` : ""}${className ? ` ${className}` : ""}`,
3532
+ type,
3533
+ ...props
2968
3534
  });
2969
3535
  }
2970
- function TooltipContent({ side = "top", sideOffset = 6, align = "center", className, children, ...popupProps }) {
2971
- return /* @__PURE__ */ jsx(TooltipPortal, { children: /* @__PURE__ */ jsx(TooltipPositioner, {
2972
- align,
2973
- className: positioner,
2974
- side,
2975
- sideOffset,
2976
- children: /* @__PURE__ */ jsx(TooltipPopup, {
2977
- className,
2978
- ...popupProps,
2979
- children
2980
- })
2981
- }) });
2982
- }
2983
- var createTooltipHandle = Tooltip.createHandle;
3536
+ var textInputClassName = input;
2984
3537
  //#endregion
2985
3538
  //#region src/components/viewport-gate/index.tsx
2986
3539
  function ViewportGate({ children, fallback, threshold = .5 }) {
@@ -3006,4 +3559,27 @@ function ViewportGate({ children, fallback, threshold = .5 }) {
3006
3559
  });
3007
3560
  }
3008
3561
  //#endregion
3009
- export { ActionBar, ActionButton, Alert, AnimatedCheckbox, AnimatedTabs, AutoResizeTextArea, Badge, CodeBlock, Collapsible, CollapsiblePanel, CollapsibleTrigger, ColorPicker, Combobox, ComboboxContent, ComboboxEmpty, ComboboxGroup, ComboboxGroupLabel, ComboboxInput, ComboboxItem, ComboboxItemIndicator, ComboboxList, ComboboxTrigger, Dialog, DialogBackdrop, DialogClose, DialogDescription, DialogFooter, DialogHeader, DialogPopup, DialogPortal, DialogStackProvider, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuTrigger, Kbd, Popover, PopoverArrow, PopoverClose, PopoverDescription, PopoverPanel, PopoverPopup, PopoverPortal, PopoverPositioner, PopoverTitle, PopoverTrigger, PortalThemeProvider, PortalThemeWrapper, QuoteAttributionPlugin, ScrollArea, SegmentedControl, Select, SelectContent, SelectGroup, SelectGroupLabel, SelectItem, SelectSeparator, SelectTrigger, SelectValue, Spinner, StatusDot, TooltipContent, TooltipPopup, TooltipPortal, TooltipPositioner, TooltipProvider, TooltipRoot, TooltipTrigger, ViewportGate, codeLanguages, createTooltipHandle, detectPlatform, dismissAllDialogs, dismissDialog, dismissTopDialog, getActionButtonClassName, highlightCode, keyDisplay, parseShortcut, presentDialog, streamdownCodePlugin, useKbdPlatform, usePopover, usePortalTheme };
3562
+ //#region src/hooks/use-live-edit.ts
3563
+ function useLiveEdit(values, open, onApply) {
3564
+ const latestRef = useRef(values);
3565
+ latestRef.current = values;
3566
+ const snapshotRef = useRef(open ? values : null);
3567
+ const changedRef = useRef(false);
3568
+ useEffect(() => {
3569
+ snapshotRef.current = open ? latestRef.current : null;
3570
+ changedRef.current = false;
3571
+ }, [open]);
3572
+ return {
3573
+ apply: useCallback((patch) => {
3574
+ onApply(patch, changedRef.current);
3575
+ changedRef.current = true;
3576
+ }, [onApply]),
3577
+ revert: useCallback(() => {
3578
+ const snapshot = snapshotRef.current;
3579
+ if (snapshot && changedRef.current) onApply(snapshot, true);
3580
+ changedRef.current = false;
3581
+ }, [onApply])
3582
+ };
3583
+ }
3584
+ //#endregion
3585
+ export { ActionBar, ActionButton, Alert, AnimatedCheckbox, AnimatedTabs, AutoResizeTextArea, Badge, CodeBlock, Collapsible, CollapsiblePanel, CollapsibleTrigger, ColorPicker, Combobox, ComboboxContent, ComboboxEmpty, ComboboxGroup, ComboboxGroupLabel, ComboboxInput, ComboboxItem, ComboboxItemIndicator, ComboboxList, ComboboxTrigger, Dialog, DialogBackdrop, DialogClose, DialogDescription, DialogFooter, DialogHeader, DialogPopup, DialogPortal, DialogStackProvider, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuTrigger, Field, Kbd, ModalShell, ModalShellBody, ModalShellFooter, ModalShellHeader, Popover, PopoverArrow, PopoverBody, PopoverClose, PopoverDescription, PopoverFooter, PopoverHeader, PopoverPanel, PopoverPopup, PopoverPortal, PopoverPositioner, PopoverTitle, PopoverTrigger, PortalThemeProvider, PortalThemeWrapper, QuoteAttributionPlugin, ScrollArea, SegmentedControl, Select, SelectContent, SelectGroup, SelectGroupLabel, SelectItem, SelectSeparator, SelectTrigger, SelectValue, Spinner, StatusDot, TextInput, ToastViewport, TooltipContent, TooltipPopup, TooltipPortal, TooltipPositioner, TooltipProvider, TooltipRoot, TooltipTrigger, ViewportGate, codeLanguages, confirmDiscardChanges, createTooltipHandle, detectPlatform, dismissAllDialogs, dismissDialog, dismissToast, dismissTopDialog, getActionButtonClassName, highlightCode, keyDisplay, parseShortcut, presentDialog, requestDismissDialog, streamdownCodePlugin, textInputClassName, toast, updateToast, useKbdPlatform, useLiveEdit, usePopover, usePortalTheme };