@tarviks/lexical-rich-editor 1.0.10 → 1.1.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.
package/dist/index.js CHANGED
@@ -5112,39 +5112,6 @@ var hsvToRgb = (h, s, v) => {
5112
5112
  b: Math.round((bb + m) * 255)
5113
5113
  };
5114
5114
  };
5115
- function useDrag(onMove, onEnd, interactingRef) {
5116
- const draggingRef = React9__namespace.useRef(false);
5117
- const start = React9__namespace.useCallback(
5118
- (e) => {
5119
- draggingRef.current = true;
5120
- if (interactingRef) interactingRef.current = true;
5121
- onMove(e.clientX, e.clientY);
5122
- const move = (ev) => {
5123
- if (!draggingRef.current) return;
5124
- onMove(ev.clientX, ev.clientY);
5125
- };
5126
- const up = () => {
5127
- draggingRef.current = false;
5128
- window.removeEventListener("mousemove", move);
5129
- window.removeEventListener("mouseup", up);
5130
- if (interactingRef) {
5131
- const clearFlag = () => {
5132
- interactingRef.current = false;
5133
- };
5134
- window.addEventListener("click", clearFlag, { once: true });
5135
- setTimeout(() => {
5136
- window.removeEventListener("click", clearFlag);
5137
- interactingRef.current = false;
5138
- }, 0);
5139
- }
5140
- };
5141
- window.addEventListener("mousemove", move);
5142
- window.addEventListener("mouseup", up);
5143
- },
5144
- [onMove, onEnd, interactingRef]
5145
- );
5146
- return start;
5147
- }
5148
5115
  var ColorPickerControl = ({ value, title, disabled, onChange, icon, onOpenChange }) => {
5149
5116
  const [open, setOpen] = React9__namespace.useState(false);
5150
5117
  const btnRef = React9__namespace.useRef(null);
@@ -5155,13 +5122,9 @@ var ColorPickerControl = ({ value, title, disabled, onChange, icon, onOpenChange
5155
5122
  },
5156
5123
  [onOpenChange]
5157
5124
  );
5158
- const interactingRef = React9__namespace.useRef(false);
5159
5125
  const handleDismiss = React9__namespace.useCallback(() => setOpenAndNotify(false), [setOpenAndNotify]);
5160
5126
  const preventDismissOnEvent = React9__namespace.useCallback(
5161
- (ev) => {
5162
- if (interactingRef.current) return true;
5163
- return ev.type !== "click";
5164
- },
5127
+ (ev) => ev.type !== "click",
5165
5128
  []
5166
5129
  );
5167
5130
  const [, forceReposition] = React9__namespace.useState(0);
@@ -5183,75 +5146,63 @@ var ColorPickerControl = ({ value, title, disabled, onChange, icon, onOpenChange
5183
5146
  window.removeEventListener("resize", reposition);
5184
5147
  };
5185
5148
  }, [open]);
5186
- const [hex, setHex] = React9__namespace.useState(normalizeHex(value || "#000000"));
5149
+ const appliedHex = React9__namespace.useMemo(() => normalizeHex(value || "#000000"), [value]);
5150
+ const [hex, setHex] = React9__namespace.useState(appliedHex);
5187
5151
  const { r, g, b } = React9__namespace.useMemo(() => hexToRgb(hex), [hex]);
5188
5152
  const hsv = React9__namespace.useMemo(() => rgbToHsv(r, g, b), [r, g, b]);
5189
5153
  const [h, setH] = React9__namespace.useState(hsv.h);
5190
5154
  const [s, setS] = React9__namespace.useState(hsv.s);
5191
5155
  const [v, setV] = React9__namespace.useState(hsv.v);
5156
+ const setDraft = React9__namespace.useCallback((nextHex) => {
5157
+ setHex(nextHex);
5158
+ const rgb = hexToRgb(nextHex);
5159
+ const next = rgbToHsv(rgb.r, rgb.g, rgb.b);
5160
+ setH(next.h);
5161
+ setS(next.s);
5162
+ setV(next.v);
5163
+ }, []);
5164
+ const setDraftFromHsv = React9__namespace.useCallback((hh, ss, vv) => {
5165
+ const rgb = hsvToRgb(hh, ss, vv);
5166
+ setHex(rgbToHex(rgb.r, rgb.g, rgb.b));
5167
+ setH(hh);
5168
+ setS(ss);
5169
+ setV(vv);
5170
+ }, []);
5192
5171
  const wasOpenRef = React9__namespace.useRef(open);
5193
- console.log("[AO-ColorPicker]", title, "render with incoming value prop:", JSON.stringify(value));
5194
5172
  React9__namespace.useEffect(() => {
5195
5173
  const justOpened = open && !wasOpenRef.current;
5196
5174
  wasOpenRef.current = open;
5197
- console.log("[AO-ColorPicker]", title, "open-seed effect", {
5198
- open,
5199
- justOpened,
5200
- incomingValue: value
5201
- });
5202
5175
  if (!justOpened) return;
5203
- const n = normalizeHex(value || "#000000");
5204
- console.log("[AO-ColorPicker]", title, "seeding local state from value on open", {
5205
- incomingValue: value,
5206
- normalized: n
5207
- });
5208
- setHex(n);
5209
- const rgb = hexToRgb(n);
5210
- const next = rgbToHsv(rgb.r, rgb.g, rgb.b);
5211
- setH(next.h);
5212
- setS(next.s);
5213
- setV(next.v);
5214
- }, [value, open]);
5215
- const commitHsv = React9__namespace.useCallback(
5216
- (hh, ss, vv, close) => {
5217
- const rgb = hsvToRgb(hh, ss, vv);
5218
- const nextHex = rgbToHex(rgb.r, rgb.g, rgb.b);
5219
- setHex(nextHex);
5220
- console.log("[AO-ColorPicker]", title, "commitHsv -> onChange", { nextHex, close: !!close });
5221
- onChange(nextHex);
5222
- if (close) setOpenAndNotify(false);
5223
- },
5224
- [onChange, title, setOpenAndNotify]
5225
- );
5176
+ setDraft(appliedHex);
5177
+ }, [appliedHex, open, setDraft]);
5226
5178
  const svRef = React9__namespace.useRef(null);
5227
- const onSVMove = React9__namespace.useCallback(
5228
- (clientX, clientY) => {
5179
+ const handleSVClick = React9__namespace.useCallback(
5180
+ (e) => {
5229
5181
  if (!svRef.current) return;
5230
5182
  const rect = svRef.current.getBoundingClientRect();
5231
- const x = clamp3(clientX - rect.left, 0, rect.width);
5232
- const y = clamp3(clientY - rect.top, 0, rect.height);
5183
+ const x = clamp3(e.clientX - rect.left, 0, rect.width);
5184
+ const y = clamp3(e.clientY - rect.top, 0, rect.height);
5233
5185
  const ss = rect.width === 0 ? 0 : x / rect.width;
5234
5186
  const vv = rect.height === 0 ? 0 : 1 - y / rect.height;
5235
- setS(ss);
5236
- setV(vv);
5237
- commitHsv(h, ss, vv);
5187
+ setDraftFromHsv(h, ss, vv);
5238
5188
  },
5239
- [h, commitHsv]
5189
+ [h, setDraftFromHsv]
5240
5190
  );
5241
- const startSV = useDrag(onSVMove, void 0, interactingRef);
5242
5191
  const hueRef = React9__namespace.useRef(null);
5243
- const onHueMove = React9__namespace.useCallback(
5244
- (clientX) => {
5192
+ const handleHueClick = React9__namespace.useCallback(
5193
+ (e) => {
5245
5194
  if (!hueRef.current) return;
5246
5195
  const rect = hueRef.current.getBoundingClientRect();
5247
- const x = clamp3(clientX - rect.left, 0, rect.width);
5196
+ const x = clamp3(e.clientX - rect.left, 0, rect.width);
5248
5197
  const hh = rect.width === 0 ? 0 : x / rect.width * 360;
5249
- setH(hh);
5250
- commitHsv(hh, s, v);
5198
+ setDraftFromHsv(hh, s, v);
5251
5199
  },
5252
- [s, v, commitHsv]
5200
+ [s, v, setDraftFromHsv]
5253
5201
  );
5254
- const startHue = useDrag((x) => onHueMove(x), void 0, interactingRef);
5202
+ const handleApply = React9__namespace.useCallback(() => {
5203
+ onChange(hex);
5204
+ setOpenAndNotify(false);
5205
+ }, [onChange, hex, setOpenAndNotify]);
5255
5206
  const svThumb = React9__namespace.useMemo(() => ({ left: `${s * 100}%`, top: `${(1 - v) * 100}%` }), [s, v]);
5256
5207
  const hueThumb = React9__namespace.useMemo(() => ({ left: `${h / 360 * 100}%` }), [h]);
5257
5208
  const hueColor = React9__namespace.useMemo(() => {
@@ -5276,10 +5227,6 @@ var ColorPickerControl = ({ value, title, disabled, onChange, icon, onOpenChange
5276
5227
  },
5277
5228
  onClick: () => {
5278
5229
  if (disabled) return;
5279
- console.log("[AO-ColorPicker]", title, "trigger button clicked", {
5280
- wasOpen: open,
5281
- activeElementBeforeToggle: document.activeElement?.tagName
5282
- });
5283
5230
  setOpenAndNotify(!open);
5284
5231
  }
5285
5232
  }
@@ -5294,7 +5241,7 @@ var ColorPickerControl = ({ value, title, disabled, onChange, icon, onOpenChange
5294
5241
  transform: "translateX(-50%)",
5295
5242
  width: 14,
5296
5243
  height: 3,
5297
- background: hex,
5244
+ background: appliedHex,
5298
5245
  borderRadius: 1,
5299
5246
  border: "0.5px solid rgba(0,0,0,0.18)",
5300
5247
  pointerEvents: "none"
@@ -5322,17 +5269,7 @@ var ColorPickerControl = ({ value, title, disabled, onChange, icon, onOpenChange
5322
5269
  {
5323
5270
  value: hex,
5324
5271
  onChange: (_, val) => setHex(normalizeHex(val || "")),
5325
- onBlur: () => {
5326
- const n = normalizeHex(hex);
5327
- setHex(n);
5328
- const rgb = hexToRgb(n);
5329
- const next = rgbToHsv(rgb.r, rgb.g, rgb.b);
5330
- setH(next.h);
5331
- setS(next.s);
5332
- setV(next.v);
5333
- console.log("[AO-ColorPicker]", title, "hex field blur -> onChange", { raw: hex, normalized: n });
5334
- onChange(n);
5335
- }
5272
+ onBlur: () => setDraft(normalizeHex(hex))
5336
5273
  }
5337
5274
  )
5338
5275
  ] }),
@@ -5342,39 +5279,21 @@ var ColorPickerControl = ({ value, title, disabled, onChange, icon, onOpenChange
5342
5279
  type: "button",
5343
5280
  className: "aoLexSwatchBtn",
5344
5281
  style: { background: c },
5345
- onClick: () => {
5346
- setHex(c);
5347
- const rgb = hexToRgb(c);
5348
- const next = rgbToHsv(rgb.r, rgb.g, rgb.b);
5349
- setH(next.h);
5350
- setS(next.s);
5351
- setV(next.v);
5352
- console.log("[AO-ColorPicker]", title, "preset swatch click -> onChange", { color: c });
5353
- onChange(c);
5354
- },
5282
+ onClick: () => setDraft(c),
5355
5283
  title: c
5356
5284
  },
5357
5285
  c
5358
5286
  )) }),
5359
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "aoLexSV", ref: svRef, onMouseDown: startSV, children: [
5287
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "aoLexSV", ref: svRef, onClick: handleSVClick, children: [
5360
5288
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aoLexSVHue", style: { background: hueColor } }),
5361
5289
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aoLexSVWhite" }),
5362
5290
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aoLexSVBlack" }),
5363
5291
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aoLexSVThumb", style: svThumb })
5364
5292
  ] }),
5365
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aoLexHue", ref: hueRef, onMouseDown: startHue, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aoLexHueThumb", style: hueThumb }) }),
5293
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aoLexHue", ref: hueRef, onClick: handleHueClick, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aoLexHueThumb", style: hueThumb }) }),
5366
5294
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aoLexPreview", style: { background: hex } }),
5367
5295
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "aoLexActions", children: [
5368
- /* @__PURE__ */ jsxRuntime.jsx(
5369
- react.DefaultButton,
5370
- {
5371
- type: "button",
5372
- text: "Apply",
5373
- onClick: () => {
5374
- commitHsv(h, s, v, true);
5375
- }
5376
- }
5377
- ),
5296
+ /* @__PURE__ */ jsxRuntime.jsx(react.DefaultButton, { type: "button", text: "Apply", onClick: handleApply }),
5378
5297
  /* @__PURE__ */ jsxRuntime.jsx(react.DefaultButton, { type: "button", text: "Close", onClick: () => setOpenAndNotify(false) })
5379
5298
  ] })
5380
5299
  ] })
@@ -5388,20 +5307,10 @@ var ColorPickerPlugin = ({ disabled }) => {
5388
5307
  const lastRangeSelectionRef = React9__namespace.default.useRef(null);
5389
5308
  const updateToolbar = () => {
5390
5309
  const selection$1 = lexical.$getSelection();
5391
- const isRange = lexical.$isRangeSelection(selection$1);
5392
- console.log("[AO-ColorPicker] updateToolbar", {
5393
- isRangeSelection: isRange,
5394
- isCollapsed: isRange ? selection$1.isCollapsed() : null
5395
- });
5396
- if (isRange) {
5310
+ if (lexical.$isRangeSelection(selection$1)) {
5397
5311
  lastRangeSelectionRef.current = selection$1.clone();
5398
5312
  const c = selection.$getSelectionStyleValueForProperty(selection$1, "color", "#000000");
5399
- const bg = selection.$getSelectionStyleValueForProperty(
5400
- selection$1,
5401
- "background-color",
5402
- "#ffffff"
5403
- );
5404
- console.log("[AO-ColorPicker] updateToolbar readback", { color: c, bgColor: bg });
5313
+ const bg = selection.$getSelectionStyleValueForProperty(selection$1, "background-color", "#ffffff");
5405
5314
  setColors({ color: c, bgColor: bg });
5406
5315
  }
5407
5316
  };
@@ -5431,15 +5340,6 @@ var ColorPickerPlugin = ({ disabled }) => {
5431
5340
  };
5432
5341
  const applyStyle = (args) => {
5433
5342
  if (disabled) return;
5434
- console.log("[AO-ColorPicker] applyStyle called", {
5435
- property: args.property,
5436
- color: args.color,
5437
- hasSavedSelection: !!lastRangeSelectionRef.current,
5438
- savedSelectionIsCollapsed: lastRangeSelectionRef.current?.isCollapsed() ?? null,
5439
- wasEditorActiveAtOpen: wasEditorActiveRef.current,
5440
- activeElementTag: document.activeElement?.tagName,
5441
- activeElementClass: document.activeElement?.className
5442
- });
5443
5343
  editor.update(
5444
5344
  () => {
5445
5345
  const saved = lastRangeSelectionRef.current;
@@ -5447,39 +5347,17 @@ var ColorPickerPlugin = ({ disabled }) => {
5447
5347
  lexical.$setSelection(saved.clone());
5448
5348
  }
5449
5349
  const selection$1 = lexical.$getSelection();
5450
- const isRange = lexical.$isRangeSelection(selection$1);
5451
- console.log("[AO-ColorPicker] applyStyle inside editor.update", {
5452
- hadSavedSelection: !!saved,
5453
- selectionAfterRestoreIsRange: isRange,
5454
- selectionAfterRestoreIsCollapsed: isRange ? selection$1.isCollapsed() : null
5455
- });
5456
- if (isRange) {
5350
+ if (lexical.$isRangeSelection(selection$1)) {
5457
5351
  selection.$patchStyleText(selection$1, { [args.property]: args.color });
5458
- const verify = selection.$getSelectionStyleValueForProperty(
5459
- selection$1,
5460
- args.property,
5461
- "<none>"
5462
- );
5463
- console.log("[AO-ColorPicker] applyStyle after patchStyleText, readback in same update", {
5464
- property: args.property,
5465
- appliedColor: args.color,
5466
- readBack: verify
5467
- });
5468
- } else {
5469
- console.warn(
5470
- "[AO-ColorPicker] applyStyle: no range selection available \u2014 style was NOT applied",
5471
- { property: args.property, color: args.color }
5472
- );
5473
5352
  }
5474
5353
  },
5475
5354
  // Without this tag, Lexical's reconciler force-focuses the editor root
5476
5355
  // whenever this update's selection diff finds the root isn't already
5477
- // focused (see Lexical.dev.mjs ~8112) — which it never is while the
5478
- // color picker's Callout legitimately holds focus. That forced focus
5479
- // then fights Fluent's Callout for focus on every single drag-driven
5480
- // commit, repeatedly bouncing focus (and, via FocusEventsPlugin,
5481
- // nulling and restoring the selection) between the editor and the
5482
- // popover until the drag's tracked color desynced from the cursor.
5356
+ // focused — which it isn't while the color picker's Callout holds
5357
+ // focus. The picker now only calls applyStyle once, on Apply, so this
5358
+ // is no longer fighting for focus on every drag pixel, but there's no
5359
+ // reason to force a focus change here at all — handleOpenChange above
5360
+ // already does that deliberately, once, on close.
5483
5361
  { tag: lexical.SKIP_SELECTION_FOCUS_TAG }
5484
5362
  );
5485
5363
  };
@@ -6825,12 +6703,6 @@ function FocusEventsPlugin({
6825
6703
  const next = e.relatedTarget;
6826
6704
  const container = containerRef.current;
6827
6705
  const stillInside = !!next && (container ? container.contains(next) : root.contains(next));
6828
- console.log("[AO-ColorPicker] FocusEventsPlugin focusout", {
6829
- relatedTargetTag: next ? next.tagName : null,
6830
- relatedTargetClass: next ? next.className : null,
6831
- stillInside,
6832
- willClearSelection: !stillInside
6833
- });
6834
6706
  if (stillInside) return;
6835
6707
  editor.update(() => {
6836
6708
  lexical.$setSelection(null);