@noya-app/noya-designsystem 0.1.61 → 0.1.63

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/.eslintrc.js +1 -5
  2. package/.turbo/turbo-build.log +10 -10
  3. package/.turbo/turbo-lint.log +0 -1
  4. package/CHANGELOG.md +16 -0
  5. package/dist/index.css +1 -1
  6. package/dist/index.d.mts +147 -69
  7. package/dist/index.d.ts +147 -69
  8. package/dist/index.js +1347 -1063
  9. package/dist/index.js.map +1 -1
  10. package/dist/index.mjs +756 -473
  11. package/dist/index.mjs.map +1 -1
  12. package/package.json +4 -4
  13. package/src/components/Button.tsx +28 -20
  14. package/src/components/DimensionInput.tsx +1 -1
  15. package/src/components/DraggableMenuButton.tsx +20 -4
  16. package/src/components/DropdownMenu.tsx +31 -5
  17. package/src/components/IconButton.tsx +2 -2
  18. package/src/components/InputField.tsx +5 -5
  19. package/src/components/Label.tsx +0 -2
  20. package/src/components/LabeledField.tsx +36 -34
  21. package/src/components/Popover.tsx +12 -3
  22. package/src/components/SegmentedControl.tsx +1 -1
  23. package/src/components/SelectMenu.tsx +3 -3
  24. package/src/components/SelectionToolbar.tsx +28 -7
  25. package/src/components/Slider.tsx +1 -1
  26. package/src/components/Spacer.tsx +0 -1
  27. package/src/components/Tabs.tsx +46 -0
  28. package/src/components/Toolbar.tsx +106 -11
  29. package/src/components/Tooltip.tsx +8 -8
  30. package/src/components/file-explorer/FileExplorerLayout.tsx +12 -6
  31. package/src/components/internal/Menu.tsx +19 -2
  32. package/src/components/internal/MenuViewport.tsx +4 -3
  33. package/src/components/workspace/DrawerWorkspaceLayout.tsx +7 -3
  34. package/src/components/workspace/PanelWorkspaceLayout.tsx +103 -3
  35. package/src/components/workspace/WorkspaceLayout.tsx +96 -15
  36. package/src/components/workspace/renderPanelChildren.tsx +12 -0
  37. package/src/components/workspace/types.ts +19 -3
  38. package/src/hooks/useLabel.ts +10 -10
  39. package/src/hooks/usePreservePanelSize.tsx +1 -1
  40. package/src/index.css +10 -6
  41. package/src/index.tsx +2 -0
  42. package/src/utils/editableBlockStyles.ts +10 -0
  43. package/src/hooks/useWindowSize.tsx +0 -26
package/dist/index.mjs CHANGED
@@ -318,6 +318,26 @@ import { useEffect as useEffect7, useState as useState9 } from "react";
318
318
  import { decodeQueryParameters } from "@noya-app/noya-utils";
319
319
  import { useEffect as useEffect8, useState as useState10 } from "react";
320
320
 
321
+ // ../noya-react-utils/src/hooks/useWindowSize.ts
322
+ import { useEffect as useEffect9, useState as useState11 } from "react";
323
+ function useWindowSize() {
324
+ const [size2, setSize] = useState11(
325
+ typeof window === "undefined" ? { width: 0, height: 0 } : {
326
+ width: window.innerWidth,
327
+ height: window.innerHeight
328
+ }
329
+ );
330
+ useEffect9(() => {
331
+ const handleResize = () => setSize({
332
+ width: window.innerWidth,
333
+ height: window.innerHeight
334
+ });
335
+ window.addEventListener("resize", handleResize);
336
+ return () => window.removeEventListener("resize", handleResize);
337
+ }, []);
338
+ return size2;
339
+ }
340
+
321
341
  // ../emitter/src/index.ts
322
342
  var Emitter = class {
323
343
  constructor(options = {}) {
@@ -472,21 +492,6 @@ function getClosestPortalScope(element) {
472
492
  return closest.dataset[portalScopeDataSetName];
473
493
  }
474
494
 
475
- // src/components/internal/Menu.tsx
476
- import { getShortcutDisplayParts } from "@noya-app/noya-keymap";
477
- import React24, { memo as memo10 } from "react";
478
-
479
- // src/contexts/DesignSystemConfiguration.tsx
480
- import { getCurrentPlatform } from "@noya-app/noya-keymap";
481
- import * as React23 from "react";
482
-
483
- // src/components/Toast.tsx
484
- import * as ToastPrimitive from "@radix-ui/react-toast";
485
- import React13 from "react";
486
-
487
- // src/components/IconButton.tsx
488
- import * as React12 from "react";
489
-
490
495
  // src/components/Button.tsx
491
496
  import React11, {
492
497
  forwardRef as forwardRef4,
@@ -707,29 +712,33 @@ var Italic = ({ children }) => /* @__PURE__ */ React9.createElement(
707
712
  var Tooltip = React10.memo(function Tooltip2({
708
713
  children,
709
714
  content,
710
- sideOffset = 2
715
+ sideOffset = 2,
716
+ side = "bottom",
717
+ portalContainer
711
718
  }) {
712
719
  const portalScopeId = usePortalScopeId();
713
- return /* @__PURE__ */ React10.createElement(TooltipPrimitive.Provider, null, /* @__PURE__ */ React10.createElement(TooltipPrimitive.Root, null, /* @__PURE__ */ React10.createElement(TooltipPrimitive.Trigger, { asChild: true }, children), /* @__PURE__ */ React10.createElement(TooltipPrimitive.Portal, null, /* @__PURE__ */ React10.createElement(
720
+ return /* @__PURE__ */ React10.createElement(TooltipPrimitive.Provider, null, /* @__PURE__ */ React10.createElement(TooltipPrimitive.Root, null, /* @__PURE__ */ React10.createElement(TooltipPrimitive.Trigger, { asChild: true }, children), /* @__PURE__ */ React10.createElement(TooltipPrimitive.Portal, { container: portalContainer }, /* @__PURE__ */ React10.createElement(
714
721
  TooltipPrimitive.Content,
715
722
  {
716
723
  ...portalScopeProps(portalScopeId),
717
- side: "bottom",
724
+ side,
718
725
  align: "center",
719
726
  sideOffset,
720
727
  collisionPadding: 8,
721
- className: `${textStyles.small} text-text rounded-[3px] py-small px-medium bg-popover-background shadow-popover border border-solid border-divider-strong z-menu`
728
+ className: `${textStyles.small} text-text rounded-sm p-2 bg-popover-background shadow-tooltip z-menu`
722
729
  },
723
730
  content
724
731
  ))));
725
732
  });
726
733
 
727
734
  // src/components/Button.tsx
735
+ var colorSchemeStyles = {
736
+ default: "bg-button-background text-button-text hover:bg-button-background-hover active:bg-button-background-active",
737
+ primary: "bg-primary text-white hover:bg-primary-light active:bg-primary",
738
+ secondary: "bg-secondary text-white hover:bg-secondary-light active:bg-secondary"
739
+ };
728
740
  var variantStyles = {
729
- normal: "bg-button-background text-button-text hover:bg-button-background-hover active:bg-button-background-active min-w-[31px]",
730
- primary: "bg-primary text-white hover:bg-primary-light active:bg-primary min-w-[31px]",
731
- secondary: "bg-secondary text-white hover:bg-secondary-light active:bg-secondary min-w-[31px]",
732
- secondaryBright: "bg-[#0ab557] text-white hover:opacity-80 active:opacity-90",
741
+ normal: "",
733
742
  floating: "bg-floating-button text-text shadow-[0_1px_2px_rgba(0,0,0,0.1)] hover:opacity-80 active:opacity-90",
734
743
  thin: "bg-transparent text-text hover:bg-input-background-light",
735
744
  none: "bg-transparent text-text hover:bg-input-background-light"
@@ -752,6 +761,7 @@ var Button = forwardRef4(function Button2({
752
761
  tooltip,
753
762
  active = false,
754
763
  disabled = false,
764
+ colorScheme: colorSchemeProp,
755
765
  variant = "normal",
756
766
  size: size2 = "normal",
757
767
  contentStyle,
@@ -760,12 +770,16 @@ var Button = forwardRef4(function Button2({
760
770
  as: Component = "button",
761
771
  ...rest
762
772
  }, forwardedRef) {
773
+ const colorScheme = colorSchemeProp ?? "default";
763
774
  const baseClassName = cx(
764
775
  "no-underline leading-[1] relative border-0 outline-none select-none text-left rounded flex items-center justify-center [&>*]:pointer-events-none [-webkit-app-region:no-drag] focus:ring-2 focus:ring-primary focus:shadow-[0_0_0_1px_var(--n-popover-background)_inset] transition-all",
765
776
  disabled ? "opacity-25" : "",
766
777
  !className?.includes("flex") ? "flex-none" : "",
767
- active ? "bg-button-background-active text-button-text-active hover:bg-button-background-active-hover min-w-[31px]" : variantStyles[variant],
768
- sizeStyles[variant === "thin" ? "thin" : variant === "floating" && size2 !== "small" ? "floating" : variant === "none" ? "none" : size2]
778
+ active ? "bg-button-background-active text-button-text-active hover:bg-button-background-active-hover" : variantStyles[variant],
779
+ sizeStyles[variant === "thin" ? "thin" : variant === "floating" && size2 !== "small" ? "floating" : variant === "none" ? "none" : size2],
780
+ variant === "normal" && (children ? "min-w-[31px]" : "min-w-[27px]"),
781
+ colorSchemeStyles[colorScheme],
782
+ !children && (icon || iconRight) && !(icon && iconRight) && "w-[27px]"
769
783
  );
770
784
  const buttonClassName = useMemo4(() => {
771
785
  return className ? mergeConflictingClassNames([baseClassName, className], {
@@ -804,7 +818,20 @@ var Button = forwardRef4(function Button2({
804
818
  });
805
819
  var Button_default = Button;
806
820
 
821
+ // src/components/internal/Menu.tsx
822
+ import { getShortcutDisplayParts } from "@noya-app/noya-keymap";
823
+ import React24, { memo as memo10 } from "react";
824
+
825
+ // src/contexts/DesignSystemConfiguration.tsx
826
+ import { getCurrentPlatform } from "@noya-app/noya-keymap";
827
+ import * as React23 from "react";
828
+
829
+ // src/components/Toast.tsx
830
+ import * as ToastPrimitive from "@radix-ui/react-toast";
831
+ import React13 from "react";
832
+
807
833
  // src/components/IconButton.tsx
834
+ import * as React12 from "react";
808
835
  var IconButton = React12.memo(
809
836
  React12.forwardRef(function IconButton2({ selected, iconName, color, size: size2, contentStyle, ...props }, forwardedRef) {
810
837
  const Icon = Icons[iconName];
@@ -861,11 +888,11 @@ var ToastProvider = ({ children }) => /* @__PURE__ */ React13.createElement(Toas
861
888
  // src/contexts/DialogContext.tsx
862
889
  import React21, {
863
890
  createContext as createContext5,
864
- useCallback as useCallback13,
891
+ useCallback as useCallback14,
865
892
  useContext as useContext5,
866
893
  useMemo as useMemo8,
867
894
  useRef as useRef12,
868
- useState as useState14
895
+ useState as useState15
869
896
  } from "react";
870
897
 
871
898
  // src/components/Dialog.tsx
@@ -991,11 +1018,11 @@ import React20, {
991
1018
  createContext as createContext4,
992
1019
  forwardRef as forwardRef9,
993
1020
  memo as memo8,
994
- useCallback as useCallback12,
1021
+ useCallback as useCallback13,
995
1022
  useContext as useContext4,
996
1023
  useId as useId2,
997
1024
  useMemo as useMemo7,
998
- useState as useState13
1025
+ useState as useState14
999
1026
  } from "react";
1000
1027
 
1001
1028
  // src/hooks/useLabel.ts
@@ -1011,12 +1038,12 @@ var useLabel = ({ label, fieldId }) => {
1011
1038
  fieldId: fieldId ?? fieldIdFromContext
1012
1039
  };
1013
1040
  };
1014
- var LabelPositionContext = React15.createContext({
1015
- position: "start"
1041
+ var LabelTypeContext = React15.createContext({
1042
+ type: "start"
1016
1043
  });
1017
- var useLabelPosition = () => {
1018
- const { position } = React15.useContext(LabelPositionContext);
1019
- return position;
1044
+ var useLabelType = () => {
1045
+ const { type } = React15.useContext(LabelTypeContext);
1046
+ return type;
1020
1047
  };
1021
1048
  var LabelWidthContext = React15.createContext({
1022
1049
  width: 100
@@ -1065,14 +1092,14 @@ import { composeRefs } from "@radix-ui/react-compose-refs";
1065
1092
  import React16, {
1066
1093
  forwardRef as forwardRef7,
1067
1094
  useCallback as useCallback11,
1068
- useEffect as useEffect10,
1095
+ useEffect as useEffect11,
1069
1096
  useLayoutEffect as useLayoutEffect3,
1070
1097
  useRef as useRef10,
1071
- useState as useState11
1098
+ useState as useState12
1072
1099
  } from "react";
1073
1100
 
1074
1101
  // src/contexts/GlobalInputBlurContext.tsx
1075
- import { createContext as createContext2, useContext as useContext2, useEffect as useEffect9 } from "react";
1102
+ import { createContext as createContext2, useContext as useContext2, useEffect as useEffect10 } from "react";
1076
1103
  var defaultValue = /* @__PURE__ */ (() => {
1077
1104
  const listeners = [];
1078
1105
  const value = {
@@ -1099,7 +1126,7 @@ var useGlobalInputBlur = () => {
1099
1126
  };
1100
1127
  function useGlobalInputBlurListener(f) {
1101
1128
  const context = useGlobalInputBlur();
1102
- useEffect9(() => {
1129
+ useEffect10(() => {
1103
1130
  context.addListener(f);
1104
1131
  return () => {
1105
1132
  context.removeListener(f);
@@ -1189,7 +1216,7 @@ var SubmittableTextInput = forwardRef7(function SubmittableTextInput2({
1189
1216
  latestValue.current = value;
1190
1217
  const userDidEdit = useRef10(false);
1191
1218
  const isSubmitTriggeredByEscapeKey = useRef10(false);
1192
- const [internalValue, setInternalValue] = useState11("");
1219
+ const [internalValue, setInternalValue] = useState12("");
1193
1220
  useLayoutEffect3(() => {
1194
1221
  setInternalValue(value);
1195
1222
  }, [value]);
@@ -1251,7 +1278,7 @@ var SubmittableTextInput = forwardRef7(function SubmittableTextInput2({
1251
1278
  );
1252
1279
  const latestHandleSubmit = useRef10(handleSubmit);
1253
1280
  latestHandleSubmit.current = handleSubmit;
1254
- useEffect10(() => {
1281
+ useEffect11(() => {
1255
1282
  if (submitAutomaticallyAfterDelay) {
1256
1283
  if (autoSubmitTimeoutRef.current) {
1257
1284
  clearTimeout(autoSubmitTimeoutRef.current);
@@ -1337,7 +1364,12 @@ var Label = memo6(
1337
1364
 
1338
1365
  // src/components/Popover.tsx
1339
1366
  import * as PopoverPrimitive from "@radix-ui/react-popover";
1340
- import React19, { useEffect as useEffect11, useId, useRef as useRef11 } from "react";
1367
+ import React19, {
1368
+ useCallback as useCallback12,
1369
+ useEffect as useEffect12,
1370
+ useId,
1371
+ useRef as useRef11
1372
+ } from "react";
1341
1373
 
1342
1374
  // src/contexts/OpenPortalsContext.tsx
1343
1375
  import * as React18 from "react";
@@ -1415,8 +1447,9 @@ function Popover({
1415
1447
  onChange: onOpenChange,
1416
1448
  defaultValue: false
1417
1449
  });
1450
+ const close = useCallback12(() => setIsOpen(false), [setIsOpen]);
1418
1451
  const { addOpenPortal, removeOpenPortal } = useOpenPortalsControls();
1419
- useEffect11(() => {
1452
+ useEffect12(() => {
1420
1453
  if (!isOpen) return;
1421
1454
  addOpenPortal(portalScopeId || defaultId);
1422
1455
  return () => {
@@ -1453,7 +1486,7 @@ function Popover({
1453
1486
  collisionPadding: 8,
1454
1487
  arrowPadding: 2
1455
1488
  },
1456
- children,
1489
+ typeof children === "function" ? children({ close }) : children,
1457
1490
  showArrow && /* @__PURE__ */ React19.createElement(PopoverPrimitive.Arrow, { className: "fill-popover-background" }),
1458
1491
  closable && /* @__PURE__ */ React19.createElement(
1459
1492
  PopoverPrimitive.Close,
@@ -1525,7 +1558,7 @@ var InputFieldButton = memo8(
1525
1558
  ...rest
1526
1559
  } = props;
1527
1560
  const { size: size2, inputRef } = useInputFieldContext();
1528
- const defaultHandleClick = useCallback12(
1561
+ const defaultHandleClick = useCallback13(
1529
1562
  (event) => {
1530
1563
  if (inputRef && typeof inputRef !== "function") {
1531
1564
  inputRef.current?.focus();
@@ -1536,7 +1569,7 @@ var InputFieldButton = memo8(
1536
1569
  },
1537
1570
  [inputRef]
1538
1571
  );
1539
- const handlePointerDown = useCallback12(
1572
+ const handlePointerDown = useCallback13(
1540
1573
  (event) => {
1541
1574
  event.preventDefault();
1542
1575
  event.stopPropagation();
@@ -1639,7 +1672,7 @@ var InputElement = forwardRef9(
1639
1672
  var InputFieldInput = forwardRef9(function InputFieldInput2({ textAlign, variant, ...rest }, forwardedRef) {
1640
1673
  const { onFocusChange, inputRef } = useInputFieldContext();
1641
1674
  const ref = useMergeRefs(inputRef, forwardedRef);
1642
- const handleFocusChange = useCallback12(
1675
+ const handleFocusChange = useCallback13(
1643
1676
  (isFocused) => {
1644
1677
  onFocusChange(isFocused);
1645
1678
  },
@@ -1686,8 +1719,8 @@ function InputFieldNumberInput(props) {
1686
1719
  const { value, placeholder, onNudge, onBlur, readOnly, ...rest } = props;
1687
1720
  const onSubmit = "onSubmit" in props ? props.onSubmit : void 0;
1688
1721
  const onChange = "onChange" in props ? props.onChange : void 0;
1689
- const [internalValue, setInternalValue] = useState13();
1690
- const handleSubmit = useCallback12(
1722
+ const [internalValue, setInternalValue] = useState14();
1723
+ const handleSubmit = useCallback13(
1691
1724
  (value2) => {
1692
1725
  const newValue = parseNumber(value2);
1693
1726
  if (!isNaN(newValue)) {
@@ -1696,7 +1729,7 @@ function InputFieldNumberInput(props) {
1696
1729
  },
1697
1730
  [onSubmit]
1698
1731
  );
1699
- const handleKeyDown = useCallback12(
1732
+ const handleKeyDown = useCallback13(
1700
1733
  (event) => {
1701
1734
  const amount = handleNudge(event);
1702
1735
  if (!amount) return;
@@ -1707,7 +1740,7 @@ function InputFieldNumberInput(props) {
1707
1740
  },
1708
1741
  [onNudge]
1709
1742
  );
1710
- const handleChange = useCallback12(
1743
+ const handleChange = useCallback13(
1711
1744
  (value2) => {
1712
1745
  if (value2 === "" || value2 === "-" || value2 === ".") {
1713
1746
  setInternalValue(value2);
@@ -1725,7 +1758,7 @@ function InputFieldNumberInput(props) {
1725
1758
  },
1726
1759
  [onChange]
1727
1760
  );
1728
- const handleBlur = useCallback12(
1761
+ const handleBlur = useCallback13(
1729
1762
  (event) => {
1730
1763
  setInternalValue(void 0);
1731
1764
  onBlur?.(event);
@@ -1783,10 +1816,10 @@ function InputFieldRoot({
1783
1816
  const measuredInputSize = useSize(inputRef, "width");
1784
1817
  const measuredStartSize = useSize(startRef, "width");
1785
1818
  const measuredEndSize = useSize(endRef, "width");
1786
- const labelPosition = useLabelPosition();
1819
+ const labelType = useLabelType();
1787
1820
  const { label } = useLabel({ fieldId: id });
1788
1821
  const endStyles = getInsetEndStyles(size2);
1789
- const handleFocusChange = useCallback12(
1822
+ const handleFocusChange = useCallback13(
1790
1823
  (isFocused2) => {
1791
1824
  setIsFocused(isFocused2);
1792
1825
  onFocusChange?.(isFocused2);
@@ -1819,7 +1852,7 @@ function InputFieldRoot({
1819
1852
  ref: endRef,
1820
1853
  className: cx(endStyles, label && end && "gap-1.5", endClassName)
1821
1854
  },
1822
- labelProp ? insetLabel : label && labelPosition === "inset" && insetLabel,
1855
+ labelProp ? insetLabel : label && labelType === "inset" && insetLabel,
1823
1856
  end
1824
1857
  ));
1825
1858
  const measuredWidthObject = useMemo7(
@@ -1947,9 +1980,9 @@ var DialogContext = createContext5(void 0);
1947
1980
  var DialogProvider = function DialogProvider2({
1948
1981
  children
1949
1982
  }) {
1950
- const [contents, setContents] = useState14();
1983
+ const [contents, setContents] = useState15();
1951
1984
  const isOpen = !!contents;
1952
- const close = useCallback13(() => {
1985
+ const close = useCallback14(() => {
1953
1986
  if (contents) {
1954
1987
  if (contents.type === "input") {
1955
1988
  contents.resolve(void 0);
@@ -1961,12 +1994,12 @@ var DialogProvider = function DialogProvider2({
1961
1994
  }, [contents]);
1962
1995
  const closeRef = useRef12(close);
1963
1996
  closeRef.current = close;
1964
- const submit = useCallback13(() => {
1997
+ const submit = useCallback14(() => {
1965
1998
  if (!contents || contents.type !== "input") return;
1966
1999
  contents.resolve(contents.inputValue);
1967
2000
  setContents(void 0);
1968
2001
  }, [contents]);
1969
- const open = useCallback13((options) => {
2002
+ const open = useCallback14((options) => {
1970
2003
  const { promise, resolve } = createDeferredPromise();
1971
2004
  const { title, description, initialValue, placeholder, style: style2, className } = typeof options === "string" ? { title: options } : options;
1972
2005
  setContents({
@@ -1984,7 +2017,7 @@ var DialogProvider = function DialogProvider2({
1984
2017
  });
1985
2018
  return promise;
1986
2019
  }, []);
1987
- const openConfirmation = useCallback13((options) => {
2020
+ const openConfirmation = useCallback14((options) => {
1988
2021
  const { promise, resolve } = createDeferredPromise();
1989
2022
  const {
1990
2023
  title,
@@ -2009,7 +2042,7 @@ var DialogProvider = function DialogProvider2({
2009
2042
  });
2010
2043
  return promise;
2011
2044
  }, []);
2012
- const openCustomDialog = useCallback13(
2045
+ const openCustomDialog = useCallback14(
2013
2046
  (options) => {
2014
2047
  const { promise, resolve } = createDeferredPromise();
2015
2048
  const { title, description, style: style2, className } = options;
@@ -2030,7 +2063,7 @@ var DialogProvider = function DialogProvider2({
2030
2063
  },
2031
2064
  []
2032
2065
  );
2033
- const handleKeyDown = useCallback13(
2066
+ const handleKeyDown = useCallback14(
2034
2067
  (event) => {
2035
2068
  if (event.key !== "Enter") return;
2036
2069
  event.stopPropagation();
@@ -2041,7 +2074,7 @@ var DialogProvider = function DialogProvider2({
2041
2074
  );
2042
2075
  const inputRef = useRef12(null);
2043
2076
  const dialogRef = useRef12(null);
2044
- const containsElement = useCallback13((element) => {
2077
+ const containsElement = useCallback14((element) => {
2045
2078
  if (!dialogRef.current) return false;
2046
2079
  return dialogRef.current.containsElement(element);
2047
2080
  }, []);
@@ -2068,7 +2101,7 @@ var DialogProvider = function DialogProvider2({
2068
2101
  open: isOpen,
2069
2102
  style: contents?.style,
2070
2103
  className: contents?.className,
2071
- onOpenChange: useCallback13(
2104
+ onOpenChange: useCallback14(
2072
2105
  (isOpen2) => {
2073
2106
  if (!isOpen2) {
2074
2107
  close();
@@ -2076,7 +2109,7 @@ var DialogProvider = function DialogProvider2({
2076
2109
  },
2077
2110
  [close]
2078
2111
  ),
2079
- onOpenAutoFocus: useCallback13(
2112
+ onOpenAutoFocus: useCallback14(
2080
2113
  (event) => {
2081
2114
  event.stopPropagation();
2082
2115
  event.preventDefault();
@@ -2156,14 +2189,14 @@ function useOpenDialog() {
2156
2189
 
2157
2190
  // src/contexts/FloatingWindowContext.tsx
2158
2191
  import { uuid } from "@noya-app/noya-utils";
2159
- import React22, { createContext as createContext6, useContext as useContext6, useMemo as useMemo9, useState as useState15 } from "react";
2192
+ import React22, { createContext as createContext6, useContext as useContext6, useMemo as useMemo9, useState as useState16 } from "react";
2160
2193
  import { createPortal } from "react-dom";
2161
2194
  var FloatingWindowContext = createContext6(void 0);
2162
2195
  var CurrentWindowContext = createContext6(void 0);
2163
2196
  var FloatingWindowProvider = ({
2164
2197
  children
2165
2198
  }) => {
2166
- const [windows, setWindows] = useState15({});
2199
+ const [windows, setWindows] = useState16({});
2167
2200
  const contextValue = useMemo9(() => {
2168
2201
  const createWindow = (element) => {
2169
2202
  const id = uuid();
@@ -2273,6 +2306,7 @@ var isSelectableMenuItem = (item) => {
2273
2306
  var isNonSelectableMenuItem = (item) => !isSelectableMenuItem(item);
2274
2307
  var isMenuItemSectionHeader = (item) => item.type === "sectionHeader";
2275
2308
  var isSelectableMenuItemWithScore = (item) => isSelectableMenuItem(item) && "index" in item && "score" in item;
2309
+ var isPopoverMenuItem = (item) => item.type === "popover";
2276
2310
  var getMenuItemKey = (item, index) => {
2277
2311
  switch (item.type) {
2278
2312
  case "separator":
@@ -2281,6 +2315,8 @@ var getMenuItemKey = (item, index) => {
2281
2315
  return item.id;
2282
2316
  case "submenu":
2283
2317
  return item.id;
2318
+ case "popover":
2319
+ return item.id;
2284
2320
  default:
2285
2321
  return item.value;
2286
2322
  }
@@ -2311,6 +2347,7 @@ var styles = {
2311
2347
  function getKeyboardShortcuts(item) {
2312
2348
  if (item.type === "separator") return [];
2313
2349
  if (item.type === "sectionHeader") return [];
2350
+ if (item.type === "popover") return [];
2314
2351
  if (item.type === "submenu") return item.items.flatMap(getKeyboardShortcuts);
2315
2352
  if (item.disabled || !item.value || !item.shortcut) return [];
2316
2353
  return [[item.shortcut, item.value]];
@@ -2389,7 +2426,7 @@ import { ChevronRightIcon } from "@noya-app/noya-icons";
2389
2426
  import React26 from "react";
2390
2427
 
2391
2428
  // src/components/internal/SelectItem.tsx
2392
- import React25, { useCallback as useCallback14 } from "react";
2429
+ import React25, { useCallback as useCallback15 } from "react";
2393
2430
  var SelectItem = React25.forwardRef(
2394
2431
  ({
2395
2432
  children,
@@ -2404,11 +2441,11 @@ var SelectItem = React25.forwardRef(
2404
2441
  testSelected,
2405
2442
  ...props
2406
2443
  }, forwardedRef) => {
2407
- const handleSelectItem = useCallback14(() => {
2444
+ const handleSelectItem = useCallback15(() => {
2408
2445
  if (!value) return;
2409
2446
  onSelect?.(value);
2410
2447
  }, [onSelect, value]);
2411
- const cancelClickPropagation = useCallback14(
2448
+ const cancelClickPropagation = useCallback15(
2412
2449
  (event) => {
2413
2450
  event.stopPropagation();
2414
2451
  },
@@ -2486,7 +2523,7 @@ var MenuViewport = ({
2486
2523
  }) => {
2487
2524
  const portalScopeId = usePortalScopeId();
2488
2525
  const hasCheckedItem = items.some(
2489
- (item) => item.type !== "separator" && item.type !== "sectionHeader" && item.checked
2526
+ (item) => isSelectableMenuItem(item) && item.checked
2490
2527
  );
2491
2528
  return /* @__PURE__ */ React26.createElement(React26.Fragment, null, items.map((item, index) => {
2492
2529
  switch (item.type) {
@@ -2508,6 +2545,8 @@ var MenuViewport = ({
2508
2545
  indented: hasCheckedItem
2509
2546
  }
2510
2547
  );
2548
+ case "popover":
2549
+ return null;
2511
2550
  case "submenu":
2512
2551
  if (item.items && Components4.Sub && Components4.SubTrigger && Components4.SubContent && Components4.Portal) {
2513
2552
  return /* @__PURE__ */ React26.createElement(Components4.Sub, { key: item.id }, /* @__PURE__ */ React26.createElement(
@@ -2595,7 +2634,7 @@ var DropdownMenuRoot = forwardRefGeneric(function DropdownMenuRoot2(props, forwa
2595
2634
  onSelect,
2596
2635
  shouldBindKeyboardShortcuts,
2597
2636
  onOpenChange,
2598
- open,
2637
+ open: openProp,
2599
2638
  onCloseAutoFocus,
2600
2639
  side,
2601
2640
  sideOffset = 4,
@@ -2603,8 +2642,15 @@ var DropdownMenuRoot = forwardRefGeneric(function DropdownMenuRoot2(props, forwa
2603
2642
  alignOffset,
2604
2643
  collisionPadding = 8,
2605
2644
  emptyState,
2606
- contentStyle
2645
+ contentStyle,
2646
+ title,
2647
+ icon
2607
2648
  } = props;
2649
+ const [open, setOpen] = useControlledOrUncontrolled({
2650
+ value: openProp,
2651
+ onChange: onOpenChange,
2652
+ defaultValue: false
2653
+ });
2608
2654
  const portalScopeId = usePortalScopeId();
2609
2655
  const keymap = useMemo11(
2610
2656
  () => shouldBindKeyboardShortcuts === false ? {} : getKeyboardShortcutsForMenuItems(items, onSelect),
@@ -2619,13 +2665,13 @@ var DropdownMenuRoot = forwardRefGeneric(function DropdownMenuRoot2(props, forwa
2619
2665
  }),
2620
2666
  [contentStyle]
2621
2667
  );
2622
- return /* @__PURE__ */ React27.createElement(RadixDropdownMenu.Root, { onOpenChange, open }, /* @__PURE__ */ React27.createElement(
2668
+ return /* @__PURE__ */ React27.createElement(RadixDropdownMenu.Root, { onOpenChange: setOpen, open }, /* @__PURE__ */ React27.createElement(
2623
2669
  RadixDropdownMenu.Trigger,
2624
2670
  {
2625
2671
  ref: forwardedRef,
2626
2672
  asChild: true
2627
2673
  },
2628
- children
2674
+ typeof children === "function" ? children({ open }) : children || /* @__PURE__ */ React27.createElement(Button_default, { icon, active: open, iconRight: "DropdownChevronIcon" }, title)
2629
2675
  ), /* @__PURE__ */ React27.createElement(RadixDropdownMenu.Portal, null, /* @__PURE__ */ React27.createElement(
2630
2676
  RadixDropdownMenu.Content,
2631
2677
  {
@@ -3002,13 +3048,13 @@ import React33, { forwardRef as forwardRef13 } from "react";
3002
3048
  import React32, {
3003
3049
  forwardRef as forwardRef12,
3004
3050
  memo as memo12,
3005
- useCallback as useCallback15,
3006
- useEffect as useEffect13,
3051
+ useCallback as useCallback16,
3052
+ useEffect as useEffect14,
3007
3053
  useRef as useRef13
3008
3054
  } from "react";
3009
3055
  var useAutoResize = (value) => {
3010
3056
  const textareaRef = useRef13(null);
3011
- useEffect13(() => {
3057
+ useEffect14(() => {
3012
3058
  if (value === void 0) return;
3013
3059
  if (!textareaRef.current) return;
3014
3060
  textareaRef.current.style.height = "auto";
@@ -3029,14 +3075,14 @@ var TextArea = memo12(
3029
3075
  const autoResizeRef = useAutoResize(
3030
3076
  autoResize ? value || rest.placeholder || "" : void 0
3031
3077
  );
3032
- const handleChange = useCallback15(
3078
+ const handleChange = useCallback16(
3033
3079
  (event) => {
3034
3080
  onChangeText?.(event.target.value);
3035
3081
  onChange?.(event);
3036
3082
  },
3037
3083
  [onChangeText, onChange]
3038
3084
  );
3039
- const handleRef = useCallback15(
3085
+ const handleRef = useCallback16(
3040
3086
  (value2) => {
3041
3087
  if (autoResize) {
3042
3088
  autoResizeRef.current = value2;
@@ -3140,11 +3186,11 @@ import { isDeepEqual as isDeepEqual3 } from "@noya-app/noya-utils";
3140
3186
  import React34, {
3141
3187
  Children as Children2,
3142
3188
  isValidElement as isValidElement2,
3143
- useCallback as useCallback16,
3144
- useEffect as useEffect14,
3189
+ useCallback as useCallback17,
3190
+ useEffect as useEffect15,
3145
3191
  useLayoutEffect as useLayoutEffect4,
3146
3192
  useRef as useRef14,
3147
- useState as useState17
3193
+ useState as useState18
3148
3194
  } from "react";
3149
3195
  var defaultDuration = 150;
3150
3196
  var defaultAnimationStyles = {
@@ -3170,7 +3216,7 @@ var PresenceChild = ({
3170
3216
  skipInitialAnimation,
3171
3217
  className
3172
3218
  }) => {
3173
- const [animationState, setAnimationState] = useState17(
3219
+ const [animationState, setAnimationState] = useState18(
3174
3220
  () => skipInitialAnimation && isPresent ? "entered" : isPresent ? "entering" : "exited"
3175
3221
  );
3176
3222
  const timeoutRef = useRef14();
@@ -3227,11 +3273,11 @@ var AnimatePresence = ({
3227
3273
  mode = "wait",
3228
3274
  className
3229
3275
  }) => {
3230
- const [mountedChildren, setMountedChildren] = useState17([]);
3276
+ const [mountedChildren, setMountedChildren] = useState18([]);
3231
3277
  const previousChildrenRef = useRef14([]);
3232
3278
  const removingChildrenRef = useRef14(/* @__PURE__ */ new Set());
3233
3279
  const waitingToEnterRef = useRef14([]);
3234
- useEffect14(() => {
3280
+ useEffect15(() => {
3235
3281
  const newChildren = Children2.toArray(children).filter(
3236
3282
  isValidElement2
3237
3283
  );
@@ -3274,7 +3320,7 @@ var AnimatePresence = ({
3274
3320
  return [...updated, ...newMounted];
3275
3321
  });
3276
3322
  }, [children, skipInitialAnimation, mode]);
3277
- const removeChild = useCallback16((childKey) => {
3323
+ const removeChild = useCallback17((childKey) => {
3278
3324
  if (!removingChildrenRef.current.has(childKey)) return;
3279
3325
  removingChildrenRef.current.delete(childKey);
3280
3326
  setMountedChildren((prev) => {
@@ -3377,7 +3423,7 @@ var BreadcrumbSlash = () => {
3377
3423
 
3378
3424
  // src/components/Checkbox.tsx
3379
3425
  import * as React37 from "react";
3380
- var colorSchemeStyles = {
3426
+ var colorSchemeStyles2 = {
3381
3427
  normal: "text-text-subtle",
3382
3428
  primary: "text-primary",
3383
3429
  secondary: "text-secondary"
@@ -3390,7 +3436,7 @@ var Checkbox = React37.memo(
3390
3436
  {
3391
3437
  className: cx(
3392
3438
  "flex-none relative inline-flex w-[19px] h-[19px]",
3393
- colorSchemeStyles[colorScheme],
3439
+ colorSchemeStyles2[colorScheme],
3394
3440
  className
3395
3441
  ),
3396
3442
  style: style2
@@ -3687,7 +3733,7 @@ var Chip = memo14(
3687
3733
  import React52 from "react";
3688
3734
 
3689
3735
  // src/components/Grid.tsx
3690
- import React44, { useImperativeHandle as useImperativeHandle3, useRef as useRef17, useState as useState21 } from "react";
3736
+ import React44, { useImperativeHandle as useImperativeHandle3, useRef as useRef17, useState as useState22 } from "react";
3691
3737
 
3692
3738
  // src/utils/selection.ts
3693
3739
  function updateSelection(allIds, selectedIds, clickedId, event) {
@@ -3718,11 +3764,11 @@ function updateSelection(allIds, selectedIds, clickedId, event) {
3718
3764
  import React40, {
3719
3765
  forwardRef as forwardRef17,
3720
3766
  memo as memo15,
3721
- useCallback as useCallback17,
3722
- useEffect as useEffect16,
3767
+ useCallback as useCallback18,
3768
+ useEffect as useEffect17,
3723
3769
  useImperativeHandle as useImperativeHandle2,
3724
3770
  useRef as useRef16,
3725
- useState as useState19
3771
+ useState as useState20
3726
3772
  } from "react";
3727
3773
  var defaultRenderPreview = (props) => /* @__PURE__ */ React40.createElement(BreadcrumbText, { ...props });
3728
3774
  var EditableText = memo15(
@@ -3744,16 +3790,16 @@ var EditableText = memo15(
3744
3790
  tabIndex = 0,
3745
3791
  ...props
3746
3792
  }, ref) {
3747
- const [inputValue, setInputValue] = useState19(value);
3748
- useEffect16(() => {
3793
+ const [inputValue, setInputValue] = useState20(value);
3794
+ useEffect17(() => {
3749
3795
  setInputValue(value);
3750
3796
  }, [value]);
3751
- const [focusedInternal, setFocused] = useState19(false);
3797
+ const [focusedInternal, setFocused] = useState20(false);
3752
3798
  const focused = focusedProp ?? focusedInternal;
3753
3799
  const inputRef = useRef16(null);
3754
3800
  const previewRef = useRef16(null);
3755
3801
  const ignoreNextBlur = useRef16(false);
3756
- const handleKeyDown = useCallback17(
3802
+ const handleKeyDown = useCallback18(
3757
3803
  (event) => {
3758
3804
  if (event.key === "Escape") {
3759
3805
  setInputValue(value);
@@ -3781,7 +3827,7 @@ var EditableText = memo15(
3781
3827
  inputRef.current?.focus();
3782
3828
  inputRef.current?.setSelectionRange(0, inputRef.current.value.length);
3783
3829
  }
3784
- useEffect16(() => {
3830
+ useEffect17(() => {
3785
3831
  if (testFocused) return;
3786
3832
  if (focused) {
3787
3833
  setTimeout(focusInput, 1);
@@ -3850,7 +3896,7 @@ import React43, {
3850
3896
  createContext as createContext8,
3851
3897
  forwardRef as forwardRef18,
3852
3898
  memo as memo17,
3853
- useCallback as useCallback20,
3899
+ useCallback as useCallback21,
3854
3900
  useContext as useContext8,
3855
3901
  useMemo as useMemo17
3856
3902
  } from "react";
@@ -3858,7 +3904,7 @@ import React43, {
3858
3904
  // src/components/ContextMenu.tsx
3859
3905
  import { useKeyboardShortcuts as useKeyboardShortcuts2 } from "@noya-app/noya-keymap";
3860
3906
  import * as RadixContextMenu from "@radix-ui/react-context-menu";
3861
- import React41, { useCallback as useCallback18, useMemo as useMemo16 } from "react";
3907
+ import React41, { useCallback as useCallback19, useMemo as useMemo16 } from "react";
3862
3908
  var Components2 = {
3863
3909
  Separator: RadixContextMenu.Separator,
3864
3910
  ItemText: React41.Fragment,
@@ -3883,10 +3929,10 @@ function ContextMenuRoot({
3883
3929
  );
3884
3930
  const portalScopeId = usePortalScopeId();
3885
3931
  useKeyboardShortcuts2(keymap);
3886
- const onPointerDown = useCallback18((event) => {
3932
+ const onPointerDown = useCallback19((event) => {
3887
3933
  event.preventDefault();
3888
3934
  }, []);
3889
- const handleSelectItem = useCallback18(
3935
+ const handleSelectItem = useCallback19(
3890
3936
  (value) => {
3891
3937
  if (!value) return;
3892
3938
  onSelect(value);
@@ -4005,7 +4051,7 @@ var GridViewItem = forwardRefGeneric(function GridViewItem2({
4005
4051
  onHoverChange
4006
4052
  });
4007
4053
  const { textPosition, bordered, disabled } = useContext8(GridViewContext);
4008
- const handleClick = useCallback20(
4054
+ const handleClick = useCallback21(
4009
4055
  (event) => {
4010
4056
  event.stopPropagation();
4011
4057
  event.preventDefault();
@@ -4014,7 +4060,7 @@ var GridViewItem = forwardRefGeneric(function GridViewItem2({
4014
4060
  },
4015
4061
  [onClick, onSelect]
4016
4062
  );
4017
- const handleKeyDown = useCallback20(
4063
+ const handleKeyDown = useCallback21(
4018
4064
  (event) => {
4019
4065
  onKeyDown?.(event);
4020
4066
  if (event.key === "Enter" || event.key === " ") {
@@ -4108,7 +4154,7 @@ var GridViewRoot = forwardRef18(function GridViewRoot2({
4108
4154
  contentClassName,
4109
4155
  ...props
4110
4156
  }, forwardedRef) {
4111
- const handleClick = useCallback20(
4157
+ const handleClick = useCallback21(
4112
4158
  (event) => {
4113
4159
  event.stopPropagation();
4114
4160
  event.preventDefault();
@@ -4255,9 +4301,9 @@ var Grid = memoGeneric(
4255
4301
  renderEmptyState
4256
4302
  // getDropTargetParentIndex,
4257
4303
  } = props;
4258
- const [hoveredId, setHoveredId] = useState21();
4259
- const [internalRenamingId, setRenamingId] = useState21();
4260
- const [dropdownOpenId, setDropdownOpenId] = useState21();
4304
+ const [hoveredId, setHoveredId] = useState22();
4305
+ const [internalRenamingId, setRenamingId] = useState22();
4306
+ const [dropdownOpenId, setDropdownOpenId] = useState22();
4261
4307
  useImperativeHandle3(ref, () => ({
4262
4308
  editName: (id) => {
4263
4309
  setRenamingId(id);
@@ -4430,7 +4476,7 @@ var Grid = memoGeneric(
4430
4476
  );
4431
4477
 
4432
4478
  // src/components/List.tsx
4433
- import React51, { memo as memo19, useImperativeHandle as useImperativeHandle5, useRef as useRef20, useState as useState23 } from "react";
4479
+ import React51, { memo as memo19, useImperativeHandle as useImperativeHandle5, useRef as useRef20, useState as useState24 } from "react";
4434
4480
 
4435
4481
  // src/components/ListView.tsx
4436
4482
  import { range } from "@noya-app/noya-utils";
@@ -4441,7 +4487,7 @@ import React49, {
4441
4487
  forwardRef as forwardRef19,
4442
4488
  isValidElement as isValidElement3,
4443
4489
  memo as memo18,
4444
- useCallback as useCallback23,
4490
+ useCallback as useCallback24,
4445
4491
  useContext as useContext11,
4446
4492
  useImperativeHandle as useImperativeHandle4,
4447
4493
  useLayoutEffect as useLayoutEffect5,
@@ -5360,7 +5406,7 @@ var ListViewRow = forwardRefGeneric(function ListViewRow2({
5360
5406
  onHoverChange
5361
5407
  });
5362
5408
  const { indentation, isDragOverlay } = useContext11(ListViewDraggingContext);
5363
- const handlePress = useCallback23(
5409
+ const handlePress = useCallback24(
5364
5410
  (event) => {
5365
5411
  event.preventDefault();
5366
5412
  if (event.button !== 0) return;
@@ -5368,7 +5414,7 @@ var ListViewRow = forwardRefGeneric(function ListViewRow2({
5368
5414
  },
5369
5415
  [onPress]
5370
5416
  );
5371
- const handleDoubleClick = useCallback23(
5417
+ const handleDoubleClick = useCallback24(
5372
5418
  (event) => {
5373
5419
  event.stopPropagation();
5374
5420
  onDoubleClick?.();
@@ -5508,7 +5554,7 @@ var VirtualizedListInner = forwardRefGeneric(function VirtualizedListInner2({
5508
5554
  scrollElement,
5509
5555
  style: useMemo21(() => ({ flex: "1 1 auto" }), [])
5510
5556
  },
5511
- useCallback23(
5557
+ useCallback24(
5512
5558
  ({
5513
5559
  registerChild,
5514
5560
  onChildScroll,
@@ -5581,7 +5627,7 @@ var ListViewRootInner = forwardRefGeneric(function ListViewRootInner2({
5581
5627
  sharedDragProps,
5582
5628
  sortableId
5583
5629
  }, forwardedRef) {
5584
- const handleClick = useCallback23(
5630
+ const handleClick = useCallback24(
5585
5631
  (event) => {
5586
5632
  if (event.target instanceof HTMLElement && event.target.classList.contains("scroll-component"))
5587
5633
  return;
@@ -5591,7 +5637,7 @@ var ListViewRootInner = forwardRefGeneric(function ListViewRootInner2({
5591
5637
  },
5592
5638
  [onPress]
5593
5639
  );
5594
- const renderChild = useCallback23(
5640
+ const renderChild = useCallback24(
5595
5641
  (index) => renderItem(data[index], index, { isDragOverlay: false }),
5596
5642
  [data, renderItem]
5597
5643
  );
@@ -5620,7 +5666,7 @@ var ListViewRootInner = forwardRefGeneric(function ListViewRootInner2({
5620
5666
  sectionHeaderVariant
5621
5667
  ]
5622
5668
  );
5623
- const getItemContextValue = useCallback23(
5669
+ const getItemContextValue = useCallback24(
5624
5670
  (i) => {
5625
5671
  if (variant === "bare" || variant === "normal")
5626
5672
  return defaultContextValue;
@@ -5686,11 +5732,11 @@ var ListViewRootInner = forwardRefGeneric(function ListViewRootInner2({
5686
5732
  () => ({ indentation, isDragOverlay: true }),
5687
5733
  [indentation]
5688
5734
  );
5689
- const renderOverlay = useCallback23(
5735
+ const renderOverlay = useCallback24(
5690
5736
  (index) => /* @__PURE__ */ React49.createElement("div", { style: { opacity: 0.25 } }, /* @__PURE__ */ React49.createElement(ListViewDraggingContext.Provider, { value: draggingContextOverlayValue }, renderItem(data[index], index, { isDragOverlay: true }))),
5691
5737
  [draggingContextOverlayValue, renderItem, data]
5692
5738
  );
5693
- const renderWrappedChild = useCallback23(
5739
+ const renderWrappedChild = useCallback24(
5694
5740
  (index) => {
5695
5741
  const contextValue = getItemContextValue(index);
5696
5742
  const current = renderChild(index);
@@ -5714,7 +5760,7 @@ var ListViewRootInner = forwardRefGeneric(function ListViewRootInner2({
5714
5760
  children
5715
5761
  ) : children;
5716
5762
  const withScrollable = (children) => scrollable ? /* @__PURE__ */ React49.createElement(ScrollArea, null, children) : children(null);
5717
- const getItemHeight = useCallback23(
5763
+ const getItemHeight = useCallback24(
5718
5764
  (index) => {
5719
5765
  const child = getItemContextValue(index);
5720
5766
  const height = child?.isSectionHeader && child.sectionHeaderVariant === "label" ? SECTION_HEADER_LABEL_HEIGHT : ROW_HEIGHT;
@@ -5722,7 +5768,7 @@ var ListViewRootInner = forwardRefGeneric(function ListViewRootInner2({
5722
5768
  },
5723
5769
  [getItemContextValue]
5724
5770
  );
5725
- const getKey = useCallback23(
5771
+ const getKey = useCallback24(
5726
5772
  (index) => keyExtractor(data[index], index),
5727
5773
  [data, keyExtractor]
5728
5774
  );
@@ -5787,11 +5833,11 @@ var ChildrenListViewInner = forwardRef19(function ChildrenListViewInner2({ child
5787
5833
  ref: forwardedRef,
5788
5834
  ...rest,
5789
5835
  data: items,
5790
- keyExtractor: useCallback23(
5836
+ keyExtractor: useCallback24(
5791
5837
  ({ key }, index) => typeof key === "string" ? key : (key ?? index).toString(),
5792
5838
  []
5793
5839
  ),
5794
- renderItem: useCallback23((item) => item, [])
5840
+ renderItem: useCallback24((item) => item, [])
5795
5841
  }
5796
5842
  );
5797
5843
  });
@@ -5824,7 +5870,7 @@ var ListView;
5824
5870
  })(ListView || (ListView = {}));
5825
5871
 
5826
5872
  // src/components/TreeView.tsx
5827
- import React50, { useCallback as useCallback24, useContext as useContext12 } from "react";
5873
+ import React50, { useCallback as useCallback25, useContext as useContext12 } from "react";
5828
5874
  var TreeRow = forwardRefGeneric(function TreeRow2({
5829
5875
  icon,
5830
5876
  expanded,
@@ -5834,7 +5880,7 @@ var TreeRow = forwardRefGeneric(function TreeRow2({
5834
5880
  ...rest
5835
5881
  }, forwardedRef) {
5836
5882
  const { expandable } = useContext12(ListView.RowContext);
5837
- const handleClickChevron = useCallback24(
5883
+ const handleClickChevron = useCallback25(
5838
5884
  (event) => {
5839
5885
  event.stopPropagation();
5840
5886
  onClickChevron?.({ altKey: event.altKey });
@@ -5906,9 +5952,9 @@ var List = memoGeneric(
5906
5952
  sortableId,
5907
5953
  sharedDragProps
5908
5954
  } = props;
5909
- const [internalHoveredId, setHoveredId] = useState23();
5910
- const [internalRenamingId, setRenamingId] = useState23();
5911
- const [dropdownOpenId, setDropdownOpenId] = useState23();
5955
+ const [internalHoveredId, setHoveredId] = useState24();
5956
+ const [internalRenamingId, setRenamingId] = useState24();
5957
+ const [dropdownOpenId, setDropdownOpenId] = useState24();
5912
5958
  const hoveredId = internalHoveredId ?? testHoveredId;
5913
5959
  const renamingId = testRenamingId ?? internalRenamingId;
5914
5960
  const handleSelect = (itemId, event) => {
@@ -6254,12 +6300,12 @@ function ColorSwatchControl(props) {
6254
6300
  // src/components/Combobox.tsx
6255
6301
  import { DropdownChevronIcon as DropdownChevronIcon2 } from "@noya-app/noya-icons";
6256
6302
  import React56, {
6257
- useCallback as useCallback25,
6258
- useEffect as useEffect19,
6303
+ useCallback as useCallback26,
6304
+ useEffect as useEffect20,
6259
6305
  useImperativeHandle as useImperativeHandle6,
6260
6306
  useMemo as useMemo23,
6261
6307
  useRef as useRef21,
6262
- useState as useState24
6308
+ useState as useState25
6263
6309
  } from "react";
6264
6310
 
6265
6311
  // src/utils/combobox.ts
@@ -6729,7 +6775,7 @@ var Combobox = memoGeneric(
6729
6775
  }
6730
6776
  }
6731
6777
  const initialValueString = getInitialValueString();
6732
- const [comboboxState] = useState24(
6778
+ const [comboboxState] = useState25(
6733
6779
  () => new ComboboxState(
6734
6780
  items,
6735
6781
  initialValueString,
@@ -6737,26 +6783,26 @@ var Combobox = memoGeneric(
6737
6783
  )
6738
6784
  );
6739
6785
  const state = useComboboxState(comboboxState);
6740
- const [isFocused, setIsFocused] = useState24(false);
6786
+ const [isFocused, setIsFocused] = useState25(false);
6741
6787
  const listRef = useRef21(null);
6742
- const [shouldBlur, setShouldBlur] = useState24(false);
6788
+ const [shouldBlur, setShouldBlur] = useState25(false);
6743
6789
  const { fieldId: id } = useLabel({
6744
6790
  fieldId: rest.id
6745
6791
  });
6746
- useEffect19(() => {
6792
+ useEffect20(() => {
6747
6793
  comboboxState.setItems(items);
6748
6794
  }, [items, comboboxState]);
6749
- useEffect19(() => {
6795
+ useEffect20(() => {
6750
6796
  comboboxState.setFilter(initialValueString);
6751
6797
  }, [comboboxState, initialValueString]);
6752
6798
  const { filter, selectedIndex, filteredItems } = state;
6753
6799
  const shouldShowMenu = isFocused && !(hideMenuWhenEmptyValue && filter === "");
6754
- useEffect19(() => {
6800
+ useEffect20(() => {
6755
6801
  if (listRef.current) {
6756
6802
  listRef.current.scrollToIndex(selectedIndex);
6757
6803
  }
6758
6804
  }, [selectedIndex]);
6759
- const handleBlur = useCallback25(() => {
6805
+ const handleBlur = useCallback26(() => {
6760
6806
  ref.current?.blur();
6761
6807
  comboboxState.reset(initialValueString);
6762
6808
  if (props.mode === "string") {
@@ -6775,7 +6821,7 @@ var Combobox = memoGeneric(
6775
6821
  }
6776
6822
  setIsFocused(false);
6777
6823
  }, [filter, initialValueString, props, state, comboboxState]);
6778
- const handleFocus = useCallback25(
6824
+ const handleFocus = useCallback26(
6779
6825
  (event) => {
6780
6826
  setIsFocused(true);
6781
6827
  comboboxState.reset(
@@ -6789,7 +6835,7 @@ var Combobox = memoGeneric(
6789
6835
  },
6790
6836
  [initialValueString, onFocus, openMenuBehavior, comboboxState]
6791
6837
  );
6792
- const handleUpdateSelection = useCallback25(
6838
+ const handleUpdateSelection = useCallback26(
6793
6839
  (item) => {
6794
6840
  if (item.type !== void 0) return;
6795
6841
  const selectedItem = comboboxState.selectCurrentItem(item);
@@ -6805,7 +6851,7 @@ var Combobox = memoGeneric(
6805
6851
  },
6806
6852
  [props, comboboxState]
6807
6853
  );
6808
- const handleIndexChange = useCallback25(
6854
+ const handleIndexChange = useCallback26(
6809
6855
  (index) => {
6810
6856
  comboboxState.setSelectedIndex(index);
6811
6857
  const item = comboboxState.getSelectedItem();
@@ -6821,7 +6867,7 @@ var Combobox = memoGeneric(
6821
6867
  },
6822
6868
  [props, comboboxState]
6823
6869
  );
6824
- const handleChange = useCallback25(
6870
+ const handleChange = useCallback26(
6825
6871
  (value) => {
6826
6872
  if (readOnly) return;
6827
6873
  comboboxState.setFilter(value);
@@ -6836,7 +6882,7 @@ var Combobox = memoGeneric(
6836
6882
  },
6837
6883
  [readOnly, props, comboboxState]
6838
6884
  );
6839
- const handleKeyDown = useCallback25(
6885
+ const handleKeyDown = useCallback26(
6840
6886
  (event) => {
6841
6887
  let handled = false;
6842
6888
  const item = comboboxState.getSelectedItem();
@@ -6944,7 +6990,7 @@ var Combobox = memoGeneric(
6944
6990
  ref.current?.setSelectionRange(0, ref.current.value.length);
6945
6991
  }
6946
6992
  }));
6947
- const handleChevronClick = useCallback25(
6993
+ const handleChevronClick = useCallback26(
6948
6994
  (event) => {
6949
6995
  event.stopPropagation();
6950
6996
  if (shouldShowMenu) {
@@ -6964,7 +7010,7 @@ var Combobox = memoGeneric(
6964
7010
  comboboxState
6965
7011
  ]
6966
7012
  );
6967
- useEffect19(() => {
7013
+ useEffect20(() => {
6968
7014
  if (!shouldBlur) return;
6969
7015
  if (document.activeElement !== ref.current) return;
6970
7016
  setShouldBlur(false);
@@ -7087,12 +7133,12 @@ import React59, { memo as memo21 } from "react";
7087
7133
  import { getCurrentPlatform as getCurrentPlatform2, handleKeyboardEvent } from "@noya-app/noya-keymap";
7088
7134
  import React58, {
7089
7135
  forwardRef as forwardRef21,
7090
- useCallback as useCallback26,
7091
- useEffect as useEffect20,
7136
+ useCallback as useCallback27,
7137
+ useEffect as useEffect21,
7092
7138
  useImperativeHandle as useImperativeHandle7,
7093
7139
  useMemo as useMemo24,
7094
7140
  useRef as useRef22,
7095
- useState as useState25
7141
+ useState as useState26
7096
7142
  } from "react";
7097
7143
 
7098
7144
  // src/components/Divider.tsx
@@ -7156,14 +7202,14 @@ var SearchCompletionMenu = forwardRef21(function SearchCompletionMenu2({
7156
7202
  testSelectedIndex,
7157
7203
  testSearch
7158
7204
  }, forwardedRef) {
7159
- const [state, setState] = useState25({
7205
+ const [state, setState] = useState26({
7160
7206
  search: testSearch ?? "",
7161
7207
  index: 0
7162
7208
  });
7163
7209
  const { index, search } = state;
7164
7210
  const listRef = React58.useRef(null);
7165
7211
  const hasCheckedItems = items.some((item) => item.checked);
7166
- useEffect20(() => {
7212
+ useEffect21(() => {
7167
7213
  listRef.current?.scrollToIndex(index);
7168
7214
  }, [index]);
7169
7215
  const results = useMemo24(
@@ -7178,13 +7224,13 @@ var SearchCompletionMenu = forwardRef21(function SearchCompletionMenu2({
7178
7224
  })),
7179
7225
  [items, search]
7180
7226
  );
7181
- const setSearch = useCallback26((search2) => {
7227
+ const setSearch = useCallback27((search2) => {
7182
7228
  setState((state2) => ({ ...state2, search: search2, index: 0 }));
7183
7229
  }, []);
7184
- const setIndex = useCallback26((index2) => {
7230
+ const setIndex = useCallback27((index2) => {
7185
7231
  setState((state2) => ({ ...state2, index: index2 }));
7186
7232
  }, []);
7187
- useEffect20(() => {
7233
+ useEffect21(() => {
7188
7234
  onHover?.(results[index]);
7189
7235
  }, [index, onHover, results]);
7190
7236
  const searchHeight = 31;
@@ -7199,14 +7245,14 @@ var SearchCompletionMenu = forwardRef21(function SearchCompletionMenu2({
7199
7245
  width: listSize.width,
7200
7246
  height: searchHeight + listSize.height
7201
7247
  };
7202
- const selectAndClose = useCallback26(
7248
+ const selectAndClose = useCallback27(
7203
7249
  (item) => {
7204
7250
  onSelect(item);
7205
7251
  onClose();
7206
7252
  },
7207
7253
  [onSelect, onClose]
7208
7254
  );
7209
- const handleKeyDown = useCallback26(
7255
+ const handleKeyDown = useCallback27(
7210
7256
  (event) => {
7211
7257
  handleKeyboardEvent(event.nativeEvent, getCurrentPlatform2(navigator), {
7212
7258
  ArrowUp: () => {
@@ -7365,18 +7411,25 @@ var ConnectedUsersMenuLayout = ({
7365
7411
 
7366
7412
  // src/components/DraggableMenuButton.tsx
7367
7413
  import { DragHandleDots2Icon } from "@noya-app/noya-icons";
7368
- import React61, { useCallback as useCallback27, useState as useState26 } from "react";
7414
+ import React61, { useCallback as useCallback28, useState as useState27 } from "react";
7369
7415
  var DraggableMenuButton = memoGeneric(function DraggableMenuButton2({
7416
+ open: openProp,
7417
+ onOpenChange: onOpenChangeProp,
7370
7418
  items,
7371
7419
  onSelect,
7372
7420
  onClick,
7373
7421
  isVisible = true,
7374
7422
  className,
7375
- style: style2
7423
+ style: style2,
7424
+ ...rest
7376
7425
  }) {
7377
- const [open, setOpen] = useState26(false);
7378
- const [downPosition, setDownPosition] = useState26(null);
7379
- const handlePointerDownCapture = useCallback27(
7426
+ const [open, setOpen] = useControlledOrUncontrolled({
7427
+ value: openProp,
7428
+ onChange: onOpenChangeProp,
7429
+ defaultValue: false
7430
+ });
7431
+ const [downPosition, setDownPosition] = useState27(null);
7432
+ const handlePointerDownCapture = useCallback28(
7380
7433
  (event) => {
7381
7434
  if (open) {
7382
7435
  setDownPosition(null);
@@ -7389,7 +7442,7 @@ var DraggableMenuButton = memoGeneric(function DraggableMenuButton2({
7389
7442
  },
7390
7443
  [open]
7391
7444
  );
7392
- const handlePointerUp = useCallback27(
7445
+ const handlePointerUp = useCallback28(
7393
7446
  (event) => {
7394
7447
  if (open || !downPosition) {
7395
7448
  setDownPosition(null);
@@ -7403,9 +7456,9 @@ var DraggableMenuButton = memoGeneric(function DraggableMenuButton2({
7403
7456
  }
7404
7457
  setDownPosition(null);
7405
7458
  },
7406
- [downPosition, open]
7459
+ [downPosition, open, setOpen]
7407
7460
  );
7408
- const handleOpenChange = useCallback27(
7461
+ const handleOpenChange = useCallback28(
7409
7462
  (isOpen) => {
7410
7463
  if (!isOpen) setOpen(false);
7411
7464
  },
@@ -7414,6 +7467,7 @@ var DraggableMenuButton = memoGeneric(function DraggableMenuButton2({
7414
7467
  return /* @__PURE__ */ React61.createElement(
7415
7468
  "div",
7416
7469
  {
7470
+ ...rest,
7417
7471
  className: cx(
7418
7472
  "cursor-pointer rounded flex items-center justify-center py-[2px] hover:bg-input-background-light active:bg-active-background ",
7419
7473
  className
@@ -7573,15 +7627,18 @@ var FileExplorerLayout = ({
7573
7627
  var FileExplorerUploadButton = ({
7574
7628
  showUploadButton,
7575
7629
  onUpload,
7630
+ isUploading,
7576
7631
  children
7577
7632
  }) => /* @__PURE__ */ React64.createElement("div", { className: "flex items-center gap-2" }, showUploadButton && /* @__PURE__ */ React64.createElement(
7578
- IconButton,
7633
+ Button,
7579
7634
  {
7580
- iconName: "UploadIcon",
7635
+ icon: isUploading ? /* @__PURE__ */ React64.createElement(ActivityIndicator, { size: 15 }) : "UploadIcon",
7581
7636
  onClick: onUpload,
7582
- "aria-label": "Upload media",
7583
- tooltip: "Upload media"
7584
- }
7637
+ "aria-label": "Upload file",
7638
+ tooltip: "Upload file",
7639
+ disabled: isUploading
7640
+ },
7641
+ "Upload"
7585
7642
  ), children);
7586
7643
  var FileExplorerCollection = forwardRefGeneric(
7587
7644
  function FileExplorerCollection2({ ...props }, ref) {
@@ -8127,7 +8184,7 @@ var FillInputField = memo25(
8127
8184
  );
8128
8185
 
8129
8186
  // src/components/FloatingWindow.tsx
8130
- import React68, { useCallback as useCallback28, useRef as useRef23, useState as useState27 } from "react";
8187
+ import React68, { useCallback as useCallback29, useRef as useRef23, useState as useState28 } from "react";
8131
8188
  var styles2 = {
8132
8189
  noSelect: {
8133
8190
  userSelect: "none",
@@ -8247,15 +8304,15 @@ var FloatingWindow = ({
8247
8304
  toolbarContent,
8248
8305
  renderToolbar = defaultRenderToolbar
8249
8306
  }) => {
8250
- const [position, setPosition] = useState27({ x: initialX, y: initialY });
8251
- const [size2, setSize] = useState27({
8307
+ const [position, setPosition] = useState28({ x: initialX, y: initialY });
8308
+ const [size2, setSize] = useState28({
8252
8309
  width: initialWidth,
8253
8310
  height: initialHeight
8254
8311
  });
8255
- const [isDragging, setIsDragging] = useState27(false);
8256
- const [isResizing, setIsResizing] = useState27(false);
8257
- const [dragOffset, setDragOffset] = useState27({ x: 0, y: 0 });
8258
- const [resizeDirection, setResizeDirection] = useState27(null);
8312
+ const [isDragging, setIsDragging] = useState28(false);
8313
+ const [isResizing, setIsResizing] = useState28(false);
8314
+ const [dragOffset, setDragOffset] = useState28({ x: 0, y: 0 });
8315
+ const [resizeDirection, setResizeDirection] = useState28(null);
8259
8316
  const wrapperRef = useRef23(null);
8260
8317
  const toggleGlobalTextSelection = (disable) => {
8261
8318
  if (disable) {
@@ -8264,7 +8321,7 @@ var FloatingWindow = ({
8264
8321
  document.body.style.userSelect = "";
8265
8322
  }
8266
8323
  };
8267
- const handleMouseDown = useCallback28((e) => {
8324
+ const handleMouseDown = useCallback29((e) => {
8268
8325
  if (!wrapperRef.current) return;
8269
8326
  const rect = wrapperRef.current.getBoundingClientRect();
8270
8327
  setDragOffset({
@@ -8273,7 +8330,7 @@ var FloatingWindow = ({
8273
8330
  });
8274
8331
  setIsDragging(true);
8275
8332
  }, []);
8276
- const handleResizeStart = useCallback28(
8333
+ const handleResizeStart = useCallback29(
8277
8334
  (direction) => (e) => {
8278
8335
  e.stopPropagation();
8279
8336
  setIsResizing(true);
@@ -8282,7 +8339,7 @@ var FloatingWindow = ({
8282
8339
  },
8283
8340
  []
8284
8341
  );
8285
- const handleMouseMove = useCallback28(
8342
+ const handleMouseMove = useCallback29(
8286
8343
  (e) => {
8287
8344
  if (isDragging) {
8288
8345
  setPosition({
@@ -8336,7 +8393,7 @@ var FloatingWindow = ({
8336
8393
  minHeight
8337
8394
  ]
8338
8395
  );
8339
- const handleMouseUp = useCallback28((_e) => {
8396
+ const handleMouseUp = useCallback29((_e) => {
8340
8397
  setIsDragging(false);
8341
8398
  setIsResizing(false);
8342
8399
  setResizeDirection(null);
@@ -8352,7 +8409,7 @@ var FloatingWindow = ({
8352
8409
  }, [handleMouseMove, handleMouseUp]);
8353
8410
  const floatingWindowManager = useFloatingWindowManager();
8354
8411
  const currentFloatingWindow = useCurrentFloatingWindowInternal();
8355
- const handleClose = useCallback28(() => {
8412
+ const handleClose = useCallback29(() => {
8356
8413
  if (onClose) onClose();
8357
8414
  floatingWindowManager.closeWindow(currentFloatingWindow.id);
8358
8415
  }, [currentFloatingWindow.id, floatingWindowManager, onClose]);
@@ -8612,18 +8669,18 @@ var useIndent = () => {
8612
8669
  };
8613
8670
 
8614
8671
  // src/components/LabeledField.tsx
8615
- var labeledFieldStyles = (labelPosition) => cx(
8672
+ var labeledFieldStyles = (labelType) => cx(
8616
8673
  "flex flex-row flex-1 flex-wrap items-center gap-x-1.5",
8617
- labelPosition === "end" && "flex-row-reverse justify-end",
8618
- labelPosition === "above" && "flex-col items-stretch justify-start"
8674
+ labelType === "end" && "flex-row-reverse justify-end",
8675
+ labelType === "above" && "flex-col items-stretch justify-start"
8619
8676
  );
8620
- var labelPositionInset = {
8621
- position: "inset"
8677
+ var labelTypeInset = {
8678
+ type: "inset"
8622
8679
  };
8623
8680
  var LabeledField = memo29(function LabeledField2({
8624
8681
  children,
8625
8682
  label,
8626
- labelPosition: labelPositionProp,
8683
+ labelType: labelTypeProp,
8627
8684
  fieldId,
8628
8685
  minWidth = 100,
8629
8686
  className,
@@ -8634,11 +8691,11 @@ var LabeledField = memo29(function LabeledField2({
8634
8691
  const indentLevel = useIndent();
8635
8692
  const labelWidthFromContext = useLabelWidth();
8636
8693
  const labelWidth = labelWidthFromContext ?? minWidth;
8637
- const labelPositionFromContext = useLabelPosition();
8638
- const labelPosition = labelPositionProp ?? labelPositionFromContext ?? "start";
8694
+ const labelTypeFromContext = useLabelType();
8695
+ const labelType = labelTypeProp ?? labelTypeFromContext;
8639
8696
  const labeledFieldClasses = useMemo30(
8640
- () => labeledFieldStyles(labelPosition),
8641
- [labelPosition]
8697
+ () => labeledFieldStyles(labelType),
8698
+ [labelType]
8642
8699
  );
8643
8700
  const labelContextValue = useMemo30(
8644
8701
  () => ({ fieldId, label }),
@@ -8666,16 +8723,16 @@ var LabeledField = memo29(function LabeledField2({
8666
8723
  }),
8667
8724
  [labelWidth, indentLevel, labelStyleProp]
8668
8725
  );
8669
- return /* @__PURE__ */ React73.createElement(LabelContext.Provider, { value: labelContextValue }, labelPosition === "inset" ? /* @__PURE__ */ React73.createElement(LabelPositionContext.Provider, { value: labelPositionInset }, children) : /* @__PURE__ */ React73.createElement("div", { className: cx("flex relative flex-1", className), style: style2 }, Boolean(indentLevel) && /* @__PURE__ */ React73.createElement("div", { style: indentStyle }), /* @__PURE__ */ React73.createElement("div", { className: labeledFieldClasses }, /* @__PURE__ */ React73.createElement(
8726
+ return /* @__PURE__ */ React73.createElement(LabelContext.Provider, { value: labelContextValue }, labelType === "inset" ? /* @__PURE__ */ React73.createElement(LabelTypeContext.Provider, { value: labelTypeInset }, children) : /* @__PURE__ */ React73.createElement("div", { className: cx("flex relative flex-1", className), style: style2 }, Boolean(indentLevel) && /* @__PURE__ */ React73.createElement("div", { style: indentStyle }), /* @__PURE__ */ React73.createElement("div", { className: labeledFieldClasses }, labelType !== "none" && /* @__PURE__ */ React73.createElement(
8670
8727
  Label,
8671
8728
  {
8672
8729
  htmlFor: fieldId,
8673
- className: labelPosition === "start" || labelPosition === "end" ? "self-start" : void 0,
8730
+ className: labelType === "start" || labelType === "end" ? "self-start" : void 0,
8674
8731
  style: labelStyle,
8675
8732
  ...props
8676
8733
  },
8677
8734
  label
8678
- ), labelPosition === "start" ? /* @__PURE__ */ React73.createElement("div", { className: "flex-auto flex", style: fieldStyle }, children) : children)));
8735
+ ), labelType === "start" ? /* @__PURE__ */ React73.createElement("div", { className: "flex-auto flex", style: fieldStyle }, children) : children)));
8679
8736
  });
8680
8737
 
8681
8738
  // src/components/MediaThumbnail.tsx
@@ -11427,7 +11484,7 @@ import * as ToggleGroupPrimitive2 from "@radix-ui/react-toggle-group";
11427
11484
  import React79, {
11428
11485
  createContext as createContext13,
11429
11486
  forwardRef as forwardRef26,
11430
- useCallback as useCallback30,
11487
+ useCallback as useCallback31,
11431
11488
  useContext as useContext14,
11432
11489
  useMemo as useMemo35
11433
11490
  } from "react";
@@ -11470,7 +11527,7 @@ var SegmentedControlItem = forwardRef26(function SegmentedControlItem2({
11470
11527
  {
11471
11528
  className: cx(
11472
11529
  "inline-flex whitespace-pre flex-nowrap gap-1.5 items-center justify-center align-middle text-center",
11473
- variant === "tabs" && "group-focus:ring-2 group-focus:ring-primary-pastel group-focus:ring-offset-2"
11530
+ variant === "tabs" && "group-focus-visible:ring-2 group-focus-visible:ring-primary-pastel group-focus-visible:ring-offset-2"
11474
11531
  )
11475
11532
  },
11476
11533
  icon && renderIcon(icon),
@@ -11492,7 +11549,7 @@ var SegmentedControl = memoGeneric(function SegmentedControl2({
11492
11549
  }) {
11493
11550
  const contextValue = useMemo35(() => ({ colorScheme }), [colorScheme]);
11494
11551
  const { fieldId: id } = useLabel({ fieldId: idProp });
11495
- const handleValueChange = useCallback30(
11552
+ const handleValueChange = useCallback31(
11496
11553
  (value2) => {
11497
11554
  if (!allowEmpty && !value2) return;
11498
11555
  onValueChange?.(value2);
@@ -11542,7 +11599,13 @@ var SelectionToolbarContainer = memo33(
11542
11599
  function SelectionToolbarContainer2({
11543
11600
  rect,
11544
11601
  children,
11545
- portalContainer
11602
+ portalContainer,
11603
+ side = "top",
11604
+ sideOffset = 10,
11605
+ align = "center",
11606
+ containerClassName,
11607
+ containerStyle,
11608
+ transitionDuration = 0.2
11546
11609
  }) {
11547
11610
  const portalScopeId = usePortalScopeId();
11548
11611
  const containerRef = React80.useRef(null);
@@ -11557,16 +11620,16 @@ var SelectionToolbarContainer = memo33(
11557
11620
  PopperPrimitive.Content,
11558
11621
  {
11559
11622
  ...portalScopeProps(portalScopeId),
11560
- side: "top",
11561
- sideOffset: 10,
11562
- align: "center",
11623
+ side,
11624
+ sideOffset,
11625
+ align,
11563
11626
  avoidCollisions: true,
11564
11627
  collisionPadding: 10,
11565
11628
  contentEditable: false,
11566
11629
  style: {
11567
11630
  zIndex: 1e3,
11568
11631
  opacity: size2 ? 1 : 0,
11569
- transition: "opacity 0.2s ease-in-out",
11632
+ transition: `opacity ${transitionDuration}s ease-in-out`,
11570
11633
  [cssVarNames.colors.inputBackground]: "transparent",
11571
11634
  [cssVarNames.colors.buttonBackground]: "transparent"
11572
11635
  }
@@ -11575,7 +11638,11 @@ var SelectionToolbarContainer = memo33(
11575
11638
  "div",
11576
11639
  {
11577
11640
  ref: containerRef,
11578
- className: "flex gap-1 bg-popover-background rounded shadow-popover p-1",
11641
+ className: cx(
11642
+ "flex gap-1 bg-popover-background rounded shadow-popover p-1",
11643
+ containerClassName
11644
+ ),
11645
+ style: containerStyle,
11579
11646
  onClick: (e) => e.stopPropagation(),
11580
11647
  onMouseDown: (e) => e.stopPropagation(),
11581
11648
  onPointerDown: (e) => e.stopPropagation(),
@@ -11597,7 +11664,7 @@ import {
11597
11664
  import * as Select from "@radix-ui/react-select";
11598
11665
  import React81, {
11599
11666
  useMemo as useMemo37,
11600
- useState as useState28
11667
+ useState as useState29
11601
11668
  } from "react";
11602
11669
  var readOnlyStyle = {
11603
11670
  justifyContent: "flex-start",
@@ -11628,7 +11695,7 @@ var SelectMenuTrigger = memoGeneric(function SelectMenuTrigger2({
11628
11695
  label: props.label,
11629
11696
  fieldId: props.id
11630
11697
  });
11631
- const labelPosition = useLabelPosition();
11698
+ const labelType = useLabelType();
11632
11699
  return /* @__PURE__ */ React81.createElement(Select.SelectTrigger, { asChild: true, onFocus, onBlur }, /* @__PURE__ */ React81.createElement(
11633
11700
  Button,
11634
11701
  {
@@ -11642,7 +11709,7 @@ var SelectMenuTrigger = memoGeneric(function SelectMenuTrigger2({
11642
11709
  disabled
11643
11710
  },
11644
11711
  icon && /* @__PURE__ */ React81.createElement("span", { className: "pr-1.5" }, renderIcon(icon)),
11645
- label && labelPosition === "inset" && /* @__PURE__ */ React81.createElement("div", { className: insetEndStyles }, /* @__PURE__ */ React81.createElement(Label, { className: "pr-4 text-text-disabled", htmlFor: id }, label)),
11712
+ label && labelType === "inset" && /* @__PURE__ */ React81.createElement("div", { className: insetEndStyles }, /* @__PURE__ */ React81.createElement(Label, { className: "pr-4 text-text-disabled", htmlFor: id }, label)),
11646
11713
  /* @__PURE__ */ React81.createElement("span", { className: "flex-1 flex" }, /* @__PURE__ */ React81.createElement(Select.Value, { placeholder })),
11647
11714
  /* @__PURE__ */ React81.createElement(
11648
11715
  DropdownChevronIcon3,
@@ -11681,7 +11748,7 @@ var SelectMenu = memoGeneric(function SelectMenu2({
11681
11748
  (item) => isSelectableMenuItem(item) && item.value === value
11682
11749
  );
11683
11750
  const icon = selectedItem?.icon;
11684
- const [internalOpen, setInternalOpen] = useState28(open);
11751
+ const [internalOpen, setInternalOpen] = useState29(open);
11685
11752
  const { label, fieldId: id } = useLabel({
11686
11753
  label: props.label,
11687
11754
  fieldId: props.id
@@ -11764,7 +11831,7 @@ var SelectMenu = memoGeneric(function SelectMenu2({
11764
11831
 
11765
11832
  // src/components/Slider.tsx
11766
11833
  import * as RadixSlider from "@radix-ui/react-slider";
11767
- import React82, { memo as memo34, useCallback as useCallback31, useMemo as useMemo38 } from "react";
11834
+ import React82, { memo as memo34, useCallback as useCallback32, useMemo as useMemo38 } from "react";
11768
11835
  var THUMB_WIDTH = 8;
11769
11836
  var thumbStyle = {
11770
11837
  width: THUMB_WIDTH
@@ -11790,7 +11857,7 @@ var Slider = memo34(function Slider2({
11790
11857
  const { fieldId: id } = useLabel({
11791
11858
  fieldId: props.id
11792
11859
  });
11793
- const handleValueChange = useCallback31(
11860
+ const handleValueChange = useCallback32(
11794
11861
  (arrayValue2) => {
11795
11862
  onValueChange(arrayValue2[0]);
11796
11863
  },
@@ -11818,7 +11885,7 @@ var Slider = memo34(function Slider2({
11818
11885
  /* @__PURE__ */ React82.createElement("div", { className: "relative flex-grow h-[3px] overflow-hidden" }, /* @__PURE__ */ React82.createElement(
11819
11886
  "div",
11820
11887
  {
11821
- className: "absolute h-full rounded-l bg-primary",
11888
+ className: "absolute h-full rounded-l bg-slider-active-background",
11822
11889
  style: {
11823
11890
  left: 0,
11824
11891
  width: `calc(${ratio * 100}% - ${ratio * 8}px - 2px)`
@@ -11907,8 +11974,35 @@ var Switch = function Switch2({
11907
11974
  );
11908
11975
  };
11909
11976
 
11977
+ // src/components/Tabs.tsx
11978
+ import * as React85 from "react";
11979
+ function Tabs({
11980
+ value,
11981
+ onValueChange,
11982
+ items,
11983
+ renderContent,
11984
+ ...props
11985
+ }) {
11986
+ const selectableItems = items.filter(isSelectableMenuItem);
11987
+ const [activeTab, setActiveTab] = useControlledOrUncontrolled({
11988
+ defaultValue: selectableItems.at(0)?.value ?? "",
11989
+ value,
11990
+ onChange: onValueChange
11991
+ });
11992
+ return /* @__PURE__ */ React85.createElement("div", { ...props, className: cx("flex flex-col", props.className) }, /* @__PURE__ */ React85.createElement("div", { className: "flex flex-row px-3" }, /* @__PURE__ */ React85.createElement(
11993
+ SegmentedControl,
11994
+ {
11995
+ className: "flex-1",
11996
+ value: activeTab,
11997
+ onValueChange: setActiveTab,
11998
+ variant: "tabs",
11999
+ items: selectableItems
12000
+ }
12001
+ )), /* @__PURE__ */ React85.createElement(Divider, null), renderContent({ value: activeTab }));
12002
+ }
12003
+
11910
12004
  // src/components/UserPointer.tsx
11911
- import React85, { memo as memo35, useMemo as useMemo39 } from "react";
12005
+ import React86, { memo as memo35, useMemo as useMemo39 } from "react";
11912
12006
  var UserPointerContainer = memo35(function UserPointerContainer2({
11913
12007
  point,
11914
12008
  visible,
@@ -11916,7 +12010,7 @@ var UserPointerContainer = memo35(function UserPointerContainer2({
11916
12010
  className,
11917
12011
  style: style2
11918
12012
  }) {
11919
- return /* @__PURE__ */ React85.createElement(
12013
+ return /* @__PURE__ */ React86.createElement(
11920
12014
  "div",
11921
12015
  {
11922
12016
  style: {
@@ -11939,7 +12033,7 @@ var UserNameTag = memo35(function UserNameTag2({
11939
12033
  style: style2,
11940
12034
  children
11941
12035
  }) {
11942
- return /* @__PURE__ */ React85.createElement(
12036
+ return /* @__PURE__ */ React86.createElement(
11943
12037
  "span",
11944
12038
  {
11945
12039
  className: cx(
@@ -11962,7 +12056,7 @@ var UserPointerIcon = memo35(function PointerIcon({
11962
12056
  style: style2
11963
12057
  }) {
11964
12058
  const points = "0,5 10,0 10,10";
11965
- return /* @__PURE__ */ React85.createElement(
12059
+ return /* @__PURE__ */ React86.createElement(
11966
12060
  "svg",
11967
12061
  {
11968
12062
  width: size2,
@@ -11977,7 +12071,7 @@ var UserPointerIcon = memo35(function PointerIcon({
11977
12071
  ...style2
11978
12072
  }
11979
12073
  },
11980
- /* @__PURE__ */ React85.createElement(
12074
+ /* @__PURE__ */ React86.createElement(
11981
12075
  "polygon",
11982
12076
  {
11983
12077
  points,
@@ -12014,7 +12108,7 @@ var UserPointer = memo35(function UserPointer2({
12014
12108
  () => ({ marginLeft: `${POINTER_SIZE - POINTER_OVERLAP + 1}px` }),
12015
12109
  []
12016
12110
  );
12017
- return /* @__PURE__ */ React85.createElement(
12111
+ return /* @__PURE__ */ React86.createElement(
12018
12112
  UserPointerContainer,
12019
12113
  {
12020
12114
  point,
@@ -12022,14 +12116,14 @@ var UserPointer = memo35(function UserPointer2({
12022
12116
  className,
12023
12117
  style: style2
12024
12118
  },
12025
- name && /* @__PURE__ */ React85.createElement("div", { className: "relative" }, /* @__PURE__ */ React85.createElement(
12119
+ name && /* @__PURE__ */ React86.createElement("div", { className: "relative" }, /* @__PURE__ */ React86.createElement(
12026
12120
  UserPointerIcon,
12027
12121
  {
12028
12122
  size: POINTER_SIZE,
12029
12123
  color: userBackgroundColor,
12030
12124
  style: pointerOverlapStyle
12031
12125
  }
12032
- ), /* @__PURE__ */ React85.createElement(
12126
+ ), /* @__PURE__ */ React86.createElement(
12033
12127
  UserNameTag,
12034
12128
  {
12035
12129
  backgroundColor: userBackgroundColor,
@@ -12041,38 +12135,17 @@ var UserPointer = memo35(function UserPointer2({
12041
12135
  });
12042
12136
 
12043
12137
  // src/components/workspace/WorkspaceLayout.tsx
12044
- import { useKeyboardShortcuts as useKeyboardShortcuts3 } from "@noya-app/noya-keymap";
12045
- import React89, {
12046
- forwardRef as forwardRef27,
12047
- memo as memo38,
12048
- useCallback as useCallback32,
12138
+ import { useKeyboardShortcuts as useKeyboardShortcuts4 } from "@noya-app/noya-keymap";
12139
+ import React92, {
12140
+ memo as memo36,
12141
+ useCallback as useCallback33,
12049
12142
  useImperativeHandle as useImperativeHandle9,
12050
12143
  useRef as useRef28,
12051
12144
  useState as useState31
12052
12145
  } from "react";
12053
12146
 
12054
- // src/hooks/useWindowSize.tsx
12055
- import { useEffect as useEffect21, useState as useState29 } from "react";
12056
- function useWindowSize() {
12057
- const [size2, setSize] = useState29(
12058
- typeof window === "undefined" ? { width: 0, height: 0 } : {
12059
- width: window.innerWidth,
12060
- height: window.innerHeight
12061
- }
12062
- );
12063
- useEffect21(() => {
12064
- const handleResize = () => setSize({
12065
- width: window.innerWidth,
12066
- height: window.innerHeight
12067
- });
12068
- window.addEventListener("resize", handleResize);
12069
- return () => window.removeEventListener("resize", handleResize);
12070
- }, []);
12071
- return size2;
12072
- }
12073
-
12074
12147
  // src/components/workspace/DrawerWorkspaceLayout.tsx
12075
- import React87, { memo as memo36, useLayoutEffect as useLayoutEffect9, useRef as useRef26, useState as useState30 } from "react";
12148
+ import React88, { useLayoutEffect as useLayoutEffect9, useRef as useRef26, useState as useState30 } from "react";
12076
12149
 
12077
12150
  // src/hooks/usePreservePanelSize.tsx
12078
12151
  import { useLayoutEffect as useLayoutEffect8, useRef as useRef25 } from "react";
@@ -12212,7 +12285,7 @@ function usePreservePanelSize(panelGroupRef, setPanelLayoutState) {
12212
12285
  }
12213
12286
 
12214
12287
  // src/components/workspace/DrawerWorkspaceLayout.tsx
12215
- var DrawerWorkspaceLayout = memo36(function DrawerWorkspaceLayout2({
12288
+ var DrawerWorkspaceLayout = memoGeneric(function DrawerWorkspaceLayout2({
12216
12289
  leftPanel,
12217
12290
  leftSidebarRef,
12218
12291
  rightPanel,
@@ -12233,14 +12306,14 @@ var DrawerWorkspaceLayout = memo36(function DrawerWorkspaceLayout2({
12233
12306
  }, [handleChangeLayoutState, mounted]);
12234
12307
  const leftSidebarCollapsed = internalLayoutState?.leftSidebarCollapsed ?? false;
12235
12308
  const rightSidebarCollapsed = internalLayoutState?.rightSidebarCollapsed ?? false;
12236
- return /* @__PURE__ */ React87.createElement(
12309
+ return /* @__PURE__ */ React88.createElement(
12237
12310
  "div",
12238
12311
  {
12239
12312
  ref: portalContainer,
12240
12313
  id: EDITOR_PANEL_GROUP_ID,
12241
12314
  className: "flex flex-1 relative focus:outline-none"
12242
12315
  },
12243
- leftPanel && /* @__PURE__ */ React87.createElement(
12316
+ leftPanel && /* @__PURE__ */ React88.createElement(
12244
12317
  Drawer,
12245
12318
  {
12246
12319
  id: LEFT_SIDEBAR_ID,
@@ -12261,7 +12334,7 @@ var DrawerWorkspaceLayout = memo36(function DrawerWorkspaceLayout2({
12261
12334
  leftPanel
12262
12335
  ),
12263
12336
  centerPanel,
12264
- rightPanel && /* @__PURE__ */ React87.createElement(
12337
+ rightPanel && /* @__PURE__ */ React88.createElement(
12265
12338
  Drawer,
12266
12339
  {
12267
12340
  id: RIGHT_SIDEBAR_ID,
@@ -12285,13 +12358,262 @@ var DrawerWorkspaceLayout = memo36(function DrawerWorkspaceLayout2({
12285
12358
  });
12286
12359
 
12287
12360
  // src/components/workspace/PanelWorkspaceLayout.tsx
12288
- import React88, { memo as memo37, useRef as useRef27 } from "react";
12361
+ import React91, { useRef as useRef27 } from "react";
12289
12362
  import {
12290
12363
  Panel,
12291
12364
  PanelGroup,
12292
12365
  PanelResizeHandle
12293
12366
  } from "react-resizable-panels";
12294
- var PanelWorkspaceLayout = memo37(function PanelWorkspaceLayout2({
12367
+
12368
+ // src/components/Toolbar.tsx
12369
+ import { useKeyboardShortcuts as useKeyboardShortcuts3 } from "@noya-app/noya-keymap";
12370
+ import React90 from "react";
12371
+
12372
+ // src/components/BaseToolbar.tsx
12373
+ import React89 from "react";
12374
+ var toolbarStyle = {
12375
+ [cssVarNames.colors.buttonBackground]: "transparent",
12376
+ [cssVarNames.colors.inputBackground]: "transparent"
12377
+ };
12378
+ function BaseToolbar({
12379
+ children,
12380
+ left,
12381
+ right,
12382
+ logo,
12383
+ showDivider = true
12384
+ }) {
12385
+ return /* @__PURE__ */ React89.createElement("div", { className: "flex flex-col", style: toolbarStyle }, /* @__PURE__ */ React89.createElement(
12386
+ "div",
12387
+ {
12388
+ className: "flex items-center pr-2.5 bg-sidebar-background flex-none relative @container/toolbar",
12389
+ style: {
12390
+ flex: `0 0 ${cssVars.spacing.toolbarHeight}`
12391
+ }
12392
+ },
12393
+ logo && /* @__PURE__ */ React89.createElement(React89.Fragment, null, logo, /* @__PURE__ */ React89.createElement(DividerVertical, null)),
12394
+ /* @__PURE__ */ React89.createElement(Spacer.Horizontal, { size: 10 }),
12395
+ left && /* @__PURE__ */ React89.createElement(React89.Fragment, null, /* @__PURE__ */ React89.createElement("div", { className: "flex gap-toolbar-separator" }, left), /* @__PURE__ */ React89.createElement(Spacer.Horizontal, { size: 10 })),
12396
+ /* @__PURE__ */ React89.createElement("div", { className: "flex items-center justify-center text-text-muted pointer-events-none @2xl/toolbar:absolute inset-0" }, /* @__PURE__ */ React89.createElement(
12397
+ "div",
12398
+ {
12399
+ style: {
12400
+ display: "flex",
12401
+ alignItems: "center",
12402
+ justifyContent: "center",
12403
+ pointerEvents: "all"
12404
+ }
12405
+ },
12406
+ children
12407
+ )),
12408
+ /* @__PURE__ */ React89.createElement(Spacer.Horizontal, null),
12409
+ /* @__PURE__ */ React89.createElement(Spacer.Horizontal, { size: 10 }),
12410
+ /* @__PURE__ */ React89.createElement("div", { className: "flex gap-toolbar-separator" }, right)
12411
+ ), showDivider && /* @__PURE__ */ React89.createElement(Divider, { variant: "strong" }));
12412
+ }
12413
+
12414
+ // src/components/Toolbar.tsx
12415
+ var SIDE_OFFSET = 6;
12416
+ var ToolbarMenuDropdown = memoGeneric(function ToolbarMenuDropdown2({
12417
+ item,
12418
+ onSelectMenuItem
12419
+ }) {
12420
+ const [open, setOpen] = React90.useState(false);
12421
+ return /* @__PURE__ */ React90.createElement(
12422
+ DropdownMenu,
12423
+ {
12424
+ open,
12425
+ onOpenChange: setOpen,
12426
+ items: item.items,
12427
+ onSelect: (value) => {
12428
+ if (onSelectMenuItem && value) {
12429
+ onSelectMenuItem(value);
12430
+ }
12431
+ }
12432
+ },
12433
+ /* @__PURE__ */ React90.createElement(
12434
+ Button,
12435
+ {
12436
+ disabled: item.disabled,
12437
+ active: item.checked || open,
12438
+ icon: item.icon,
12439
+ iconRight: "DropdownChevronIcon"
12440
+ },
12441
+ item.title
12442
+ )
12443
+ );
12444
+ });
12445
+ var ToolbarShortcut = ({
12446
+ shortcut,
12447
+ label
12448
+ }) => {
12449
+ return /* @__PURE__ */ React90.createElement("div", { className: "flex items-center" }, label, /* @__PURE__ */ React90.createElement(Spacer.Horizontal, { size: 6 }), /* @__PURE__ */ React90.createElement(KeyboardShortcut, { shortcut }));
12450
+ };
12451
+ var ToolbarMenuPopover = memoGeneric(function ToolbarMenuPopover2({
12452
+ item,
12453
+ portalContainer
12454
+ }) {
12455
+ const {
12456
+ disabled,
12457
+ icon,
12458
+ title,
12459
+ tooltip,
12460
+ content: itemContent,
12461
+ checked
12462
+ } = item;
12463
+ const [open, setOpen] = React90.useState(false);
12464
+ const content = /* @__PURE__ */ React90.createElement("span", null, /* @__PURE__ */ React90.createElement(
12465
+ Popover,
12466
+ {
12467
+ open,
12468
+ onOpenChange: setOpen,
12469
+ side: "top",
12470
+ showArrow: false,
12471
+ sideOffset: SIDE_OFFSET,
12472
+ portalContainer,
12473
+ trigger: /* @__PURE__ */ React90.createElement(
12474
+ Button,
12475
+ {
12476
+ disabled,
12477
+ active: checked || open,
12478
+ icon,
12479
+ iconRight: "DropdownChevronIcon"
12480
+ },
12481
+ title
12482
+ )
12483
+ },
12484
+ typeof itemContent === "function" ? itemContent({ close: () => setOpen(false) }) : itemContent
12485
+ ));
12486
+ return tooltip && !open ? /* @__PURE__ */ React90.createElement(
12487
+ Tooltip,
12488
+ {
12489
+ sideOffset: SIDE_OFFSET,
12490
+ side: "top",
12491
+ content: tooltip,
12492
+ portalContainer
12493
+ },
12494
+ content
12495
+ ) : content;
12496
+ });
12497
+ var ToolbarMenuButton = memoGeneric(function ToolbarMenuButton2({
12498
+ item,
12499
+ onSelectMenuItem,
12500
+ as,
12501
+ activeValue,
12502
+ tooltipSide
12503
+ }) {
12504
+ const content = /* @__PURE__ */ React90.createElement(
12505
+ Button,
12506
+ {
12507
+ as,
12508
+ disabled: item.disabled,
12509
+ active: item.checked || activeValue === item.value,
12510
+ icon: item.icon,
12511
+ ...as === "a" && { href: item.value },
12512
+ onClick: () => {
12513
+ if (onSelectMenuItem && item.value) {
12514
+ onSelectMenuItem(item.value);
12515
+ }
12516
+ }
12517
+ },
12518
+ item.title
12519
+ );
12520
+ return item.tooltip ? /* @__PURE__ */ React90.createElement(Tooltip, { sideOffset: SIDE_OFFSET, content: item.tooltip, side: tooltipSide }, content) : content;
12521
+ });
12522
+ var ToolbarMenuItem = memoGeneric(function ToolbarMenuItem2({
12523
+ item,
12524
+ onSelectMenuItem,
12525
+ buttonAs,
12526
+ activeValue,
12527
+ tooltipSide,
12528
+ portalContainer
12529
+ }) {
12530
+ if (item.type === "sectionHeader") return null;
12531
+ if (item.type === "separator") {
12532
+ return /* @__PURE__ */ React90.createElement(DividerVertical, { overflow: 4 });
12533
+ }
12534
+ if (item.type === "popover") {
12535
+ return /* @__PURE__ */ React90.createElement(ToolbarMenuPopover, { item, portalContainer });
12536
+ }
12537
+ if (isSelectableMenuItem(item)) {
12538
+ return /* @__PURE__ */ React90.createElement(
12539
+ ToolbarMenuButton,
12540
+ {
12541
+ item,
12542
+ onSelectMenuItem,
12543
+ as: buttonAs,
12544
+ activeValue,
12545
+ tooltipSide
12546
+ }
12547
+ );
12548
+ }
12549
+ return /* @__PURE__ */ React90.createElement(ToolbarMenuDropdown, { item, onSelectMenuItem });
12550
+ });
12551
+ var ToolbarMenu = memoGeneric(function ToolbarMenu2({
12552
+ items,
12553
+ onSelectMenuItem,
12554
+ buttonAs,
12555
+ activeValue,
12556
+ tooltipSide,
12557
+ portalContainer
12558
+ }) {
12559
+ return /* @__PURE__ */ React90.createElement(React90.Fragment, null, items.map((item, i) => {
12560
+ return /* @__PURE__ */ React90.createElement(
12561
+ ToolbarMenuItem,
12562
+ {
12563
+ key: i,
12564
+ item,
12565
+ onSelectMenuItem,
12566
+ buttonAs,
12567
+ activeValue,
12568
+ tooltipSide,
12569
+ portalContainer
12570
+ }
12571
+ );
12572
+ }));
12573
+ });
12574
+ function Toolbar({
12575
+ children,
12576
+ logo,
12577
+ leftMenuItems = [],
12578
+ rightMenuItems = [],
12579
+ onSelectMenuItem,
12580
+ shouldBindKeyboardShortcuts = true
12581
+ }) {
12582
+ const allMenuItems = React90.useMemo(
12583
+ () => [...leftMenuItems, ...rightMenuItems],
12584
+ [leftMenuItems, rightMenuItems]
12585
+ );
12586
+ useKeyboardShortcuts3(
12587
+ React90.useMemo(
12588
+ () => onSelectMenuItem && shouldBindKeyboardShortcuts ? getKeyboardShortcutsForMenuItems(allMenuItems, onSelectMenuItem) : {},
12589
+ [allMenuItems, onSelectMenuItem, shouldBindKeyboardShortcuts]
12590
+ )
12591
+ );
12592
+ return /* @__PURE__ */ React90.createElement(
12593
+ BaseToolbar,
12594
+ {
12595
+ logo,
12596
+ left: leftMenuItems.length > 0 && /* @__PURE__ */ React90.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ React90.createElement(
12597
+ ToolbarMenu,
12598
+ {
12599
+ items: leftMenuItems,
12600
+ onSelectMenuItem
12601
+ }
12602
+ )),
12603
+ right: rightMenuItems.length > 0 && /* @__PURE__ */ React90.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ React90.createElement(
12604
+ ToolbarMenu,
12605
+ {
12606
+ items: rightMenuItems,
12607
+ onSelectMenuItem
12608
+ }
12609
+ ))
12610
+ },
12611
+ children
12612
+ );
12613
+ }
12614
+
12615
+ // src/components/workspace/PanelWorkspaceLayout.tsx
12616
+ var PanelWorkspaceLayout = memoGeneric(function PanelWorkspaceLayout2({
12295
12617
  leftPanel,
12296
12618
  rightPanel,
12297
12619
  centerPanel,
@@ -12302,11 +12624,17 @@ var PanelWorkspaceLayout = memo37(function PanelWorkspaceLayout2({
12302
12624
  internalLayoutState,
12303
12625
  leftSidebarRef,
12304
12626
  rightSidebarRef,
12627
+ leftTabItems,
12628
+ rightTabItems,
12629
+ leftTabValue,
12630
+ rightTabValue,
12631
+ onChangeLeftTab,
12632
+ onChangeRightTab,
12305
12633
  handleChangeLayoutState
12306
12634
  }) {
12307
12635
  const panelGroupRef = useRef27(null);
12308
12636
  usePreservePanelSize(panelGroupRef, handleChangeLayoutState);
12309
- return /* @__PURE__ */ React88.createElement(
12637
+ return /* @__PURE__ */ React91.createElement(
12310
12638
  PanelGroup,
12311
12639
  {
12312
12640
  ref: panelGroupRef,
@@ -12315,7 +12643,29 @@ var PanelWorkspaceLayout = memo37(function PanelWorkspaceLayout2({
12315
12643
  direction: "horizontal",
12316
12644
  autoSaveId: autoSavePrefix ? `${autoSavePrefix}--${EDITOR_PANEL_GROUP_ID}` : void 0
12317
12645
  },
12318
- leftPanel && /* @__PURE__ */ React88.createElement(React88.Fragment, null, /* @__PURE__ */ React88.createElement(
12646
+ leftPanel && /* @__PURE__ */ React91.createElement(React91.Fragment, null, leftTabItems && /* @__PURE__ */ React91.createElement(
12647
+ VerticalTabMenu,
12648
+ {
12649
+ tooltipSide: "right",
12650
+ items: leftTabItems,
12651
+ activeValue: leftTabValue,
12652
+ isSidebarCollapsed: internalLayoutState?.leftSidebarCollapsed ?? false,
12653
+ onChange: (value) => {
12654
+ if (value === leftTabValue) {
12655
+ if (leftSidebarRef.current?.isExpanded()) {
12656
+ leftSidebarRef.current?.collapse();
12657
+ } else {
12658
+ leftSidebarRef.current?.expand();
12659
+ }
12660
+ } else {
12661
+ if (!leftSidebarRef.current?.isExpanded()) {
12662
+ leftSidebarRef.current?.expand();
12663
+ }
12664
+ onChangeLeftTab?.(value);
12665
+ }
12666
+ }
12667
+ }
12668
+ ), leftTabItems && !internalLayoutState?.leftSidebarCollapsed && /* @__PURE__ */ React91.createElement(DividerVertical, { className: "h-full" }), /* @__PURE__ */ React91.createElement(
12319
12669
  Panel,
12320
12670
  {
12321
12671
  id: LEFT_SIDEBAR_ID,
@@ -12328,8 +12678,8 @@ var PanelWorkspaceLayout = memo37(function PanelWorkspaceLayout2({
12328
12678
  collapsible: true
12329
12679
  },
12330
12680
  internalLayoutState?.leftSidebarCollapsed ? null : leftPanel
12331
- ), /* @__PURE__ */ React88.createElement(PanelResizeHandle, { className: "cursor-col-resize w-px h-full bg-divider" })),
12332
- /* @__PURE__ */ React88.createElement(
12681
+ ), /* @__PURE__ */ React91.createElement(PanelResizeHandle, { className: "cursor-col-resize w-px h-full bg-divider" })),
12682
+ /* @__PURE__ */ React91.createElement(
12333
12683
  Panel,
12334
12684
  {
12335
12685
  id: CONTENT_AREA_ID,
@@ -12340,7 +12690,7 @@ var PanelWorkspaceLayout = memo37(function PanelWorkspaceLayout2({
12340
12690
  },
12341
12691
  centerPanel
12342
12692
  ),
12343
- rightPanel && /* @__PURE__ */ React88.createElement(React88.Fragment, null, /* @__PURE__ */ React88.createElement(PanelResizeHandle, { className: "cursor-col-resize w-px h-full bg-divider" }), /* @__PURE__ */ React88.createElement(
12693
+ rightPanel && /* @__PURE__ */ React91.createElement(React91.Fragment, null, /* @__PURE__ */ React91.createElement(PanelResizeHandle, { className: "cursor-col-resize w-px h-full bg-divider" }), /* @__PURE__ */ React91.createElement(
12344
12694
  Panel,
12345
12695
  {
12346
12696
  id: RIGHT_SIDEBAR_ID,
@@ -12353,15 +12703,94 @@ var PanelWorkspaceLayout = memo37(function PanelWorkspaceLayout2({
12353
12703
  collapsible: true
12354
12704
  },
12355
12705
  internalLayoutState?.rightSidebarCollapsed ? null : rightPanel
12706
+ ), rightTabItems && !internalLayoutState?.rightSidebarCollapsed && /* @__PURE__ */ React91.createElement(DividerVertical, { className: "h-full" }), rightTabItems && /* @__PURE__ */ React91.createElement(
12707
+ VerticalTabMenu,
12708
+ {
12709
+ tooltipSide: "left",
12710
+ items: rightTabItems,
12711
+ activeValue: rightTabValue,
12712
+ isSidebarCollapsed: internalLayoutState?.rightSidebarCollapsed ?? false,
12713
+ onChange: (value) => {
12714
+ if (value === rightTabValue) {
12715
+ if (rightSidebarRef.current?.isExpanded()) {
12716
+ rightSidebarRef.current?.collapse();
12717
+ } else {
12718
+ rightSidebarRef.current?.expand();
12719
+ }
12720
+ } else {
12721
+ if (!rightSidebarRef.current?.isExpanded()) {
12722
+ rightSidebarRef.current?.expand();
12723
+ }
12724
+ onChangeRightTab?.(value);
12725
+ }
12726
+ }
12727
+ }
12356
12728
  ))
12357
12729
  );
12358
12730
  });
12731
+ function VerticalTabMenu({
12732
+ items,
12733
+ activeValue,
12734
+ isSidebarCollapsed,
12735
+ onChange,
12736
+ tooltipSide
12737
+ }) {
12738
+ return /* @__PURE__ */ React91.createElement(
12739
+ "div",
12740
+ {
12741
+ className: "w-[47px] h-full bg-sidebar-background flex flex-col items-center py-3 gap-3",
12742
+ style: {
12743
+ [cssVarNames.colors.inputBackground]: "transparent",
12744
+ [cssVarNames.colors.buttonBackground]: "transparent"
12745
+ }
12746
+ },
12747
+ /* @__PURE__ */ React91.createElement(
12748
+ ToolbarMenu,
12749
+ {
12750
+ items,
12751
+ activeValue: isSidebarCollapsed ? void 0 : activeValue,
12752
+ onSelectMenuItem: onChange,
12753
+ tooltipSide
12754
+ }
12755
+ )
12756
+ );
12757
+ }
12758
+
12759
+ // src/components/workspace/renderPanelChildren.tsx
12760
+ function renderPanelChildren(fn, activeTabValue) {
12761
+ if (typeof fn === "function") {
12762
+ return fn({ activeTabValue });
12763
+ }
12764
+ return fn;
12765
+ }
12359
12766
 
12360
12767
  // src/components/workspace/WorkspaceLayout.tsx
12361
- var WorkspaceLayout = forwardRef27(function WorkspaceLayout2({
12768
+ var defaultLeftTabItems = [
12769
+ {
12770
+ title: "",
12771
+ value: "default",
12772
+ icon: "BorderLeftIcon",
12773
+ tooltip: "Sidebar"
12774
+ }
12775
+ ];
12776
+ var defaultRightTabItems = [
12777
+ {
12778
+ title: "",
12779
+ value: "default",
12780
+ icon: "BorderRightIcon",
12781
+ tooltip: "Sidebar"
12782
+ }
12783
+ ];
12784
+ var WorkspaceLayout = forwardRefGeneric(function WorkspaceLayout2({
12362
12785
  autoSavePrefix,
12363
12786
  left,
12787
+ leftTabItems = defaultLeftTabItems,
12788
+ leftTabValue: leftTabValueProp,
12789
+ onChangeLeftTab,
12364
12790
  right,
12791
+ rightTabItems = defaultRightTabItems,
12792
+ rightTabValue: rightTabValueProp,
12793
+ onChangeRightTab,
12365
12794
  id,
12366
12795
  className,
12367
12796
  style: style2,
@@ -12377,7 +12806,8 @@ var WorkspaceLayout = forwardRef27(function WorkspaceLayout2({
12377
12806
  initialSize: leftInitialSize = 280,
12378
12807
  resizable: leftResizable = true,
12379
12808
  style: leftStyle,
12380
- className: leftClassName
12809
+ className: leftClassName,
12810
+ defaultCollapsed: leftDefaultCollapsed = false
12381
12811
  } = {},
12382
12812
  rightOptions: {
12383
12813
  minSize: rightMinSize = 200,
@@ -12385,11 +12815,12 @@ var WorkspaceLayout = forwardRef27(function WorkspaceLayout2({
12385
12815
  initialSize: rightInitialSize = 280,
12386
12816
  resizable: rightResizable = true,
12387
12817
  style: rightStyle,
12388
- className: rightClassName
12818
+ className: rightClassName,
12819
+ defaultCollapsed: rightDefaultCollapsed = false
12389
12820
  } = {},
12390
12821
  theme
12391
12822
  }, forwardedRef) {
12392
- const containerRef = React89.useRef(null);
12823
+ const containerRef = React92.useRef(null);
12393
12824
  const containerSize = useSize(containerRef);
12394
12825
  const windowSize = useWindowSize();
12395
12826
  const parentSize = detectSize === "window" ? windowSize : containerSize && containerSize.width > 0 ? containerSize : windowSize;
@@ -12422,8 +12853,21 @@ var WorkspaceLayout = forwardRef27(function WorkspaceLayout2({
12422
12853
  );
12423
12854
  const leftSidebarRef = useRef28(null);
12424
12855
  const rightSidebarRef = useRef28(null);
12425
- const [internalLayoutState, setInternalLayoutState] = useState31(null);
12426
- const handleChangeLayoutState = useCallback32(
12856
+ const [leftTabValue, setLeftTabValue] = useControlledOrUncontrolled({
12857
+ value: leftTabValueProp,
12858
+ onChange: onChangeLeftTab,
12859
+ defaultValue: getFirstTabValue(leftTabItems, "")
12860
+ });
12861
+ const [rightTabValue, setRightTabValue] = useControlledOrUncontrolled({
12862
+ value: rightTabValueProp,
12863
+ onChange: onChangeRightTab,
12864
+ defaultValue: getFirstTabValue(rightTabItems, "")
12865
+ });
12866
+ const [internalLayoutState, setInternalLayoutState] = useState31({
12867
+ leftSidebarCollapsed: leftDefaultCollapsed,
12868
+ rightSidebarCollapsed: rightDefaultCollapsed
12869
+ });
12870
+ const handleChangeLayoutState = useCallback33(
12427
12871
  (state) => {
12428
12872
  setInternalLayoutState(state);
12429
12873
  onChangeLayoutState?.(state);
@@ -12473,7 +12917,7 @@ var WorkspaceLayout = forwardRef27(function WorkspaceLayout2({
12473
12917
  }
12474
12918
  }
12475
12919
  }));
12476
- useKeyboardShortcuts3({
12920
+ useKeyboardShortcuts4({
12477
12921
  "Mod-.": () => {
12478
12922
  const isLeftSidebarExpanded = leftSidebarRef.current?.isExpanded();
12479
12923
  const isRightSidebarExpanded = rightSidebarRef.current?.isExpanded();
@@ -12487,23 +12931,23 @@ var WorkspaceLayout = forwardRef27(function WorkspaceLayout2({
12487
12931
  }
12488
12932
  });
12489
12933
  const centerPanelPercentage = 100 - (left ? leftSidebarPercentage : 0) - (right ? rightSidebarPercentage : 0);
12490
- const leftPanel = left ? /* @__PURE__ */ React89.createElement(
12934
+ const leftPanel = left ? /* @__PURE__ */ React92.createElement(
12491
12935
  PanelInner,
12492
12936
  {
12493
12937
  style: leftStyle,
12494
12938
  className: cx("bg-sidebar-background flex-col", leftClassName)
12495
12939
  },
12496
- left
12940
+ leftTabValue ? renderPanelChildren(left, leftTabValue) : null
12497
12941
  ) : null;
12498
- const rightPanel = right ? /* @__PURE__ */ React89.createElement(
12942
+ const rightPanel = right ? /* @__PURE__ */ React92.createElement(
12499
12943
  PanelInner,
12500
12944
  {
12501
12945
  style: rightStyle,
12502
12946
  className: cx("bg-sidebar-background flex-col", rightClassName)
12503
12947
  },
12504
- right
12948
+ rightTabValue ? renderPanelChildren(right, rightTabValue) : null
12505
12949
  ) : null;
12506
- const centerPanel = /* @__PURE__ */ React89.createElement(PanelInner, { className: "bg-canvas-background" }, children);
12950
+ const centerPanel = /* @__PURE__ */ React92.createElement(PanelInner, { className: "bg-canvas-background" }, children);
12507
12951
  const leftSidebarOptions = {
12508
12952
  minSize: leftSidebarMinPercentage,
12509
12953
  maxSize: leftSidebarMaxPercentage,
@@ -12518,7 +12962,7 @@ var WorkspaceLayout = forwardRef27(function WorkspaceLayout2({
12518
12962
  };
12519
12963
  const LayoutComponent = sideType === "panel" ? PanelWorkspaceLayout : sideType === "drawer" ? DrawerWorkspaceLayout : parentSize.width > sideTypeBreakpoint ? PanelWorkspaceLayout : DrawerWorkspaceLayout;
12520
12964
  const readyToRender = detectSize === "window" || containerSize && containerSize.width > 0;
12521
- return /* @__PURE__ */ React89.createElement(
12965
+ return /* @__PURE__ */ React92.createElement(
12522
12966
  "div",
12523
12967
  {
12524
12968
  ref: containerRef,
@@ -12528,12 +12972,18 @@ var WorkspaceLayout = forwardRef27(function WorkspaceLayout2({
12528
12972
  "data-theme": theme
12529
12973
  },
12530
12974
  toolbar,
12531
- /* @__PURE__ */ React89.createElement("div", { className: "flex flex-row flex-1 relative" }, readyToRender && /* @__PURE__ */ React89.createElement(
12975
+ /* @__PURE__ */ React92.createElement("div", { className: "flex flex-row flex-1 relative" }, readyToRender && /* @__PURE__ */ React92.createElement(
12532
12976
  LayoutComponent,
12533
12977
  {
12534
12978
  leftPanel,
12535
12979
  rightPanel,
12536
12980
  centerPanel,
12981
+ leftTabItems,
12982
+ leftTabValue,
12983
+ onChangeLeftTab: setLeftTabValue,
12984
+ rightTabItems,
12985
+ rightTabValue,
12986
+ onChangeRightTab: setRightTabValue,
12537
12987
  leftSidebarOptions,
12538
12988
  rightSidebarOptions,
12539
12989
  centerPanelPercentage,
@@ -12546,13 +12996,17 @@ var WorkspaceLayout = forwardRef27(function WorkspaceLayout2({
12546
12996
  ))
12547
12997
  );
12548
12998
  });
12549
- var PanelInner = memo38(function PanelInner2({
12999
+ var PanelInner = memo36(function PanelInner2({
12550
13000
  children,
12551
13001
  style: style2,
12552
13002
  className
12553
13003
  }) {
12554
- return /* @__PURE__ */ React89.createElement("div", { style: style2, className: cx("absolute inset-0 flex", className) }, children);
13004
+ return /* @__PURE__ */ React92.createElement("div", { style: style2, className: cx("absolute inset-0 flex", className) }, children);
12555
13005
  });
13006
+ function getFirstTabValue(items, defaultValue2) {
13007
+ const firstItem = items.at(0);
13008
+ return firstItem?.type === void 0 ? firstItem?.value ?? defaultValue2 : defaultValue2;
13009
+ }
12556
13010
 
12557
13011
  // src/hooks/usePlatform.ts
12558
13012
  function usePlatform() {
@@ -12628,6 +13082,12 @@ function createSectionedMenu(...sections) {
12628
13082
  }).flat();
12629
13083
  }
12630
13084
 
13085
+ // src/utils/editableBlockStyles.ts
13086
+ var editableBlockStyles = (viewType = "editable") => cx(
13087
+ "relative outline-primary focus:outline focus:outline-1",
13088
+ viewType !== "preview" && "hover:outline-2 [&:not(:has([data-editor-selectable-block]:hover))]:hover:outline"
13089
+ );
13090
+
12631
13091
  // src/utils/moveTreeItem.ts
12632
13092
  import { isDeepEqual as isDeepEqual4 } from "@noya-app/noya-utils";
12633
13093
  function moveTreeItem({
@@ -12706,11 +13166,11 @@ var SUPPORTED_CANVAS_UPLOAD_TYPES = [
12706
13166
 
12707
13167
  // src/components/DimensionInput.tsx
12708
13168
  import { round } from "@noya-app/noya-utils";
12709
- import * as React90 from "react";
13169
+ import * as React93 from "react";
12710
13170
  function getNewValue(value, mode, delta) {
12711
13171
  return delta === void 0 ? value : mode === "replace" ? delta : value + delta;
12712
13172
  }
12713
- var DimensionInput = React90.memo(function DimensionInput2({
13173
+ var DimensionInput = React93.memo(function DimensionInput2({
12714
13174
  id,
12715
13175
  value,
12716
13176
  onSetValue,
@@ -12720,15 +13180,15 @@ var DimensionInput = React90.memo(function DimensionInput2({
12720
13180
  disabled,
12721
13181
  trigger = "submit"
12722
13182
  }) {
12723
- const handleNudgeValue = React90.useCallback(
13183
+ const handleNudgeValue = React93.useCallback(
12724
13184
  (value2) => onSetValue(value2, "adjust"),
12725
13185
  [onSetValue]
12726
13186
  );
12727
- const handleSetValue = React90.useCallback(
13187
+ const handleSetValue = React93.useCallback(
12728
13188
  (value2) => onSetValue(value2, "replace"),
12729
13189
  [onSetValue]
12730
13190
  );
12731
- return /* @__PURE__ */ React90.createElement(LabeledField, { label, labelPosition: "inset" }, /* @__PURE__ */ React90.createElement(InputField2.Root, { id, width: size2 }, /* @__PURE__ */ React90.createElement(
13191
+ return /* @__PURE__ */ React93.createElement(LabeledField, { label, labelType: "inset" }, /* @__PURE__ */ React93.createElement(InputField2.Root, { id, width: size2 }, /* @__PURE__ */ React93.createElement(
12732
13192
  InputField2.NumberInput,
12733
13193
  {
12734
13194
  value: value === void 0 ? value : round(value, 2),
@@ -12755,11 +13215,11 @@ __export(InspectorPrimitives_exports, {
12755
13215
  Title: () => Title4,
12756
13216
  VerticalSeparator: () => VerticalSeparator
12757
13217
  });
12758
- import React91, {
12759
- forwardRef as forwardRef28,
12760
- memo as memo40
13218
+ import React94, {
13219
+ forwardRef as forwardRef27,
13220
+ memo as memo38
12761
13221
  } from "react";
12762
- var Section2 = forwardRef28(({ className, ...props }, ref) => /* @__PURE__ */ React91.createElement(
13222
+ var Section2 = forwardRef27(({ className, ...props }, ref) => /* @__PURE__ */ React94.createElement(
12763
13223
  "div",
12764
13224
  {
12765
13225
  ref,
@@ -12767,8 +13227,8 @@ var Section2 = forwardRef28(({ className, ...props }, ref) => /* @__PURE__ */ Re
12767
13227
  ...props
12768
13228
  }
12769
13229
  ));
12770
- var SectionHeader3 = forwardRef28(({ className, ...props }, ref) => /* @__PURE__ */ React91.createElement("div", { ref, className: cx(`flex items-center `, className), ...props }));
12771
- var Title4 = forwardRef28(({ className, $textStyle, ...props }, ref) => /* @__PURE__ */ React91.createElement(
13230
+ var SectionHeader3 = forwardRef27(({ className, ...props }, ref) => /* @__PURE__ */ React94.createElement("div", { ref, className: cx(`flex items-center `, className), ...props }));
13231
+ var Title4 = forwardRef27(({ className, $textStyle, ...props }, ref) => /* @__PURE__ */ React94.createElement(
12772
13232
  "div",
12773
13233
  {
12774
13234
  ref,
@@ -12779,7 +13239,7 @@ var Title4 = forwardRef28(({ className, $textStyle, ...props }, ref) => /* @__PU
12779
13239
  ...props
12780
13240
  }
12781
13241
  ));
12782
- var Row = forwardRef28(({ className, ...props }, ref) => /* @__PURE__ */ React91.createElement(
13242
+ var Row = forwardRef27(({ className, ...props }, ref) => /* @__PURE__ */ React94.createElement(
12783
13243
  "div",
12784
13244
  {
12785
13245
  ref,
@@ -12787,7 +13247,7 @@ var Row = forwardRef28(({ className, ...props }, ref) => /* @__PURE__ */ React91
12787
13247
  ...props
12788
13248
  }
12789
13249
  ));
12790
- var Column = forwardRef28(({ className, ...props }, ref) => /* @__PURE__ */ React91.createElement(
13250
+ var Column = forwardRef27(({ className, ...props }, ref) => /* @__PURE__ */ React94.createElement(
12791
13251
  "div",
12792
13252
  {
12793
13253
  ref,
@@ -12795,7 +13255,7 @@ var Column = forwardRef28(({ className, ...props }, ref) => /* @__PURE__ */ Reac
12795
13255
  ...props
12796
13256
  }
12797
13257
  ));
12798
- var Checkbox3 = forwardRef28(({ className, ...props }, ref) => /* @__PURE__ */ React91.createElement(
13258
+ var Checkbox3 = forwardRef27(({ className, ...props }, ref) => /* @__PURE__ */ React94.createElement(
12799
13259
  "input",
12800
13260
  {
12801
13261
  ref,
@@ -12804,7 +13264,7 @@ var Checkbox3 = forwardRef28(({ className, ...props }, ref) => /* @__PURE__ */ R
12804
13264
  ...props
12805
13265
  }
12806
13266
  ));
12807
- var Text3 = forwardRef28(({ className, ...props }, ref) => /* @__PURE__ */ React91.createElement(
13267
+ var Text3 = forwardRef27(({ className, ...props }, ref) => /* @__PURE__ */ React94.createElement(
12808
13268
  "span",
12809
13269
  {
12810
13270
  ref,
@@ -12812,14 +13272,14 @@ var Text3 = forwardRef28(({ className, ...props }, ref) => /* @__PURE__ */ React
12812
13272
  ...props
12813
13273
  }
12814
13274
  ));
12815
- var VerticalSeparator = () => /* @__PURE__ */ React91.createElement(Spacer.Vertical, { size: "inspector-v-separator" });
12816
- var HorizontalSeparator = () => /* @__PURE__ */ React91.createElement(Spacer.Horizontal, { size: "inspector-h-separator" });
12817
- var RowLabel = forwardRef28(function RowLabel2({
13275
+ var VerticalSeparator = () => /* @__PURE__ */ React94.createElement(Spacer.Vertical, { size: "inspector-v-separator" });
13276
+ var HorizontalSeparator = () => /* @__PURE__ */ React94.createElement(Spacer.Horizontal, { size: "inspector-h-separator" });
13277
+ var RowLabel = forwardRef27(function RowLabel2({
12818
13278
  className,
12819
13279
  $textStyle,
12820
13280
  ...props
12821
13281
  }, ref) {
12822
- return /* @__PURE__ */ React91.createElement(
13282
+ return /* @__PURE__ */ React94.createElement(
12823
13283
  "label",
12824
13284
  {
12825
13285
  ref,
@@ -12831,7 +13291,7 @@ var RowLabel = forwardRef28(function RowLabel2({
12831
13291
  }
12832
13292
  );
12833
13293
  });
12834
- var LabeledRow = memo40(function LabeledRow2({
13294
+ var LabeledRow = memo38(function LabeledRow2({
12835
13295
  id,
12836
13296
  children,
12837
13297
  label,
@@ -12839,190 +13299,8 @@ var LabeledRow = memo40(function LabeledRow2({
12839
13299
  right,
12840
13300
  className
12841
13301
  }) {
12842
- return /* @__PURE__ */ React91.createElement(Row, { id, className }, /* @__PURE__ */ React91.createElement(Column, null, /* @__PURE__ */ React91.createElement(RowLabel, { $textStyle: labelTextStyle }, label, right && /* @__PURE__ */ React91.createElement(Spacer.Horizontal, null), right), /* @__PURE__ */ React91.createElement(Row, null, children)));
12843
- });
12844
-
12845
- // src/components/BaseToolbar.tsx
12846
- import React92 from "react";
12847
- var toolbarStyle = {
12848
- [cssVarNames.colors.buttonBackground]: "transparent",
12849
- [cssVarNames.colors.inputBackground]: "transparent"
12850
- };
12851
- function BaseToolbar({
12852
- children,
12853
- left,
12854
- right,
12855
- logo,
12856
- showDivider = true
12857
- }) {
12858
- return /* @__PURE__ */ React92.createElement("div", { className: "flex flex-col", style: toolbarStyle }, /* @__PURE__ */ React92.createElement(
12859
- "div",
12860
- {
12861
- className: "flex items-center pr-2.5 bg-sidebar-background flex-none relative @container/toolbar",
12862
- style: {
12863
- flex: `0 0 ${cssVars.spacing.toolbarHeight}`
12864
- }
12865
- },
12866
- logo && /* @__PURE__ */ React92.createElement(React92.Fragment, null, logo, /* @__PURE__ */ React92.createElement(DividerVertical, null)),
12867
- /* @__PURE__ */ React92.createElement(Spacer.Horizontal, { size: 10 }),
12868
- left && /* @__PURE__ */ React92.createElement(React92.Fragment, null, /* @__PURE__ */ React92.createElement("div", { className: "flex gap-toolbar-separator" }, left), /* @__PURE__ */ React92.createElement(Spacer.Horizontal, { size: 10 })),
12869
- /* @__PURE__ */ React92.createElement("div", { className: "flex items-center justify-center text-text-muted pointer-events-none @2xl/toolbar:absolute inset-0" }, /* @__PURE__ */ React92.createElement(
12870
- "div",
12871
- {
12872
- style: {
12873
- display: "flex",
12874
- alignItems: "center",
12875
- justifyContent: "center",
12876
- pointerEvents: "all"
12877
- }
12878
- },
12879
- children
12880
- )),
12881
- /* @__PURE__ */ React92.createElement(Spacer.Horizontal, null),
12882
- /* @__PURE__ */ React92.createElement(Spacer.Horizontal, { size: 10 }),
12883
- /* @__PURE__ */ React92.createElement("div", { className: "flex gap-toolbar-separator" }, right)
12884
- ), showDivider && /* @__PURE__ */ React92.createElement(Divider, { variant: "strong" }));
12885
- }
12886
-
12887
- // src/components/Toolbar.tsx
12888
- import { useKeyboardShortcuts as useKeyboardShortcuts4 } from "@noya-app/noya-keymap";
12889
- import React93 from "react";
12890
- var iconButtonStyle = {
12891
- height: 27,
12892
- width: 27,
12893
- minWidth: 27
12894
- };
12895
- var ToolbarMenuDropdown = memoGeneric(function ToolbarMenuDropdown2({
12896
- item,
12897
- onSelectMenuItem
12898
- }) {
12899
- const [open, setOpen] = React93.useState(false);
12900
- return /* @__PURE__ */ React93.createElement(
12901
- DropdownMenu,
12902
- {
12903
- open,
12904
- onOpenChange: setOpen,
12905
- items: item.items,
12906
- onSelect: (value) => {
12907
- if (onSelectMenuItem && value) {
12908
- onSelectMenuItem(value);
12909
- }
12910
- }
12911
- },
12912
- /* @__PURE__ */ React93.createElement(
12913
- Button,
12914
- {
12915
- disabled: item.disabled,
12916
- active: item.checked || open,
12917
- icon: item.icon,
12918
- iconRight: "DropdownChevronIcon"
12919
- },
12920
- item.title
12921
- )
12922
- );
12923
- });
12924
- var ToolbarMenuButton = memoGeneric(function ToolbarMenuButton2({
12925
- item,
12926
- onSelectMenuItem,
12927
- as
12928
- }) {
12929
- const content = /* @__PURE__ */ React93.createElement(
12930
- Button,
12931
- {
12932
- as,
12933
- disabled: item.disabled,
12934
- active: item.checked,
12935
- icon: item.icon,
12936
- style: item.icon && !item.title ? iconButtonStyle : void 0,
12937
- ...as === "a" && { href: item.value },
12938
- onClick: () => {
12939
- if (onSelectMenuItem && item.value) {
12940
- onSelectMenuItem(item.value);
12941
- }
12942
- }
12943
- },
12944
- item.title
12945
- );
12946
- return item.tooltip ? /* @__PURE__ */ React93.createElement(Tooltip, { sideOffset: 10, content: item.tooltip }, content) : content;
13302
+ return /* @__PURE__ */ React94.createElement(Row, { id, className }, /* @__PURE__ */ React94.createElement(Column, null, /* @__PURE__ */ React94.createElement(RowLabel, { $textStyle: labelTextStyle }, label, right && /* @__PURE__ */ React94.createElement(Spacer.Horizontal, null), right), /* @__PURE__ */ React94.createElement(Row, null, children)));
12947
13303
  });
12948
- var ToolbarMenuItem = memoGeneric(function ToolbarMenuItem2({
12949
- item,
12950
- onSelectMenuItem,
12951
- buttonAs
12952
- }) {
12953
- if (item.type === "sectionHeader") return null;
12954
- if (item.type === "separator") {
12955
- return /* @__PURE__ */ React93.createElement(DividerVertical, { overflow: 4 });
12956
- }
12957
- if (isSelectableMenuItem(item)) {
12958
- return /* @__PURE__ */ React93.createElement(
12959
- ToolbarMenuButton,
12960
- {
12961
- item,
12962
- onSelectMenuItem,
12963
- as: buttonAs
12964
- }
12965
- );
12966
- }
12967
- return /* @__PURE__ */ React93.createElement(ToolbarMenuDropdown, { item, onSelectMenuItem });
12968
- });
12969
- var ToolbarMenu = memoGeneric(function ToolbarMenu2({
12970
- items,
12971
- onSelectMenuItem,
12972
- buttonAs
12973
- }) {
12974
- return /* @__PURE__ */ React93.createElement(React93.Fragment, null, items.map((item, i) => {
12975
- return /* @__PURE__ */ React93.createElement(
12976
- ToolbarMenuItem,
12977
- {
12978
- key: i,
12979
- item,
12980
- onSelectMenuItem,
12981
- buttonAs
12982
- }
12983
- );
12984
- }));
12985
- });
12986
- function Toolbar({
12987
- children,
12988
- logo,
12989
- leftMenuItems = [],
12990
- rightMenuItems = [],
12991
- onSelectMenuItem,
12992
- shouldBindKeyboardShortcuts = true
12993
- }) {
12994
- const allMenuItems = React93.useMemo(
12995
- () => [...leftMenuItems, ...rightMenuItems],
12996
- [leftMenuItems, rightMenuItems]
12997
- );
12998
- useKeyboardShortcuts4(
12999
- React93.useMemo(
13000
- () => onSelectMenuItem && shouldBindKeyboardShortcuts ? getKeyboardShortcutsForMenuItems(allMenuItems, onSelectMenuItem) : {},
13001
- [allMenuItems, onSelectMenuItem, shouldBindKeyboardShortcuts]
13002
- )
13003
- );
13004
- return /* @__PURE__ */ React93.createElement(
13005
- BaseToolbar,
13006
- {
13007
- logo,
13008
- left: leftMenuItems.length > 0 && /* @__PURE__ */ React93.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ React93.createElement(
13009
- ToolbarMenu,
13010
- {
13011
- items: leftMenuItems,
13012
- onSelectMenuItem
13013
- }
13014
- )),
13015
- right: rightMenuItems.length > 0 && /* @__PURE__ */ React93.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ React93.createElement(
13016
- ToolbarMenu,
13017
- {
13018
- items: rightMenuItems,
13019
- onSelectMenuItem
13020
- }
13021
- ))
13022
- },
13023
- children
13024
- );
13025
- }
13026
13304
  export {
13027
13305
  AIAssistantInput,
13028
13306
  AIAssistantLayout,
@@ -13097,7 +13375,7 @@ export {
13097
13375
  LEFT_SIDEBAR_ID,
13098
13376
  Label,
13099
13377
  LabelContext,
13100
- LabelPositionContext,
13378
+ LabelTypeContext,
13101
13379
  LabelWidthContext,
13102
13380
  LabeledElementView,
13103
13381
  LabeledField,
@@ -13131,6 +13409,7 @@ export {
13131
13409
  SortableItemContext,
13132
13410
  Spacer,
13133
13411
  Switch,
13412
+ Tabs,
13134
13413
  Text,
13135
13414
  TextArea,
13136
13415
  TextAreaRow,
@@ -13141,6 +13420,8 @@ export {
13141
13420
  ToolbarMenuButton,
13142
13421
  ToolbarMenuDropdown,
13143
13422
  ToolbarMenuItem,
13423
+ ToolbarMenuPopover,
13424
+ ToolbarShortcut,
13144
13425
  Tooltip,
13145
13426
  TreeView,
13146
13427
  UserAvatar,
@@ -13158,6 +13439,7 @@ export {
13158
13439
  cx,
13159
13440
  defaultAcceptsDrop,
13160
13441
  dragItemKeySeparator,
13442
+ editableBlockStyles,
13161
13443
  filterWithGroupedSections,
13162
13444
  fuzzyFilter,
13163
13445
  fuzzyScore,
@@ -13175,6 +13457,7 @@ export {
13175
13457
  getThumbnailColors,
13176
13458
  isMenuItemSectionHeader,
13177
13459
  isNonSelectableMenuItem,
13460
+ isPopoverMenuItem,
13178
13461
  isSelectableMenuItem,
13179
13462
  isSelectableMenuItemWithScore,
13180
13463
  labeledFieldStyles,
@@ -13213,7 +13496,7 @@ export {
13213
13496
  useIndent,
13214
13497
  useInputFieldContext,
13215
13498
  useLabel,
13216
- useLabelPosition,
13499
+ useLabelType,
13217
13500
  useLabelWidth,
13218
13501
  useOpenConfirmationDialog,
13219
13502
  useOpenDialog,