@uniformdev/design-system 19.186.4-alpha.4 → 19.187.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/esm/index.js CHANGED
@@ -50,6 +50,7 @@ var Theme = ({ disableReset = false, disableGlobalReset = false }) => {
50
50
  --purple-rain-600: #6340a9;
51
51
 
52
52
  /* raspberry spectrum*/
53
+ --raspberry-beret-50: #fefafc;
53
54
  --raspberry-beret-100: #ffbee1;
54
55
  --raspberry-beret-200: #ff94ce;
55
56
  --raspberry-beret-300: #ff6aba;
@@ -11824,6 +11825,9 @@ var avatarImageStyles = css19`
11824
11825
  height: 100%;
11825
11826
  object-fit: cover;
11826
11827
  `;
11828
+ var avatarSize2xsStyles = css19`
11829
+ width: 1rem;
11830
+ `;
11827
11831
  var avatarSizeXsStyles = css19`
11828
11832
  width: 1.5rem;
11829
11833
  `;
@@ -11837,20 +11841,26 @@ var avatarSizeLgStyles = css19`
11837
11841
  width: 3rem;
11838
11842
  `;
11839
11843
  var avatarSizeXlStyles = css19`
11840
- width: 3.5rem;
11844
+ width: 4rem;
11845
+ `;
11846
+ var avatarSize2xlStyles = css19`
11847
+ width: 5rem;
11841
11848
  `;
11842
11849
 
11843
11850
  // src/components/Avatar/Avatar.tsx
11844
11851
  import { jsx as jsx20, jsxs as jsxs8 } from "@emotion/react/jsx-runtime";
11845
11852
  var avatarSizeStylesMap = {
11853
+ "2xs": avatarSize2xsStyles,
11846
11854
  xs: avatarSizeXsStyles,
11847
11855
  sm: avatarSizeSmStyles,
11848
11856
  md: avatarSizeMdStyles,
11849
11857
  lg: avatarSizeLgStyles,
11850
- xl: avatarSizeXlStyles
11858
+ xl: avatarSizeXlStyles,
11859
+ "2xl": avatarSize2xlStyles
11851
11860
  };
11852
- var Avatar = ({ src, label = "", children, size = "md", ...props }) => {
11853
- return /* @__PURE__ */ jsx20(Tooltip, { title: label, children: /* @__PURE__ */ jsxs8("div", { css: [avatarStyles, avatarSizeStylesMap[size]], ...props, children: [
11861
+ var Avatar = ({ src, label = "", children, size = "md", as = "div", ...props }) => {
11862
+ const Element = as;
11863
+ return /* @__PURE__ */ jsx20(Tooltip, { title: label, children: /* @__PURE__ */ jsxs8(Element, { css: [avatarStyles, avatarSizeStylesMap[size]], ...props, children: [
11854
11864
  !src ? null : /* @__PURE__ */ jsx20("img", { role: "presentation", src, css: avatarImageStyles }),
11855
11865
  children
11856
11866
  ] }) });
@@ -12357,7 +12367,7 @@ var menuItem = (textTheme, forceActive) => css26`
12357
12367
  align-items: center;
12358
12368
  border-radius: var(--rounded-base);
12359
12369
  background: none;
12360
- color: ${textTheme === "base" ? "var(--typography-base)" : "var(--brand-secondary-5)"};
12370
+ color: ${textTheme === "base" ? "var(--typography-base)" : textTheme === "accent-alt" ? "var(--accent-alt-dark)" : "var(--brand-secondary-5)"};
12361
12371
  display: flex;
12362
12372
  padding: var(--spacing-3);
12363
12373
  font-weight: var(--fw-regular);
@@ -16409,6 +16419,7 @@ var DrawerContentInner = css59`
16409
16419
  height: 100%;
16410
16420
  overflow-y: auto;
16411
16421
  ${scrollbarStyles}
16422
+ border-radius: var(--rounded-base);
16412
16423
  `;
16413
16424
  var DrawerContentBtnGroup = css59`
16414
16425
  display: flex;
@@ -18170,10 +18181,10 @@ var loader = css77`
18170
18181
  display: inline-flex;
18171
18182
  justify-content: center;
18172
18183
  `;
18173
- function loadingDot(size) {
18184
+ function loadingDot(size, backgroundColor) {
18174
18185
  const dotSize = size === "lg" ? 8 : 4;
18175
18186
  return css77`
18176
- background-color: var(--gray-700);
18187
+ background-color: ${backgroundColor};
18177
18188
  display: block;
18178
18189
  border-radius: var(--rounded-full);
18179
18190
  animation: ${bounceFade(size)} 0.75s infinite ease-in-out;
@@ -18198,11 +18209,13 @@ function loadingDot(size) {
18198
18209
 
18199
18210
  // src/components/LoadingIndicator/LoadingIndicator.tsx
18200
18211
  import { jsx as jsx98, jsxs as jsxs63 } from "@emotion/react/jsx-runtime";
18201
- var LoadingIndicator = ({
18202
- size = "lg",
18203
- ...props
18204
- }) => {
18205
- const dotStyle = loadingDot(size);
18212
+ var cssColorMap = {
18213
+ gray: "var(--gray-700)",
18214
+ "accent-alt": "var(--accent-alt-dark)"
18215
+ };
18216
+ var LoadingIndicator = ({ size = "lg", color = "gray", ...props }) => {
18217
+ const cssColor = cssColorMap[color];
18218
+ const dotStyle = loadingDot(size, cssColor);
18206
18219
  return /* @__PURE__ */ jsxs63("div", { role: "alert", css: loader, "data-testid": "loading-indicator", ...props, children: [
18207
18220
  /* @__PURE__ */ jsx98("span", { css: dotStyle }),
18208
18221
  /* @__PURE__ */ jsx98("span", { css: dotStyle }),
@@ -20392,7 +20405,7 @@ import {
20392
20405
  UNORDERED_LIST
20393
20406
  } from "@lexical/markdown";
20394
20407
  import { LexicalComposer } from "@lexical/react/LexicalComposer";
20395
- import { useLexicalComposerContext as useLexicalComposerContext8 } from "@lexical/react/LexicalComposerContext";
20408
+ import { useLexicalComposerContext as useLexicalComposerContext9 } from "@lexical/react/LexicalComposerContext";
20396
20409
  import { ContentEditable } from "@lexical/react/LexicalContentEditable";
20397
20410
  import LexicalErrorBoundary from "@lexical/react/LexicalErrorBoundary";
20398
20411
  import { HistoryPlugin } from "@lexical/react/LexicalHistoryPlugin";
@@ -20404,6 +20417,12 @@ import { HeadingNode, QuoteNode } from "@lexical/rich-text";
20404
20417
  import { TableCellNode as TableCellNode3, TableNode, TableRowNode as TableRowNode2 } from "@lexical/table";
20405
20418
 
20406
20419
  // ../richtext/dist/index.mjs
20420
+ function isRichTextNode(node) {
20421
+ return !!node && typeof node === "object" && "type" in node;
20422
+ }
20423
+ function isRichTextNodeType(node, type) {
20424
+ return isRichTextNode(node) && node.type === type;
20425
+ }
20407
20426
  var richTextBuiltInElements = [
20408
20427
  {
20409
20428
  label: "Heading 1",
@@ -20453,6 +20472,10 @@ var richTextBuiltInElements = [
20453
20472
  label: "Table",
20454
20473
  type: "table"
20455
20474
  },
20475
+ {
20476
+ label: "Asset",
20477
+ type: "asset"
20478
+ },
20456
20479
  {
20457
20480
  label: "Dynamic Token",
20458
20481
  type: "variable"
@@ -20500,7 +20523,7 @@ var getLabelForElement = (type) => {
20500
20523
  // src/components/ParameterInputs/ParameterRichText.tsx
20501
20524
  import { deepEqual as deepEqual2 } from "fast-equals";
20502
20525
  import { ParagraphNode as ParagraphNode2 } from "lexical";
20503
- import { useEffect as useEffect24, useState as useState21 } from "react";
20526
+ import { useEffect as useEffect25, useState as useState21 } from "react";
20504
20527
 
20505
20528
  // src/components/ParameterInputs/rich-text/CustomCodeNode.ts
20506
20529
  import { CodeNode } from "@lexical/code";
@@ -20779,11 +20802,70 @@ var tableHeaderElement = css96`
20779
20802
  width: 7rem;
20780
20803
  `;
20781
20804
 
20805
+ // src/components/ParameterInputs/rich-text/ImprovedAssetSelectionPlugin.tsx
20806
+ import { useLexicalComposerContext as useLexicalComposerContext2 } from "@lexical/react/LexicalComposerContext";
20807
+ import { $insertFirst } from "@lexical/utils";
20808
+ import { $createParagraphNode, $getRoot, $insertNodes } from "lexical";
20809
+ import { useEffect as useEffect18 } from "react";
20810
+ var ImprovedAssetSelectionPlugin = () => {
20811
+ const [editor] = useLexicalComposerContext2();
20812
+ useEffect18(() => {
20813
+ editor.getRootElement();
20814
+ const onRootClick = (event) => {
20815
+ if (event.target !== editor.getRootElement()) {
20816
+ return;
20817
+ }
20818
+ const clickArea = event.offsetY <= 60 ? "top" : "bottom";
20819
+ const state = editor.getEditorState().toJSON();
20820
+ const firstNode = state.root.children[0];
20821
+ const lastNode = state.root.children.at(-1);
20822
+ if (isRichTextNodeType(firstNode, "asset") && clickArea === "top") {
20823
+ editor.update(() => {
20824
+ $insertFirst($getRoot(), $createParagraphNode());
20825
+ requestAnimationFrame(() => {
20826
+ var _a, _b;
20827
+ (_b = (_a = editor.getRootElement()) == null ? void 0 : _a.parentElement) == null ? void 0 : _b.scrollTo({
20828
+ top: 0,
20829
+ behavior: "instant"
20830
+ });
20831
+ });
20832
+ });
20833
+ } else if (isRichTextNodeType(lastNode, "asset") && clickArea === "bottom") {
20834
+ editor.update(() => {
20835
+ $getRoot().selectEnd();
20836
+ $insertNodes([$createParagraphNode()]);
20837
+ requestAnimationFrame(() => {
20838
+ var _a, _b, _c, _d;
20839
+ (_d = (_a = editor.getRootElement()) == null ? void 0 : _a.parentElement) == null ? void 0 : _d.scrollTo({
20840
+ top: (_c = (_b = editor.getRootElement()) == null ? void 0 : _b.parentElement) == null ? void 0 : _c.scrollHeight,
20841
+ behavior: "instant"
20842
+ });
20843
+ });
20844
+ });
20845
+ }
20846
+ };
20847
+ const removeRootListener = editor.registerRootListener((rootElement, prevRootElement) => {
20848
+ rootElement == null ? void 0 : rootElement.addEventListener("click", onRootClick);
20849
+ prevRootElement == null ? void 0 : prevRootElement.removeEventListener("click", onRootClick);
20850
+ });
20851
+ return () => {
20852
+ removeRootListener();
20853
+ };
20854
+ }, [editor]);
20855
+ return null;
20856
+ };
20857
+ var ImprovedAssetSelectionPlugin_default = ImprovedAssetSelectionPlugin;
20858
+
20782
20859
  // src/components/ParameterInputs/rich-text/LinkNodePlugin.tsx
20783
20860
  import { css as css97 } from "@emotion/react";
20784
- import { useLexicalComposerContext as useLexicalComposerContext2 } from "@lexical/react/LexicalComposerContext";
20861
+ import { useLexicalComposerContext as useLexicalComposerContext3 } from "@lexical/react/LexicalComposerContext";
20785
20862
  import { NodeEventPlugin } from "@lexical/react/LexicalNodeEventPlugin";
20786
- import { addClassNamesToElement, isHTMLAnchorElement, mergeRegister as mergeRegister2 } from "@lexical/utils";
20863
+ import {
20864
+ addClassNamesToElement,
20865
+ isHTMLAnchorElement,
20866
+ mergeRegister as mergeRegister2,
20867
+ objectKlassEquals
20868
+ } from "@lexical/utils";
20787
20869
  import { deepEqual } from "fast-equals";
20788
20870
  import {
20789
20871
  $applyNodeReplacement,
@@ -20792,11 +20874,13 @@ import {
20792
20874
  $isRangeSelection,
20793
20875
  BLUR_COMMAND,
20794
20876
  COMMAND_PRIORITY_EDITOR,
20877
+ COMMAND_PRIORITY_LOW,
20795
20878
  createCommand,
20796
20879
  ElementNode as ElementNode2,
20797
- FOCUS_COMMAND
20880
+ FOCUS_COMMAND,
20881
+ PASTE_COMMAND
20798
20882
  } from "lexical";
20799
- import { useCallback as useCallback10, useEffect as useEffect18, useRef as useRef11, useState as useState16 } from "react";
20883
+ import { useCallback as useCallback10, useEffect as useEffect19, useRef as useRef11, useState as useState16 } from "react";
20800
20884
 
20801
20885
  // src/components/ParameterInputs/rich-text/utils.ts
20802
20886
  import { $isAtNodeEnd } from "@lexical/selection";
@@ -20913,9 +20997,7 @@ function convertAnchorElement(domNode) {
20913
20997
  nodeId,
20914
20998
  dynamicInputValues
20915
20999
  };
20916
- if (isProjectMapLinkValue(value)) {
20917
- node = $createLinkNode(value);
20918
- } else if (isNonProjectMapLinkValue(value)) {
21000
+ if (isProjectMapLinkValue(value) || isNonProjectMapLinkValue(value)) {
20919
21001
  node = $createLinkNode(value);
20920
21002
  }
20921
21003
  return { node };
@@ -21069,6 +21151,10 @@ function upsertLinkNode(props) {
21069
21151
  continue;
21070
21152
  }
21071
21153
  const linkNodeAncestor = getLinkAncestor(node);
21154
+ if ($isLinkNode(node)) {
21155
+ node.setLink(props);
21156
+ continue;
21157
+ }
21072
21158
  if (!linkNodeAncestor) {
21073
21159
  const newLinkNode = $createLinkNode(props);
21074
21160
  node.insertBefore(newLinkNode);
@@ -21141,18 +21227,18 @@ function LinkNodePlugin({
21141
21227
  const parsePath = getBoundPath != null ? getBoundPath : function(path) {
21142
21228
  return path;
21143
21229
  };
21144
- const [editor] = useLexicalComposerContext2();
21230
+ const [editor] = useLexicalComposerContext3();
21145
21231
  const [linkPopoverState, setLinkPopoverState] = useState16();
21146
21232
  const linkPopoverElRef = useRef11(null);
21147
21233
  const [isEditorFocused, setIsEditorFocused] = useState16(false);
21148
21234
  const [isLinkPopoverFocused, setIsLinkPopoverFocused] = useState16(false);
21149
- useEffect18(() => {
21235
+ useEffect19(() => {
21150
21236
  if (!isEditorFocused && !isLinkPopoverFocused) {
21151
21237
  setLinkPopoverState(void 0);
21152
21238
  return;
21153
21239
  }
21154
21240
  }, [isEditorFocused, isLinkPopoverFocused]);
21155
- useEffect18(() => {
21241
+ useEffect19(() => {
21156
21242
  if (!editor.hasNodes([LinkNode])) {
21157
21243
  throw new Error("LinkNode not registered on editor");
21158
21244
  }
@@ -21218,6 +21304,41 @@ function LinkNodePlugin({
21218
21304
  return true;
21219
21305
  },
21220
21306
  COMMAND_PRIORITY_EDITOR
21307
+ ),
21308
+ // Support pasting of links from clipboard
21309
+ editor.registerCommand(
21310
+ PASTE_COMMAND,
21311
+ (event) => {
21312
+ const selection = $getSelection();
21313
+ if (!$isRangeSelection(selection) || selection.isCollapsed() || !objectKlassEquals(event, ClipboardEvent)) {
21314
+ return false;
21315
+ }
21316
+ const clipboardEvent = event;
21317
+ if (clipboardEvent.clipboardData === null) {
21318
+ return false;
21319
+ }
21320
+ const clipboardText = clipboardEvent.clipboardData.getData("text");
21321
+ if (!isValidUrl(clipboardText)) {
21322
+ return false;
21323
+ }
21324
+ if (selection.getNodes().some((node) => $isElementNode2(node) && !$isLinkNode(node))) {
21325
+ return false;
21326
+ }
21327
+ let path = clipboardText;
21328
+ const type = guessLinkTypeFromPath(path);
21329
+ if (type === "email" && path.startsWith("mailto:")) {
21330
+ path = path.replace("mailto:", "");
21331
+ } else if (type === "tel" && path.startsWith("tel:")) {
21332
+ path = path.replace("tel:", "");
21333
+ }
21334
+ upsertLinkNode({
21335
+ path,
21336
+ type
21337
+ });
21338
+ event.preventDefault();
21339
+ return true;
21340
+ },
21341
+ COMMAND_PRIORITY_LOW
21221
21342
  )
21222
21343
  );
21223
21344
  }, [editor, onConnectLink]);
@@ -21255,7 +21376,7 @@ function LinkNodePlugin({
21255
21376
  }
21256
21377
  });
21257
21378
  }, [editor, positioningAnchorEl]);
21258
- useEffect18(() => {
21379
+ useEffect19(() => {
21259
21380
  return editor.registerUpdateListener(({ editorState }) => {
21260
21381
  requestAnimationFrame(() => {
21261
21382
  editorState.read(() => {
@@ -21339,7 +21460,7 @@ function getLinkAncestor(node) {
21339
21460
 
21340
21461
  // src/components/ParameterInputs/rich-text/ListIndentPlugin.tsx
21341
21462
  import { $getListDepth, $isListItemNode, $isListNode, ListNode } from "@lexical/list";
21342
- import { useLexicalComposerContext as useLexicalComposerContext3 } from "@lexical/react/LexicalComposerContext";
21463
+ import { useLexicalComposerContext as useLexicalComposerContext4 } from "@lexical/react/LexicalComposerContext";
21343
21464
  import {
21344
21465
  $filter,
21345
21466
  $getNearestBlockElementAncestorOrThrow,
@@ -21359,7 +21480,7 @@ import {
21359
21480
  OUTDENT_CONTENT_COMMAND,
21360
21481
  SELECTION_CHANGE_COMMAND
21361
21482
  } from "lexical";
21362
- import { useEffect as useEffect19, useRef as useRef12 } from "react";
21483
+ import { useEffect as useEffect20, useRef as useRef12 } from "react";
21363
21484
  function isIndentPermitted(maxDepth) {
21364
21485
  const selection = $getSelection2();
21365
21486
  if (!$isRangeSelection2(selection)) {
@@ -21413,9 +21534,9 @@ function $indentOverTab(selection) {
21413
21534
  return false;
21414
21535
  }
21415
21536
  function ListIndentPlugin({ maxDepth }) {
21416
- const [editor] = useLexicalComposerContext3();
21537
+ const [editor] = useLexicalComposerContext4();
21417
21538
  const isInListItemNode = useRef12(false);
21418
- useEffect19(() => {
21539
+ useEffect20(() => {
21419
21540
  return editor.registerCommand(
21420
21541
  SELECTION_CHANGE_COMMAND,
21421
21542
  () => {
@@ -21432,7 +21553,7 @@ function ListIndentPlugin({ maxDepth }) {
21432
21553
  COMMAND_PRIORITY_NORMAL
21433
21554
  );
21434
21555
  }, [editor]);
21435
- useEffect19(() => {
21556
+ useEffect20(() => {
21436
21557
  return mergeRegister3(
21437
21558
  editor.registerCommand(
21438
21559
  INDENT_CONTENT_COMMAND,
@@ -21460,1242 +21581,1269 @@ function ListIndentPlugin({ maxDepth }) {
21460
21581
  return null;
21461
21582
  }
21462
21583
 
21463
- // src/components/ParameterInputs/rich-text/RichTextToolbar.tsx
21584
+ // src/components/ParameterInputs/rich-text/TableActionMenuPlugin.tsx
21464
21585
  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";
21586
+ import { useLexicalComposerContext as useLexicalComposerContext5 } from "@lexical/react/LexicalComposerContext";
21587
+ import { useLexicalEditable } from "@lexical/react/useLexicalEditable";
21478
21588
  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);
21589
+ $deleteTableColumn__EXPERIMENTAL,
21590
+ $deleteTableRow__EXPERIMENTAL,
21591
+ $getTableCellNodeFromLexicalNode,
21592
+ $getTableColumnIndexFromTableCellNode,
21593
+ $getTableNodeFromLexicalNodeOrThrow,
21594
+ $getTableRowIndexFromTableCellNode,
21595
+ $insertTableColumn__EXPERIMENTAL,
21596
+ $insertTableRow__EXPERIMENTAL,
21597
+ $isTableCellNode,
21598
+ $isTableRowNode,
21599
+ $isTableSelection,
21600
+ getTableObserverFromTableElement,
21601
+ TableCellHeaderStates,
21602
+ TableCellNode
21603
+ } from "@lexical/table";
21604
+ import { $getRoot as $getRoot2, $getSelection as $getSelection3, $isRangeSelection as $isRangeSelection3 } from "lexical";
21605
+ import { forwardRef as forwardRef22, useCallback as useCallback11, useEffect as useEffect21, useLayoutEffect, useState as useState17 } from "react";
21606
+ import { jsx as jsx130, jsxs as jsxs86 } from "@emotion/react/jsx-runtime";
21607
+ function computeSelectionCount(selection) {
21608
+ const selectionShape = selection.getShape();
21609
+ return {
21610
+ columns: selectionShape.toX - selectionShape.fromX + 1,
21611
+ rows: selectionShape.toY - selectionShape.fromY + 1
21612
+ };
21613
+ }
21614
+ var tableActionMenuTrigger = css98`
21615
+ position: absolute;
21616
+ transform: translate(calc(-100% - 1px), 1px);
21547
21617
  `;
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
- });
21618
+ var TableActionMenuTrigger = forwardRef22((props, ref) => {
21619
+ const { tableCellEl, positioningAnchorEl, ...rest } = props;
21620
+ const [coordinates, setCoordinates] = useState17({ x: 0, y: 0 });
21621
+ useLayoutEffect(() => {
21622
+ const rect = tableCellEl.getBoundingClientRect();
21623
+ const parentRect = positioningAnchorEl.getBoundingClientRect();
21624
+ const relativeX = rect.right - parentRect.left + positioningAnchorEl.scrollLeft;
21625
+ const relativeY = rect.top - parentRect.top + positioningAnchorEl.scrollTop;
21626
+ setCoordinates({ x: relativeX, y: relativeY });
21627
+ }, [tableCellEl, positioningAnchorEl]);
21628
+ return /* @__PURE__ */ jsx130(
21629
+ IconButton,
21630
+ {
21631
+ ref,
21632
+ css: [
21633
+ tableActionMenuTrigger,
21634
+ {
21635
+ top: coordinates.y,
21636
+ left: coordinates.x
21609
21637
  }
21610
- });
21611
- });
21612
- };
21613
- const updateToolbar = useCallback11(() => {
21614
- const selection = $getSelection3();
21615
- if (!$isRangeSelection3(selection)) {
21616
- return;
21638
+ ],
21639
+ size: "xs",
21640
+ buttonType: "unimportant",
21641
+ ...rest,
21642
+ children: /* @__PURE__ */ jsx130(Icon, { icon: "chevron-down", size: "1rem", iconColor: "currentColor" })
21617
21643
  }
21618
- const newActiveFormats = [];
21619
- for (const format of richTextBuiltInFormats) {
21620
- if (selection.hasFormat(format.type)) {
21621
- newActiveFormats.push(format.type);
21644
+ );
21645
+ });
21646
+ TableActionMenuTrigger.displayName = "TableActionMenuTrigger";
21647
+ function TableActionMenu({
21648
+ tableCellNode: _tableCellNode,
21649
+ menuPortalEl,
21650
+ tableCellEl,
21651
+ positioningAnchorEl
21652
+ }) {
21653
+ const [editor] = useLexicalComposerContext5();
21654
+ const [tableCellNode, updateTableCellNode] = useState17(_tableCellNode);
21655
+ const [selectionCounts, updateSelectionCounts] = useState17({
21656
+ columns: 1,
21657
+ rows: 1
21658
+ });
21659
+ const [menuTriggerKey, setMenuTriggerKey] = useState17(0);
21660
+ const incrementMenuTriggerKey = () => {
21661
+ setMenuTriggerKey((key) => key += 1);
21662
+ };
21663
+ useEffect21(() => {
21664
+ return editor.registerMutationListener(
21665
+ TableCellNode,
21666
+ (nodeMutations) => {
21667
+ const nodeUpdated = nodeMutations.get(tableCellNode.getKey()) === "updated";
21668
+ if (nodeUpdated) {
21669
+ editor.getEditorState().read(() => {
21670
+ updateTableCellNode(tableCellNode.getLatest());
21671
+ });
21672
+ }
21673
+ },
21674
+ { skipInitialization: true }
21675
+ );
21676
+ }, [editor, tableCellNode]);
21677
+ useEffect21(() => {
21678
+ editor.getEditorState().read(() => {
21679
+ const selection = $getSelection3();
21680
+ if ($isTableSelection(selection)) {
21681
+ updateSelectionCounts(computeSelectionCount(selection));
21622
21682
  }
21623
- }
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
21683
  });
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);
21684
+ }, [editor]);
21685
+ const clearTableSelection = useCallback11(() => {
21686
+ editor.update(() => {
21687
+ if (tableCellNode.isAttached()) {
21688
+ const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
21689
+ const tableElement2 = editor.getElementByKey(
21690
+ tableNode.getKey()
21691
+ );
21692
+ if (!tableElement2) {
21693
+ throw new Error("Expected to find tableElement in DOM");
21694
+ }
21695
+ const tableSelection = getTableObserverFromTableElement(tableElement2);
21696
+ if (tableSelection !== null) {
21697
+ tableSelection.clearHighlight();
21698
+ }
21699
+ tableNode.markDirty();
21700
+ updateTableCellNode(tableCellNode.getLatest());
21643
21701
  }
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;
21658
- },
21659
- COMMAND_PRIORITY_CRITICAL2
21660
- );
21661
- }, [editor, updateToolbar]);
21662
- useEffect20(() => {
21663
- return editor.registerUpdateListener(({ editorState }) => {
21664
- requestAnimationFrame(() => {
21665
- editorState.read(() => {
21666
- updateToolbar();
21667
- });
21702
+ const rootNode = $getRoot2();
21703
+ rootNode.selectStart();
21704
+ });
21705
+ }, [editor, tableCellNode]);
21706
+ const insertTableRowAtSelection = useCallback11(
21707
+ (shouldInsertAfter) => {
21708
+ editor.update(() => {
21709
+ $insertTableRow__EXPERIMENTAL(shouldInsertAfter);
21710
+ });
21711
+ incrementMenuTriggerKey();
21712
+ },
21713
+ [editor]
21714
+ );
21715
+ const insertTableColumnAtSelection = useCallback11(
21716
+ (shouldInsertAfter) => {
21717
+ editor.update(() => {
21718
+ for (let i = 0; i < selectionCounts.columns; i++) {
21719
+ $insertTableColumn__EXPERIMENTAL(shouldInsertAfter);
21720
+ }
21668
21721
  });
21722
+ incrementMenuTriggerKey();
21723
+ },
21724
+ [editor, selectionCounts.columns]
21725
+ );
21726
+ const deleteTableRowAtSelection = useCallback11(() => {
21727
+ editor.update(() => {
21728
+ $deleteTableRow__EXPERIMENTAL();
21669
21729
  });
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
- ]
21730
+ incrementMenuTriggerKey();
21731
+ }, [editor]);
21732
+ const deleteTableAtSelection = useCallback11(() => {
21733
+ editor.update(() => {
21734
+ const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
21735
+ tableNode.remove();
21736
+ clearTableSelection();
21737
+ });
21738
+ }, [editor, tableCellNode, clearTableSelection]);
21739
+ const deleteTableColumnAtSelection = useCallback11(() => {
21740
+ editor.update(() => {
21741
+ $deleteTableColumn__EXPERIMENTAL();
21742
+ });
21743
+ incrementMenuTriggerKey();
21744
+ }, [editor]);
21745
+ const toggleTableRowIsHeader = useCallback11(() => {
21746
+ editor.update(() => {
21747
+ const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
21748
+ const tableRowIndex = $getTableRowIndexFromTableCellNode(tableCellNode);
21749
+ const tableRows = tableNode.getChildren();
21750
+ if (tableRowIndex >= tableRows.length || tableRowIndex < 0) {
21751
+ throw new Error("Expected table cell to be inside of table row.");
21700
21752
  }
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) })
21753
+ const tableRow2 = tableRows[tableRowIndex];
21754
+ if (!$isTableRowNode(tableRow2)) {
21755
+ throw new Error("Expected table row");
21756
+ }
21757
+ tableRow2.getChildren().forEach((tableCell) => {
21758
+ if (!$isTableCellNode(tableCell)) {
21759
+ throw new Error("Expected table cell");
21714
21760
  }
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
- ))
21761
+ tableCell.toggleHeaderStyle(TableCellHeaderStates.ROW);
21762
+ });
21763
+ clearTableSelection();
21764
+ });
21765
+ }, [editor, tableCellNode, clearTableSelection]);
21766
+ const toggleTableColumnIsHeader = useCallback11(() => {
21767
+ editor.update(() => {
21768
+ const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
21769
+ const tableColumnIndex = $getTableColumnIndexFromTableCellNode(tableCellNode);
21770
+ const tableRows = tableNode.getChildren();
21771
+ const maxRowsLength = Math.max(...tableRows.map((row) => row.getChildren().length));
21772
+ if (tableColumnIndex >= maxRowsLength || tableColumnIndex < 0) {
21773
+ throw new Error("Expected table cell to be inside of table row.");
21774
+ }
21775
+ for (let r = 0; r < tableRows.length; r++) {
21776
+ const tableRow2 = tableRows[r];
21777
+ if (!$isTableRowNode(tableRow2)) {
21778
+ throw new Error("Expected table row");
21732
21779
  }
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" })
21780
+ const tableCells = tableRow2.getChildren();
21781
+ if (tableColumnIndex >= tableCells.length) {
21782
+ continue;
21744
21783
  }
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",
21784
+ const tableCell = tableCells[tableColumnIndex];
21785
+ if (!$isTableCellNode(tableCell)) {
21786
+ throw new Error("Expected table cell");
21787
+ }
21788
+ tableCell.toggleHeaderStyle(TableCellHeaderStates.COLUMN);
21789
+ }
21790
+ clearTableSelection();
21791
+ });
21792
+ }, [editor, tableCellNode, clearTableSelection]);
21793
+ const menuItemCss = css98({
21794
+ fontSize: "var(--fs-sm)"
21795
+ });
21796
+ return /* @__PURE__ */ jsxs86(
21797
+ Menu,
21798
+ {
21799
+ menuTrigger: /* @__PURE__ */ jsx130(
21800
+ TableActionMenuTrigger,
21801
+ {
21802
+ tableCellEl,
21803
+ positioningAnchorEl
21804
+ },
21805
+ menuTriggerKey
21806
+ ),
21807
+ portalElement: menuPortalEl,
21808
+ maxMenuHeight: "300px",
21809
+ children: [
21810
+ /* @__PURE__ */ jsxs86(
21811
+ MenuItem,
21749
21812
  {
21750
21813
  onClick: () => {
21751
- activeElement === "unorderedList" ? editor.dispatchCommand(REMOVE_LIST_COMMAND, void 0) : editor.dispatchCommand(INSERT_UNORDERED_LIST_COMMAND, void 0);
21814
+ insertTableRowAtSelection(false);
21752
21815
  },
21753
- css: [
21754
- richTextToolbarButton,
21755
- activeElement === "unorderedList" ? richTextToolbarButtonActive : null
21756
- ],
21757
- children: /* @__PURE__ */ jsx130(RichTextToolbarIcon, { icon: "layout-list" })
21758
- }
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" })
21816
+ css: menuItemCss,
21817
+ children: [
21818
+ "Insert ",
21819
+ selectionCounts.rows === 1 ? "row" : `${selectionCounts.rows} rows`,
21820
+ " above"
21821
+ ]
21771
21822
  }
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" })
21823
+ ),
21824
+ /* @__PURE__ */ jsxs86(MenuItem, { onClick: () => insertTableRowAtSelection(true), css: menuItemCss, children: [
21825
+ "Insert ",
21826
+ selectionCounts.rows === 1 ? "row" : `${selectionCounts.rows} rows`,
21827
+ " below"
21782
21828
  ] }),
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)
21829
+ /* @__PURE__ */ jsx130(MenuItemSeparator, {}),
21830
+ /* @__PURE__ */ jsxs86(MenuItem, { onClick: () => insertTableColumnAtSelection(false), css: menuItemCss, children: [
21831
+ "Insert ",
21832
+ selectionCounts.columns === 1 ? "column" : `${selectionCounts.columns} columns`,
21833
+ " left"
21834
+ ] }),
21835
+ /* @__PURE__ */ jsxs86(MenuItem, { onClick: () => insertTableColumnAtSelection(true), css: menuItemCss, children: [
21836
+ "Insert ",
21837
+ selectionCounts.columns === 1 ? "column" : `${selectionCounts.columns} columns`,
21838
+ " right"
21839
+ ] }),
21840
+ /* @__PURE__ */ jsx130(MenuItemSeparator, {}),
21841
+ /* @__PURE__ */ jsx130(MenuItem, { onClick: () => deleteTableColumnAtSelection(), css: menuItemCss, children: "Delete column" }),
21842
+ /* @__PURE__ */ jsx130(MenuItem, { onClick: () => deleteTableRowAtSelection(), css: menuItemCss, children: "Delete row" }),
21843
+ /* @__PURE__ */ jsx130(MenuItem, { onClick: () => deleteTableAtSelection(), css: menuItemCss, children: "Delete table" }),
21844
+ /* @__PURE__ */ jsx130(MenuItemSeparator, {}),
21845
+ /* @__PURE__ */ jsxs86(MenuItem, { onClick: () => toggleTableRowIsHeader(), css: menuItemCss, children: [
21846
+ (tableCellNode.__headerState & TableCellHeaderStates.ROW) === TableCellHeaderStates.ROW ? "Remove" : "Add",
21847
+ " ",
21848
+ "row header"
21849
+ ] }),
21850
+ /* @__PURE__ */ jsxs86(MenuItem, { onClick: () => toggleTableColumnIsHeader(), css: menuItemCss, children: [
21851
+ (tableCellNode.__headerState & TableCellHeaderStates.COLUMN) === TableCellHeaderStates.COLUMN ? "Remove" : "Add",
21852
+ " ",
21853
+ "column header"
21854
+ ] })
21855
+ ]
21856
+ }
21865
21857
  );
21866
- const visibleTextualElements = useMemo6(() => {
21867
- if (!TEXTUAL_ELEMENTS.includes(activeElement)) {
21868
- return enabledTextualElements;
21858
+ }
21859
+ function TableCellActionMenuContainer({
21860
+ menuPortalEl,
21861
+ positioningAnchorEl
21862
+ }) {
21863
+ const [editor] = useLexicalComposerContext5();
21864
+ const [tableCellNode, setTableMenuCellNode] = useState17(null);
21865
+ const [tableCellNodeEl, _setTableMenuCellNodeEl] = useState17(null);
21866
+ const [tableCellMenuPortalEl, setTableMenuCellMenuPortalEl] = useState17(null);
21867
+ useEffect21(() => {
21868
+ const newPortalEl = document.createElement("div");
21869
+ setTableMenuCellMenuPortalEl(newPortalEl);
21870
+ menuPortalEl.appendChild(newPortalEl);
21871
+ return () => {
21872
+ newPortalEl.remove();
21873
+ };
21874
+ }, [menuPortalEl]);
21875
+ const setTableMenuCellNodeElem = useCallback11((elem) => {
21876
+ if (elem) {
21877
+ _setTableMenuCellNodeEl(elem);
21878
+ } else {
21879
+ _setTableMenuCellNodeEl(null);
21869
21880
  }
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);
21881
+ }, []);
21882
+ const $moveMenu = useCallback11(() => {
21883
+ const selection = $getSelection3();
21884
+ const nativeSelection = window.getSelection();
21885
+ const activeElement = document.activeElement;
21886
+ if (selection == null) {
21887
+ setTableMenuCellNode(null);
21888
+ return;
21889
+ }
21890
+ const rootElement = editor.getRootElement();
21891
+ if ($isRangeSelection3(selection) && rootElement !== null && nativeSelection !== null && rootElement.contains(nativeSelection.anchorNode)) {
21892
+ const tableCellNodeFromSelection = $getTableCellNodeFromLexicalNode(selection.anchor.getNode());
21893
+ if (tableCellNodeFromSelection == null) {
21894
+ setTableMenuCellNode(null);
21895
+ setTableMenuCellNodeElem(null);
21896
+ return;
21874
21897
  }
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");
21898
+ const tableCellParentNodeDOM = editor.getElementByKey(tableCellNodeFromSelection.getKey());
21899
+ if (tableCellParentNodeDOM == null) {
21900
+ setTableMenuCellNode(null);
21901
+ setTableMenuCellNodeElem(null);
21902
+ return;
21903
+ }
21904
+ setTableMenuCellNode(tableCellNodeFromSelection);
21905
+ setTableMenuCellNodeElem(tableCellParentNodeDOM);
21906
+ } else if (!activeElement) {
21907
+ setTableMenuCellNode(null);
21908
+ setTableMenuCellNodeElem(null);
21901
21909
  }
21902
- if (visibleLists.size > 0) {
21903
- visibleLists.forEach((type) => {
21904
- visibleElements.add(type);
21910
+ }, [editor, setTableMenuCellNodeElem]);
21911
+ useEffect21(() => {
21912
+ return editor.registerUpdateListener(() => {
21913
+ editor.getEditorState().read(() => {
21914
+ $moveMenu();
21905
21915
  });
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
- };
21916
+ });
21917
+ });
21918
+ return tableCellNode != null && tableCellNodeEl != null && tableCellMenuPortalEl != null && /* @__PURE__ */ jsx130(
21919
+ TableActionMenu,
21920
+ {
21921
+ tableCellNode,
21922
+ menuPortalEl: tableCellMenuPortalEl,
21923
+ tableCellEl: tableCellNodeEl,
21924
+ positioningAnchorEl
21925
+ },
21926
+ tableCellNode.getKey()
21927
+ );
21928
+ }
21929
+ function TableActionMenuPlugin({
21930
+ positioningAnchorEl,
21931
+ menuPortalEl
21932
+ }) {
21933
+ const isEditable = useLexicalEditable();
21934
+ return isEditable ? /* @__PURE__ */ jsx130(TableCellActionMenuContainer, { menuPortalEl, positioningAnchorEl }) : null;
21935
+ }
21941
21936
 
21942
- // src/components/ParameterInputs/rich-text/TableActionMenuPlugin.tsx
21937
+ // src/components/ParameterInputs/rich-text/TableCellResizerPlugin.tsx
21943
21938
  import { css as css99 } from "@emotion/react";
21944
- import { useLexicalComposerContext as useLexicalComposerContext5 } from "@lexical/react/LexicalComposerContext";
21945
- import { useLexicalEditable } from "@lexical/react/useLexicalEditable";
21939
+ import { useLexicalComposerContext as useLexicalComposerContext6 } from "@lexical/react/LexicalComposerContext";
21940
+ import { useLexicalEditable as useLexicalEditable2 } from "@lexical/react/useLexicalEditable";
21946
21941
  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
21942
+ $computeTableMapSkipCellCheck,
21943
+ $getTableNodeFromLexicalNodeOrThrow as $getTableNodeFromLexicalNodeOrThrow2,
21944
+ $getTableRowIndexFromTableCellNode as $getTableRowIndexFromTableCellNode2,
21945
+ $isTableCellNode as $isTableCellNode2,
21946
+ $isTableRowNode as $isTableRowNode2
21961
21947
  } 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`
21948
+ import { calculateZoomLevel } from "@lexical/utils";
21949
+ import { $getNearestNodeFromDOMNode } from "lexical";
21950
+ import { useCallback as useCallback12, useEffect as useEffect22, useMemo as useMemo6, useRef as useRef13, useState as useState18 } from "react";
21951
+ import { createPortal as createPortal3 } from "react-dom";
21952
+ import { Fragment as Fragment19, jsx as jsx131, jsxs as jsxs87 } from "@emotion/react/jsx-runtime";
21953
+ var MIN_ROW_HEIGHT = 33;
21954
+ var MIN_COLUMN_WIDTH = 50;
21955
+ var tableResizer = css99`
21973
21956
  position: absolute;
21974
- transform: translate(calc(-100% - 1px), 1px);
21957
+ z-index: var(--z-10);
21975
21958
  `;
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" })
21959
+ var fixedGetDOMCellFromTarget = (node) => {
21960
+ let currentNode = node;
21961
+ while (currentNode != null) {
21962
+ const nodeName = currentNode.nodeName;
21963
+ if (nodeName === "TD" || nodeName === "TH") {
21964
+ const cell2 = currentNode._cell;
21965
+ if (cell2 === void 0) {
21966
+ return {
21967
+ elem: currentNode
21968
+ };
21969
+ }
21970
+ return cell2;
22001
21971
  }
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);
21972
+ currentNode = currentNode.parentNode;
21973
+ }
21974
+ return null;
21975
+ };
21976
+ function TableCellResizer({ editor, positioningAnchorEl }) {
21977
+ const targetRef = useRef13(null);
21978
+ const resizerRef = useRef13(null);
21979
+ const tableRectRef = useRef13(null);
21980
+ const mouseStartPosRef = useRef13(null);
21981
+ const [mouseCurrentPos, updateMouseCurrentPos] = useState18(null);
21982
+ const [activeCell, updateActiveCell] = useState18(null);
21983
+ const [isMouseDown, updateIsMouseDown] = useState18(false);
21984
+ const [draggingDirection, updateDraggingDirection] = useState18(null);
21985
+ const resetState = useCallback12(() => {
21986
+ updateActiveCell(null);
21987
+ targetRef.current = null;
21988
+ updateDraggingDirection(null);
21989
+ mouseStartPosRef.current = null;
21990
+ tableRectRef.current = null;
21991
+ }, []);
21992
+ const isMouseDownOnEvent = (event) => {
21993
+ return (event.buttons & 1) === 1;
22020
21994
  };
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());
21995
+ useEffect22(() => {
21996
+ const onMouseMove = (event) => {
21997
+ setTimeout(() => {
21998
+ const target = event.target;
21999
+ if (draggingDirection) {
22000
+ updateMouseCurrentPos({
22001
+ x: event.clientX,
22002
+ y: event.clientY
22029
22003
  });
22004
+ return;
22030
22005
  }
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");
22006
+ updateIsMouseDown(isMouseDownOnEvent(event));
22007
+ if (resizerRef.current && resizerRef.current.contains(target)) {
22008
+ return;
22052
22009
  }
22053
- const tableSelection = getTableObserverFromTableElement(tableElement2);
22054
- if (tableSelection !== null) {
22055
- tableSelection.clearHighlight();
22010
+ if (targetRef.current !== target) {
22011
+ targetRef.current = target;
22012
+ const cell2 = fixedGetDOMCellFromTarget(target);
22013
+ if (cell2 && activeCell !== cell2) {
22014
+ editor.update(() => {
22015
+ const tableCellNode = $getNearestNodeFromDOMNode(cell2.elem);
22016
+ if (!tableCellNode) {
22017
+ throw new Error("TableCellResizer: Table cell node not found.");
22018
+ }
22019
+ const tableNode = $getTableNodeFromLexicalNodeOrThrow2(tableCellNode);
22020
+ const tableElement2 = editor.getElementByKey(tableNode.getKey());
22021
+ if (!tableElement2) {
22022
+ throw new Error("TableCellResizer: Table element not found.");
22023
+ }
22024
+ targetRef.current = target;
22025
+ tableRectRef.current = tableElement2.getBoundingClientRect();
22026
+ updateActiveCell(cell2);
22027
+ });
22028
+ } else if (cell2 == null) {
22029
+ resetState();
22030
+ }
22056
22031
  }
22057
- tableNode.markDirty();
22058
- updateTableCellNode(tableCellNode.getLatest());
22059
- }
22060
- const rootNode = $getRoot();
22061
- rootNode.selectStart();
22032
+ }, 0);
22033
+ };
22034
+ const onMouseDown = () => {
22035
+ setTimeout(() => {
22036
+ updateIsMouseDown(true);
22037
+ }, 0);
22038
+ };
22039
+ const onMouseUp = () => {
22040
+ setTimeout(() => {
22041
+ updateIsMouseDown(false);
22042
+ }, 0);
22043
+ };
22044
+ const removeRootListener = editor.registerRootListener((rootElement, prevRootElement) => {
22045
+ rootElement == null ? void 0 : rootElement.addEventListener("mousemove", onMouseMove);
22046
+ rootElement == null ? void 0 : rootElement.addEventListener("mousedown", onMouseDown);
22047
+ rootElement == null ? void 0 : rootElement.addEventListener("mouseup", onMouseUp);
22048
+ prevRootElement == null ? void 0 : prevRootElement.removeEventListener("mousemove", onMouseMove);
22049
+ prevRootElement == null ? void 0 : prevRootElement.removeEventListener("mousedown", onMouseDown);
22050
+ prevRootElement == null ? void 0 : prevRootElement.removeEventListener("mouseup", onMouseUp);
22062
22051
  });
22063
- }, [editor, tableCellNode]);
22064
- const insertTableRowAtSelection = useCallback12(
22065
- (shouldInsertAfter) => {
22066
- editor.update(() => {
22067
- $insertTableRow__EXPERIMENTAL(shouldInsertAfter);
22068
- });
22069
- incrementMenuTriggerKey();
22052
+ return () => {
22053
+ removeRootListener();
22054
+ };
22055
+ }, [activeCell, draggingDirection, editor, resetState]);
22056
+ const isHeightChanging = (direction) => {
22057
+ if (direction === "bottom") {
22058
+ return true;
22059
+ }
22060
+ return false;
22061
+ };
22062
+ const updateRowHeight = useCallback12(
22063
+ (heightChange) => {
22064
+ if (!activeCell) {
22065
+ throw new Error("TableCellResizer: Expected active cell.");
22066
+ }
22067
+ editor.update(
22068
+ () => {
22069
+ const tableCellNode = $getNearestNodeFromDOMNode(activeCell.elem);
22070
+ if (!$isTableCellNode2(tableCellNode)) {
22071
+ throw new Error("TableCellResizer: Table cell node not found.");
22072
+ }
22073
+ const tableNode = $getTableNodeFromLexicalNodeOrThrow2(tableCellNode);
22074
+ const tableRowIndex = $getTableRowIndexFromTableCellNode2(tableCellNode);
22075
+ const tableRows = tableNode.getChildren();
22076
+ if (tableRowIndex >= tableRows.length || tableRowIndex < 0) {
22077
+ throw new Error("Expected table cell to be inside of table row.");
22078
+ }
22079
+ const tableRow2 = tableRows[tableRowIndex];
22080
+ if (!$isTableRowNode2(tableRow2)) {
22081
+ throw new Error("Expected table row");
22082
+ }
22083
+ let height = tableRow2.getHeight();
22084
+ if (height === void 0) {
22085
+ const rowCells = tableRow2.getChildren();
22086
+ height = Math.min(...rowCells.map((cell2) => {
22087
+ var _a;
22088
+ return (_a = getCellNodeHeight(cell2, editor)) != null ? _a : Infinity;
22089
+ }));
22090
+ }
22091
+ const newHeight = Math.max(height + heightChange, MIN_ROW_HEIGHT);
22092
+ tableRow2.setHeight(newHeight);
22093
+ },
22094
+ { tag: "skip-scroll-into-view" }
22095
+ );
22070
22096
  },
22071
- [editor]
22097
+ [activeCell, editor]
22072
22098
  );
22073
- const insertTableColumnAtSelection = useCallback12(
22074
- (shouldInsertAfter) => {
22075
- editor.update(() => {
22076
- for (let i = 0; i < selectionCounts.columns; i++) {
22077
- $insertTableColumn__EXPERIMENTAL(shouldInsertAfter);
22099
+ const getCellNodeWidth = (cell2, activeEditor) => {
22100
+ const width = cell2.getWidth();
22101
+ if (width !== void 0) {
22102
+ return width;
22103
+ }
22104
+ const domCellNode = activeEditor.getElementByKey(cell2.getKey());
22105
+ if (domCellNode == null) {
22106
+ return void 0;
22107
+ }
22108
+ const computedStyle = getComputedStyle(domCellNode);
22109
+ return domCellNode.clientWidth - parseFloat(computedStyle.paddingLeft) - parseFloat(computedStyle.paddingRight);
22110
+ };
22111
+ const getCellNodeHeight = (cell2, activeEditor) => {
22112
+ const domCellNode = activeEditor.getElementByKey(cell2.getKey());
22113
+ return domCellNode == null ? void 0 : domCellNode.clientHeight;
22114
+ };
22115
+ const getCellColumnIndex = (tableCellNode, tableMap) => {
22116
+ for (let row = 0; row < tableMap.length; row++) {
22117
+ for (let column = 0; column < tableMap[row].length; column++) {
22118
+ if (tableMap[row][column].cell === tableCellNode) {
22119
+ return column;
22078
22120
  }
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
22121
  }
22111
- const tableRow2 = tableRows[tableRowIndex];
22112
- if (!$isTableRowNode(tableRow2)) {
22113
- throw new Error("Expected table row");
22122
+ }
22123
+ };
22124
+ const updateColumnWidth = useCallback12(
22125
+ (widthChange) => {
22126
+ if (!activeCell) {
22127
+ throw new Error("TableCellResizer: Expected active cell.");
22114
22128
  }
22115
- tableRow2.getChildren().forEach((tableCell) => {
22116
- if (!$isTableCellNode(tableCell)) {
22117
- throw new Error("Expected table cell");
22129
+ editor.update(
22130
+ () => {
22131
+ const tableCellNode = $getNearestNodeFromDOMNode(activeCell.elem);
22132
+ if (!$isTableCellNode2(tableCellNode)) {
22133
+ throw new Error("TableCellResizer: Table cell node not found.");
22134
+ }
22135
+ const tableNode = $getTableNodeFromLexicalNodeOrThrow2(tableCellNode);
22136
+ const [tableMap] = $computeTableMapSkipCellCheck(tableNode, null, null);
22137
+ const columnIndex = getCellColumnIndex(tableCellNode, tableMap);
22138
+ if (columnIndex === void 0) {
22139
+ throw new Error("TableCellResizer: Table column not found.");
22140
+ }
22141
+ for (let row = 0; row < tableMap.length; row++) {
22142
+ const cell2 = tableMap[row][columnIndex];
22143
+ if (cell2.startRow === row && (columnIndex === tableMap[row].length - 1 || tableMap[row][columnIndex].cell !== tableMap[row][columnIndex + 1].cell)) {
22144
+ const width = getCellNodeWidth(cell2.cell, editor);
22145
+ if (width === void 0) {
22146
+ continue;
22147
+ }
22148
+ const newWidth = Math.max(width + widthChange, MIN_COLUMN_WIDTH);
22149
+ cell2.cell.setWidth(newWidth);
22150
+ }
22151
+ }
22152
+ },
22153
+ { tag: "skip-scroll-into-view" }
22154
+ );
22155
+ },
22156
+ [activeCell, editor]
22157
+ );
22158
+ const mouseUpHandler = useCallback12(
22159
+ (direction) => {
22160
+ const handler = (event) => {
22161
+ event.preventDefault();
22162
+ event.stopPropagation();
22163
+ if (!activeCell) {
22164
+ throw new Error("TableCellResizer: Expected active cell.");
22118
22165
  }
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");
22166
+ if (mouseStartPosRef.current) {
22167
+ const { x, y } = mouseStartPosRef.current;
22168
+ if (activeCell === null) {
22169
+ return;
22170
+ }
22171
+ const zoom = calculateZoomLevel(event.target);
22172
+ if (isHeightChanging(direction)) {
22173
+ const heightChange = (event.clientY - y) / zoom;
22174
+ updateRowHeight(heightChange);
22175
+ } else {
22176
+ const widthChange = (event.clientX - x) / zoom;
22177
+ updateColumnWidth(widthChange);
22178
+ }
22179
+ resetState();
22180
+ document.removeEventListener("mouseup", handler);
22137
22181
  }
22138
- const tableCells = tableRow2.getChildren();
22139
- if (tableColumnIndex >= tableCells.length) {
22140
- continue;
22182
+ };
22183
+ return handler;
22184
+ },
22185
+ [activeCell, resetState, updateColumnWidth, updateRowHeight]
22186
+ );
22187
+ const toggleResize = useCallback12(
22188
+ (direction) => (event) => {
22189
+ event.preventDefault();
22190
+ event.stopPropagation();
22191
+ if (!activeCell) {
22192
+ throw new Error("TableCellResizer: Expected active cell.");
22193
+ }
22194
+ mouseStartPosRef.current = {
22195
+ x: event.clientX,
22196
+ y: event.clientY
22197
+ };
22198
+ updateMouseCurrentPos(mouseStartPosRef.current);
22199
+ updateDraggingDirection(direction);
22200
+ document.addEventListener("mouseup", mouseUpHandler(direction));
22201
+ },
22202
+ [activeCell, mouseUpHandler]
22203
+ );
22204
+ const getResizers = useCallback12(() => {
22205
+ if (activeCell) {
22206
+ const { height, width, top, left } = activeCell.elem.getBoundingClientRect();
22207
+ const parentRect = positioningAnchorEl.getBoundingClientRect();
22208
+ const zoom = calculateZoomLevel(activeCell.elem);
22209
+ const zoneWidth = 10;
22210
+ const styles = {
22211
+ bottom: {
22212
+ backgroundColor: "none",
22213
+ cursor: "row-resize",
22214
+ height: `${zoneWidth}px`,
22215
+ left: `${left - parentRect.left}px`,
22216
+ top: `${top - parentRect.top + positioningAnchorEl.scrollTop + height - zoneWidth / 2}px`,
22217
+ width: `${width}px`
22218
+ },
22219
+ right: {
22220
+ backgroundColor: "none",
22221
+ cursor: "col-resize",
22222
+ height: `${height}px`,
22223
+ left: `${left - parentRect.left + width - zoneWidth / 2}px`,
22224
+ top: `${top - parentRect.top + positioningAnchorEl.scrollTop}px`,
22225
+ width: `${zoneWidth}px`
22141
22226
  }
22142
- const tableCell = tableCells[tableColumnIndex];
22143
- if (!$isTableCellNode(tableCell)) {
22144
- throw new Error("Expected table cell");
22227
+ };
22228
+ const tableRect = tableRectRef.current;
22229
+ if (draggingDirection && mouseCurrentPos && tableRect) {
22230
+ if (isHeightChanging(draggingDirection)) {
22231
+ styles[draggingDirection].left = `${tableRect.left - parentRect.left}px`;
22232
+ styles[draggingDirection].top = `${(mouseCurrentPos.y - parentRect.top + positioningAnchorEl.scrollTop) / zoom}px`;
22233
+ styles[draggingDirection].height = "3px";
22234
+ styles[draggingDirection].width = `${tableRect.width}px`;
22235
+ } else {
22236
+ styles[draggingDirection].top = `${tableRect.top - parentRect.top + positioningAnchorEl.scrollTop}px`;
22237
+ styles[draggingDirection].left = `${(mouseCurrentPos.x - parentRect.left) / zoom}px`;
22238
+ styles[draggingDirection].width = "3px";
22239
+ styles[draggingDirection].height = `${tableRect.height}px`;
22145
22240
  }
22146
- tableCell.toggleHeaderStyle(TableCellHeaderStates.COLUMN);
22241
+ styles[draggingDirection].backgroundColor = "#adf";
22147
22242
  }
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
- ]
22243
+ return styles;
22214
22244
  }
22245
+ return {
22246
+ bottom: null,
22247
+ left: null,
22248
+ right: null,
22249
+ top: null
22250
+ };
22251
+ }, [activeCell, draggingDirection, mouseCurrentPos, positioningAnchorEl]);
22252
+ const resizerStyles = getResizers();
22253
+ return /* @__PURE__ */ jsx131("div", { ref: resizerRef, children: activeCell != null && !isMouseDown && /* @__PURE__ */ jsxs87(Fragment19, { children: [
22254
+ /* @__PURE__ */ jsx131(
22255
+ "div",
22256
+ {
22257
+ css: tableResizer,
22258
+ style: resizerStyles.right || void 0,
22259
+ onMouseDown: toggleResize("right")
22260
+ }
22261
+ ),
22262
+ /* @__PURE__ */ jsx131(
22263
+ "div",
22264
+ {
22265
+ css: tableResizer,
22266
+ style: resizerStyles.bottom || void 0,
22267
+ onMouseDown: toggleResize("bottom")
22268
+ }
22269
+ )
22270
+ ] }) });
22271
+ }
22272
+ function TableCellResizerPlugin({ positioningAnchorEl }) {
22273
+ const [editor] = useLexicalComposerContext6();
22274
+ const isEditable = useLexicalEditable2();
22275
+ return useMemo6(
22276
+ () => isEditable ? createPortal3(
22277
+ /* @__PURE__ */ jsx131(TableCellResizer, { editor, positioningAnchorEl }),
22278
+ positioningAnchorEl
22279
+ ) : null,
22280
+ [editor, isEditable, positioningAnchorEl]
22215
22281
  );
22216
22282
  }
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();
22231
- };
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;
22255
- }
22256
- const tableCellParentNodeDOM = editor.getElementByKey(tableCellNodeFromSelection.getKey());
22257
- if (tableCellParentNodeDOM == null) {
22258
- setTableMenuCellNode(null);
22259
- setTableMenuCellNodeElem(null);
22260
- return;
22283
+
22284
+ // src/components/ParameterInputs/rich-text/TableSelectionPlugin.tsx
22285
+ import { useLexicalComposerContext as useLexicalComposerContext7 } from "@lexical/react/LexicalComposerContext";
22286
+ import { $findCellNode } from "@lexical/table";
22287
+ import {
22288
+ $getSelection as $getSelection4,
22289
+ $isRangeSelection as $isRangeSelection4,
22290
+ $setSelection,
22291
+ COMMAND_PRIORITY_NORMAL as COMMAND_PRIORITY_NORMAL2,
22292
+ SELECTION_CHANGE_COMMAND as SELECTION_CHANGE_COMMAND2
22293
+ } from "lexical";
22294
+ import { useEffect as useEffect23, useState as useState19 } from "react";
22295
+ var TableSelectionPlugin = () => {
22296
+ const [editor] = useLexicalComposerContext7();
22297
+ const [closestTableCellNode, setClosestTableCellNode] = useState19(null);
22298
+ useEffect23(() => {
22299
+ return editor.registerCommand(
22300
+ SELECTION_CHANGE_COMMAND2,
22301
+ () => {
22302
+ editor.read(() => {
22303
+ const selection = $getSelection4();
22304
+ if (!$isRangeSelection4(selection) || !selection.isCollapsed()) {
22305
+ setClosestTableCellNode(null);
22306
+ return false;
22307
+ }
22308
+ const tableCellNode = $findCellNode(selection.anchor.getNode());
22309
+ if (tableCellNode === null) {
22310
+ setClosestTableCellNode(null);
22311
+ return false;
22312
+ }
22313
+ setClosestTableCellNode(tableCellNode);
22314
+ });
22315
+ return false;
22316
+ },
22317
+ COMMAND_PRIORITY_NORMAL2
22318
+ );
22319
+ }, [editor]);
22320
+ useEffect23(() => {
22321
+ const onControlA = (event) => {
22322
+ if (event.key === "a" && (event.ctrlKey || event.metaKey)) {
22323
+ if (!closestTableCellNode) {
22324
+ return;
22325
+ }
22326
+ event.preventDefault();
22327
+ editor.update(() => {
22328
+ const selection = closestTableCellNode.select(0, closestTableCellNode.getChildrenSize());
22329
+ $setSelection(selection);
22330
+ });
22261
22331
  }
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
- });
22332
+ };
22333
+ return editor.registerRootListener((rootElement, prevRootElement) => {
22334
+ rootElement == null ? void 0 : rootElement.addEventListener("keydown", onControlA);
22335
+ prevRootElement == null ? void 0 : prevRootElement.removeEventListener("keydown", onControlA);
22274
22336
  });
22275
- });
22276
- return tableCellNode != null && tableCellNodeEl != null && tableCellMenuPortalEl != null && /* @__PURE__ */ jsx131(
22277
- TableActionMenu,
22278
- {
22279
- tableCellNode,
22280
- menuPortalEl: tableCellMenuPortalEl,
22281
- tableCellEl: tableCellNodeEl,
22282
- positioningAnchorEl
22283
- },
22284
- tableCellNode.getKey()
22285
- );
22286
- }
22287
- function TableActionMenuPlugin({
22288
- positioningAnchorEl,
22289
- menuPortalEl
22290
- }) {
22291
- const isEditable = useLexicalEditable();
22292
- return isEditable ? /* @__PURE__ */ jsx131(TableCellActionMenuContainer, { menuPortalEl, positioningAnchorEl }) : null;
22293
- }
22337
+ }, [editor, closestTableCellNode]);
22338
+ return null;
22339
+ };
22340
+ var TableSelectionPlugin_default = TableSelectionPlugin;
22294
22341
 
22295
- // src/components/ParameterInputs/rich-text/TableCellResizerPlugin.tsx
22342
+ // src/components/ParameterInputs/rich-text/toolbar/RichTextToolbar.tsx
22296
22343
  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";
22344
+ import { $createCodeNode } from "@lexical/code";
22299
22345
  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
- };
22346
+ $isListNode as $isListNode2,
22347
+ INSERT_ORDERED_LIST_COMMAND,
22348
+ INSERT_UNORDERED_LIST_COMMAND,
22349
+ ListNode as ListNode2,
22350
+ REMOVE_LIST_COMMAND
22351
+ } from "@lexical/list";
22352
+ import { useLexicalComposerContext as useLexicalComposerContext8 } from "@lexical/react/LexicalComposerContext";
22353
+ import { $createHeadingNode, $createQuoteNode, $isHeadingNode } from "@lexical/rich-text";
22354
+ import { $setBlocksType } from "@lexical/selection";
22355
+ import { $createTableNodeWithDimensions } from "@lexical/table";
22356
+ import { $findMatchingParent, $getNearestNodeOfType as $getNearestNodeOfType2 } from "@lexical/utils";
22357
+ import {
22358
+ $createParagraphNode as $createParagraphNode2,
22359
+ $getSelection as $getSelection5,
22360
+ $insertNodes as $insertNodes2,
22361
+ $isRangeSelection as $isRangeSelection5,
22362
+ $isRootOrShadowRoot,
22363
+ COMMAND_PRIORITY_CRITICAL as COMMAND_PRIORITY_CRITICAL2,
22364
+ FORMAT_TEXT_COMMAND,
22365
+ SELECTION_CHANGE_COMMAND as SELECTION_CHANGE_COMMAND3
22366
+ } from "lexical";
22367
+ import { useCallback as useCallback13, useEffect as useEffect24 } from "react";
22368
+
22369
+ // src/components/ParameterInputs/rich-text/toolbar/constants.ts
22370
+ var FORMATS_WITH_ICON = /* @__PURE__ */ new Map([
22371
+ ["bold", "format-bold"],
22372
+ ["italic", "format-italic"],
22373
+ ["underline", "format-underline"],
22374
+ ["strikethrough", "format-strike"],
22375
+ ["code", "format-code"],
22376
+ ["superscript", "format-superscript"],
22377
+ ["subscript", "format-subscript"]
22378
+ ]);
22379
+ var HEADING_ELEMENTS = ["h1", "h2", "h3", "h4", "h5", "h6"];
22380
+ var TEXTUAL_ELEMENTS = HEADING_ELEMENTS;
22381
+
22382
+ // src/components/ParameterInputs/rich-text/toolbar/useRichTextToolbarState.ts
22383
+ import { useMemo as useMemo7, useState as useState20 } from "react";
22384
+ var useRichTextToolbarState = ({ config }) => {
22385
+ var _a;
22386
+ const enabledBuiltInFormats = useMemo7(() => {
22387
+ return richTextBuiltInFormats.filter((format) => {
22388
+ var _a2, _b;
22389
+ return (_b = (_a2 = config == null ? void 0 : config.formatting) == null ? void 0 : _a2.builtIn) == null ? void 0 : _b.includes(format.type);
22390
+ });
22391
+ }, [config]);
22392
+ const enabledBuiltInElements = useMemo7(() => {
22393
+ return richTextBuiltInElements.filter((element) => {
22394
+ var _a2, _b;
22395
+ return (_b = (_a2 = config == null ? void 0 : config.elements) == null ? void 0 : _a2.builtIn) == null ? void 0 : _b.includes(element.type);
22396
+ });
22397
+ }, [config]);
22398
+ const enabledBuiltInFormatsWithIcon = useMemo7(() => {
22399
+ return enabledBuiltInFormats.filter((format) => FORMATS_WITH_ICON.has(format.type));
22400
+ }, [enabledBuiltInFormats]);
22401
+ const enabledBuiltInFormatsWithoutIcon = enabledBuiltInFormats.filter(
22402
+ (format) => !FORMATS_WITH_ICON.has(format.type)
22403
+ );
22404
+ const [activeFormats, setActiveFormats] = useState20([]);
22405
+ const visibleFormatsWithIcon = useMemo7(() => {
22406
+ const visibleFormats = /* @__PURE__ */ new Set();
22407
+ activeFormats.filter((type) => FORMATS_WITH_ICON.has(type)).forEach((type) => {
22408
+ visibleFormats.add(type);
22409
+ });
22410
+ enabledBuiltInFormatsWithIcon.forEach((format) => {
22411
+ visibleFormats.add(format.type);
22412
+ });
22413
+ return richTextBuiltInFormats.filter((format) => visibleFormats.has(format.type));
22414
+ }, [activeFormats, enabledBuiltInFormatsWithIcon]);
22415
+ const visibleFormatsWithoutIcon = useMemo7(() => {
22416
+ const visibleFormats = /* @__PURE__ */ new Set();
22417
+ activeFormats.filter((type) => !FORMATS_WITH_ICON.has(type)).forEach((type) => {
22418
+ visibleFormats.add(type);
22419
+ });
22420
+ enabledBuiltInFormatsWithoutIcon.forEach((format) => {
22421
+ visibleFormats.add(format.type);
22422
+ });
22423
+ return richTextBuiltInFormats.filter((format) => visibleFormats.has(format.type));
22424
+ }, [activeFormats, enabledBuiltInFormatsWithoutIcon]);
22425
+ const [activeElement, setActiveElement] = useState20("paragraph");
22426
+ const enabledTextualElements = enabledBuiltInElements.filter(
22427
+ (element) => TEXTUAL_ELEMENTS.includes(element.type)
22428
+ );
22429
+ const visibleTextualElements = useMemo7(() => {
22430
+ if (!TEXTUAL_ELEMENTS.includes(activeElement)) {
22431
+ return enabledTextualElements;
22432
+ }
22433
+ return richTextBuiltInElements.filter(
22434
+ (element) => {
22435
+ var _a2, _b;
22436
+ 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);
22327
22437
  }
22328
- return cell2;
22438
+ );
22439
+ }, [activeElement, (_a = config == null ? void 0 : config.elements) == null ? void 0 : _a.builtIn, enabledTextualElements]);
22440
+ const [isLink, setIsLink] = useState20(false);
22441
+ const linkElementVisible = useMemo7(() => {
22442
+ return enabledBuiltInElements.some((element) => element.type === "link") || isLink;
22443
+ }, [isLink, enabledBuiltInElements]);
22444
+ const visibleLists = useMemo7(() => {
22445
+ return new Set(
22446
+ ["orderedList", "unorderedList"].filter(
22447
+ (type) => enabledBuiltInElements.some((element) => element.type === type) || activeElement === type
22448
+ )
22449
+ );
22450
+ }, [activeElement, enabledBuiltInElements]);
22451
+ const quoteElementVisible = useMemo7(() => {
22452
+ return enabledBuiltInElements.some((element) => element.type === "quote") || activeElement === "quote";
22453
+ }, [activeElement, enabledBuiltInElements]);
22454
+ const codeElementVisible = useMemo7(() => {
22455
+ return enabledBuiltInElements.some((element) => element.type === "code") || activeElement === "code";
22456
+ }, [activeElement, enabledBuiltInElements]);
22457
+ const tableElementVisible = useMemo7(() => {
22458
+ return enabledBuiltInElements.some((element) => element.type === "table") || activeElement === "table";
22459
+ }, [activeElement, enabledBuiltInElements]);
22460
+ const assetElementVisible = useMemo7(() => {
22461
+ return enabledBuiltInElements.some((element) => element.type === "asset") || activeElement === "asset";
22462
+ }, [activeElement, enabledBuiltInElements]);
22463
+ const visibleElementsWithIcons = useMemo7(() => {
22464
+ const visibleElements = /* @__PURE__ */ new Set();
22465
+ if (linkElementVisible) {
22466
+ visibleElements.add("link");
22329
22467
  }
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;
22468
+ if (visibleLists.size > 0) {
22469
+ visibleLists.forEach((type) => {
22470
+ visibleElements.add(type);
22471
+ });
22417
22472
  }
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");
22440
- }
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
- }));
22448
- }
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;
22473
+ return visibleElements;
22474
+ }, [linkElementVisible, visibleLists]);
22475
+ const visibleInsertElementsWithIcons = useMemo7(() => {
22476
+ const visibleElements = /* @__PURE__ */ new Set();
22477
+ if (quoteElementVisible) {
22478
+ visibleElements.add("quote");
22461
22479
  }
22462
- const domCellNode = activeEditor.getElementByKey(cell2.getKey());
22463
- if (domCellNode == null) {
22464
- return void 0;
22480
+ if (codeElementVisible) {
22481
+ visibleElements.add("code");
22465
22482
  }
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;
22478
- }
22479
- }
22483
+ if (tableElementVisible) {
22484
+ visibleElements.add("table");
22480
22485
  }
22486
+ if (assetElementVisible) {
22487
+ visibleElements.add("asset");
22488
+ }
22489
+ return visibleElements;
22490
+ }, [codeElementVisible, quoteElementVisible, tableElementVisible, assetElementVisible]);
22491
+ return {
22492
+ activeFormats,
22493
+ setActiveFormats,
22494
+ activeElement,
22495
+ setActiveElement,
22496
+ visibleFormatsWithIcon,
22497
+ visibleFormatsWithoutIcon,
22498
+ visibleTextualElements,
22499
+ isLink,
22500
+ setIsLink,
22501
+ linkElementVisible,
22502
+ visibleLists,
22503
+ quoteElementVisible,
22504
+ codeElementVisible,
22505
+ tableElementVisible,
22506
+ assetElementVisible,
22507
+ visibleElementsWithIcons,
22508
+ visibleInsertElementsWithIcons
22481
22509
  };
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);
22510
+ };
22511
+
22512
+ // src/components/ParameterInputs/rich-text/toolbar/RichTextToolbar.tsx
22513
+ import { Fragment as Fragment20, jsx as jsx132, jsxs as jsxs88 } from "@emotion/react/jsx-runtime";
22514
+ var toolbar = css100`
22515
+ ${scrollbarStyles}
22516
+ background: var(--gray-50);
22517
+ border-radius: var(--rounded-base);
22518
+ display: flex;
22519
+ /* We add 1px because we use a 1px wide separator */
22520
+ gap: calc(var(--spacing-sm) + 1px);
22521
+ margin: 0 0 calc(var(--spacing-sm) + var(--spacing-xs)) 0;
22522
+ overflow: auto;
22523
+ padding: var(--spacing-sm);
22524
+ position: sticky;
22525
+ top: calc(var(--spacing-sm) * -2);
22526
+ z-index: 10;
22527
+ `;
22528
+ var toolbarGroup = css100`
22529
+ display: flex;
22530
+ flex-shrink: 0;
22531
+ gap: var(--spacing-xs);
22532
+ position: relative;
22533
+
22534
+ &:not(:first-child)::before {
22535
+ background-color: var(--gray-300);
22536
+ content: '';
22537
+ display: block;
22538
+ height: 24px;
22539
+ left: calc(var(--spacing-xs) * -1);
22540
+ position: absolute;
22541
+ top: 4px;
22542
+ width: 1px;
22543
+ }
22544
+ `;
22545
+ var richTextToolbarButton = css100`
22546
+ align-items: center;
22547
+ appearance: none;
22548
+ border: 0;
22549
+ border-radius: var(--rounded-sm);
22550
+ box-shadow: none;
22551
+ color: var(--gray-900);
22552
+ display: flex;
22553
+ flex-shrink: 0;
22554
+ height: 32px;
22555
+ justify-content: center;
22556
+ min-width: 32px;
22557
+ padding: 0 var(--spacing-sm);
22558
+ `;
22559
+ var richTextToolbarButtonActive = css100`
22560
+ background: var(--gray-200);
22561
+ `;
22562
+ var textStyleButton = css100`
22563
+ justify-content: space-between;
22564
+ min-width: 7rem;
22565
+ `;
22566
+ var toolbarIcon = css100`
22567
+ color: inherit;
22568
+ `;
22569
+ var toolbarChevron = css100`
22570
+ margin-left: var(--spacing-xs);
22571
+ `;
22572
+ var RichTextToolbarIcon = ({ icon }) => {
22573
+ return /* @__PURE__ */ jsx132(Icon, { icon, css: toolbarIcon, size: "1rem" });
22574
+ };
22575
+ var RichTextToolbar = ({ config, customControls, onInsertTable, onInsertAsset }) => {
22576
+ const [editor] = useLexicalComposerContext8();
22577
+ const {
22578
+ activeElement,
22579
+ setActiveElement,
22580
+ activeFormats,
22581
+ setActiveFormats,
22582
+ visibleFormatsWithIcon,
22583
+ visibleFormatsWithoutIcon,
22584
+ visibleTextualElements,
22585
+ isLink,
22586
+ setIsLink,
22587
+ linkElementVisible,
22588
+ visibleLists,
22589
+ codeElementVisible,
22590
+ quoteElementVisible,
22591
+ visibleElementsWithIcons,
22592
+ visibleInsertElementsWithIcons,
22593
+ tableElementVisible,
22594
+ assetElementVisible
22595
+ } = useRichTextToolbarState({ config });
22596
+ const onSelectElement = (type) => {
22597
+ if (activeElement === type) {
22598
+ return;
22599
+ }
22600
+ editor.focus(() => {
22601
+ editor.update(() => {
22602
+ const selection = $getSelection5();
22603
+ if (HEADING_ELEMENTS.includes(type)) {
22604
+ $setBlocksType(selection, () => $createHeadingNode(type));
22605
+ } else if (type === "paragraph") {
22606
+ $setBlocksType(selection, () => $createParagraphNode2());
22607
+ } else if (type === "quote") {
22608
+ $setBlocksType(selection, () => $createQuoteNode());
22609
+ } else if (type === "code") {
22610
+ $setBlocksType(selection, () => $createCodeNode());
22611
+ } else if (type === "table" && onInsertTable) {
22612
+ onInsertTable().then((dimensions) => {
22613
+ if (!dimensions) {
22614
+ return;
22508
22615
  }
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]
22544
- );
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]
22561
- );
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`;
22616
+ const { rows, columns } = dimensions;
22617
+ editor.focus(() => {
22618
+ editor.update(() => {
22619
+ $insertNodes2([$createTableNodeWithDimensions(rows, columns, false)]);
22620
+ });
22621
+ });
22622
+ });
22623
+ } else if (type === "asset" && onInsertAsset) {
22624
+ onInsertAsset();
22598
22625
  }
22599
- styles[draggingDirection].backgroundColor = "#adf";
22600
- }
22601
- return styles;
22602
- }
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")
22626
+ });
22627
+ });
22628
+ };
22629
+ const updateToolbar = useCallback13(() => {
22630
+ const selection = $getSelection5();
22631
+ if (!$isRangeSelection5(selection)) {
22632
+ return;
22633
+ }
22634
+ const newActiveFormats = [];
22635
+ for (const format of richTextBuiltInFormats) {
22636
+ if (selection.hasFormat(format.type)) {
22637
+ newActiveFormats.push(format.type);
22618
22638
  }
22619
- ),
22620
- /* @__PURE__ */ jsx132(
22621
- "div",
22622
- {
22623
- css: tableResizer,
22624
- style: resizerStyles.bottom || void 0,
22625
- onMouseDown: toggleResize("bottom")
22639
+ }
22640
+ setActiveFormats(newActiveFormats);
22641
+ const anchorNode = selection.anchor.getNode();
22642
+ let element = anchorNode.getKey() === "root" ? anchorNode : $findMatchingParent(anchorNode, (e) => {
22643
+ const parent = e.getParent();
22644
+ return parent !== null && $isRootOrShadowRoot(parent);
22645
+ });
22646
+ if (element === null) {
22647
+ element = anchorNode.getTopLevelElementOrThrow();
22648
+ }
22649
+ const elementKey = element.getKey();
22650
+ const elementDOM = editor.getElementByKey(elementKey);
22651
+ if (elementDOM !== null) {
22652
+ if ($isListNode2(element)) {
22653
+ const parentList = $getNearestNodeOfType2(anchorNode, ListNode2);
22654
+ const type = parentList ? parentList.getListType() : element.getListType();
22655
+ setActiveElement(type === "bullet" ? "unorderedList" : "orderedList");
22656
+ } else {
22657
+ const type = $isHeadingNode(element) ? element.getTag() : element.getType();
22658
+ setActiveElement(type);
22626
22659
  }
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(() => {
22660
+ }
22661
+ const node = getSelectedNode(selection);
22662
+ if (getLinkAncestor(node) !== null) {
22663
+ setIsLink(true);
22664
+ } else {
22665
+ setIsLink(false);
22666
+ }
22667
+ }, [editor, setActiveElement, setActiveFormats, setIsLink]);
22668
+ useEffect24(() => {
22657
22669
  return editor.registerCommand(
22658
22670
  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
- });
22671
+ (_payload) => {
22672
+ updateToolbar();
22673
22673
  return false;
22674
22674
  },
22675
- COMMAND_PRIORITY_NORMAL2
22675
+ COMMAND_PRIORITY_CRITICAL2
22676
22676
  );
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);
22677
+ }, [editor, updateToolbar]);
22678
+ useEffect24(() => {
22679
+ return editor.registerUpdateListener(({ editorState }) => {
22680
+ requestAnimationFrame(() => {
22681
+ editorState.read(() => {
22682
+ updateToolbar();
22688
22683
  });
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);
22684
+ });
22694
22685
  });
22695
- }, [editor, closestTableCellNode]);
22696
- return null;
22686
+ }, [editor, updateToolbar]);
22687
+ return /* @__PURE__ */ jsxs88("div", { css: toolbar, children: [
22688
+ /* @__PURE__ */ jsxs88(
22689
+ Menu,
22690
+ {
22691
+ menuTrigger: /* @__PURE__ */ jsxs88("button", { css: [richTextToolbarButton, textStyleButton], title: "Text styles", children: [
22692
+ visibleTextualElements.some((element) => element.type === activeElement) ? getLabelForElement(activeElement) : getLabelForElement("paragraph"),
22693
+ " ",
22694
+ /* @__PURE__ */ jsx132(Icon, { icon: "chevron-down", css: [toolbarIcon, toolbarChevron], size: "1rem" })
22695
+ ] }),
22696
+ placement: "bottom-start",
22697
+ children: [
22698
+ [
22699
+ {
22700
+ label: "Normal",
22701
+ type: "paragraph"
22702
+ },
22703
+ ...visibleTextualElements
22704
+ ].map((element) => /* @__PURE__ */ jsx132(
22705
+ MenuItem,
22706
+ {
22707
+ onClick: () => {
22708
+ onSelectElement(element.type);
22709
+ },
22710
+ children: element.label
22711
+ },
22712
+ element.type
22713
+ )),
22714
+ visibleTextualElements.length === 0 ? /* @__PURE__ */ jsx132(MenuItem, { disabled: true, children: "Alternative text styles are not available" }) : null
22715
+ ]
22716
+ }
22717
+ ),
22718
+ visibleFormatsWithIcon.length > 0 || visibleFormatsWithoutIcon.length > 0 ? /* @__PURE__ */ jsxs88("div", { css: toolbarGroup, children: [
22719
+ visibleFormatsWithIcon.map((format) => /* @__PURE__ */ jsx132(Tooltip, { title: format.label, placement: "top", children: /* @__PURE__ */ jsx132(
22720
+ "button",
22721
+ {
22722
+ onClick: () => {
22723
+ editor.dispatchCommand(FORMAT_TEXT_COMMAND, format.type);
22724
+ },
22725
+ css: [
22726
+ richTextToolbarButton,
22727
+ activeFormats.includes(format.type) ? richTextToolbarButtonActive : null
22728
+ ],
22729
+ children: /* @__PURE__ */ jsx132(RichTextToolbarIcon, { icon: FORMATS_WITH_ICON.get(format.type) })
22730
+ }
22731
+ ) }, format.type)),
22732
+ visibleFormatsWithoutIcon.length > 0 ? /* @__PURE__ */ jsx132(
22733
+ Menu,
22734
+ {
22735
+ menuLabel: "Alternative text styles",
22736
+ menuTrigger: /* @__PURE__ */ jsx132("button", { css: richTextToolbarButton, title: "Alternative text styles", children: /* @__PURE__ */ jsx132(Icon, { icon: "more-alt", css: toolbarIcon }) }),
22737
+ placement: "bottom-start",
22738
+ children: visibleFormatsWithoutIcon.map((format) => /* @__PURE__ */ jsx132(
22739
+ MenuItem,
22740
+ {
22741
+ onClick: () => {
22742
+ editor.dispatchCommand(FORMAT_TEXT_COMMAND, format.type);
22743
+ },
22744
+ children: format.label
22745
+ },
22746
+ format.type
22747
+ ))
22748
+ }
22749
+ ) : null
22750
+ ] }) : null,
22751
+ visibleElementsWithIcons.size > 0 || customControls ? /* @__PURE__ */ jsxs88("div", { css: toolbarGroup, children: [
22752
+ linkElementVisible ? /* @__PURE__ */ jsx132(Tooltip, { title: "Link", placement: "top", children: /* @__PURE__ */ jsx132(
22753
+ "button",
22754
+ {
22755
+ onClick: () => {
22756
+ isLink ? editor.dispatchCommand(REMOVE_LINK_NODE_COMMAND, {}) : editor.dispatchCommand(OPEN_LINK_NODE_MODAL_COMMAND, {});
22757
+ },
22758
+ css: [richTextToolbarButton, isLink ? richTextToolbarButtonActive : null],
22759
+ children: /* @__PURE__ */ jsx132(RichTextToolbarIcon, { icon: "link" })
22760
+ }
22761
+ ) }) : null,
22762
+ visibleLists.size > 0 ? /* @__PURE__ */ jsxs88(Fragment20, { children: [
22763
+ visibleLists.has("unorderedList") ? /* @__PURE__ */ jsx132(Tooltip, { title: "Bullet List", placement: "top", children: /* @__PURE__ */ jsx132(
22764
+ "button",
22765
+ {
22766
+ onClick: () => {
22767
+ activeElement === "unorderedList" ? editor.dispatchCommand(REMOVE_LIST_COMMAND, void 0) : editor.dispatchCommand(INSERT_UNORDERED_LIST_COMMAND, void 0);
22768
+ },
22769
+ css: [
22770
+ richTextToolbarButton,
22771
+ activeElement === "unorderedList" ? richTextToolbarButtonActive : null
22772
+ ],
22773
+ children: /* @__PURE__ */ jsx132(RichTextToolbarIcon, { icon: "layout-list" })
22774
+ }
22775
+ ) }) : null,
22776
+ visibleLists.has("orderedList") ? /* @__PURE__ */ jsx132(Tooltip, { title: "Ordered List", placement: "top", children: /* @__PURE__ */ jsx132(
22777
+ "button",
22778
+ {
22779
+ onClick: () => {
22780
+ activeElement === "orderedList" ? editor.dispatchCommand(REMOVE_LIST_COMMAND, void 0) : editor.dispatchCommand(INSERT_ORDERED_LIST_COMMAND, void 0);
22781
+ },
22782
+ css: [
22783
+ richTextToolbarButton,
22784
+ activeElement === "orderedList" ? richTextToolbarButtonActive : null
22785
+ ],
22786
+ children: /* @__PURE__ */ jsx132(RichTextToolbarIcon, { icon: "layout-list-numbered" })
22787
+ }
22788
+ ) }) : null
22789
+ ] }) : null,
22790
+ customControls ? customControls : null
22791
+ ] }) : null,
22792
+ visibleInsertElementsWithIcons.size > 0 ? /* @__PURE__ */ jsx132("div", { css: toolbarGroup, children: /* @__PURE__ */ jsxs88(
22793
+ Menu,
22794
+ {
22795
+ menuTrigger: /* @__PURE__ */ jsxs88("button", { css: richTextToolbarButton, title: "Insert block element", children: [
22796
+ "Insert",
22797
+ /* @__PURE__ */ jsx132(Icon, { icon: "chevron-down", css: [toolbarIcon, toolbarChevron], size: "1rem" })
22798
+ ] }),
22799
+ placement: "bottom-start",
22800
+ children: [
22801
+ quoteElementVisible ? /* @__PURE__ */ jsx132(
22802
+ MenuItem,
22803
+ {
22804
+ onClick: () => {
22805
+ onSelectElement("quote");
22806
+ },
22807
+ icon: /* @__PURE__ */ jsx132(Icon, { icon: "quote", iconColor: "currentColor" }),
22808
+ children: "Quote"
22809
+ }
22810
+ ) : null,
22811
+ codeElementVisible ? /* @__PURE__ */ jsx132(
22812
+ MenuItem,
22813
+ {
22814
+ onClick: () => {
22815
+ onSelectElement("code");
22816
+ },
22817
+ icon: /* @__PURE__ */ jsx132(Icon, { icon: "code-slash", iconColor: "currentColor" }),
22818
+ children: "Code"
22819
+ }
22820
+ ) : null,
22821
+ tableElementVisible && onInsertTable !== void 0 ? /* @__PURE__ */ jsx132(
22822
+ MenuItem,
22823
+ {
22824
+ onClick: () => {
22825
+ onSelectElement("table");
22826
+ },
22827
+ icon: /* @__PURE__ */ jsx132(Icon, { icon: "view-grid", iconColor: "currentColor" }),
22828
+ children: "Table"
22829
+ }
22830
+ ) : null,
22831
+ assetElementVisible && onInsertAsset !== void 0 ? /* @__PURE__ */ jsx132(
22832
+ MenuItem,
22833
+ {
22834
+ onClick: () => {
22835
+ onSelectElement("asset");
22836
+ },
22837
+ icon: /* @__PURE__ */ jsx132(Icon, { icon: "image", iconColor: "currentColor" }),
22838
+ children: "Asset"
22839
+ }
22840
+ ) : null
22841
+ ]
22842
+ }
22843
+ ) }) : null
22844
+ ] });
22697
22845
  };
22698
- var TableSelectionPlugin_default = TableSelectionPlugin;
22846
+ var RichTextToolbar_default = RichTextToolbar;
22699
22847
 
22700
22848
  // src/components/ParameterInputs/ParameterRichText.tsx
22701
22849
  import { Fragment as Fragment21, jsx as jsx133, jsxs as jsxs89 } from "@emotion/react/jsx-runtime";
@@ -22724,6 +22872,7 @@ var ParameterRichText = ({
22724
22872
  variables,
22725
22873
  customControls,
22726
22874
  onInsertTable,
22875
+ onInsertAsset,
22727
22876
  minimalInteractivity
22728
22877
  }) => {
22729
22878
  return /* @__PURE__ */ jsxs89(
@@ -22757,6 +22906,7 @@ var ParameterRichText = ({
22757
22906
  variables,
22758
22907
  customControls,
22759
22908
  onInsertTable,
22909
+ onInsertAsset,
22760
22910
  minimalInteractivity,
22761
22911
  children
22762
22912
  }
@@ -22799,7 +22949,7 @@ var editorContainer = css101`
22799
22949
  font-size: var(--fs-base);
22800
22950
  height: max-content;
22801
22951
  line-height: 1.2;
22802
- max-height: 300px;
22952
+ max-height: 320px;
22803
22953
  min-height: 50px;
22804
22954
  overflow-y: auto;
22805
22955
  padding: var(--spacing-sm);
@@ -22815,7 +22965,7 @@ var editorContainer = css101`
22815
22965
  }
22816
22966
 
22817
22967
  &[style*='height:'] {
22818
- min-height: 50px;
22968
+ min-height: calc(3rem + (2 * var(--spacing-sm)));
22819
22969
  max-height: unset;
22820
22970
  }
22821
22971
  `;
@@ -22835,11 +22985,12 @@ var editorPlaceholder = css101`
22835
22985
  left: calc(var(--spacing-sm) + 1px);
22836
22986
  pointer-events: none;
22837
22987
  position: absolute;
22838
- top: var(--spacing-sm);
22988
+ top: calc(1rem + var(--spacing-sm));
22839
22989
  user-select: none;
22840
22990
  `;
22841
22991
  var editorInput = css101`
22842
22992
  min-height: 100%;
22993
+ flex-grow: 1;
22843
22994
 
22844
22995
  &:focus,
22845
22996
  &:focus-within {
@@ -22862,6 +23013,7 @@ var ParameterRichTextInner = ({
22862
23013
  variables,
22863
23014
  customControls,
22864
23015
  onInsertTable,
23016
+ onInsertAsset,
22865
23017
  minimalInteractivity
22866
23018
  }) => {
22867
23019
  const lexicalConfig = {
@@ -22934,6 +23086,7 @@ var ParameterRichTextInner = ({
22934
23086
  variables,
22935
23087
  customControls,
22936
23088
  onInsertTable,
23089
+ onInsertAsset,
22937
23090
  minimalInteractivity,
22938
23091
  children
22939
23092
  }
@@ -22962,15 +23115,16 @@ var RichText = ({
22962
23115
  variables,
22963
23116
  customControls,
22964
23117
  onInsertTable,
23118
+ onInsertAsset,
22965
23119
  minimalInteractivity
22966
23120
  }) => {
22967
- const [editor] = useLexicalComposerContext8();
22968
- useEffect24(() => {
23121
+ const [editor] = useLexicalComposerContext9();
23122
+ useEffect25(() => {
22969
23123
  if (onRichTextInit) {
22970
23124
  onRichTextInit(editor);
22971
23125
  }
22972
23126
  }, [editor, onRichTextInit]);
22973
- useEffect24(() => {
23127
+ useEffect25(() => {
22974
23128
  const removeUpdateListener = editor.registerUpdateListener(({ editorState, prevEditorState, tags }) => {
22975
23129
  requestAnimationFrame(() => {
22976
23130
  if (!deepEqual2(editorState.toJSON(), prevEditorState.toJSON())) {
@@ -22982,7 +23136,7 @@ var RichText = ({
22982
23136
  removeUpdateListener();
22983
23137
  };
22984
23138
  }, [editor, onChange]);
22985
- useEffect24(() => {
23139
+ useEffect25(() => {
22986
23140
  editor.setEditable(!readOnly);
22987
23141
  }, [editor, readOnly]);
22988
23142
  const [editorContainerRef, setEditorContainerRef] = useState21(null);
@@ -22998,7 +23152,15 @@ var RichText = ({
22998
23152
  }
22999
23153
  };
23000
23154
  return /* @__PURE__ */ jsxs89(Fragment21, { children: [
23001
- readOnly || minimalInteractivity ? null : /* @__PURE__ */ jsx133(RichTextToolbar_default, { config, customControls, onInsertTable }),
23155
+ readOnly || minimalInteractivity ? null : /* @__PURE__ */ jsx133(
23156
+ RichTextToolbar_default,
23157
+ {
23158
+ config,
23159
+ customControls,
23160
+ onInsertTable,
23161
+ onInsertAsset
23162
+ }
23163
+ ),
23002
23164
  /* @__PURE__ */ jsxs89("div", { css: editorContainerWrapper, ref: onPortalContainerRef, children: [
23003
23165
  /* @__PURE__ */ jsxs89(
23004
23166
  "div",
@@ -23045,7 +23207,8 @@ var RichText = ({
23045
23207
  positioningAnchorEl: editorContainerRef
23046
23208
  }
23047
23209
  ) : null,
23048
- /* @__PURE__ */ jsx133(TableSelectionPlugin_default, {})
23210
+ /* @__PURE__ */ jsx133(TableSelectionPlugin_default, {}),
23211
+ /* @__PURE__ */ jsx133(ImprovedAssetSelectionPlugin_default, {})
23049
23212
  ] })
23050
23213
  ] });
23051
23214
  };
@@ -23322,7 +23485,7 @@ var ProgressListItem = ({
23322
23485
  // src/components/SegmentedControl/SegmentedControl.tsx
23323
23486
  import { css as css106 } from "@emotion/react";
23324
23487
  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";
23488
+ import { useCallback as useCallback14, useEffect as useEffect26, useMemo as useMemo9, useRef as useRef14, useState as useState22 } from "react";
23326
23489
 
23327
23490
  // src/components/SegmentedControl/SegmentedControl.styles.ts
23328
23491
  import { css as css105 } from "@emotion/react";
@@ -23536,7 +23699,7 @@ var SegmentedControl = ({
23536
23699
  const isIconOnly = useMemo9(() => {
23537
23700
  return options.every((option) => option && option.icon && !option.label);
23538
23701
  }, [options]);
23539
- useEffect25(() => {
23702
+ useEffect26(() => {
23540
23703
  const wrapperElement = wrapperRef.current;
23541
23704
  const onScroll = () => {
23542
23705
  if (!wrapperElement) {
@@ -23864,7 +24027,7 @@ import {
23864
24027
  TabProvider as AriakitTabProvider,
23865
24028
  useTabStore as useAriakitTabStore
23866
24029
  } from "@ariakit/react";
23867
- import { useCallback as useCallback15, useEffect as useEffect26, useMemo as useMemo10 } from "react";
24030
+ import { useCallback as useCallback15, useEffect as useEffect27, useMemo as useMemo10 } from "react";
23868
24031
 
23869
24032
  // src/components/Tabs/Tabs.styles.ts
23870
24033
  import { css as css110 } from "@emotion/react";
@@ -23924,7 +24087,7 @@ var Tabs = ({
23924
24087
  },
23925
24088
  [onSelectedIdChange, useHashForState]
23926
24089
  );
23927
- useEffect26(() => {
24090
+ useEffect27(() => {
23928
24091
  if (selected && selected !== tab.getState().activeId) {
23929
24092
  tab.setSelectedId(selected);
23930
24093
  }