@uniformdev/design-system 19.186.1 → 19.186.2-alpha.14

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/esm/index.js CHANGED
@@ -20392,7 +20392,7 @@ import {
20392
20392
  UNORDERED_LIST
20393
20393
  } from "@lexical/markdown";
20394
20394
  import { LexicalComposer } from "@lexical/react/LexicalComposer";
20395
- import { useLexicalComposerContext as useLexicalComposerContext8 } from "@lexical/react/LexicalComposerContext";
20395
+ import { useLexicalComposerContext as useLexicalComposerContext9 } from "@lexical/react/LexicalComposerContext";
20396
20396
  import { ContentEditable } from "@lexical/react/LexicalContentEditable";
20397
20397
  import LexicalErrorBoundary from "@lexical/react/LexicalErrorBoundary";
20398
20398
  import { HistoryPlugin } from "@lexical/react/LexicalHistoryPlugin";
@@ -20404,6 +20404,12 @@ import { HeadingNode, QuoteNode } from "@lexical/rich-text";
20404
20404
  import { TableCellNode as TableCellNode3, TableNode, TableRowNode as TableRowNode2 } from "@lexical/table";
20405
20405
 
20406
20406
  // ../richtext/dist/index.mjs
20407
+ function isRichTextNode(node) {
20408
+ return !!node && typeof node === "object" && "type" in node;
20409
+ }
20410
+ function isRichTextNodeType(node, type) {
20411
+ return isRichTextNode(node) && node.type === type;
20412
+ }
20407
20413
  var richTextBuiltInElements = [
20408
20414
  {
20409
20415
  label: "Heading 1",
@@ -20453,6 +20459,10 @@ var richTextBuiltInElements = [
20453
20459
  label: "Table",
20454
20460
  type: "table"
20455
20461
  },
20462
+ {
20463
+ label: "Asset",
20464
+ type: "asset"
20465
+ },
20456
20466
  {
20457
20467
  label: "Dynamic Token",
20458
20468
  type: "variable"
@@ -20500,7 +20510,7 @@ var getLabelForElement = (type) => {
20500
20510
  // src/components/ParameterInputs/ParameterRichText.tsx
20501
20511
  import { deepEqual as deepEqual2 } from "fast-equals";
20502
20512
  import { ParagraphNode as ParagraphNode2 } from "lexical";
20503
- import { useEffect as useEffect24, useState as useState21 } from "react";
20513
+ import { useEffect as useEffect25, useState as useState21 } from "react";
20504
20514
 
20505
20515
  // src/components/ParameterInputs/rich-text/CustomCodeNode.ts
20506
20516
  import { CodeNode } from "@lexical/code";
@@ -20779,11 +20789,70 @@ var tableHeaderElement = css96`
20779
20789
  width: 7rem;
20780
20790
  `;
20781
20791
 
20792
+ // src/components/ParameterInputs/rich-text/ImprovedAssetSelectionPlugin.tsx
20793
+ import { useLexicalComposerContext as useLexicalComposerContext2 } from "@lexical/react/LexicalComposerContext";
20794
+ import { $insertFirst } from "@lexical/utils";
20795
+ import { $createParagraphNode, $getRoot, $insertNodes } from "lexical";
20796
+ import { useEffect as useEffect18 } from "react";
20797
+ var ImprovedAssetSelectionPlugin = () => {
20798
+ const [editor] = useLexicalComposerContext2();
20799
+ useEffect18(() => {
20800
+ editor.getRootElement();
20801
+ const onRootClick = (event) => {
20802
+ if (event.target !== editor.getRootElement()) {
20803
+ return;
20804
+ }
20805
+ const clickArea = event.offsetY <= 60 ? "top" : "bottom";
20806
+ const state = editor.getEditorState().toJSON();
20807
+ const firstNode = state.root.children[0];
20808
+ const lastNode = state.root.children.at(-1);
20809
+ if (isRichTextNodeType(firstNode, "asset") && clickArea === "top") {
20810
+ editor.update(() => {
20811
+ $insertFirst($getRoot(), $createParagraphNode());
20812
+ requestAnimationFrame(() => {
20813
+ var _a, _b;
20814
+ (_b = (_a = editor.getRootElement()) == null ? void 0 : _a.parentElement) == null ? void 0 : _b.scrollTo({
20815
+ top: 0,
20816
+ behavior: "instant"
20817
+ });
20818
+ });
20819
+ });
20820
+ } else if (isRichTextNodeType(lastNode, "asset") && clickArea === "bottom") {
20821
+ editor.update(() => {
20822
+ $getRoot().selectEnd();
20823
+ $insertNodes([$createParagraphNode()]);
20824
+ requestAnimationFrame(() => {
20825
+ var _a, _b, _c, _d;
20826
+ (_d = (_a = editor.getRootElement()) == null ? void 0 : _a.parentElement) == null ? void 0 : _d.scrollTo({
20827
+ top: (_c = (_b = editor.getRootElement()) == null ? void 0 : _b.parentElement) == null ? void 0 : _c.scrollHeight,
20828
+ behavior: "instant"
20829
+ });
20830
+ });
20831
+ });
20832
+ }
20833
+ };
20834
+ const removeRootListener = editor.registerRootListener((rootElement, prevRootElement) => {
20835
+ rootElement == null ? void 0 : rootElement.addEventListener("click", onRootClick);
20836
+ prevRootElement == null ? void 0 : prevRootElement.removeEventListener("click", onRootClick);
20837
+ });
20838
+ return () => {
20839
+ removeRootListener();
20840
+ };
20841
+ }, [editor]);
20842
+ return null;
20843
+ };
20844
+ var ImprovedAssetSelectionPlugin_default = ImprovedAssetSelectionPlugin;
20845
+
20782
20846
  // src/components/ParameterInputs/rich-text/LinkNodePlugin.tsx
20783
20847
  import { css as css97 } from "@emotion/react";
20784
- import { useLexicalComposerContext as useLexicalComposerContext2 } from "@lexical/react/LexicalComposerContext";
20848
+ import { useLexicalComposerContext as useLexicalComposerContext3 } from "@lexical/react/LexicalComposerContext";
20785
20849
  import { NodeEventPlugin } from "@lexical/react/LexicalNodeEventPlugin";
20786
- import { addClassNamesToElement, isHTMLAnchorElement, mergeRegister as mergeRegister2 } from "@lexical/utils";
20850
+ import {
20851
+ addClassNamesToElement,
20852
+ isHTMLAnchorElement,
20853
+ mergeRegister as mergeRegister2,
20854
+ objectKlassEquals
20855
+ } from "@lexical/utils";
20787
20856
  import { deepEqual } from "fast-equals";
20788
20857
  import {
20789
20858
  $applyNodeReplacement,
@@ -20792,11 +20861,13 @@ import {
20792
20861
  $isRangeSelection,
20793
20862
  BLUR_COMMAND,
20794
20863
  COMMAND_PRIORITY_EDITOR,
20864
+ COMMAND_PRIORITY_LOW,
20795
20865
  createCommand,
20796
20866
  ElementNode as ElementNode2,
20797
- FOCUS_COMMAND
20867
+ FOCUS_COMMAND,
20868
+ PASTE_COMMAND
20798
20869
  } from "lexical";
20799
- import { useCallback as useCallback10, useEffect as useEffect18, useRef as useRef11, useState as useState16 } from "react";
20870
+ import { useCallback as useCallback10, useEffect as useEffect19, useRef as useRef11, useState as useState16 } from "react";
20800
20871
 
20801
20872
  // src/components/ParameterInputs/rich-text/utils.ts
20802
20873
  import { $isAtNodeEnd } from "@lexical/selection";
@@ -20913,9 +20984,7 @@ function convertAnchorElement(domNode) {
20913
20984
  nodeId,
20914
20985
  dynamicInputValues
20915
20986
  };
20916
- if (isProjectMapLinkValue(value)) {
20917
- node = $createLinkNode(value);
20918
- } else if (isNonProjectMapLinkValue(value)) {
20987
+ if (isProjectMapLinkValue(value) || isNonProjectMapLinkValue(value)) {
20919
20988
  node = $createLinkNode(value);
20920
20989
  }
20921
20990
  return { node };
@@ -21069,6 +21138,10 @@ function upsertLinkNode(props) {
21069
21138
  continue;
21070
21139
  }
21071
21140
  const linkNodeAncestor = getLinkAncestor(node);
21141
+ if ($isLinkNode(node)) {
21142
+ node.setLink(props);
21143
+ continue;
21144
+ }
21072
21145
  if (!linkNodeAncestor) {
21073
21146
  const newLinkNode = $createLinkNode(props);
21074
21147
  node.insertBefore(newLinkNode);
@@ -21141,18 +21214,18 @@ function LinkNodePlugin({
21141
21214
  const parsePath = getBoundPath != null ? getBoundPath : function(path) {
21142
21215
  return path;
21143
21216
  };
21144
- const [editor] = useLexicalComposerContext2();
21217
+ const [editor] = useLexicalComposerContext3();
21145
21218
  const [linkPopoverState, setLinkPopoverState] = useState16();
21146
21219
  const linkPopoverElRef = useRef11(null);
21147
21220
  const [isEditorFocused, setIsEditorFocused] = useState16(false);
21148
21221
  const [isLinkPopoverFocused, setIsLinkPopoverFocused] = useState16(false);
21149
- useEffect18(() => {
21222
+ useEffect19(() => {
21150
21223
  if (!isEditorFocused && !isLinkPopoverFocused) {
21151
21224
  setLinkPopoverState(void 0);
21152
21225
  return;
21153
21226
  }
21154
21227
  }, [isEditorFocused, isLinkPopoverFocused]);
21155
- useEffect18(() => {
21228
+ useEffect19(() => {
21156
21229
  if (!editor.hasNodes([LinkNode])) {
21157
21230
  throw new Error("LinkNode not registered on editor");
21158
21231
  }
@@ -21218,6 +21291,41 @@ function LinkNodePlugin({
21218
21291
  return true;
21219
21292
  },
21220
21293
  COMMAND_PRIORITY_EDITOR
21294
+ ),
21295
+ // Support pasting of links from clipboard
21296
+ editor.registerCommand(
21297
+ PASTE_COMMAND,
21298
+ (event) => {
21299
+ const selection = $getSelection();
21300
+ if (!$isRangeSelection(selection) || selection.isCollapsed() || !objectKlassEquals(event, ClipboardEvent)) {
21301
+ return false;
21302
+ }
21303
+ const clipboardEvent = event;
21304
+ if (clipboardEvent.clipboardData === null) {
21305
+ return false;
21306
+ }
21307
+ const clipboardText = clipboardEvent.clipboardData.getData("text");
21308
+ if (!isValidUrl(clipboardText)) {
21309
+ return false;
21310
+ }
21311
+ if (selection.getNodes().some((node) => $isElementNode2(node) && !$isLinkNode(node))) {
21312
+ return false;
21313
+ }
21314
+ let path = clipboardText;
21315
+ const type = guessLinkTypeFromPath(path);
21316
+ if (type === "email" && path.startsWith("mailto:")) {
21317
+ path = path.replace("mailto:", "");
21318
+ } else if (type === "tel" && path.startsWith("tel:")) {
21319
+ path = path.replace("tel:", "");
21320
+ }
21321
+ upsertLinkNode({
21322
+ path,
21323
+ type
21324
+ });
21325
+ event.preventDefault();
21326
+ return true;
21327
+ },
21328
+ COMMAND_PRIORITY_LOW
21221
21329
  )
21222
21330
  );
21223
21331
  }, [editor, onConnectLink]);
@@ -21255,7 +21363,7 @@ function LinkNodePlugin({
21255
21363
  }
21256
21364
  });
21257
21365
  }, [editor, positioningAnchorEl]);
21258
- useEffect18(() => {
21366
+ useEffect19(() => {
21259
21367
  return editor.registerUpdateListener(({ editorState }) => {
21260
21368
  requestAnimationFrame(() => {
21261
21369
  editorState.read(() => {
@@ -21339,7 +21447,7 @@ function getLinkAncestor(node) {
21339
21447
 
21340
21448
  // src/components/ParameterInputs/rich-text/ListIndentPlugin.tsx
21341
21449
  import { $getListDepth, $isListItemNode, $isListNode, ListNode } from "@lexical/list";
21342
- import { useLexicalComposerContext as useLexicalComposerContext3 } from "@lexical/react/LexicalComposerContext";
21450
+ import { useLexicalComposerContext as useLexicalComposerContext4 } from "@lexical/react/LexicalComposerContext";
21343
21451
  import {
21344
21452
  $filter,
21345
21453
  $getNearestBlockElementAncestorOrThrow,
@@ -21359,7 +21467,7 @@ import {
21359
21467
  OUTDENT_CONTENT_COMMAND,
21360
21468
  SELECTION_CHANGE_COMMAND
21361
21469
  } from "lexical";
21362
- import { useEffect as useEffect19, useRef as useRef12 } from "react";
21470
+ import { useEffect as useEffect20, useRef as useRef12 } from "react";
21363
21471
  function isIndentPermitted(maxDepth) {
21364
21472
  const selection = $getSelection2();
21365
21473
  if (!$isRangeSelection2(selection)) {
@@ -21413,9 +21521,9 @@ function $indentOverTab(selection) {
21413
21521
  return false;
21414
21522
  }
21415
21523
  function ListIndentPlugin({ maxDepth }) {
21416
- const [editor] = useLexicalComposerContext3();
21524
+ const [editor] = useLexicalComposerContext4();
21417
21525
  const isInListItemNode = useRef12(false);
21418
- useEffect19(() => {
21526
+ useEffect20(() => {
21419
21527
  return editor.registerCommand(
21420
21528
  SELECTION_CHANGE_COMMAND,
21421
21529
  () => {
@@ -21432,7 +21540,7 @@ function ListIndentPlugin({ maxDepth }) {
21432
21540
  COMMAND_PRIORITY_NORMAL
21433
21541
  );
21434
21542
  }, [editor]);
21435
- useEffect19(() => {
21543
+ useEffect20(() => {
21436
21544
  return mergeRegister3(
21437
21545
  editor.registerCommand(
21438
21546
  INDENT_CONTENT_COMMAND,
@@ -21460,1242 +21568,1269 @@ function ListIndentPlugin({ maxDepth }) {
21460
21568
  return null;
21461
21569
  }
21462
21570
 
21463
- // src/components/ParameterInputs/rich-text/RichTextToolbar.tsx
21571
+ // src/components/ParameterInputs/rich-text/TableActionMenuPlugin.tsx
21464
21572
  import { css as css98 } from "@emotion/react";
21465
- import { $createCodeNode } from "@lexical/code";
21466
- import {
21467
- $isListNode as $isListNode2,
21468
- INSERT_ORDERED_LIST_COMMAND,
21469
- INSERT_UNORDERED_LIST_COMMAND,
21470
- ListNode as ListNode2,
21471
- REMOVE_LIST_COMMAND
21472
- } from "@lexical/list";
21473
- import { useLexicalComposerContext as useLexicalComposerContext4 } from "@lexical/react/LexicalComposerContext";
21474
- import { $createHeadingNode, $createQuoteNode, $isHeadingNode } from "@lexical/rich-text";
21475
- import { $setBlocksType } from "@lexical/selection";
21476
- import { $createTableNodeWithDimensions } from "@lexical/table";
21477
- import { $findMatchingParent, $getNearestNodeOfType as $getNearestNodeOfType2 } from "@lexical/utils";
21573
+ import { useLexicalComposerContext as useLexicalComposerContext5 } from "@lexical/react/LexicalComposerContext";
21574
+ import { useLexicalEditable } from "@lexical/react/useLexicalEditable";
21478
21575
  import {
21479
- $createParagraphNode,
21480
- $getSelection as $getSelection3,
21481
- $insertNodes,
21482
- $isRangeSelection as $isRangeSelection3,
21483
- $isRootOrShadowRoot,
21484
- COMMAND_PRIORITY_CRITICAL as COMMAND_PRIORITY_CRITICAL2,
21485
- FORMAT_TEXT_COMMAND,
21486
- SELECTION_CHANGE_COMMAND as SELECTION_CHANGE_COMMAND2
21487
- } from "lexical";
21488
- import { useCallback as useCallback11, useEffect as useEffect20, useMemo as useMemo6, useState as useState17 } from "react";
21489
- import { Fragment as Fragment19, jsx as jsx130, jsxs as jsxs86 } from "@emotion/react/jsx-runtime";
21490
- var toolbar = css98`
21491
- ${scrollbarStyles}
21492
- background: var(--gray-50);
21493
- border-radius: var(--rounded-base);
21494
- display: flex;
21495
- /* We add 1px because we use a 1px wide separator */
21496
- gap: calc(var(--spacing-sm) + 1px);
21497
- margin: 0 0 calc(var(--spacing-sm) + var(--spacing-xs)) 0;
21498
- overflow: auto;
21499
- padding: var(--spacing-sm);
21500
- position: sticky;
21501
- top: calc(var(--spacing-sm) * -2);
21502
- z-index: 10;
21503
- `;
21504
- var toolbarGroup = css98`
21505
- display: flex;
21506
- flex-shrink: 0;
21507
- gap: var(--spacing-xs);
21508
- position: relative;
21509
-
21510
- &:not(:first-child)::before {
21511
- background-color: var(--gray-300);
21512
- content: '';
21513
- display: block;
21514
- height: 24px;
21515
- left: calc(var(--spacing-xs) * -1);
21516
- position: absolute;
21517
- top: 4px;
21518
- width: 1px;
21519
- }
21520
- `;
21521
- var richTextToolbarButton = css98`
21522
- align-items: center;
21523
- appearance: none;
21524
- border: 0;
21525
- border-radius: var(--rounded-sm);
21526
- box-shadow: none;
21527
- color: var(--gray-900);
21528
- display: flex;
21529
- flex-shrink: 0;
21530
- height: 32px;
21531
- justify-content: center;
21532
- min-width: 32px;
21533
- padding: 0 var(--spacing-sm);
21534
- `;
21535
- var richTextToolbarButtonActive = css98`
21536
- background: var(--gray-200);
21537
- `;
21538
- var textStyleButton = css98`
21539
- justify-content: space-between;
21540
- min-width: 7rem;
21541
- `;
21542
- var toolbarIcon = css98`
21543
- color: inherit;
21544
- `;
21545
- var toolbarChevron = css98`
21546
- margin-left: var(--spacing-xs);
21576
+ $deleteTableColumn__EXPERIMENTAL,
21577
+ $deleteTableRow__EXPERIMENTAL,
21578
+ $getTableCellNodeFromLexicalNode,
21579
+ $getTableColumnIndexFromTableCellNode,
21580
+ $getTableNodeFromLexicalNodeOrThrow,
21581
+ $getTableRowIndexFromTableCellNode,
21582
+ $insertTableColumn__EXPERIMENTAL,
21583
+ $insertTableRow__EXPERIMENTAL,
21584
+ $isTableCellNode,
21585
+ $isTableRowNode,
21586
+ $isTableSelection,
21587
+ getTableObserverFromTableElement,
21588
+ TableCellHeaderStates,
21589
+ TableCellNode
21590
+ } from "@lexical/table";
21591
+ import { $getRoot as $getRoot2, $getSelection as $getSelection3, $isRangeSelection as $isRangeSelection3 } from "lexical";
21592
+ import { forwardRef as forwardRef22, useCallback as useCallback11, useEffect as useEffect21, useLayoutEffect, useState as useState17 } from "react";
21593
+ import { jsx as jsx130, jsxs as jsxs86 } from "@emotion/react/jsx-runtime";
21594
+ function computeSelectionCount(selection) {
21595
+ const selectionShape = selection.getShape();
21596
+ return {
21597
+ columns: selectionShape.toX - selectionShape.fromX + 1,
21598
+ rows: selectionShape.toY - selectionShape.fromY + 1
21599
+ };
21600
+ }
21601
+ var tableActionMenuTrigger = css98`
21602
+ position: absolute;
21603
+ transform: translate(calc(-100% - 1px), 1px);
21547
21604
  `;
21548
- var RichTextToolbarIcon = ({ icon }) => {
21549
- return /* @__PURE__ */ jsx130(Icon, { icon, css: toolbarIcon, size: "1rem" });
21550
- };
21551
- var FORMATS_WITH_ICON = /* @__PURE__ */ new Map([
21552
- ["bold", "format-bold"],
21553
- ["italic", "format-italic"],
21554
- ["underline", "format-underline"],
21555
- ["strikethrough", "format-strike"],
21556
- ["code", "format-code"],
21557
- ["superscript", "format-superscript"],
21558
- ["subscript", "format-subscript"]
21559
- ]);
21560
- var HEADING_ELEMENTS = ["h1", "h2", "h3", "h4", "h5", "h6"];
21561
- var TEXTUAL_ELEMENTS = HEADING_ELEMENTS;
21562
- var RichTextToolbar = ({ config, customControls, onInsertTable }) => {
21563
- const [editor] = useLexicalComposerContext4();
21564
- const {
21565
- activeElement,
21566
- setActiveElement,
21567
- activeFormats,
21568
- setActiveFormats,
21569
- visibleFormatsWithIcon,
21570
- visibleFormatsWithoutIcon,
21571
- visibleTextualElements,
21572
- isLink,
21573
- setIsLink,
21574
- linkElementVisible,
21575
- visibleLists,
21576
- codeElementVisible,
21577
- quoteElementVisible,
21578
- visibleElementsWithIcons,
21579
- visibleInsertElementsWithIcons,
21580
- tableElementVisible
21581
- } = useRichTextToolbarState({ config });
21582
- const onSelectElement = (type) => {
21583
- if (activeElement === type) {
21584
- return;
21585
- }
21586
- editor.focus(() => {
21587
- editor.update(() => {
21588
- const selection = $getSelection3();
21589
- if (HEADING_ELEMENTS.includes(type)) {
21590
- $setBlocksType(selection, () => $createHeadingNode(type));
21591
- } else if (type === "paragraph") {
21592
- $setBlocksType(selection, () => $createParagraphNode());
21593
- } else if (type === "quote") {
21594
- $setBlocksType(selection, () => $createQuoteNode());
21595
- } else if (type === "code") {
21596
- $setBlocksType(selection, () => $createCodeNode());
21597
- } else if (type === "table" && onInsertTable) {
21598
- onInsertTable().then((dimensions) => {
21599
- if (!dimensions) {
21600
- return;
21601
- }
21602
- const { rows, columns } = dimensions;
21603
- editor.focus(() => {
21604
- editor.update(() => {
21605
- $insertNodes([$createTableNodeWithDimensions(rows, columns, false)]);
21606
- });
21607
- });
21608
- });
21605
+ var TableActionMenuTrigger = forwardRef22((props, ref) => {
21606
+ const { tableCellEl, positioningAnchorEl, ...rest } = props;
21607
+ const [coordinates, setCoordinates] = useState17({ x: 0, y: 0 });
21608
+ useLayoutEffect(() => {
21609
+ const rect = tableCellEl.getBoundingClientRect();
21610
+ const parentRect = positioningAnchorEl.getBoundingClientRect();
21611
+ const relativeX = rect.right - parentRect.left + positioningAnchorEl.scrollLeft;
21612
+ const relativeY = rect.top - parentRect.top + positioningAnchorEl.scrollTop;
21613
+ setCoordinates({ x: relativeX, y: relativeY });
21614
+ }, [tableCellEl, positioningAnchorEl]);
21615
+ return /* @__PURE__ */ jsx130(
21616
+ IconButton,
21617
+ {
21618
+ ref,
21619
+ css: [
21620
+ tableActionMenuTrigger,
21621
+ {
21622
+ top: coordinates.y,
21623
+ left: coordinates.x
21609
21624
  }
21610
- });
21611
- });
21612
- };
21613
- const updateToolbar = useCallback11(() => {
21614
- const selection = $getSelection3();
21615
- if (!$isRangeSelection3(selection)) {
21616
- return;
21617
- }
21618
- const newActiveFormats = [];
21619
- for (const format of richTextBuiltInFormats) {
21620
- if (selection.hasFormat(format.type)) {
21621
- newActiveFormats.push(format.type);
21622
- }
21625
+ ],
21626
+ size: "xs",
21627
+ buttonType: "unimportant",
21628
+ ...rest,
21629
+ children: /* @__PURE__ */ jsx130(Icon, { icon: "chevron-down", size: "1rem", iconColor: "currentColor" })
21623
21630
  }
21624
- setActiveFormats(newActiveFormats);
21625
- const anchorNode = selection.anchor.getNode();
21626
- let element = anchorNode.getKey() === "root" ? anchorNode : $findMatchingParent(anchorNode, (e) => {
21627
- const parent = e.getParent();
21628
- return parent !== null && $isRootOrShadowRoot(parent);
21629
- });
21630
- if (element === null) {
21631
- element = anchorNode.getTopLevelElementOrThrow();
21632
- }
21633
- const elementKey = element.getKey();
21634
- const elementDOM = editor.getElementByKey(elementKey);
21635
- if (elementDOM !== null) {
21636
- if ($isListNode2(element)) {
21637
- const parentList = $getNearestNodeOfType2(anchorNode, ListNode2);
21638
- const type = parentList ? parentList.getListType() : element.getListType();
21639
- setActiveElement(type === "bullet" ? "unorderedList" : "orderedList");
21640
- } else {
21641
- const type = $isHeadingNode(element) ? element.getTag() : element.getType();
21642
- setActiveElement(type);
21643
- }
21644
- }
21645
- const node = getSelectedNode(selection);
21646
- if (getLinkAncestor(node) !== null) {
21647
- setIsLink(true);
21648
- } else {
21649
- setIsLink(false);
21650
- }
21651
- }, [editor, setActiveElement, setActiveFormats, setIsLink]);
21652
- useEffect20(() => {
21653
- return editor.registerCommand(
21654
- SELECTION_CHANGE_COMMAND2,
21655
- (_payload) => {
21656
- updateToolbar();
21657
- return false;
21631
+ );
21632
+ });
21633
+ TableActionMenuTrigger.displayName = "TableActionMenuTrigger";
21634
+ function TableActionMenu({
21635
+ tableCellNode: _tableCellNode,
21636
+ menuPortalEl,
21637
+ tableCellEl,
21638
+ positioningAnchorEl
21639
+ }) {
21640
+ const [editor] = useLexicalComposerContext5();
21641
+ const [tableCellNode, updateTableCellNode] = useState17(_tableCellNode);
21642
+ const [selectionCounts, updateSelectionCounts] = useState17({
21643
+ columns: 1,
21644
+ rows: 1
21645
+ });
21646
+ const [menuTriggerKey, setMenuTriggerKey] = useState17(0);
21647
+ const incrementMenuTriggerKey = () => {
21648
+ setMenuTriggerKey((key) => key += 1);
21649
+ };
21650
+ useEffect21(() => {
21651
+ return editor.registerMutationListener(
21652
+ TableCellNode,
21653
+ (nodeMutations) => {
21654
+ const nodeUpdated = nodeMutations.get(tableCellNode.getKey()) === "updated";
21655
+ if (nodeUpdated) {
21656
+ editor.getEditorState().read(() => {
21657
+ updateTableCellNode(tableCellNode.getLatest());
21658
+ });
21659
+ }
21658
21660
  },
21659
- COMMAND_PRIORITY_CRITICAL2
21661
+ { skipInitialization: true }
21660
21662
  );
21661
- }, [editor, updateToolbar]);
21662
- useEffect20(() => {
21663
- return editor.registerUpdateListener(({ editorState }) => {
21664
- requestAnimationFrame(() => {
21665
- editorState.read(() => {
21666
- updateToolbar();
21667
- });
21663
+ }, [editor, tableCellNode]);
21664
+ useEffect21(() => {
21665
+ editor.getEditorState().read(() => {
21666
+ const selection = $getSelection3();
21667
+ if ($isTableSelection(selection)) {
21668
+ updateSelectionCounts(computeSelectionCount(selection));
21669
+ }
21670
+ });
21671
+ }, [editor]);
21672
+ const clearTableSelection = useCallback11(() => {
21673
+ editor.update(() => {
21674
+ if (tableCellNode.isAttached()) {
21675
+ const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
21676
+ const tableElement2 = editor.getElementByKey(
21677
+ tableNode.getKey()
21678
+ );
21679
+ if (!tableElement2) {
21680
+ throw new Error("Expected to find tableElement in DOM");
21681
+ }
21682
+ const tableSelection = getTableObserverFromTableElement(tableElement2);
21683
+ if (tableSelection !== null) {
21684
+ tableSelection.clearHighlight();
21685
+ }
21686
+ tableNode.markDirty();
21687
+ updateTableCellNode(tableCellNode.getLatest());
21688
+ }
21689
+ const rootNode = $getRoot2();
21690
+ rootNode.selectStart();
21691
+ });
21692
+ }, [editor, tableCellNode]);
21693
+ const insertTableRowAtSelection = useCallback11(
21694
+ (shouldInsertAfter) => {
21695
+ editor.update(() => {
21696
+ $insertTableRow__EXPERIMENTAL(shouldInsertAfter);
21668
21697
  });
21698
+ incrementMenuTriggerKey();
21699
+ },
21700
+ [editor]
21701
+ );
21702
+ const insertTableColumnAtSelection = useCallback11(
21703
+ (shouldInsertAfter) => {
21704
+ editor.update(() => {
21705
+ for (let i = 0; i < selectionCounts.columns; i++) {
21706
+ $insertTableColumn__EXPERIMENTAL(shouldInsertAfter);
21707
+ }
21708
+ });
21709
+ incrementMenuTriggerKey();
21710
+ },
21711
+ [editor, selectionCounts.columns]
21712
+ );
21713
+ const deleteTableRowAtSelection = useCallback11(() => {
21714
+ editor.update(() => {
21715
+ $deleteTableRow__EXPERIMENTAL();
21669
21716
  });
21670
- }, [editor, updateToolbar]);
21671
- return /* @__PURE__ */ jsxs86("div", { css: toolbar, children: [
21672
- /* @__PURE__ */ jsxs86(
21673
- Menu,
21674
- {
21675
- menuTrigger: /* @__PURE__ */ jsxs86("button", { css: [richTextToolbarButton, textStyleButton], title: "Text styles", children: [
21676
- visibleTextualElements.some((element) => element.type === activeElement) ? getLabelForElement(activeElement) : getLabelForElement("paragraph"),
21677
- " ",
21678
- /* @__PURE__ */ jsx130(Icon, { icon: "chevron-down", css: [toolbarIcon, toolbarChevron], size: "1rem" })
21679
- ] }),
21680
- placement: "bottom-start",
21681
- children: [
21682
- [
21683
- {
21684
- label: "Normal",
21685
- type: "paragraph"
21686
- },
21687
- ...visibleTextualElements
21688
- ].map((element) => /* @__PURE__ */ jsx130(
21689
- MenuItem,
21690
- {
21691
- onClick: () => {
21692
- onSelectElement(element.type);
21693
- },
21694
- children: element.label
21695
- },
21696
- element.type
21697
- )),
21698
- visibleTextualElements.length === 0 ? /* @__PURE__ */ jsx130(MenuItem, { disabled: true, children: "Alternative text styles are not available" }) : null
21699
- ]
21717
+ incrementMenuTriggerKey();
21718
+ }, [editor]);
21719
+ const deleteTableAtSelection = useCallback11(() => {
21720
+ editor.update(() => {
21721
+ const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
21722
+ tableNode.remove();
21723
+ clearTableSelection();
21724
+ });
21725
+ }, [editor, tableCellNode, clearTableSelection]);
21726
+ const deleteTableColumnAtSelection = useCallback11(() => {
21727
+ editor.update(() => {
21728
+ $deleteTableColumn__EXPERIMENTAL();
21729
+ });
21730
+ incrementMenuTriggerKey();
21731
+ }, [editor]);
21732
+ const toggleTableRowIsHeader = useCallback11(() => {
21733
+ editor.update(() => {
21734
+ const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
21735
+ const tableRowIndex = $getTableRowIndexFromTableCellNode(tableCellNode);
21736
+ const tableRows = tableNode.getChildren();
21737
+ if (tableRowIndex >= tableRows.length || tableRowIndex < 0) {
21738
+ throw new Error("Expected table cell to be inside of table row.");
21700
21739
  }
21701
- ),
21702
- visibleFormatsWithIcon.length > 0 || visibleFormatsWithoutIcon.length > 0 ? /* @__PURE__ */ jsxs86("div", { css: toolbarGroup, children: [
21703
- visibleFormatsWithIcon.map((format) => /* @__PURE__ */ jsx130(Tooltip, { title: format.label, placement: "top", children: /* @__PURE__ */ jsx130(
21704
- "button",
21705
- {
21706
- onClick: () => {
21707
- editor.dispatchCommand(FORMAT_TEXT_COMMAND, format.type);
21708
- },
21709
- css: [
21710
- richTextToolbarButton,
21711
- activeFormats.includes(format.type) ? richTextToolbarButtonActive : null
21712
- ],
21713
- children: /* @__PURE__ */ jsx130(RichTextToolbarIcon, { icon: FORMATS_WITH_ICON.get(format.type) })
21740
+ const tableRow2 = tableRows[tableRowIndex];
21741
+ if (!$isTableRowNode(tableRow2)) {
21742
+ throw new Error("Expected table row");
21743
+ }
21744
+ tableRow2.getChildren().forEach((tableCell) => {
21745
+ if (!$isTableCellNode(tableCell)) {
21746
+ throw new Error("Expected table cell");
21714
21747
  }
21715
- ) }, format.type)),
21716
- visibleFormatsWithoutIcon.length > 0 ? /* @__PURE__ */ jsx130(
21717
- Menu,
21718
- {
21719
- menuLabel: "Alternative text styles",
21720
- menuTrigger: /* @__PURE__ */ jsx130("button", { css: richTextToolbarButton, title: "Alternative text styles", children: /* @__PURE__ */ jsx130(Icon, { icon: "more-alt", css: toolbarIcon }) }),
21721
- placement: "bottom-start",
21722
- children: visibleFormatsWithoutIcon.map((format) => /* @__PURE__ */ jsx130(
21723
- MenuItem,
21724
- {
21725
- onClick: () => {
21726
- editor.dispatchCommand(FORMAT_TEXT_COMMAND, format.type);
21727
- },
21728
- children: format.label
21729
- },
21730
- format.type
21731
- ))
21748
+ tableCell.toggleHeaderStyle(TableCellHeaderStates.ROW);
21749
+ });
21750
+ clearTableSelection();
21751
+ });
21752
+ }, [editor, tableCellNode, clearTableSelection]);
21753
+ const toggleTableColumnIsHeader = useCallback11(() => {
21754
+ editor.update(() => {
21755
+ const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
21756
+ const tableColumnIndex = $getTableColumnIndexFromTableCellNode(tableCellNode);
21757
+ const tableRows = tableNode.getChildren();
21758
+ const maxRowsLength = Math.max(...tableRows.map((row) => row.getChildren().length));
21759
+ if (tableColumnIndex >= maxRowsLength || tableColumnIndex < 0) {
21760
+ throw new Error("Expected table cell to be inside of table row.");
21761
+ }
21762
+ for (let r = 0; r < tableRows.length; r++) {
21763
+ const tableRow2 = tableRows[r];
21764
+ if (!$isTableRowNode(tableRow2)) {
21765
+ throw new Error("Expected table row");
21732
21766
  }
21733
- ) : null
21734
- ] }) : null,
21735
- visibleElementsWithIcons.size > 0 || customControls ? /* @__PURE__ */ jsxs86("div", { css: toolbarGroup, children: [
21736
- linkElementVisible ? /* @__PURE__ */ jsx130(Tooltip, { title: "Link", placement: "top", children: /* @__PURE__ */ jsx130(
21737
- "button",
21738
- {
21739
- onClick: () => {
21740
- isLink ? editor.dispatchCommand(REMOVE_LINK_NODE_COMMAND, {}) : editor.dispatchCommand(OPEN_LINK_NODE_MODAL_COMMAND, {});
21741
- },
21742
- css: [richTextToolbarButton, isLink ? richTextToolbarButtonActive : null],
21743
- children: /* @__PURE__ */ jsx130(RichTextToolbarIcon, { icon: "link" })
21767
+ const tableCells = tableRow2.getChildren();
21768
+ if (tableColumnIndex >= tableCells.length) {
21769
+ continue;
21744
21770
  }
21745
- ) }) : null,
21746
- visibleLists.size > 0 ? /* @__PURE__ */ jsxs86(Fragment19, { children: [
21747
- visibleLists.has("unorderedList") ? /* @__PURE__ */ jsx130(Tooltip, { title: "Bullet List", placement: "top", children: /* @__PURE__ */ jsx130(
21748
- "button",
21771
+ const tableCell = tableCells[tableColumnIndex];
21772
+ if (!$isTableCellNode(tableCell)) {
21773
+ throw new Error("Expected table cell");
21774
+ }
21775
+ tableCell.toggleHeaderStyle(TableCellHeaderStates.COLUMN);
21776
+ }
21777
+ clearTableSelection();
21778
+ });
21779
+ }, [editor, tableCellNode, clearTableSelection]);
21780
+ const menuItemCss = css98({
21781
+ fontSize: "var(--fs-sm)"
21782
+ });
21783
+ return /* @__PURE__ */ jsxs86(
21784
+ Menu,
21785
+ {
21786
+ menuTrigger: /* @__PURE__ */ jsx130(
21787
+ TableActionMenuTrigger,
21788
+ {
21789
+ tableCellEl,
21790
+ positioningAnchorEl
21791
+ },
21792
+ menuTriggerKey
21793
+ ),
21794
+ portalElement: menuPortalEl,
21795
+ maxMenuHeight: "300px",
21796
+ children: [
21797
+ /* @__PURE__ */ jsxs86(
21798
+ MenuItem,
21749
21799
  {
21750
21800
  onClick: () => {
21751
- activeElement === "unorderedList" ? editor.dispatchCommand(REMOVE_LIST_COMMAND, void 0) : editor.dispatchCommand(INSERT_UNORDERED_LIST_COMMAND, void 0);
21801
+ insertTableRowAtSelection(false);
21752
21802
  },
21753
- css: [
21754
- richTextToolbarButton,
21755
- activeElement === "unorderedList" ? richTextToolbarButtonActive : null
21756
- ],
21757
- children: /* @__PURE__ */ jsx130(RichTextToolbarIcon, { icon: "layout-list" })
21803
+ css: menuItemCss,
21804
+ children: [
21805
+ "Insert ",
21806
+ selectionCounts.rows === 1 ? "row" : `${selectionCounts.rows} rows`,
21807
+ " above"
21808
+ ]
21758
21809
  }
21759
- ) }) : null,
21760
- visibleLists.has("orderedList") ? /* @__PURE__ */ jsx130(Tooltip, { title: "Ordered List", placement: "top", children: /* @__PURE__ */ jsx130(
21761
- "button",
21762
- {
21763
- onClick: () => {
21764
- activeElement === "orderedList" ? editor.dispatchCommand(REMOVE_LIST_COMMAND, void 0) : editor.dispatchCommand(INSERT_ORDERED_LIST_COMMAND, void 0);
21765
- },
21766
- css: [
21767
- richTextToolbarButton,
21768
- activeElement === "orderedList" ? richTextToolbarButtonActive : null
21769
- ],
21770
- children: /* @__PURE__ */ jsx130(RichTextToolbarIcon, { icon: "layout-list-numbered" })
21771
- }
21772
- ) }) : null
21773
- ] }) : null,
21774
- customControls ? customControls : null
21775
- ] }) : null,
21776
- visibleInsertElementsWithIcons.size > 0 ? /* @__PURE__ */ jsx130("div", { css: toolbarGroup, children: /* @__PURE__ */ jsxs86(
21777
- Menu,
21778
- {
21779
- menuTrigger: /* @__PURE__ */ jsxs86("button", { css: richTextToolbarButton, title: "Insert block element", children: [
21780
- "Insert",
21781
- /* @__PURE__ */ jsx130(Icon, { icon: "chevron-down", css: [toolbarIcon, toolbarChevron], size: "1rem" })
21810
+ ),
21811
+ /* @__PURE__ */ jsxs86(MenuItem, { onClick: () => insertTableRowAtSelection(true), css: menuItemCss, children: [
21812
+ "Insert ",
21813
+ selectionCounts.rows === 1 ? "row" : `${selectionCounts.rows} rows`,
21814
+ " below"
21782
21815
  ] }),
21783
- placement: "bottom-start",
21784
- children: [
21785
- quoteElementVisible ? /* @__PURE__ */ jsx130(
21786
- MenuItem,
21787
- {
21788
- onClick: () => {
21789
- onSelectElement("quote");
21790
- },
21791
- icon: /* @__PURE__ */ jsx130(Icon, { icon: "quote", iconColor: "currentColor" }),
21792
- children: "Quote"
21793
- }
21794
- ) : null,
21795
- codeElementVisible ? /* @__PURE__ */ jsx130(
21796
- MenuItem,
21797
- {
21798
- onClick: () => {
21799
- onSelectElement("code");
21800
- },
21801
- icon: /* @__PURE__ */ jsx130(Icon, { icon: "code-slash", iconColor: "currentColor" }),
21802
- children: "Code"
21803
- }
21804
- ) : null,
21805
- tableElementVisible && onInsertTable !== void 0 ? /* @__PURE__ */ jsx130(
21806
- MenuItem,
21807
- {
21808
- onClick: () => {
21809
- onSelectElement("table");
21810
- },
21811
- icon: /* @__PURE__ */ jsx130(Icon, { icon: "view-grid", iconColor: "currentColor" }),
21812
- children: "Table"
21813
- }
21814
- ) : null
21815
- ]
21816
- }
21817
- ) }) : null
21818
- ] });
21819
- };
21820
- var RichTextToolbar_default = RichTextToolbar;
21821
- var useRichTextToolbarState = ({ config }) => {
21822
- var _a;
21823
- const enabledBuiltInFormats = useMemo6(() => {
21824
- return richTextBuiltInFormats.filter((format) => {
21825
- var _a2, _b;
21826
- return (_b = (_a2 = config == null ? void 0 : config.formatting) == null ? void 0 : _a2.builtIn) == null ? void 0 : _b.includes(format.type);
21827
- });
21828
- }, [config]);
21829
- const enabledBuiltInElements = useMemo6(() => {
21830
- return richTextBuiltInElements.filter((element) => {
21831
- var _a2, _b;
21832
- return (_b = (_a2 = config == null ? void 0 : config.elements) == null ? void 0 : _a2.builtIn) == null ? void 0 : _b.includes(element.type);
21833
- });
21834
- }, [config]);
21835
- const enabledBuiltInFormatsWithIcon = useMemo6(() => {
21836
- return enabledBuiltInFormats.filter((format) => FORMATS_WITH_ICON.has(format.type));
21837
- }, [enabledBuiltInFormats]);
21838
- const enabledBuiltInFormatsWithoutIcon = enabledBuiltInFormats.filter(
21839
- (format) => !FORMATS_WITH_ICON.has(format.type)
21840
- );
21841
- const [activeFormats, setActiveFormats] = useState17([]);
21842
- const visibleFormatsWithIcon = useMemo6(() => {
21843
- const visibleFormats = /* @__PURE__ */ new Set();
21844
- activeFormats.filter((type) => FORMATS_WITH_ICON.has(type)).forEach((type) => {
21845
- visibleFormats.add(type);
21846
- });
21847
- enabledBuiltInFormatsWithIcon.forEach((format) => {
21848
- visibleFormats.add(format.type);
21849
- });
21850
- return richTextBuiltInFormats.filter((format) => visibleFormats.has(format.type));
21851
- }, [activeFormats, enabledBuiltInFormatsWithIcon]);
21852
- const visibleFormatsWithoutIcon = useMemo6(() => {
21853
- const visibleFormats = /* @__PURE__ */ new Set();
21854
- activeFormats.filter((type) => !FORMATS_WITH_ICON.has(type)).forEach((type) => {
21855
- visibleFormats.add(type);
21856
- });
21857
- enabledBuiltInFormatsWithoutIcon.forEach((format) => {
21858
- visibleFormats.add(format.type);
21859
- });
21860
- return richTextBuiltInFormats.filter((format) => visibleFormats.has(format.type));
21861
- }, [activeFormats, enabledBuiltInFormatsWithoutIcon]);
21862
- const [activeElement, setActiveElement] = useState17("paragraph");
21863
- const enabledTextualElements = enabledBuiltInElements.filter(
21864
- (element) => TEXTUAL_ELEMENTS.includes(element.type)
21816
+ /* @__PURE__ */ jsx130(MenuItemSeparator, {}),
21817
+ /* @__PURE__ */ jsxs86(MenuItem, { onClick: () => insertTableColumnAtSelection(false), css: menuItemCss, children: [
21818
+ "Insert ",
21819
+ selectionCounts.columns === 1 ? "column" : `${selectionCounts.columns} columns`,
21820
+ " left"
21821
+ ] }),
21822
+ /* @__PURE__ */ jsxs86(MenuItem, { onClick: () => insertTableColumnAtSelection(true), css: menuItemCss, children: [
21823
+ "Insert ",
21824
+ selectionCounts.columns === 1 ? "column" : `${selectionCounts.columns} columns`,
21825
+ " right"
21826
+ ] }),
21827
+ /* @__PURE__ */ jsx130(MenuItemSeparator, {}),
21828
+ /* @__PURE__ */ jsx130(MenuItem, { onClick: () => deleteTableColumnAtSelection(), css: menuItemCss, children: "Delete column" }),
21829
+ /* @__PURE__ */ jsx130(MenuItem, { onClick: () => deleteTableRowAtSelection(), css: menuItemCss, children: "Delete row" }),
21830
+ /* @__PURE__ */ jsx130(MenuItem, { onClick: () => deleteTableAtSelection(), css: menuItemCss, children: "Delete table" }),
21831
+ /* @__PURE__ */ jsx130(MenuItemSeparator, {}),
21832
+ /* @__PURE__ */ jsxs86(MenuItem, { onClick: () => toggleTableRowIsHeader(), css: menuItemCss, children: [
21833
+ (tableCellNode.__headerState & TableCellHeaderStates.ROW) === TableCellHeaderStates.ROW ? "Remove" : "Add",
21834
+ " ",
21835
+ "row header"
21836
+ ] }),
21837
+ /* @__PURE__ */ jsxs86(MenuItem, { onClick: () => toggleTableColumnIsHeader(), css: menuItemCss, children: [
21838
+ (tableCellNode.__headerState & TableCellHeaderStates.COLUMN) === TableCellHeaderStates.COLUMN ? "Remove" : "Add",
21839
+ " ",
21840
+ "column header"
21841
+ ] })
21842
+ ]
21843
+ }
21865
21844
  );
21866
- const visibleTextualElements = useMemo6(() => {
21867
- if (!TEXTUAL_ELEMENTS.includes(activeElement)) {
21868
- return enabledTextualElements;
21845
+ }
21846
+ function TableCellActionMenuContainer({
21847
+ menuPortalEl,
21848
+ positioningAnchorEl
21849
+ }) {
21850
+ const [editor] = useLexicalComposerContext5();
21851
+ const [tableCellNode, setTableMenuCellNode] = useState17(null);
21852
+ const [tableCellNodeEl, _setTableMenuCellNodeEl] = useState17(null);
21853
+ const [tableCellMenuPortalEl, setTableMenuCellMenuPortalEl] = useState17(null);
21854
+ useEffect21(() => {
21855
+ const newPortalEl = document.createElement("div");
21856
+ setTableMenuCellMenuPortalEl(newPortalEl);
21857
+ menuPortalEl.appendChild(newPortalEl);
21858
+ return () => {
21859
+ newPortalEl.remove();
21860
+ };
21861
+ }, [menuPortalEl]);
21862
+ const setTableMenuCellNodeElem = useCallback11((elem) => {
21863
+ if (elem) {
21864
+ _setTableMenuCellNodeEl(elem);
21865
+ } else {
21866
+ _setTableMenuCellNodeEl(null);
21869
21867
  }
21870
- return richTextBuiltInElements.filter(
21871
- (element) => {
21872
- var _a2, _b;
21873
- return TEXTUAL_ELEMENTS.includes(element.type) && (((_b = (_a2 = config == null ? void 0 : config.elements) == null ? void 0 : _a2.builtIn) == null ? void 0 : _b.includes(element.type)) || element.type === activeElement);
21868
+ }, []);
21869
+ const $moveMenu = useCallback11(() => {
21870
+ const selection = $getSelection3();
21871
+ const nativeSelection = window.getSelection();
21872
+ const activeElement = document.activeElement;
21873
+ if (selection == null) {
21874
+ setTableMenuCellNode(null);
21875
+ return;
21876
+ }
21877
+ const rootElement = editor.getRootElement();
21878
+ if ($isRangeSelection3(selection) && rootElement !== null && nativeSelection !== null && rootElement.contains(nativeSelection.anchorNode)) {
21879
+ const tableCellNodeFromSelection = $getTableCellNodeFromLexicalNode(selection.anchor.getNode());
21880
+ if (tableCellNodeFromSelection == null) {
21881
+ setTableMenuCellNode(null);
21882
+ setTableMenuCellNodeElem(null);
21883
+ return;
21874
21884
  }
21875
- );
21876
- }, [activeElement, (_a = config == null ? void 0 : config.elements) == null ? void 0 : _a.builtIn, enabledTextualElements]);
21877
- const [isLink, setIsLink] = useState17(false);
21878
- const linkElementVisible = useMemo6(() => {
21879
- return enabledBuiltInElements.some((element) => element.type === "link") || isLink;
21880
- }, [isLink, enabledBuiltInElements]);
21881
- const visibleLists = useMemo6(() => {
21882
- return new Set(
21883
- ["orderedList", "unorderedList"].filter(
21884
- (type) => enabledBuiltInElements.some((element) => element.type === type) || activeElement === type
21885
- )
21886
- );
21887
- }, [activeElement, enabledBuiltInElements]);
21888
- const quoteElementVisible = useMemo6(() => {
21889
- return enabledBuiltInElements.some((element) => element.type === "quote") || activeElement === "quote";
21890
- }, [activeElement, enabledBuiltInElements]);
21891
- const codeElementVisible = useMemo6(() => {
21892
- return enabledBuiltInElements.some((element) => element.type === "code") || activeElement === "code";
21893
- }, [activeElement, enabledBuiltInElements]);
21894
- const tableElementVisible = useMemo6(() => {
21895
- return enabledBuiltInElements.some((element) => element.type === "table") || activeElement === "table";
21896
- }, [activeElement, enabledBuiltInElements]);
21897
- const visibleElementsWithIcons = useMemo6(() => {
21898
- const visibleElements = /* @__PURE__ */ new Set();
21899
- if (linkElementVisible) {
21900
- visibleElements.add("link");
21885
+ const tableCellParentNodeDOM = editor.getElementByKey(tableCellNodeFromSelection.getKey());
21886
+ if (tableCellParentNodeDOM == null) {
21887
+ setTableMenuCellNode(null);
21888
+ setTableMenuCellNodeElem(null);
21889
+ return;
21890
+ }
21891
+ setTableMenuCellNode(tableCellNodeFromSelection);
21892
+ setTableMenuCellNodeElem(tableCellParentNodeDOM);
21893
+ } else if (!activeElement) {
21894
+ setTableMenuCellNode(null);
21895
+ setTableMenuCellNodeElem(null);
21901
21896
  }
21902
- if (visibleLists.size > 0) {
21903
- visibleLists.forEach((type) => {
21904
- visibleElements.add(type);
21897
+ }, [editor, setTableMenuCellNodeElem]);
21898
+ useEffect21(() => {
21899
+ return editor.registerUpdateListener(() => {
21900
+ editor.getEditorState().read(() => {
21901
+ $moveMenu();
21905
21902
  });
21906
- }
21907
- return visibleElements;
21908
- }, [linkElementVisible, visibleLists]);
21909
- const visibleInsertElementsWithIcons = useMemo6(() => {
21910
- const visibleElements = /* @__PURE__ */ new Set();
21911
- if (quoteElementVisible) {
21912
- visibleElements.add("quote");
21913
- }
21914
- if (codeElementVisible) {
21915
- visibleElements.add("code");
21916
- }
21917
- if (tableElementVisible) {
21918
- visibleElements.add("table");
21919
- }
21920
- return visibleElements;
21921
- }, [codeElementVisible, quoteElementVisible, tableElementVisible]);
21922
- return {
21923
- activeFormats,
21924
- setActiveFormats,
21925
- activeElement,
21926
- setActiveElement,
21927
- visibleFormatsWithIcon,
21928
- visibleFormatsWithoutIcon,
21929
- visibleTextualElements,
21930
- isLink,
21931
- setIsLink,
21932
- linkElementVisible,
21933
- visibleLists,
21934
- quoteElementVisible,
21935
- codeElementVisible,
21936
- tableElementVisible,
21937
- visibleElementsWithIcons,
21938
- visibleInsertElementsWithIcons
21939
- };
21940
- };
21903
+ });
21904
+ });
21905
+ return tableCellNode != null && tableCellNodeEl != null && tableCellMenuPortalEl != null && /* @__PURE__ */ jsx130(
21906
+ TableActionMenu,
21907
+ {
21908
+ tableCellNode,
21909
+ menuPortalEl: tableCellMenuPortalEl,
21910
+ tableCellEl: tableCellNodeEl,
21911
+ positioningAnchorEl
21912
+ },
21913
+ tableCellNode.getKey()
21914
+ );
21915
+ }
21916
+ function TableActionMenuPlugin({
21917
+ positioningAnchorEl,
21918
+ menuPortalEl
21919
+ }) {
21920
+ const isEditable = useLexicalEditable();
21921
+ return isEditable ? /* @__PURE__ */ jsx130(TableCellActionMenuContainer, { menuPortalEl, positioningAnchorEl }) : null;
21922
+ }
21941
21923
 
21942
- // src/components/ParameterInputs/rich-text/TableActionMenuPlugin.tsx
21924
+ // src/components/ParameterInputs/rich-text/TableCellResizerPlugin.tsx
21943
21925
  import { css as css99 } from "@emotion/react";
21944
- import { useLexicalComposerContext as useLexicalComposerContext5 } from "@lexical/react/LexicalComposerContext";
21945
- import { useLexicalEditable } from "@lexical/react/useLexicalEditable";
21926
+ import { useLexicalComposerContext as useLexicalComposerContext6 } from "@lexical/react/LexicalComposerContext";
21927
+ import { useLexicalEditable as useLexicalEditable2 } from "@lexical/react/useLexicalEditable";
21946
21928
  import {
21947
- $deleteTableColumn__EXPERIMENTAL,
21948
- $deleteTableRow__EXPERIMENTAL,
21949
- $getTableCellNodeFromLexicalNode,
21950
- $getTableColumnIndexFromTableCellNode,
21951
- $getTableNodeFromLexicalNodeOrThrow,
21952
- $getTableRowIndexFromTableCellNode,
21953
- $insertTableColumn__EXPERIMENTAL,
21954
- $insertTableRow__EXPERIMENTAL,
21955
- $isTableCellNode,
21956
- $isTableRowNode,
21957
- $isTableSelection,
21958
- getTableObserverFromTableElement,
21959
- TableCellHeaderStates,
21960
- TableCellNode
21961
- } from "@lexical/table";
21962
- import { $getRoot, $getSelection as $getSelection4, $isRangeSelection as $isRangeSelection4 } from "lexical";
21963
- import { forwardRef as forwardRef22, useCallback as useCallback12, useEffect as useEffect21, useLayoutEffect, useState as useState18 } from "react";
21964
- import { jsx as jsx131, jsxs as jsxs87 } from "@emotion/react/jsx-runtime";
21965
- function computeSelectionCount(selection) {
21966
- const selectionShape = selection.getShape();
21967
- return {
21968
- columns: selectionShape.toX - selectionShape.fromX + 1,
21969
- rows: selectionShape.toY - selectionShape.fromY + 1
21970
- };
21971
- }
21972
- var tableActionMenuTrigger = css99`
21929
+ $computeTableMapSkipCellCheck,
21930
+ $getTableNodeFromLexicalNodeOrThrow as $getTableNodeFromLexicalNodeOrThrow2,
21931
+ $getTableRowIndexFromTableCellNode as $getTableRowIndexFromTableCellNode2,
21932
+ $isTableCellNode as $isTableCellNode2,
21933
+ $isTableRowNode as $isTableRowNode2
21934
+ } from "@lexical/table";
21935
+ import { calculateZoomLevel } from "@lexical/utils";
21936
+ import { $getNearestNodeFromDOMNode } from "lexical";
21937
+ import { useCallback as useCallback12, useEffect as useEffect22, useMemo as useMemo6, useRef as useRef13, useState as useState18 } from "react";
21938
+ import { createPortal as createPortal3 } from "react-dom";
21939
+ import { Fragment as Fragment19, jsx as jsx131, jsxs as jsxs87 } from "@emotion/react/jsx-runtime";
21940
+ var MIN_ROW_HEIGHT = 33;
21941
+ var MIN_COLUMN_WIDTH = 50;
21942
+ var tableResizer = css99`
21973
21943
  position: absolute;
21974
- transform: translate(calc(-100% - 1px), 1px);
21944
+ z-index: var(--z-10);
21975
21945
  `;
21976
- var TableActionMenuTrigger = forwardRef22((props, ref) => {
21977
- const { tableCellEl, positioningAnchorEl, ...rest } = props;
21978
- const [coordinates, setCoordinates] = useState18({ x: 0, y: 0 });
21979
- useLayoutEffect(() => {
21980
- const rect = tableCellEl.getBoundingClientRect();
21981
- const parentRect = positioningAnchorEl.getBoundingClientRect();
21982
- const relativeX = rect.right - parentRect.left + positioningAnchorEl.scrollLeft;
21983
- const relativeY = rect.top - parentRect.top + positioningAnchorEl.scrollTop;
21984
- setCoordinates({ x: relativeX, y: relativeY });
21985
- }, [tableCellEl, positioningAnchorEl]);
21986
- return /* @__PURE__ */ jsx131(
21987
- IconButton,
21988
- {
21989
- ref,
21990
- css: [
21991
- tableActionMenuTrigger,
21992
- {
21993
- top: coordinates.y,
21994
- left: coordinates.x
21995
- }
21996
- ],
21997
- size: "xs",
21998
- buttonType: "unimportant",
21999
- ...rest,
22000
- children: /* @__PURE__ */ jsx131(Icon, { icon: "chevron-down", size: "1rem", iconColor: "currentColor" })
21946
+ var fixedGetDOMCellFromTarget = (node) => {
21947
+ let currentNode = node;
21948
+ while (currentNode != null) {
21949
+ const nodeName = currentNode.nodeName;
21950
+ if (nodeName === "TD" || nodeName === "TH") {
21951
+ const cell2 = currentNode._cell;
21952
+ if (cell2 === void 0) {
21953
+ return {
21954
+ elem: currentNode
21955
+ };
21956
+ }
21957
+ return cell2;
22001
21958
  }
22002
- );
22003
- });
22004
- TableActionMenuTrigger.displayName = "TableActionMenuTrigger";
22005
- function TableActionMenu({
22006
- tableCellNode: _tableCellNode,
22007
- menuPortalEl,
22008
- tableCellEl,
22009
- positioningAnchorEl
22010
- }) {
22011
- const [editor] = useLexicalComposerContext5();
22012
- const [tableCellNode, updateTableCellNode] = useState18(_tableCellNode);
22013
- const [selectionCounts, updateSelectionCounts] = useState18({
22014
- columns: 1,
22015
- rows: 1
22016
- });
22017
- const [menuTriggerKey, setMenuTriggerKey] = useState18(0);
22018
- const incrementMenuTriggerKey = () => {
22019
- setMenuTriggerKey((key) => key += 1);
21959
+ currentNode = currentNode.parentNode;
21960
+ }
21961
+ return null;
21962
+ };
21963
+ function TableCellResizer({ editor, positioningAnchorEl }) {
21964
+ const targetRef = useRef13(null);
21965
+ const resizerRef = useRef13(null);
21966
+ const tableRectRef = useRef13(null);
21967
+ const mouseStartPosRef = useRef13(null);
21968
+ const [mouseCurrentPos, updateMouseCurrentPos] = useState18(null);
21969
+ const [activeCell, updateActiveCell] = useState18(null);
21970
+ const [isMouseDown, updateIsMouseDown] = useState18(false);
21971
+ const [draggingDirection, updateDraggingDirection] = useState18(null);
21972
+ const resetState = useCallback12(() => {
21973
+ updateActiveCell(null);
21974
+ targetRef.current = null;
21975
+ updateDraggingDirection(null);
21976
+ mouseStartPosRef.current = null;
21977
+ tableRectRef.current = null;
21978
+ }, []);
21979
+ const isMouseDownOnEvent = (event) => {
21980
+ return (event.buttons & 1) === 1;
22020
21981
  };
22021
- useEffect21(() => {
22022
- return editor.registerMutationListener(
22023
- TableCellNode,
22024
- (nodeMutations) => {
22025
- const nodeUpdated = nodeMutations.get(tableCellNode.getKey()) === "updated";
22026
- if (nodeUpdated) {
22027
- editor.getEditorState().read(() => {
22028
- updateTableCellNode(tableCellNode.getLatest());
21982
+ useEffect22(() => {
21983
+ const onMouseMove = (event) => {
21984
+ setTimeout(() => {
21985
+ const target = event.target;
21986
+ if (draggingDirection) {
21987
+ updateMouseCurrentPos({
21988
+ x: event.clientX,
21989
+ y: event.clientY
22029
21990
  });
21991
+ return;
22030
21992
  }
22031
- },
22032
- { skipInitialization: true }
22033
- );
22034
- }, [editor, tableCellNode]);
22035
- useEffect21(() => {
22036
- editor.getEditorState().read(() => {
22037
- const selection = $getSelection4();
22038
- if ($isTableSelection(selection)) {
22039
- updateSelectionCounts(computeSelectionCount(selection));
22040
- }
22041
- });
22042
- }, [editor]);
22043
- const clearTableSelection = useCallback12(() => {
22044
- editor.update(() => {
22045
- if (tableCellNode.isAttached()) {
22046
- const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
22047
- const tableElement2 = editor.getElementByKey(
22048
- tableNode.getKey()
22049
- );
22050
- if (!tableElement2) {
22051
- throw new Error("Expected to find tableElement in DOM");
21993
+ updateIsMouseDown(isMouseDownOnEvent(event));
21994
+ if (resizerRef.current && resizerRef.current.contains(target)) {
21995
+ return;
22052
21996
  }
22053
- const tableSelection = getTableObserverFromTableElement(tableElement2);
22054
- if (tableSelection !== null) {
22055
- tableSelection.clearHighlight();
21997
+ if (targetRef.current !== target) {
21998
+ targetRef.current = target;
21999
+ const cell2 = fixedGetDOMCellFromTarget(target);
22000
+ if (cell2 && activeCell !== cell2) {
22001
+ editor.update(() => {
22002
+ const tableCellNode = $getNearestNodeFromDOMNode(cell2.elem);
22003
+ if (!tableCellNode) {
22004
+ throw new Error("TableCellResizer: Table cell node not found.");
22005
+ }
22006
+ const tableNode = $getTableNodeFromLexicalNodeOrThrow2(tableCellNode);
22007
+ const tableElement2 = editor.getElementByKey(tableNode.getKey());
22008
+ if (!tableElement2) {
22009
+ throw new Error("TableCellResizer: Table element not found.");
22010
+ }
22011
+ targetRef.current = target;
22012
+ tableRectRef.current = tableElement2.getBoundingClientRect();
22013
+ updateActiveCell(cell2);
22014
+ });
22015
+ } else if (cell2 == null) {
22016
+ resetState();
22017
+ }
22056
22018
  }
22057
- tableNode.markDirty();
22058
- updateTableCellNode(tableCellNode.getLatest());
22059
- }
22060
- const rootNode = $getRoot();
22061
- rootNode.selectStart();
22019
+ }, 0);
22020
+ };
22021
+ const onMouseDown = () => {
22022
+ setTimeout(() => {
22023
+ updateIsMouseDown(true);
22024
+ }, 0);
22025
+ };
22026
+ const onMouseUp = () => {
22027
+ setTimeout(() => {
22028
+ updateIsMouseDown(false);
22029
+ }, 0);
22030
+ };
22031
+ const removeRootListener = editor.registerRootListener((rootElement, prevRootElement) => {
22032
+ rootElement == null ? void 0 : rootElement.addEventListener("mousemove", onMouseMove);
22033
+ rootElement == null ? void 0 : rootElement.addEventListener("mousedown", onMouseDown);
22034
+ rootElement == null ? void 0 : rootElement.addEventListener("mouseup", onMouseUp);
22035
+ prevRootElement == null ? void 0 : prevRootElement.removeEventListener("mousemove", onMouseMove);
22036
+ prevRootElement == null ? void 0 : prevRootElement.removeEventListener("mousedown", onMouseDown);
22037
+ prevRootElement == null ? void 0 : prevRootElement.removeEventListener("mouseup", onMouseUp);
22062
22038
  });
22063
- }, [editor, tableCellNode]);
22064
- const insertTableRowAtSelection = useCallback12(
22065
- (shouldInsertAfter) => {
22066
- editor.update(() => {
22067
- $insertTableRow__EXPERIMENTAL(shouldInsertAfter);
22068
- });
22069
- incrementMenuTriggerKey();
22039
+ return () => {
22040
+ removeRootListener();
22041
+ };
22042
+ }, [activeCell, draggingDirection, editor, resetState]);
22043
+ const isHeightChanging = (direction) => {
22044
+ if (direction === "bottom") {
22045
+ return true;
22046
+ }
22047
+ return false;
22048
+ };
22049
+ const updateRowHeight = useCallback12(
22050
+ (heightChange) => {
22051
+ if (!activeCell) {
22052
+ throw new Error("TableCellResizer: Expected active cell.");
22053
+ }
22054
+ editor.update(
22055
+ () => {
22056
+ const tableCellNode = $getNearestNodeFromDOMNode(activeCell.elem);
22057
+ if (!$isTableCellNode2(tableCellNode)) {
22058
+ throw new Error("TableCellResizer: Table cell node not found.");
22059
+ }
22060
+ const tableNode = $getTableNodeFromLexicalNodeOrThrow2(tableCellNode);
22061
+ const tableRowIndex = $getTableRowIndexFromTableCellNode2(tableCellNode);
22062
+ const tableRows = tableNode.getChildren();
22063
+ if (tableRowIndex >= tableRows.length || tableRowIndex < 0) {
22064
+ throw new Error("Expected table cell to be inside of table row.");
22065
+ }
22066
+ const tableRow2 = tableRows[tableRowIndex];
22067
+ if (!$isTableRowNode2(tableRow2)) {
22068
+ throw new Error("Expected table row");
22069
+ }
22070
+ let height = tableRow2.getHeight();
22071
+ if (height === void 0) {
22072
+ const rowCells = tableRow2.getChildren();
22073
+ height = Math.min(...rowCells.map((cell2) => {
22074
+ var _a;
22075
+ return (_a = getCellNodeHeight(cell2, editor)) != null ? _a : Infinity;
22076
+ }));
22077
+ }
22078
+ const newHeight = Math.max(height + heightChange, MIN_ROW_HEIGHT);
22079
+ tableRow2.setHeight(newHeight);
22080
+ },
22081
+ { tag: "skip-scroll-into-view" }
22082
+ );
22070
22083
  },
22071
- [editor]
22084
+ [activeCell, editor]
22072
22085
  );
22073
- const insertTableColumnAtSelection = useCallback12(
22074
- (shouldInsertAfter) => {
22075
- editor.update(() => {
22076
- for (let i = 0; i < selectionCounts.columns; i++) {
22077
- $insertTableColumn__EXPERIMENTAL(shouldInsertAfter);
22086
+ const getCellNodeWidth = (cell2, activeEditor) => {
22087
+ const width = cell2.getWidth();
22088
+ if (width !== void 0) {
22089
+ return width;
22090
+ }
22091
+ const domCellNode = activeEditor.getElementByKey(cell2.getKey());
22092
+ if (domCellNode == null) {
22093
+ return void 0;
22094
+ }
22095
+ const computedStyle = getComputedStyle(domCellNode);
22096
+ return domCellNode.clientWidth - parseFloat(computedStyle.paddingLeft) - parseFloat(computedStyle.paddingRight);
22097
+ };
22098
+ const getCellNodeHeight = (cell2, activeEditor) => {
22099
+ const domCellNode = activeEditor.getElementByKey(cell2.getKey());
22100
+ return domCellNode == null ? void 0 : domCellNode.clientHeight;
22101
+ };
22102
+ const getCellColumnIndex = (tableCellNode, tableMap) => {
22103
+ for (let row = 0; row < tableMap.length; row++) {
22104
+ for (let column = 0; column < tableMap[row].length; column++) {
22105
+ if (tableMap[row][column].cell === tableCellNode) {
22106
+ return column;
22078
22107
  }
22079
- });
22080
- incrementMenuTriggerKey();
22081
- },
22082
- [editor, selectionCounts.columns]
22083
- );
22084
- const deleteTableRowAtSelection = useCallback12(() => {
22085
- editor.update(() => {
22086
- $deleteTableRow__EXPERIMENTAL();
22087
- });
22088
- incrementMenuTriggerKey();
22089
- }, [editor]);
22090
- const deleteTableAtSelection = useCallback12(() => {
22091
- editor.update(() => {
22092
- const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
22093
- tableNode.remove();
22094
- clearTableSelection();
22095
- });
22096
- }, [editor, tableCellNode, clearTableSelection]);
22097
- const deleteTableColumnAtSelection = useCallback12(() => {
22098
- editor.update(() => {
22099
- $deleteTableColumn__EXPERIMENTAL();
22100
- });
22101
- incrementMenuTriggerKey();
22102
- }, [editor]);
22103
- const toggleTableRowIsHeader = useCallback12(() => {
22104
- editor.update(() => {
22105
- const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
22106
- const tableRowIndex = $getTableRowIndexFromTableCellNode(tableCellNode);
22107
- const tableRows = tableNode.getChildren();
22108
- if (tableRowIndex >= tableRows.length || tableRowIndex < 0) {
22109
- throw new Error("Expected table cell to be inside of table row.");
22110
22108
  }
22111
- const tableRow2 = tableRows[tableRowIndex];
22112
- if (!$isTableRowNode(tableRow2)) {
22113
- throw new Error("Expected table row");
22109
+ }
22110
+ };
22111
+ const updateColumnWidth = useCallback12(
22112
+ (widthChange) => {
22113
+ if (!activeCell) {
22114
+ throw new Error("TableCellResizer: Expected active cell.");
22114
22115
  }
22115
- tableRow2.getChildren().forEach((tableCell) => {
22116
- if (!$isTableCellNode(tableCell)) {
22117
- throw new Error("Expected table cell");
22116
+ editor.update(
22117
+ () => {
22118
+ const tableCellNode = $getNearestNodeFromDOMNode(activeCell.elem);
22119
+ if (!$isTableCellNode2(tableCellNode)) {
22120
+ throw new Error("TableCellResizer: Table cell node not found.");
22121
+ }
22122
+ const tableNode = $getTableNodeFromLexicalNodeOrThrow2(tableCellNode);
22123
+ const [tableMap] = $computeTableMapSkipCellCheck(tableNode, null, null);
22124
+ const columnIndex = getCellColumnIndex(tableCellNode, tableMap);
22125
+ if (columnIndex === void 0) {
22126
+ throw new Error("TableCellResizer: Table column not found.");
22127
+ }
22128
+ for (let row = 0; row < tableMap.length; row++) {
22129
+ const cell2 = tableMap[row][columnIndex];
22130
+ if (cell2.startRow === row && (columnIndex === tableMap[row].length - 1 || tableMap[row][columnIndex].cell !== tableMap[row][columnIndex + 1].cell)) {
22131
+ const width = getCellNodeWidth(cell2.cell, editor);
22132
+ if (width === void 0) {
22133
+ continue;
22134
+ }
22135
+ const newWidth = Math.max(width + widthChange, MIN_COLUMN_WIDTH);
22136
+ cell2.cell.setWidth(newWidth);
22137
+ }
22138
+ }
22139
+ },
22140
+ { tag: "skip-scroll-into-view" }
22141
+ );
22142
+ },
22143
+ [activeCell, editor]
22144
+ );
22145
+ const mouseUpHandler = useCallback12(
22146
+ (direction) => {
22147
+ const handler = (event) => {
22148
+ event.preventDefault();
22149
+ event.stopPropagation();
22150
+ if (!activeCell) {
22151
+ throw new Error("TableCellResizer: Expected active cell.");
22118
22152
  }
22119
- tableCell.toggleHeaderStyle(TableCellHeaderStates.ROW);
22120
- });
22121
- clearTableSelection();
22122
- });
22123
- }, [editor, tableCellNode, clearTableSelection]);
22124
- const toggleTableColumnIsHeader = useCallback12(() => {
22125
- editor.update(() => {
22126
- const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
22127
- const tableColumnIndex = $getTableColumnIndexFromTableCellNode(tableCellNode);
22128
- const tableRows = tableNode.getChildren();
22129
- const maxRowsLength = Math.max(...tableRows.map((row) => row.getChildren().length));
22130
- if (tableColumnIndex >= maxRowsLength || tableColumnIndex < 0) {
22131
- throw new Error("Expected table cell to be inside of table row.");
22132
- }
22133
- for (let r = 0; r < tableRows.length; r++) {
22134
- const tableRow2 = tableRows[r];
22135
- if (!$isTableRowNode(tableRow2)) {
22136
- throw new Error("Expected table row");
22153
+ if (mouseStartPosRef.current) {
22154
+ const { x, y } = mouseStartPosRef.current;
22155
+ if (activeCell === null) {
22156
+ return;
22157
+ }
22158
+ const zoom = calculateZoomLevel(event.target);
22159
+ if (isHeightChanging(direction)) {
22160
+ const heightChange = (event.clientY - y) / zoom;
22161
+ updateRowHeight(heightChange);
22162
+ } else {
22163
+ const widthChange = (event.clientX - x) / zoom;
22164
+ updateColumnWidth(widthChange);
22165
+ }
22166
+ resetState();
22167
+ document.removeEventListener("mouseup", handler);
22137
22168
  }
22138
- const tableCells = tableRow2.getChildren();
22139
- if (tableColumnIndex >= tableCells.length) {
22140
- continue;
22169
+ };
22170
+ return handler;
22171
+ },
22172
+ [activeCell, resetState, updateColumnWidth, updateRowHeight]
22173
+ );
22174
+ const toggleResize = useCallback12(
22175
+ (direction) => (event) => {
22176
+ event.preventDefault();
22177
+ event.stopPropagation();
22178
+ if (!activeCell) {
22179
+ throw new Error("TableCellResizer: Expected active cell.");
22180
+ }
22181
+ mouseStartPosRef.current = {
22182
+ x: event.clientX,
22183
+ y: event.clientY
22184
+ };
22185
+ updateMouseCurrentPos(mouseStartPosRef.current);
22186
+ updateDraggingDirection(direction);
22187
+ document.addEventListener("mouseup", mouseUpHandler(direction));
22188
+ },
22189
+ [activeCell, mouseUpHandler]
22190
+ );
22191
+ const getResizers = useCallback12(() => {
22192
+ if (activeCell) {
22193
+ const { height, width, top, left } = activeCell.elem.getBoundingClientRect();
22194
+ const parentRect = positioningAnchorEl.getBoundingClientRect();
22195
+ const zoom = calculateZoomLevel(activeCell.elem);
22196
+ const zoneWidth = 10;
22197
+ const styles = {
22198
+ bottom: {
22199
+ backgroundColor: "none",
22200
+ cursor: "row-resize",
22201
+ height: `${zoneWidth}px`,
22202
+ left: `${left - parentRect.left}px`,
22203
+ top: `${top - parentRect.top + positioningAnchorEl.scrollTop + height - zoneWidth / 2}px`,
22204
+ width: `${width}px`
22205
+ },
22206
+ right: {
22207
+ backgroundColor: "none",
22208
+ cursor: "col-resize",
22209
+ height: `${height}px`,
22210
+ left: `${left - parentRect.left + width - zoneWidth / 2}px`,
22211
+ top: `${top - parentRect.top + positioningAnchorEl.scrollTop}px`,
22212
+ width: `${zoneWidth}px`
22141
22213
  }
22142
- const tableCell = tableCells[tableColumnIndex];
22143
- if (!$isTableCellNode(tableCell)) {
22144
- throw new Error("Expected table cell");
22214
+ };
22215
+ const tableRect = tableRectRef.current;
22216
+ if (draggingDirection && mouseCurrentPos && tableRect) {
22217
+ if (isHeightChanging(draggingDirection)) {
22218
+ styles[draggingDirection].left = `${tableRect.left - parentRect.left}px`;
22219
+ styles[draggingDirection].top = `${(mouseCurrentPos.y - parentRect.top + positioningAnchorEl.scrollTop) / zoom}px`;
22220
+ styles[draggingDirection].height = "3px";
22221
+ styles[draggingDirection].width = `${tableRect.width}px`;
22222
+ } else {
22223
+ styles[draggingDirection].top = `${tableRect.top - parentRect.top + positioningAnchorEl.scrollTop}px`;
22224
+ styles[draggingDirection].left = `${(mouseCurrentPos.x - parentRect.left) / zoom}px`;
22225
+ styles[draggingDirection].width = "3px";
22226
+ styles[draggingDirection].height = `${tableRect.height}px`;
22145
22227
  }
22146
- tableCell.toggleHeaderStyle(TableCellHeaderStates.COLUMN);
22228
+ styles[draggingDirection].backgroundColor = "#adf";
22147
22229
  }
22148
- clearTableSelection();
22149
- });
22150
- }, [editor, tableCellNode, clearTableSelection]);
22151
- const menuItemCss = css99({
22152
- fontSize: "var(--fs-sm)"
22153
- });
22154
- return /* @__PURE__ */ jsxs87(
22155
- Menu,
22156
- {
22157
- menuTrigger: /* @__PURE__ */ jsx131(
22158
- TableActionMenuTrigger,
22159
- {
22160
- tableCellEl,
22161
- positioningAnchorEl
22162
- },
22163
- menuTriggerKey
22164
- ),
22165
- portalElement: menuPortalEl,
22166
- maxMenuHeight: "300px",
22167
- children: [
22168
- /* @__PURE__ */ jsxs87(
22169
- MenuItem,
22170
- {
22171
- onClick: () => {
22172
- insertTableRowAtSelection(false);
22173
- },
22174
- css: menuItemCss,
22175
- children: [
22176
- "Insert ",
22177
- selectionCounts.rows === 1 ? "row" : `${selectionCounts.rows} rows`,
22178
- " above"
22179
- ]
22180
- }
22181
- ),
22182
- /* @__PURE__ */ jsxs87(MenuItem, { onClick: () => insertTableRowAtSelection(true), css: menuItemCss, children: [
22183
- "Insert ",
22184
- selectionCounts.rows === 1 ? "row" : `${selectionCounts.rows} rows`,
22185
- " below"
22186
- ] }),
22187
- /* @__PURE__ */ jsx131(MenuItemSeparator, {}),
22188
- /* @__PURE__ */ jsxs87(MenuItem, { onClick: () => insertTableColumnAtSelection(false), css: menuItemCss, children: [
22189
- "Insert ",
22190
- selectionCounts.columns === 1 ? "column" : `${selectionCounts.columns} columns`,
22191
- " left"
22192
- ] }),
22193
- /* @__PURE__ */ jsxs87(MenuItem, { onClick: () => insertTableColumnAtSelection(true), css: menuItemCss, children: [
22194
- "Insert ",
22195
- selectionCounts.columns === 1 ? "column" : `${selectionCounts.columns} columns`,
22196
- " right"
22197
- ] }),
22198
- /* @__PURE__ */ jsx131(MenuItemSeparator, {}),
22199
- /* @__PURE__ */ jsx131(MenuItem, { onClick: () => deleteTableColumnAtSelection(), css: menuItemCss, children: "Delete column" }),
22200
- /* @__PURE__ */ jsx131(MenuItem, { onClick: () => deleteTableRowAtSelection(), css: menuItemCss, children: "Delete row" }),
22201
- /* @__PURE__ */ jsx131(MenuItem, { onClick: () => deleteTableAtSelection(), css: menuItemCss, children: "Delete table" }),
22202
- /* @__PURE__ */ jsx131(MenuItemSeparator, {}),
22203
- /* @__PURE__ */ jsxs87(MenuItem, { onClick: () => toggleTableRowIsHeader(), css: menuItemCss, children: [
22204
- (tableCellNode.__headerState & TableCellHeaderStates.ROW) === TableCellHeaderStates.ROW ? "Remove" : "Add",
22205
- " ",
22206
- "row header"
22207
- ] }),
22208
- /* @__PURE__ */ jsxs87(MenuItem, { onClick: () => toggleTableColumnIsHeader(), css: menuItemCss, children: [
22209
- (tableCellNode.__headerState & TableCellHeaderStates.COLUMN) === TableCellHeaderStates.COLUMN ? "Remove" : "Add",
22210
- " ",
22211
- "column header"
22212
- ] })
22213
- ]
22230
+ return styles;
22214
22231
  }
22215
- );
22216
- }
22217
- function TableCellActionMenuContainer({
22218
- menuPortalEl,
22219
- positioningAnchorEl
22220
- }) {
22221
- const [editor] = useLexicalComposerContext5();
22222
- const [tableCellNode, setTableMenuCellNode] = useState18(null);
22223
- const [tableCellNodeEl, _setTableMenuCellNodeEl] = useState18(null);
22224
- const [tableCellMenuPortalEl, setTableMenuCellMenuPortalEl] = useState18(null);
22225
- useEffect21(() => {
22226
- const newPortalEl = document.createElement("div");
22227
- setTableMenuCellMenuPortalEl(newPortalEl);
22228
- menuPortalEl.appendChild(newPortalEl);
22229
- return () => {
22230
- newPortalEl.remove();
22232
+ return {
22233
+ bottom: null,
22234
+ left: null,
22235
+ right: null,
22236
+ top: null
22231
22237
  };
22232
- }, [menuPortalEl]);
22233
- const setTableMenuCellNodeElem = useCallback12((elem) => {
22234
- if (elem) {
22235
- _setTableMenuCellNodeEl(elem);
22236
- } else {
22237
- _setTableMenuCellNodeEl(null);
22238
- }
22239
- }, []);
22240
- const $moveMenu = useCallback12(() => {
22241
- const selection = $getSelection4();
22242
- const nativeSelection = window.getSelection();
22243
- const activeElement = document.activeElement;
22244
- if (selection == null) {
22245
- setTableMenuCellNode(null);
22246
- return;
22247
- }
22248
- const rootElement = editor.getRootElement();
22249
- if ($isRangeSelection4(selection) && rootElement !== null && nativeSelection !== null && rootElement.contains(nativeSelection.anchorNode)) {
22250
- const tableCellNodeFromSelection = $getTableCellNodeFromLexicalNode(selection.anchor.getNode());
22251
- if (tableCellNodeFromSelection == null) {
22252
- setTableMenuCellNode(null);
22253
- setTableMenuCellNodeElem(null);
22254
- return;
22238
+ }, [activeCell, draggingDirection, mouseCurrentPos, positioningAnchorEl]);
22239
+ const resizerStyles = getResizers();
22240
+ return /* @__PURE__ */ jsx131("div", { ref: resizerRef, children: activeCell != null && !isMouseDown && /* @__PURE__ */ jsxs87(Fragment19, { children: [
22241
+ /* @__PURE__ */ jsx131(
22242
+ "div",
22243
+ {
22244
+ css: tableResizer,
22245
+ style: resizerStyles.right || void 0,
22246
+ onMouseDown: toggleResize("right")
22255
22247
  }
22256
- const tableCellParentNodeDOM = editor.getElementByKey(tableCellNodeFromSelection.getKey());
22257
- if (tableCellParentNodeDOM == null) {
22258
- setTableMenuCellNode(null);
22259
- setTableMenuCellNodeElem(null);
22260
- return;
22248
+ ),
22249
+ /* @__PURE__ */ jsx131(
22250
+ "div",
22251
+ {
22252
+ css: tableResizer,
22253
+ style: resizerStyles.bottom || void 0,
22254
+ onMouseDown: toggleResize("bottom")
22261
22255
  }
22262
- setTableMenuCellNode(tableCellNodeFromSelection);
22263
- setTableMenuCellNodeElem(tableCellParentNodeDOM);
22264
- } else if (!activeElement) {
22265
- setTableMenuCellNode(null);
22266
- setTableMenuCellNodeElem(null);
22267
- }
22268
- }, [editor, setTableMenuCellNodeElem]);
22269
- useEffect21(() => {
22270
- return editor.registerUpdateListener(() => {
22271
- editor.getEditorState().read(() => {
22272
- $moveMenu();
22273
- });
22274
- });
22275
- });
22276
- return tableCellNode != null && tableCellNodeEl != null && tableCellMenuPortalEl != null && /* @__PURE__ */ jsx131(
22277
- TableActionMenu,
22278
- {
22279
- tableCellNode,
22280
- menuPortalEl: tableCellMenuPortalEl,
22281
- tableCellEl: tableCellNodeEl,
22256
+ )
22257
+ ] }) });
22258
+ }
22259
+ function TableCellResizerPlugin({ positioningAnchorEl }) {
22260
+ const [editor] = useLexicalComposerContext6();
22261
+ const isEditable = useLexicalEditable2();
22262
+ return useMemo6(
22263
+ () => isEditable ? createPortal3(
22264
+ /* @__PURE__ */ jsx131(TableCellResizer, { editor, positioningAnchorEl }),
22282
22265
  positioningAnchorEl
22283
- },
22284
- tableCellNode.getKey()
22266
+ ) : null,
22267
+ [editor, isEditable, positioningAnchorEl]
22285
22268
  );
22286
22269
  }
22287
- function TableActionMenuPlugin({
22288
- positioningAnchorEl,
22289
- menuPortalEl
22290
- }) {
22291
- const isEditable = useLexicalEditable();
22292
- return isEditable ? /* @__PURE__ */ jsx131(TableCellActionMenuContainer, { menuPortalEl, positioningAnchorEl }) : null;
22293
- }
22294
22270
 
22295
- // src/components/ParameterInputs/rich-text/TableCellResizerPlugin.tsx
22296
- import { css as css100 } from "@emotion/react";
22297
- import { useLexicalComposerContext as useLexicalComposerContext6 } from "@lexical/react/LexicalComposerContext";
22298
- import { useLexicalEditable as useLexicalEditable2 } from "@lexical/react/useLexicalEditable";
22271
+ // src/components/ParameterInputs/rich-text/TableSelectionPlugin.tsx
22272
+ import { useLexicalComposerContext as useLexicalComposerContext7 } from "@lexical/react/LexicalComposerContext";
22273
+ import { $findCellNode } from "@lexical/table";
22299
22274
  import {
22300
- $computeTableMapSkipCellCheck,
22301
- $getTableNodeFromLexicalNodeOrThrow as $getTableNodeFromLexicalNodeOrThrow2,
22302
- $getTableRowIndexFromTableCellNode as $getTableRowIndexFromTableCellNode2,
22303
- $isTableCellNode as $isTableCellNode2,
22304
- $isTableRowNode as $isTableRowNode2
22305
- } from "@lexical/table";
22306
- import { calculateZoomLevel } from "@lexical/utils";
22307
- import { $getNearestNodeFromDOMNode } from "lexical";
22308
- import { useCallback as useCallback13, useEffect as useEffect22, useMemo as useMemo7, useRef as useRef13, useState as useState19 } from "react";
22309
- import { createPortal as createPortal3 } from "react-dom";
22310
- import { Fragment as Fragment20, jsx as jsx132, jsxs as jsxs88 } from "@emotion/react/jsx-runtime";
22311
- var MIN_ROW_HEIGHT = 33;
22312
- var MIN_COLUMN_WIDTH = 50;
22313
- var tableResizer = css100`
22314
- position: absolute;
22315
- z-index: var(--z-10);
22316
- `;
22317
- var fixedGetDOMCellFromTarget = (node) => {
22318
- let currentNode = node;
22319
- while (currentNode != null) {
22320
- const nodeName = currentNode.nodeName;
22321
- if (nodeName === "TD" || nodeName === "TH") {
22322
- const cell2 = currentNode._cell;
22323
- if (cell2 === void 0) {
22324
- return {
22325
- elem: currentNode
22326
- };
22327
- }
22328
- return cell2;
22329
- }
22330
- currentNode = currentNode.parentNode;
22331
- }
22332
- return null;
22333
- };
22334
- function TableCellResizer({ editor, positioningAnchorEl }) {
22335
- const targetRef = useRef13(null);
22336
- const resizerRef = useRef13(null);
22337
- const tableRectRef = useRef13(null);
22338
- const mouseStartPosRef = useRef13(null);
22339
- const [mouseCurrentPos, updateMouseCurrentPos] = useState19(null);
22340
- const [activeCell, updateActiveCell] = useState19(null);
22341
- const [isMouseDown, updateIsMouseDown] = useState19(false);
22342
- const [draggingDirection, updateDraggingDirection] = useState19(null);
22343
- const resetState = useCallback13(() => {
22344
- updateActiveCell(null);
22345
- targetRef.current = null;
22346
- updateDraggingDirection(null);
22347
- mouseStartPosRef.current = null;
22348
- tableRectRef.current = null;
22349
- }, []);
22350
- const isMouseDownOnEvent = (event) => {
22351
- return (event.buttons & 1) === 1;
22352
- };
22353
- useEffect22(() => {
22354
- const onMouseMove = (event) => {
22355
- setTimeout(() => {
22356
- const target = event.target;
22357
- if (draggingDirection) {
22358
- updateMouseCurrentPos({
22359
- x: event.clientX,
22360
- y: event.clientY
22361
- });
22362
- return;
22363
- }
22364
- updateIsMouseDown(isMouseDownOnEvent(event));
22365
- if (resizerRef.current && resizerRef.current.contains(target)) {
22366
- return;
22367
- }
22368
- if (targetRef.current !== target) {
22369
- targetRef.current = target;
22370
- const cell2 = fixedGetDOMCellFromTarget(target);
22371
- if (cell2 && activeCell !== cell2) {
22372
- editor.update(() => {
22373
- const tableCellNode = $getNearestNodeFromDOMNode(cell2.elem);
22374
- if (!tableCellNode) {
22375
- throw new Error("TableCellResizer: Table cell node not found.");
22376
- }
22377
- const tableNode = $getTableNodeFromLexicalNodeOrThrow2(tableCellNode);
22378
- const tableElement2 = editor.getElementByKey(tableNode.getKey());
22379
- if (!tableElement2) {
22380
- throw new Error("TableCellResizer: Table element not found.");
22381
- }
22382
- targetRef.current = target;
22383
- tableRectRef.current = tableElement2.getBoundingClientRect();
22384
- updateActiveCell(cell2);
22385
- });
22386
- } else if (cell2 == null) {
22387
- resetState();
22388
- }
22389
- }
22390
- }, 0);
22391
- };
22392
- const onMouseDown = () => {
22393
- setTimeout(() => {
22394
- updateIsMouseDown(true);
22395
- }, 0);
22396
- };
22397
- const onMouseUp = () => {
22398
- setTimeout(() => {
22399
- updateIsMouseDown(false);
22400
- }, 0);
22401
- };
22402
- const removeRootListener = editor.registerRootListener((rootElement, prevRootElement) => {
22403
- rootElement == null ? void 0 : rootElement.addEventListener("mousemove", onMouseMove);
22404
- rootElement == null ? void 0 : rootElement.addEventListener("mousedown", onMouseDown);
22405
- rootElement == null ? void 0 : rootElement.addEventListener("mouseup", onMouseUp);
22406
- prevRootElement == null ? void 0 : prevRootElement.removeEventListener("mousemove", onMouseMove);
22407
- prevRootElement == null ? void 0 : prevRootElement.removeEventListener("mousedown", onMouseDown);
22408
- prevRootElement == null ? void 0 : prevRootElement.removeEventListener("mouseup", onMouseUp);
22409
- });
22410
- return () => {
22411
- removeRootListener();
22412
- };
22413
- }, [activeCell, draggingDirection, editor, resetState]);
22414
- const isHeightChanging = (direction) => {
22415
- if (direction === "bottom") {
22416
- return true;
22417
- }
22418
- return false;
22419
- };
22420
- const updateRowHeight = useCallback13(
22421
- (heightChange) => {
22422
- if (!activeCell) {
22423
- throw new Error("TableCellResizer: Expected active cell.");
22424
- }
22425
- editor.update(
22426
- () => {
22427
- const tableCellNode = $getNearestNodeFromDOMNode(activeCell.elem);
22428
- if (!$isTableCellNode2(tableCellNode)) {
22429
- throw new Error("TableCellResizer: Table cell node not found.");
22430
- }
22431
- const tableNode = $getTableNodeFromLexicalNodeOrThrow2(tableCellNode);
22432
- const tableRowIndex = $getTableRowIndexFromTableCellNode2(tableCellNode);
22433
- const tableRows = tableNode.getChildren();
22434
- if (tableRowIndex >= tableRows.length || tableRowIndex < 0) {
22435
- throw new Error("Expected table cell to be inside of table row.");
22436
- }
22437
- const tableRow2 = tableRows[tableRowIndex];
22438
- if (!$isTableRowNode2(tableRow2)) {
22439
- throw new Error("Expected table row");
22275
+ $getSelection as $getSelection4,
22276
+ $isRangeSelection as $isRangeSelection4,
22277
+ $setSelection,
22278
+ COMMAND_PRIORITY_NORMAL as COMMAND_PRIORITY_NORMAL2,
22279
+ SELECTION_CHANGE_COMMAND as SELECTION_CHANGE_COMMAND2
22280
+ } from "lexical";
22281
+ import { useEffect as useEffect23, useState as useState19 } from "react";
22282
+ var TableSelectionPlugin = () => {
22283
+ const [editor] = useLexicalComposerContext7();
22284
+ const [closestTableCellNode, setClosestTableCellNode] = useState19(null);
22285
+ useEffect23(() => {
22286
+ return editor.registerCommand(
22287
+ SELECTION_CHANGE_COMMAND2,
22288
+ () => {
22289
+ editor.read(() => {
22290
+ const selection = $getSelection4();
22291
+ if (!$isRangeSelection4(selection) || !selection.isCollapsed()) {
22292
+ setClosestTableCellNode(null);
22293
+ return false;
22440
22294
  }
22441
- let height = tableRow2.getHeight();
22442
- if (height === void 0) {
22443
- const rowCells = tableRow2.getChildren();
22444
- height = Math.min(...rowCells.map((cell2) => {
22445
- var _a;
22446
- return (_a = getCellNodeHeight(cell2, editor)) != null ? _a : Infinity;
22447
- }));
22295
+ const tableCellNode = $findCellNode(selection.anchor.getNode());
22296
+ if (tableCellNode === null) {
22297
+ setClosestTableCellNode(null);
22298
+ return false;
22448
22299
  }
22449
- const newHeight = Math.max(height + heightChange, MIN_ROW_HEIGHT);
22450
- tableRow2.setHeight(newHeight);
22451
- },
22452
- { tag: "skip-scroll-into-view" }
22453
- );
22454
- },
22455
- [activeCell, editor]
22456
- );
22457
- const getCellNodeWidth = (cell2, activeEditor) => {
22458
- const width = cell2.getWidth();
22459
- if (width !== void 0) {
22460
- return width;
22461
- }
22462
- const domCellNode = activeEditor.getElementByKey(cell2.getKey());
22463
- if (domCellNode == null) {
22464
- return void 0;
22465
- }
22466
- const computedStyle = getComputedStyle(domCellNode);
22467
- return domCellNode.clientWidth - parseFloat(computedStyle.paddingLeft) - parseFloat(computedStyle.paddingRight);
22468
- };
22469
- const getCellNodeHeight = (cell2, activeEditor) => {
22470
- const domCellNode = activeEditor.getElementByKey(cell2.getKey());
22471
- return domCellNode == null ? void 0 : domCellNode.clientHeight;
22472
- };
22473
- const getCellColumnIndex = (tableCellNode, tableMap) => {
22474
- for (let row = 0; row < tableMap.length; row++) {
22475
- for (let column = 0; column < tableMap[row].length; column++) {
22476
- if (tableMap[row][column].cell === tableCellNode) {
22477
- return column;
22300
+ setClosestTableCellNode(tableCellNode);
22301
+ });
22302
+ return false;
22303
+ },
22304
+ COMMAND_PRIORITY_NORMAL2
22305
+ );
22306
+ }, [editor]);
22307
+ useEffect23(() => {
22308
+ const onControlA = (event) => {
22309
+ if (event.key === "a" && (event.ctrlKey || event.metaKey)) {
22310
+ if (!closestTableCellNode) {
22311
+ return;
22478
22312
  }
22313
+ event.preventDefault();
22314
+ editor.update(() => {
22315
+ const selection = closestTableCellNode.select(0, closestTableCellNode.getChildrenSize());
22316
+ $setSelection(selection);
22317
+ });
22479
22318
  }
22480
- }
22481
- };
22482
- const updateColumnWidth = useCallback13(
22483
- (widthChange) => {
22484
- if (!activeCell) {
22485
- throw new Error("TableCellResizer: Expected active cell.");
22486
- }
22487
- editor.update(
22488
- () => {
22489
- const tableCellNode = $getNearestNodeFromDOMNode(activeCell.elem);
22490
- if (!$isTableCellNode2(tableCellNode)) {
22491
- throw new Error("TableCellResizer: Table cell node not found.");
22492
- }
22493
- const tableNode = $getTableNodeFromLexicalNodeOrThrow2(tableCellNode);
22494
- const [tableMap] = $computeTableMapSkipCellCheck(tableNode, null, null);
22495
- const columnIndex = getCellColumnIndex(tableCellNode, tableMap);
22496
- if (columnIndex === void 0) {
22497
- throw new Error("TableCellResizer: Table column not found.");
22498
- }
22499
- for (let row = 0; row < tableMap.length; row++) {
22500
- const cell2 = tableMap[row][columnIndex];
22501
- if (cell2.startRow === row && (columnIndex === tableMap[row].length - 1 || tableMap[row][columnIndex].cell !== tableMap[row][columnIndex + 1].cell)) {
22502
- const width = getCellNodeWidth(cell2.cell, editor);
22503
- if (width === void 0) {
22504
- continue;
22505
- }
22506
- const newWidth = Math.max(width + widthChange, MIN_COLUMN_WIDTH);
22507
- cell2.cell.setWidth(newWidth);
22508
- }
22509
- }
22510
- },
22511
- { tag: "skip-scroll-into-view" }
22512
- );
22513
- },
22514
- [activeCell, editor]
22515
- );
22516
- const mouseUpHandler = useCallback13(
22517
- (direction) => {
22518
- const handler = (event) => {
22519
- event.preventDefault();
22520
- event.stopPropagation();
22521
- if (!activeCell) {
22522
- throw new Error("TableCellResizer: Expected active cell.");
22523
- }
22524
- if (mouseStartPosRef.current) {
22525
- const { x, y } = mouseStartPosRef.current;
22526
- if (activeCell === null) {
22527
- return;
22528
- }
22529
- const zoom = calculateZoomLevel(event.target);
22530
- if (isHeightChanging(direction)) {
22531
- const heightChange = (event.clientY - y) / zoom;
22532
- updateRowHeight(heightChange);
22533
- } else {
22534
- const widthChange = (event.clientX - x) / zoom;
22535
- updateColumnWidth(widthChange);
22536
- }
22537
- resetState();
22538
- document.removeEventListener("mouseup", handler);
22539
- }
22540
- };
22541
- return handler;
22542
- },
22543
- [activeCell, resetState, updateColumnWidth, updateRowHeight]
22319
+ };
22320
+ return editor.registerRootListener((rootElement, prevRootElement) => {
22321
+ rootElement == null ? void 0 : rootElement.addEventListener("keydown", onControlA);
22322
+ prevRootElement == null ? void 0 : prevRootElement.removeEventListener("keydown", onControlA);
22323
+ });
22324
+ }, [editor, closestTableCellNode]);
22325
+ return null;
22326
+ };
22327
+ var TableSelectionPlugin_default = TableSelectionPlugin;
22328
+
22329
+ // src/components/ParameterInputs/rich-text/toolbar/RichTextToolbar.tsx
22330
+ import { css as css100 } from "@emotion/react";
22331
+ import { $createCodeNode } from "@lexical/code";
22332
+ import {
22333
+ $isListNode as $isListNode2,
22334
+ INSERT_ORDERED_LIST_COMMAND,
22335
+ INSERT_UNORDERED_LIST_COMMAND,
22336
+ ListNode as ListNode2,
22337
+ REMOVE_LIST_COMMAND
22338
+ } from "@lexical/list";
22339
+ import { useLexicalComposerContext as useLexicalComposerContext8 } from "@lexical/react/LexicalComposerContext";
22340
+ import { $createHeadingNode, $createQuoteNode, $isHeadingNode } from "@lexical/rich-text";
22341
+ import { $setBlocksType } from "@lexical/selection";
22342
+ import { $createTableNodeWithDimensions } from "@lexical/table";
22343
+ import { $findMatchingParent, $getNearestNodeOfType as $getNearestNodeOfType2 } from "@lexical/utils";
22344
+ import {
22345
+ $createParagraphNode as $createParagraphNode2,
22346
+ $getSelection as $getSelection5,
22347
+ $insertNodes as $insertNodes2,
22348
+ $isRangeSelection as $isRangeSelection5,
22349
+ $isRootOrShadowRoot,
22350
+ COMMAND_PRIORITY_CRITICAL as COMMAND_PRIORITY_CRITICAL2,
22351
+ FORMAT_TEXT_COMMAND,
22352
+ SELECTION_CHANGE_COMMAND as SELECTION_CHANGE_COMMAND3
22353
+ } from "lexical";
22354
+ import { useCallback as useCallback13, useEffect as useEffect24 } from "react";
22355
+
22356
+ // src/components/ParameterInputs/rich-text/toolbar/constants.ts
22357
+ var FORMATS_WITH_ICON = /* @__PURE__ */ new Map([
22358
+ ["bold", "format-bold"],
22359
+ ["italic", "format-italic"],
22360
+ ["underline", "format-underline"],
22361
+ ["strikethrough", "format-strike"],
22362
+ ["code", "format-code"],
22363
+ ["superscript", "format-superscript"],
22364
+ ["subscript", "format-subscript"]
22365
+ ]);
22366
+ var HEADING_ELEMENTS = ["h1", "h2", "h3", "h4", "h5", "h6"];
22367
+ var TEXTUAL_ELEMENTS = HEADING_ELEMENTS;
22368
+
22369
+ // src/components/ParameterInputs/rich-text/toolbar/useRichTextToolbarState.ts
22370
+ import { useMemo as useMemo7, useState as useState20 } from "react";
22371
+ var useRichTextToolbarState = ({ config }) => {
22372
+ var _a;
22373
+ const enabledBuiltInFormats = useMemo7(() => {
22374
+ return richTextBuiltInFormats.filter((format) => {
22375
+ var _a2, _b;
22376
+ return (_b = (_a2 = config == null ? void 0 : config.formatting) == null ? void 0 : _a2.builtIn) == null ? void 0 : _b.includes(format.type);
22377
+ });
22378
+ }, [config]);
22379
+ const enabledBuiltInElements = useMemo7(() => {
22380
+ return richTextBuiltInElements.filter((element) => {
22381
+ var _a2, _b;
22382
+ return (_b = (_a2 = config == null ? void 0 : config.elements) == null ? void 0 : _a2.builtIn) == null ? void 0 : _b.includes(element.type);
22383
+ });
22384
+ }, [config]);
22385
+ const enabledBuiltInFormatsWithIcon = useMemo7(() => {
22386
+ return enabledBuiltInFormats.filter((format) => FORMATS_WITH_ICON.has(format.type));
22387
+ }, [enabledBuiltInFormats]);
22388
+ const enabledBuiltInFormatsWithoutIcon = enabledBuiltInFormats.filter(
22389
+ (format) => !FORMATS_WITH_ICON.has(format.type)
22544
22390
  );
22545
- const toggleResize = useCallback13(
22546
- (direction) => (event) => {
22547
- event.preventDefault();
22548
- event.stopPropagation();
22549
- if (!activeCell) {
22550
- throw new Error("TableCellResizer: Expected active cell.");
22551
- }
22552
- mouseStartPosRef.current = {
22553
- x: event.clientX,
22554
- y: event.clientY
22555
- };
22556
- updateMouseCurrentPos(mouseStartPosRef.current);
22557
- updateDraggingDirection(direction);
22558
- document.addEventListener("mouseup", mouseUpHandler(direction));
22559
- },
22560
- [activeCell, mouseUpHandler]
22391
+ const [activeFormats, setActiveFormats] = useState20([]);
22392
+ const visibleFormatsWithIcon = useMemo7(() => {
22393
+ const visibleFormats = /* @__PURE__ */ new Set();
22394
+ activeFormats.filter((type) => FORMATS_WITH_ICON.has(type)).forEach((type) => {
22395
+ visibleFormats.add(type);
22396
+ });
22397
+ enabledBuiltInFormatsWithIcon.forEach((format) => {
22398
+ visibleFormats.add(format.type);
22399
+ });
22400
+ return richTextBuiltInFormats.filter((format) => visibleFormats.has(format.type));
22401
+ }, [activeFormats, enabledBuiltInFormatsWithIcon]);
22402
+ const visibleFormatsWithoutIcon = useMemo7(() => {
22403
+ const visibleFormats = /* @__PURE__ */ new Set();
22404
+ activeFormats.filter((type) => !FORMATS_WITH_ICON.has(type)).forEach((type) => {
22405
+ visibleFormats.add(type);
22406
+ });
22407
+ enabledBuiltInFormatsWithoutIcon.forEach((format) => {
22408
+ visibleFormats.add(format.type);
22409
+ });
22410
+ return richTextBuiltInFormats.filter((format) => visibleFormats.has(format.type));
22411
+ }, [activeFormats, enabledBuiltInFormatsWithoutIcon]);
22412
+ const [activeElement, setActiveElement] = useState20("paragraph");
22413
+ const enabledTextualElements = enabledBuiltInElements.filter(
22414
+ (element) => TEXTUAL_ELEMENTS.includes(element.type)
22561
22415
  );
22562
- const getResizers = useCallback13(() => {
22563
- if (activeCell) {
22564
- const { height, width, top, left } = activeCell.elem.getBoundingClientRect();
22565
- const parentRect = positioningAnchorEl.getBoundingClientRect();
22566
- const zoom = calculateZoomLevel(activeCell.elem);
22567
- const zoneWidth = 10;
22568
- const styles = {
22569
- bottom: {
22570
- backgroundColor: "none",
22571
- cursor: "row-resize",
22572
- height: `${zoneWidth}px`,
22573
- left: `${left - parentRect.left}px`,
22574
- top: `${top - parentRect.top + positioningAnchorEl.scrollTop + height - zoneWidth / 2}px`,
22575
- width: `${width}px`
22576
- },
22577
- right: {
22578
- backgroundColor: "none",
22579
- cursor: "col-resize",
22580
- height: `${height}px`,
22581
- left: `${left - parentRect.left + width - zoneWidth / 2}px`,
22582
- top: `${top - parentRect.top + positioningAnchorEl.scrollTop}px`,
22583
- width: `${zoneWidth}px`
22584
- }
22585
- };
22586
- const tableRect = tableRectRef.current;
22587
- if (draggingDirection && mouseCurrentPos && tableRect) {
22588
- if (isHeightChanging(draggingDirection)) {
22589
- styles[draggingDirection].left = `${tableRect.left - parentRect.left}px`;
22590
- styles[draggingDirection].top = `${(mouseCurrentPos.y - parentRect.top + positioningAnchorEl.scrollTop) / zoom}px`;
22591
- styles[draggingDirection].height = "3px";
22592
- styles[draggingDirection].width = `${tableRect.width}px`;
22593
- } else {
22594
- styles[draggingDirection].top = `${tableRect.top - parentRect.top + positioningAnchorEl.scrollTop}px`;
22595
- styles[draggingDirection].left = `${(mouseCurrentPos.x - parentRect.left) / zoom}px`;
22596
- styles[draggingDirection].width = "3px";
22597
- styles[draggingDirection].height = `${tableRect.height}px`;
22598
- }
22599
- styles[draggingDirection].backgroundColor = "#adf";
22416
+ const visibleTextualElements = useMemo7(() => {
22417
+ if (!TEXTUAL_ELEMENTS.includes(activeElement)) {
22418
+ return enabledTextualElements;
22419
+ }
22420
+ return richTextBuiltInElements.filter(
22421
+ (element) => {
22422
+ var _a2, _b;
22423
+ return TEXTUAL_ELEMENTS.includes(element.type) && (((_b = (_a2 = config == null ? void 0 : config.elements) == null ? void 0 : _a2.builtIn) == null ? void 0 : _b.includes(element.type)) || element.type === activeElement);
22600
22424
  }
22601
- return styles;
22425
+ );
22426
+ }, [activeElement, (_a = config == null ? void 0 : config.elements) == null ? void 0 : _a.builtIn, enabledTextualElements]);
22427
+ const [isLink, setIsLink] = useState20(false);
22428
+ const linkElementVisible = useMemo7(() => {
22429
+ return enabledBuiltInElements.some((element) => element.type === "link") || isLink;
22430
+ }, [isLink, enabledBuiltInElements]);
22431
+ const visibleLists = useMemo7(() => {
22432
+ return new Set(
22433
+ ["orderedList", "unorderedList"].filter(
22434
+ (type) => enabledBuiltInElements.some((element) => element.type === type) || activeElement === type
22435
+ )
22436
+ );
22437
+ }, [activeElement, enabledBuiltInElements]);
22438
+ const quoteElementVisible = useMemo7(() => {
22439
+ return enabledBuiltInElements.some((element) => element.type === "quote") || activeElement === "quote";
22440
+ }, [activeElement, enabledBuiltInElements]);
22441
+ const codeElementVisible = useMemo7(() => {
22442
+ return enabledBuiltInElements.some((element) => element.type === "code") || activeElement === "code";
22443
+ }, [activeElement, enabledBuiltInElements]);
22444
+ const tableElementVisible = useMemo7(() => {
22445
+ return enabledBuiltInElements.some((element) => element.type === "table") || activeElement === "table";
22446
+ }, [activeElement, enabledBuiltInElements]);
22447
+ const assetElementVisible = useMemo7(() => {
22448
+ return enabledBuiltInElements.some((element) => element.type === "asset") || activeElement === "asset";
22449
+ }, [activeElement, enabledBuiltInElements]);
22450
+ const visibleElementsWithIcons = useMemo7(() => {
22451
+ const visibleElements = /* @__PURE__ */ new Set();
22452
+ if (linkElementVisible) {
22453
+ visibleElements.add("link");
22602
22454
  }
22603
- return {
22604
- bottom: null,
22605
- left: null,
22606
- right: null,
22607
- top: null
22608
- };
22609
- }, [activeCell, draggingDirection, mouseCurrentPos, positioningAnchorEl]);
22610
- const resizerStyles = getResizers();
22611
- return /* @__PURE__ */ jsx132("div", { ref: resizerRef, children: activeCell != null && !isMouseDown && /* @__PURE__ */ jsxs88(Fragment20, { children: [
22612
- /* @__PURE__ */ jsx132(
22613
- "div",
22614
- {
22615
- css: tableResizer,
22616
- style: resizerStyles.right || void 0,
22617
- onMouseDown: toggleResize("right")
22455
+ if (visibleLists.size > 0) {
22456
+ visibleLists.forEach((type) => {
22457
+ visibleElements.add(type);
22458
+ });
22459
+ }
22460
+ return visibleElements;
22461
+ }, [linkElementVisible, visibleLists]);
22462
+ const visibleInsertElementsWithIcons = useMemo7(() => {
22463
+ const visibleElements = /* @__PURE__ */ new Set();
22464
+ if (quoteElementVisible) {
22465
+ visibleElements.add("quote");
22466
+ }
22467
+ if (codeElementVisible) {
22468
+ visibleElements.add("code");
22469
+ }
22470
+ if (tableElementVisible) {
22471
+ visibleElements.add("table");
22472
+ }
22473
+ if (assetElementVisible) {
22474
+ visibleElements.add("asset");
22475
+ }
22476
+ return visibleElements;
22477
+ }, [codeElementVisible, quoteElementVisible, tableElementVisible, assetElementVisible]);
22478
+ return {
22479
+ activeFormats,
22480
+ setActiveFormats,
22481
+ activeElement,
22482
+ setActiveElement,
22483
+ visibleFormatsWithIcon,
22484
+ visibleFormatsWithoutIcon,
22485
+ visibleTextualElements,
22486
+ isLink,
22487
+ setIsLink,
22488
+ linkElementVisible,
22489
+ visibleLists,
22490
+ quoteElementVisible,
22491
+ codeElementVisible,
22492
+ tableElementVisible,
22493
+ assetElementVisible,
22494
+ visibleElementsWithIcons,
22495
+ visibleInsertElementsWithIcons
22496
+ };
22497
+ };
22498
+
22499
+ // src/components/ParameterInputs/rich-text/toolbar/RichTextToolbar.tsx
22500
+ import { Fragment as Fragment20, jsx as jsx132, jsxs as jsxs88 } from "@emotion/react/jsx-runtime";
22501
+ var toolbar = css100`
22502
+ ${scrollbarStyles}
22503
+ background: var(--gray-50);
22504
+ border-radius: var(--rounded-base);
22505
+ display: flex;
22506
+ /* We add 1px because we use a 1px wide separator */
22507
+ gap: calc(var(--spacing-sm) + 1px);
22508
+ margin: 0 0 calc(var(--spacing-sm) + var(--spacing-xs)) 0;
22509
+ overflow: auto;
22510
+ padding: var(--spacing-sm);
22511
+ position: sticky;
22512
+ top: calc(var(--spacing-sm) * -2);
22513
+ z-index: 10;
22514
+ `;
22515
+ var toolbarGroup = css100`
22516
+ display: flex;
22517
+ flex-shrink: 0;
22518
+ gap: var(--spacing-xs);
22519
+ position: relative;
22520
+
22521
+ &:not(:first-child)::before {
22522
+ background-color: var(--gray-300);
22523
+ content: '';
22524
+ display: block;
22525
+ height: 24px;
22526
+ left: calc(var(--spacing-xs) * -1);
22527
+ position: absolute;
22528
+ top: 4px;
22529
+ width: 1px;
22530
+ }
22531
+ `;
22532
+ var richTextToolbarButton = css100`
22533
+ align-items: center;
22534
+ appearance: none;
22535
+ border: 0;
22536
+ border-radius: var(--rounded-sm);
22537
+ box-shadow: none;
22538
+ color: var(--gray-900);
22539
+ display: flex;
22540
+ flex-shrink: 0;
22541
+ height: 32px;
22542
+ justify-content: center;
22543
+ min-width: 32px;
22544
+ padding: 0 var(--spacing-sm);
22545
+ `;
22546
+ var richTextToolbarButtonActive = css100`
22547
+ background: var(--gray-200);
22548
+ `;
22549
+ var textStyleButton = css100`
22550
+ justify-content: space-between;
22551
+ min-width: 7rem;
22552
+ `;
22553
+ var toolbarIcon = css100`
22554
+ color: inherit;
22555
+ `;
22556
+ var toolbarChevron = css100`
22557
+ margin-left: var(--spacing-xs);
22558
+ `;
22559
+ var RichTextToolbarIcon = ({ icon }) => {
22560
+ return /* @__PURE__ */ jsx132(Icon, { icon, css: toolbarIcon, size: "1rem" });
22561
+ };
22562
+ var RichTextToolbar = ({ config, customControls, onInsertTable, onInsertAsset }) => {
22563
+ const [editor] = useLexicalComposerContext8();
22564
+ const {
22565
+ activeElement,
22566
+ setActiveElement,
22567
+ activeFormats,
22568
+ setActiveFormats,
22569
+ visibleFormatsWithIcon,
22570
+ visibleFormatsWithoutIcon,
22571
+ visibleTextualElements,
22572
+ isLink,
22573
+ setIsLink,
22574
+ linkElementVisible,
22575
+ visibleLists,
22576
+ codeElementVisible,
22577
+ quoteElementVisible,
22578
+ visibleElementsWithIcons,
22579
+ visibleInsertElementsWithIcons,
22580
+ tableElementVisible,
22581
+ assetElementVisible
22582
+ } = useRichTextToolbarState({ config });
22583
+ const onSelectElement = (type) => {
22584
+ if (activeElement === type) {
22585
+ return;
22586
+ }
22587
+ editor.focus(() => {
22588
+ editor.update(() => {
22589
+ const selection = $getSelection5();
22590
+ if (HEADING_ELEMENTS.includes(type)) {
22591
+ $setBlocksType(selection, () => $createHeadingNode(type));
22592
+ } else if (type === "paragraph") {
22593
+ $setBlocksType(selection, () => $createParagraphNode2());
22594
+ } else if (type === "quote") {
22595
+ $setBlocksType(selection, () => $createQuoteNode());
22596
+ } else if (type === "code") {
22597
+ $setBlocksType(selection, () => $createCodeNode());
22598
+ } else if (type === "table" && onInsertTable) {
22599
+ onInsertTable().then((dimensions) => {
22600
+ if (!dimensions) {
22601
+ return;
22602
+ }
22603
+ const { rows, columns } = dimensions;
22604
+ editor.focus(() => {
22605
+ editor.update(() => {
22606
+ $insertNodes2([$createTableNodeWithDimensions(rows, columns, false)]);
22607
+ });
22608
+ });
22609
+ });
22610
+ } else if (type === "asset" && onInsertAsset) {
22611
+ onInsertAsset();
22612
+ }
22613
+ });
22614
+ });
22615
+ };
22616
+ const updateToolbar = useCallback13(() => {
22617
+ const selection = $getSelection5();
22618
+ if (!$isRangeSelection5(selection)) {
22619
+ return;
22620
+ }
22621
+ const newActiveFormats = [];
22622
+ for (const format of richTextBuiltInFormats) {
22623
+ if (selection.hasFormat(format.type)) {
22624
+ newActiveFormats.push(format.type);
22618
22625
  }
22619
- ),
22620
- /* @__PURE__ */ jsx132(
22621
- "div",
22622
- {
22623
- css: tableResizer,
22624
- style: resizerStyles.bottom || void 0,
22625
- onMouseDown: toggleResize("bottom")
22626
+ }
22627
+ setActiveFormats(newActiveFormats);
22628
+ const anchorNode = selection.anchor.getNode();
22629
+ let element = anchorNode.getKey() === "root" ? anchorNode : $findMatchingParent(anchorNode, (e) => {
22630
+ const parent = e.getParent();
22631
+ return parent !== null && $isRootOrShadowRoot(parent);
22632
+ });
22633
+ if (element === null) {
22634
+ element = anchorNode.getTopLevelElementOrThrow();
22635
+ }
22636
+ const elementKey = element.getKey();
22637
+ const elementDOM = editor.getElementByKey(elementKey);
22638
+ if (elementDOM !== null) {
22639
+ if ($isListNode2(element)) {
22640
+ const parentList = $getNearestNodeOfType2(anchorNode, ListNode2);
22641
+ const type = parentList ? parentList.getListType() : element.getListType();
22642
+ setActiveElement(type === "bullet" ? "unorderedList" : "orderedList");
22643
+ } else {
22644
+ const type = $isHeadingNode(element) ? element.getTag() : element.getType();
22645
+ setActiveElement(type);
22626
22646
  }
22627
- )
22628
- ] }) });
22629
- }
22630
- function TableCellResizerPlugin({ positioningAnchorEl }) {
22631
- const [editor] = useLexicalComposerContext6();
22632
- const isEditable = useLexicalEditable2();
22633
- return useMemo7(
22634
- () => isEditable ? createPortal3(
22635
- /* @__PURE__ */ jsx132(TableCellResizer, { editor, positioningAnchorEl }),
22636
- positioningAnchorEl
22637
- ) : null,
22638
- [editor, isEditable, positioningAnchorEl]
22639
- );
22640
- }
22641
-
22642
- // src/components/ParameterInputs/rich-text/TableSelectionPlugin.tsx
22643
- import { useLexicalComposerContext as useLexicalComposerContext7 } from "@lexical/react/LexicalComposerContext";
22644
- import { $findCellNode } from "@lexical/table";
22645
- import {
22646
- $getSelection as $getSelection5,
22647
- $isRangeSelection as $isRangeSelection5,
22648
- $setSelection,
22649
- COMMAND_PRIORITY_NORMAL as COMMAND_PRIORITY_NORMAL2,
22650
- SELECTION_CHANGE_COMMAND as SELECTION_CHANGE_COMMAND3
22651
- } from "lexical";
22652
- import { useEffect as useEffect23, useState as useState20 } from "react";
22653
- var TableSelectionPlugin = () => {
22654
- const [editor] = useLexicalComposerContext7();
22655
- const [closestTableCellNode, setClosestTableCellNode] = useState20(null);
22656
- useEffect23(() => {
22647
+ }
22648
+ const node = getSelectedNode(selection);
22649
+ if (getLinkAncestor(node) !== null) {
22650
+ setIsLink(true);
22651
+ } else {
22652
+ setIsLink(false);
22653
+ }
22654
+ }, [editor, setActiveElement, setActiveFormats, setIsLink]);
22655
+ useEffect24(() => {
22657
22656
  return editor.registerCommand(
22658
22657
  SELECTION_CHANGE_COMMAND3,
22659
- () => {
22660
- editor.read(() => {
22661
- const selection = $getSelection5();
22662
- if (!$isRangeSelection5(selection) || !selection.isCollapsed()) {
22663
- setClosestTableCellNode(null);
22664
- return false;
22665
- }
22666
- const tableCellNode = $findCellNode(selection.anchor.getNode());
22667
- if (tableCellNode === null) {
22668
- setClosestTableCellNode(null);
22669
- return false;
22670
- }
22671
- setClosestTableCellNode(tableCellNode);
22672
- });
22658
+ (_payload) => {
22659
+ updateToolbar();
22673
22660
  return false;
22674
22661
  },
22675
- COMMAND_PRIORITY_NORMAL2
22662
+ COMMAND_PRIORITY_CRITICAL2
22676
22663
  );
22677
- }, [editor]);
22678
- useEffect23(() => {
22679
- const onControlA = (event) => {
22680
- if (event.key === "a" && (event.ctrlKey || event.metaKey)) {
22681
- if (!closestTableCellNode) {
22682
- return;
22683
- }
22684
- event.preventDefault();
22685
- editor.update(() => {
22686
- const selection = closestTableCellNode.select(0, closestTableCellNode.getChildrenSize());
22687
- $setSelection(selection);
22664
+ }, [editor, updateToolbar]);
22665
+ useEffect24(() => {
22666
+ return editor.registerUpdateListener(({ editorState }) => {
22667
+ requestAnimationFrame(() => {
22668
+ editorState.read(() => {
22669
+ updateToolbar();
22688
22670
  });
22689
- }
22690
- };
22691
- return editor.registerRootListener((rootElement, prevRootElement) => {
22692
- rootElement == null ? void 0 : rootElement.addEventListener("keydown", onControlA);
22693
- prevRootElement == null ? void 0 : prevRootElement.removeEventListener("keydown", onControlA);
22671
+ });
22694
22672
  });
22695
- }, [editor, closestTableCellNode]);
22696
- return null;
22673
+ }, [editor, updateToolbar]);
22674
+ return /* @__PURE__ */ jsxs88("div", { css: toolbar, children: [
22675
+ /* @__PURE__ */ jsxs88(
22676
+ Menu,
22677
+ {
22678
+ menuTrigger: /* @__PURE__ */ jsxs88("button", { css: [richTextToolbarButton, textStyleButton], title: "Text styles", children: [
22679
+ visibleTextualElements.some((element) => element.type === activeElement) ? getLabelForElement(activeElement) : getLabelForElement("paragraph"),
22680
+ " ",
22681
+ /* @__PURE__ */ jsx132(Icon, { icon: "chevron-down", css: [toolbarIcon, toolbarChevron], size: "1rem" })
22682
+ ] }),
22683
+ placement: "bottom-start",
22684
+ children: [
22685
+ [
22686
+ {
22687
+ label: "Normal",
22688
+ type: "paragraph"
22689
+ },
22690
+ ...visibleTextualElements
22691
+ ].map((element) => /* @__PURE__ */ jsx132(
22692
+ MenuItem,
22693
+ {
22694
+ onClick: () => {
22695
+ onSelectElement(element.type);
22696
+ },
22697
+ children: element.label
22698
+ },
22699
+ element.type
22700
+ )),
22701
+ visibleTextualElements.length === 0 ? /* @__PURE__ */ jsx132(MenuItem, { disabled: true, children: "Alternative text styles are not available" }) : null
22702
+ ]
22703
+ }
22704
+ ),
22705
+ visibleFormatsWithIcon.length > 0 || visibleFormatsWithoutIcon.length > 0 ? /* @__PURE__ */ jsxs88("div", { css: toolbarGroup, children: [
22706
+ visibleFormatsWithIcon.map((format) => /* @__PURE__ */ jsx132(Tooltip, { title: format.label, placement: "top", children: /* @__PURE__ */ jsx132(
22707
+ "button",
22708
+ {
22709
+ onClick: () => {
22710
+ editor.dispatchCommand(FORMAT_TEXT_COMMAND, format.type);
22711
+ },
22712
+ css: [
22713
+ richTextToolbarButton,
22714
+ activeFormats.includes(format.type) ? richTextToolbarButtonActive : null
22715
+ ],
22716
+ children: /* @__PURE__ */ jsx132(RichTextToolbarIcon, { icon: FORMATS_WITH_ICON.get(format.type) })
22717
+ }
22718
+ ) }, format.type)),
22719
+ visibleFormatsWithoutIcon.length > 0 ? /* @__PURE__ */ jsx132(
22720
+ Menu,
22721
+ {
22722
+ menuLabel: "Alternative text styles",
22723
+ menuTrigger: /* @__PURE__ */ jsx132("button", { css: richTextToolbarButton, title: "Alternative text styles", children: /* @__PURE__ */ jsx132(Icon, { icon: "more-alt", css: toolbarIcon }) }),
22724
+ placement: "bottom-start",
22725
+ children: visibleFormatsWithoutIcon.map((format) => /* @__PURE__ */ jsx132(
22726
+ MenuItem,
22727
+ {
22728
+ onClick: () => {
22729
+ editor.dispatchCommand(FORMAT_TEXT_COMMAND, format.type);
22730
+ },
22731
+ children: format.label
22732
+ },
22733
+ format.type
22734
+ ))
22735
+ }
22736
+ ) : null
22737
+ ] }) : null,
22738
+ visibleElementsWithIcons.size > 0 || customControls ? /* @__PURE__ */ jsxs88("div", { css: toolbarGroup, children: [
22739
+ linkElementVisible ? /* @__PURE__ */ jsx132(Tooltip, { title: "Link", placement: "top", children: /* @__PURE__ */ jsx132(
22740
+ "button",
22741
+ {
22742
+ onClick: () => {
22743
+ isLink ? editor.dispatchCommand(REMOVE_LINK_NODE_COMMAND, {}) : editor.dispatchCommand(OPEN_LINK_NODE_MODAL_COMMAND, {});
22744
+ },
22745
+ css: [richTextToolbarButton, isLink ? richTextToolbarButtonActive : null],
22746
+ children: /* @__PURE__ */ jsx132(RichTextToolbarIcon, { icon: "link" })
22747
+ }
22748
+ ) }) : null,
22749
+ visibleLists.size > 0 ? /* @__PURE__ */ jsxs88(Fragment20, { children: [
22750
+ visibleLists.has("unorderedList") ? /* @__PURE__ */ jsx132(Tooltip, { title: "Bullet List", placement: "top", children: /* @__PURE__ */ jsx132(
22751
+ "button",
22752
+ {
22753
+ onClick: () => {
22754
+ activeElement === "unorderedList" ? editor.dispatchCommand(REMOVE_LIST_COMMAND, void 0) : editor.dispatchCommand(INSERT_UNORDERED_LIST_COMMAND, void 0);
22755
+ },
22756
+ css: [
22757
+ richTextToolbarButton,
22758
+ activeElement === "unorderedList" ? richTextToolbarButtonActive : null
22759
+ ],
22760
+ children: /* @__PURE__ */ jsx132(RichTextToolbarIcon, { icon: "layout-list" })
22761
+ }
22762
+ ) }) : null,
22763
+ visibleLists.has("orderedList") ? /* @__PURE__ */ jsx132(Tooltip, { title: "Ordered List", placement: "top", children: /* @__PURE__ */ jsx132(
22764
+ "button",
22765
+ {
22766
+ onClick: () => {
22767
+ activeElement === "orderedList" ? editor.dispatchCommand(REMOVE_LIST_COMMAND, void 0) : editor.dispatchCommand(INSERT_ORDERED_LIST_COMMAND, void 0);
22768
+ },
22769
+ css: [
22770
+ richTextToolbarButton,
22771
+ activeElement === "orderedList" ? richTextToolbarButtonActive : null
22772
+ ],
22773
+ children: /* @__PURE__ */ jsx132(RichTextToolbarIcon, { icon: "layout-list-numbered" })
22774
+ }
22775
+ ) }) : null
22776
+ ] }) : null,
22777
+ customControls ? customControls : null
22778
+ ] }) : null,
22779
+ visibleInsertElementsWithIcons.size > 0 ? /* @__PURE__ */ jsx132("div", { css: toolbarGroup, children: /* @__PURE__ */ jsxs88(
22780
+ Menu,
22781
+ {
22782
+ menuTrigger: /* @__PURE__ */ jsxs88("button", { css: richTextToolbarButton, title: "Insert block element", children: [
22783
+ "Insert",
22784
+ /* @__PURE__ */ jsx132(Icon, { icon: "chevron-down", css: [toolbarIcon, toolbarChevron], size: "1rem" })
22785
+ ] }),
22786
+ placement: "bottom-start",
22787
+ children: [
22788
+ quoteElementVisible ? /* @__PURE__ */ jsx132(
22789
+ MenuItem,
22790
+ {
22791
+ onClick: () => {
22792
+ onSelectElement("quote");
22793
+ },
22794
+ icon: /* @__PURE__ */ jsx132(Icon, { icon: "quote", iconColor: "currentColor" }),
22795
+ children: "Quote"
22796
+ }
22797
+ ) : null,
22798
+ codeElementVisible ? /* @__PURE__ */ jsx132(
22799
+ MenuItem,
22800
+ {
22801
+ onClick: () => {
22802
+ onSelectElement("code");
22803
+ },
22804
+ icon: /* @__PURE__ */ jsx132(Icon, { icon: "code-slash", iconColor: "currentColor" }),
22805
+ children: "Code"
22806
+ }
22807
+ ) : null,
22808
+ tableElementVisible && onInsertTable !== void 0 ? /* @__PURE__ */ jsx132(
22809
+ MenuItem,
22810
+ {
22811
+ onClick: () => {
22812
+ onSelectElement("table");
22813
+ },
22814
+ icon: /* @__PURE__ */ jsx132(Icon, { icon: "view-grid", iconColor: "currentColor" }),
22815
+ children: "Table"
22816
+ }
22817
+ ) : null,
22818
+ assetElementVisible && onInsertAsset !== void 0 ? /* @__PURE__ */ jsx132(
22819
+ MenuItem,
22820
+ {
22821
+ onClick: () => {
22822
+ onSelectElement("asset");
22823
+ },
22824
+ icon: /* @__PURE__ */ jsx132(Icon, { icon: "image", iconColor: "currentColor" }),
22825
+ children: "Asset"
22826
+ }
22827
+ ) : null
22828
+ ]
22829
+ }
22830
+ ) }) : null
22831
+ ] });
22697
22832
  };
22698
- var TableSelectionPlugin_default = TableSelectionPlugin;
22833
+ var RichTextToolbar_default = RichTextToolbar;
22699
22834
 
22700
22835
  // src/components/ParameterInputs/ParameterRichText.tsx
22701
22836
  import { Fragment as Fragment21, jsx as jsx133, jsxs as jsxs89 } from "@emotion/react/jsx-runtime";
@@ -22724,6 +22859,7 @@ var ParameterRichText = ({
22724
22859
  variables,
22725
22860
  customControls,
22726
22861
  onInsertTable,
22862
+ onInsertAsset,
22727
22863
  minimalInteractivity
22728
22864
  }) => {
22729
22865
  return /* @__PURE__ */ jsxs89(
@@ -22757,6 +22893,7 @@ var ParameterRichText = ({
22757
22893
  variables,
22758
22894
  customControls,
22759
22895
  onInsertTable,
22896
+ onInsertAsset,
22760
22897
  minimalInteractivity,
22761
22898
  children
22762
22899
  }
@@ -22799,7 +22936,7 @@ var editorContainer = css101`
22799
22936
  font-size: var(--fs-base);
22800
22937
  height: max-content;
22801
22938
  line-height: 1.2;
22802
- max-height: 300px;
22939
+ max-height: 320px;
22803
22940
  min-height: 50px;
22804
22941
  overflow-y: auto;
22805
22942
  padding: var(--spacing-sm);
@@ -22840,6 +22977,7 @@ var editorPlaceholder = css101`
22840
22977
  `;
22841
22978
  var editorInput = css101`
22842
22979
  min-height: 100%;
22980
+ flex-grow: 1;
22843
22981
 
22844
22982
  &:focus,
22845
22983
  &:focus-within {
@@ -22862,6 +23000,7 @@ var ParameterRichTextInner = ({
22862
23000
  variables,
22863
23001
  customControls,
22864
23002
  onInsertTable,
23003
+ onInsertAsset,
22865
23004
  minimalInteractivity
22866
23005
  }) => {
22867
23006
  const lexicalConfig = {
@@ -22934,6 +23073,7 @@ var ParameterRichTextInner = ({
22934
23073
  variables,
22935
23074
  customControls,
22936
23075
  onInsertTable,
23076
+ onInsertAsset,
22937
23077
  minimalInteractivity,
22938
23078
  children
22939
23079
  }
@@ -22962,15 +23102,16 @@ var RichText = ({
22962
23102
  variables,
22963
23103
  customControls,
22964
23104
  onInsertTable,
23105
+ onInsertAsset,
22965
23106
  minimalInteractivity
22966
23107
  }) => {
22967
- const [editor] = useLexicalComposerContext8();
22968
- useEffect24(() => {
23108
+ const [editor] = useLexicalComposerContext9();
23109
+ useEffect25(() => {
22969
23110
  if (onRichTextInit) {
22970
23111
  onRichTextInit(editor);
22971
23112
  }
22972
23113
  }, [editor, onRichTextInit]);
22973
- useEffect24(() => {
23114
+ useEffect25(() => {
22974
23115
  const removeUpdateListener = editor.registerUpdateListener(({ editorState, prevEditorState, tags }) => {
22975
23116
  requestAnimationFrame(() => {
22976
23117
  if (!deepEqual2(editorState.toJSON(), prevEditorState.toJSON())) {
@@ -22982,7 +23123,7 @@ var RichText = ({
22982
23123
  removeUpdateListener();
22983
23124
  };
22984
23125
  }, [editor, onChange]);
22985
- useEffect24(() => {
23126
+ useEffect25(() => {
22986
23127
  editor.setEditable(!readOnly);
22987
23128
  }, [editor, readOnly]);
22988
23129
  const [editorContainerRef, setEditorContainerRef] = useState21(null);
@@ -22998,7 +23139,15 @@ var RichText = ({
22998
23139
  }
22999
23140
  };
23000
23141
  return /* @__PURE__ */ jsxs89(Fragment21, { children: [
23001
- readOnly || minimalInteractivity ? null : /* @__PURE__ */ jsx133(RichTextToolbar_default, { config, customControls, onInsertTable }),
23142
+ readOnly || minimalInteractivity ? null : /* @__PURE__ */ jsx133(
23143
+ RichTextToolbar_default,
23144
+ {
23145
+ config,
23146
+ customControls,
23147
+ onInsertTable,
23148
+ onInsertAsset
23149
+ }
23150
+ ),
23002
23151
  /* @__PURE__ */ jsxs89("div", { css: editorContainerWrapper, ref: onPortalContainerRef, children: [
23003
23152
  /* @__PURE__ */ jsxs89(
23004
23153
  "div",
@@ -23045,7 +23194,8 @@ var RichText = ({
23045
23194
  positioningAnchorEl: editorContainerRef
23046
23195
  }
23047
23196
  ) : null,
23048
- /* @__PURE__ */ jsx133(TableSelectionPlugin_default, {})
23197
+ /* @__PURE__ */ jsx133(TableSelectionPlugin_default, {}),
23198
+ /* @__PURE__ */ jsx133(ImprovedAssetSelectionPlugin_default, {})
23049
23199
  ] })
23050
23200
  ] });
23051
23201
  };
@@ -23322,7 +23472,7 @@ var ProgressListItem = ({
23322
23472
  // src/components/SegmentedControl/SegmentedControl.tsx
23323
23473
  import { css as css106 } from "@emotion/react";
23324
23474
  import { CgCheck as CgCheck5 } from "@react-icons/all-files/cg/CgCheck";
23325
- import { useCallback as useCallback14, useEffect as useEffect25, useMemo as useMemo9, useRef as useRef14, useState as useState22 } from "react";
23475
+ import { useCallback as useCallback14, useEffect as useEffect26, useMemo as useMemo9, useRef as useRef14, useState as useState22 } from "react";
23326
23476
 
23327
23477
  // src/components/SegmentedControl/SegmentedControl.styles.ts
23328
23478
  import { css as css105 } from "@emotion/react";
@@ -23536,7 +23686,7 @@ var SegmentedControl = ({
23536
23686
  const isIconOnly = useMemo9(() => {
23537
23687
  return options.every((option) => option && option.icon && !option.label);
23538
23688
  }, [options]);
23539
- useEffect25(() => {
23689
+ useEffect26(() => {
23540
23690
  const wrapperElement = wrapperRef.current;
23541
23691
  const onScroll = () => {
23542
23692
  if (!wrapperElement) {
@@ -23864,7 +24014,7 @@ import {
23864
24014
  TabProvider as AriakitTabProvider,
23865
24015
  useTabStore as useAriakitTabStore
23866
24016
  } from "@ariakit/react";
23867
- import { useCallback as useCallback15, useEffect as useEffect26, useMemo as useMemo10 } from "react";
24017
+ import { useCallback as useCallback15, useEffect as useEffect27, useMemo as useMemo10 } from "react";
23868
24018
 
23869
24019
  // src/components/Tabs/Tabs.styles.ts
23870
24020
  import { css as css110 } from "@emotion/react";
@@ -23924,7 +24074,7 @@ var Tabs = ({
23924
24074
  },
23925
24075
  [onSelectedIdChange, useHashForState]
23926
24076
  );
23927
- useEffect26(() => {
24077
+ useEffect27(() => {
23928
24078
  if (selected && selected !== tab.getState().activeId) {
23929
24079
  tab.setSelectedId(selected);
23930
24080
  }