@thangph2146/lexical-editor 0.0.5 → 0.0.7

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 (40) hide show
  1. package/README.md +47 -0
  2. package/dist/editor-x/editor.cjs +610 -493
  3. package/dist/editor-x/editor.cjs.map +1 -1
  4. package/dist/editor-x/editor.css +157 -69
  5. package/dist/editor-x/editor.css.map +1 -1
  6. package/dist/editor-x/editor.d.cts +2 -1
  7. package/dist/editor-x/editor.d.ts +2 -1
  8. package/dist/editor-x/editor.js +350 -233
  9. package/dist/editor-x/editor.js.map +1 -1
  10. package/dist/index.cjs +620 -501
  11. package/dist/index.cjs.map +1 -1
  12. package/dist/index.css +157 -69
  13. package/dist/index.css.map +1 -1
  14. package/dist/index.d.cts +1 -1
  15. package/dist/index.d.ts +1 -1
  16. package/dist/index.js +354 -235
  17. package/dist/index.js.map +1 -1
  18. package/package.json +3 -1
  19. package/src/components/lexical-editor.tsx +2 -0
  20. package/src/editor-x/editor.tsx +4 -2
  21. package/src/editor-x/plugins.tsx +7 -6
  22. package/src/plugins/images-plugin.tsx +3 -2
  23. package/src/plugins/layout-plugin.tsx +96 -61
  24. package/src/themes/_mixins.scss +12 -7
  25. package/src/themes/_variables.scss +2 -1
  26. package/src/themes/core/_reset.scss +10 -6
  27. package/src/themes/plugins/_color-picker.scss +1 -0
  28. package/src/themes/plugins/_layout.scss +3 -7
  29. package/src/themes/plugins/_list-color.scss +2 -0
  30. package/src/themes/plugins/_toolbar.scss +7 -7
  31. package/src/themes/ui-components/_button.scss +3 -3
  32. package/src/themes/ui-components/_flex.scss +2 -0
  33. package/src/themes/ui-components/_number-input.scss +81 -0
  34. package/src/themes/ui-components/_text-utilities.scss +1 -1
  35. package/src/themes/ui-components.scss +1 -0
  36. package/src/ui/flex.tsx +9 -2
  37. package/src/ui/number-input.tsx +104 -0
  38. package/src/themes/editor-theme copy.scss +0 -763
  39. package/src/themes/plugins copy.scss +0 -656
  40. package/src/themes/ui-components copy.scss +0 -1335
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import * as React20 from 'react';
1
+ import * as React21 from 'react';
2
2
  import { createContext, useRef, useState, useEffect, useCallback, Suspense, useMemo, useContext, useLayoutEffect } from 'react';
3
3
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
4
  import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
@@ -91,9 +91,9 @@ var init_tooltip = __esm({
91
91
  TooltipProvider = ({ children }) => /* @__PURE__ */ jsx(Fragment, { children });
92
92
  Tooltip = ({ children }) => /* @__PURE__ */ jsx("div", { className: "editor-tooltip-group", children });
93
93
  TooltipTrigger = ({ asChild, children, ...props }) => {
94
- const child = asChild ? React20.Children.only(children) : children;
95
- if (!React20.isValidElement(child)) return null;
96
- return React20.cloneElement(child, {
94
+ const child = asChild ? React21.Children.only(children) : children;
95
+ if (!React21.isValidElement(child)) return null;
96
+ return React21.cloneElement(child, {
97
97
  ...props,
98
98
  className: cn(child.props.className, "editor-tooltip-trigger")
99
99
  });
@@ -2963,7 +2963,7 @@ var Button;
2963
2963
  var init_button = __esm({
2964
2964
  "src/ui/button.tsx"() {
2965
2965
  init_utils();
2966
- Button = React20.forwardRef(
2966
+ Button = React21.forwardRef(
2967
2967
  ({ className, variant = "default", size = "default", type = "button", isLoading, disabled, children, ...props }, ref) => {
2968
2968
  return /* @__PURE__ */ jsxs(
2969
2969
  "button",
@@ -3104,22 +3104,22 @@ var init_typography = __esm({
3104
3104
  md: "editor-icon-md",
3105
3105
  lg: "editor-icon-lg"
3106
3106
  };
3107
- if (React20.isValidElement(children)) {
3108
- return React20.cloneElement(children, {
3107
+ if (React21.isValidElement(children)) {
3108
+ return React21.cloneElement(children, {
3109
3109
  className: cn(sizeMap[size] || sizeMap.medium, children.props.className, className)
3110
3110
  });
3111
3111
  }
3112
3112
  return /* @__PURE__ */ jsx(Fragment, { children });
3113
3113
  };
3114
- TypographyP = React20.forwardRef(
3114
+ TypographyP = React21.forwardRef(
3115
3115
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx("p", { ref, className: cn("editor-typography-p", className), ...props })
3116
3116
  );
3117
3117
  TypographyP.displayName = "TypographyP";
3118
- TypographyPSmall = React20.forwardRef(
3118
+ TypographyPSmall = React21.forwardRef(
3119
3119
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx("p", { ref, className: cn("editor-typography-p-small", className), ...props })
3120
3120
  );
3121
3121
  TypographyPSmall.displayName = "TypographyPSmall";
3122
- TypographySpanSmallMuted = React20.forwardRef(
3122
+ TypographySpanSmallMuted = React21.forwardRef(
3123
3123
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx("span", { ref, className: cn("editor-typography-span-small-muted", className), ...props })
3124
3124
  );
3125
3125
  TypographySpanSmallMuted.displayName = "TypographySpanSmallMuted";
@@ -3171,7 +3171,7 @@ function MediaResizer({
3171
3171
  const hardWidthLimit = maxWidth ?? editorContainer?.maxWidth;
3172
3172
  const minWidth = 100;
3173
3173
  const minHeight = 100;
3174
- React20.useEffect(() => {
3174
+ React21.useEffect(() => {
3175
3175
  }, [mediaRef, unlockBoundaries]);
3176
3176
  const setStartCursor = (direction) => {
3177
3177
  const ew = direction === Direction.east || direction === Direction.west;
@@ -3518,14 +3518,14 @@ function YouTubeComponent({
3518
3518
  }) {
3519
3519
  const isEditable = useLexicalEditable();
3520
3520
  const [isSelected, setSelected, clearSelection] = useLexicalNodeSelection(nodeKey);
3521
- const [isResizing, setIsResizing] = React20.useState(false);
3522
- const wrapperRef = React20.useRef(null);
3523
- const [wrapperElement, setWrapperElement] = React20.useState(null);
3524
- const buttonRef = React20.useRef(null);
3525
- const [containerWidth, setContainerWidth] = React20.useState(maxWidth);
3521
+ const [isResizing, setIsResizing] = React21.useState(false);
3522
+ const wrapperRef = React21.useRef(null);
3523
+ const [wrapperElement, setWrapperElement] = React21.useState(null);
3524
+ const buttonRef = React21.useRef(null);
3525
+ const [containerWidth, setContainerWidth] = React21.useState(maxWidth);
3526
3526
  const editorContainer = useEditorContainer();
3527
3527
  const editorHardWidthLimit = editorContainer?.maxWidth;
3528
- const updateNode = React20.useCallback(
3528
+ const updateNode = React21.useCallback(
3529
3529
  (updater) => {
3530
3530
  editor.update(() => {
3531
3531
  const node = $getNodeByKey(nodeKey);
@@ -3537,14 +3537,14 @@ function YouTubeComponent({
3537
3537
  [editor, nodeKey]
3538
3538
  );
3539
3539
  const aspectRatio = 16 / 9;
3540
- const clampToContainer = React20.useCallback(
3540
+ const clampToContainer = React21.useCallback(
3541
3541
  (value) => {
3542
3542
  const limit = typeof editorHardWidthLimit === "number" && editorHardWidthLimit > 0 ? editorHardWidthLimit : containerWidth || value;
3543
3543
  return Math.min(value, limit);
3544
3544
  },
3545
3545
  [containerWidth, editorHardWidthLimit]
3546
3546
  );
3547
- React20.useEffect(() => {
3547
+ React21.useEffect(() => {
3548
3548
  if (!wrapperElement) {
3549
3549
  return;
3550
3550
  }
@@ -3589,7 +3589,7 @@ function YouTubeComponent({
3589
3589
  return () => window.removeEventListener("resize", updateAvailableWidth);
3590
3590
  }
3591
3591
  }, [editor, editorHardWidthLimit, maxWidth, wrapperElement]);
3592
- React20.useEffect(() => {
3592
+ React21.useEffect(() => {
3593
3593
  if (!containerWidth) {
3594
3594
  return;
3595
3595
  }
@@ -3616,11 +3616,11 @@ function YouTubeComponent({
3616
3616
  const disablePlaybackInteractions = isEditable;
3617
3617
  const iframeWidth = safeRenderedWidth;
3618
3618
  const iframeHeight = Math.round(iframeWidth / aspectRatio);
3619
- const handleWrapperRef = React20.useCallback((node) => {
3619
+ const handleWrapperRef = React21.useCallback((node) => {
3620
3620
  wrapperRef.current = node;
3621
3621
  setWrapperElement(node);
3622
3622
  }, []);
3623
- React20.useEffect(() => {
3623
+ React21.useEffect(() => {
3624
3624
  if (!isEditable) {
3625
3625
  return;
3626
3626
  }
@@ -3651,7 +3651,7 @@ function YouTubeComponent({
3651
3651
  )
3652
3652
  );
3653
3653
  }, [clearSelection, editor, isEditable, isResizing, isSelected, setSelected]);
3654
- React20.useEffect(() => {
3654
+ React21.useEffect(() => {
3655
3655
  if (!containerWidth || typeof width !== "number" || fullWidth || width <= containerWidth) {
3656
3656
  return;
3657
3657
  }
@@ -3951,15 +3951,15 @@ function Dialog({ open = false, onOpenChange = () => {
3951
3951
  return /* @__PURE__ */ jsx(DialogContext.Provider, { value: { open, onOpenChange }, children });
3952
3952
  }
3953
3953
  function DialogTrigger({ asChild, children, className, ...props }) {
3954
- const context = React20.useContext(DialogContext);
3954
+ const context = React21.useContext(DialogContext);
3955
3955
  const handleClick = (e) => {
3956
3956
  context?.onOpenChange(true);
3957
- if (React20.isValidElement(children)) {
3957
+ if (React21.isValidElement(children)) {
3958
3958
  children.props.onClick?.(e);
3959
3959
  }
3960
3960
  };
3961
- if (asChild && React20.isValidElement(children)) {
3962
- return React20.cloneElement(children, {
3961
+ if (asChild && React21.isValidElement(children)) {
3962
+ return React21.cloneElement(children, {
3963
3963
  onClick: handleClick,
3964
3964
  ...props
3965
3965
  });
@@ -3967,15 +3967,15 @@ function DialogTrigger({ asChild, children, className, ...props }) {
3967
3967
  return /* @__PURE__ */ jsx("button", { type: "button", onClick: handleClick, className, ...props, children });
3968
3968
  }
3969
3969
  function DialogClose({ asChild, children, className, ...props }) {
3970
- const context = React20.useContext(DialogContext);
3970
+ const context = React21.useContext(DialogContext);
3971
3971
  const handleClick = (e) => {
3972
3972
  context?.onOpenChange(false);
3973
- if (React20.isValidElement(children)) {
3973
+ if (React21.isValidElement(children)) {
3974
3974
  children.props.onClick?.(e);
3975
3975
  }
3976
3976
  };
3977
- if (asChild && React20.isValidElement(children)) {
3978
- return React20.cloneElement(children, {
3977
+ if (asChild && React21.isValidElement(children)) {
3978
+ return React21.cloneElement(children, {
3979
3979
  onClick: handleClick,
3980
3980
  ...props
3981
3981
  });
@@ -3983,9 +3983,9 @@ function DialogClose({ asChild, children, className, ...props }) {
3983
3983
  return /* @__PURE__ */ jsx("button", { type: "button", onClick: handleClick, className, ...props, children });
3984
3984
  }
3985
3985
  function DialogContent({ children, className, disableOutsideClick, ...props }) {
3986
- const context = React20.useContext(DialogContext);
3987
- const [mounted, setMounted] = React20.useState(false);
3988
- React20.useEffect(() => {
3986
+ const context = React21.useContext(DialogContext);
3987
+ const [mounted, setMounted] = React21.useState(false);
3988
+ React21.useEffect(() => {
3989
3989
  setMounted(true);
3990
3990
  return () => setMounted(false);
3991
3991
  }, []);
@@ -4044,7 +4044,7 @@ var DialogContext;
4044
4044
  var init_dialog = __esm({
4045
4045
  "src/ui/dialog.tsx"() {
4046
4046
  init_utils();
4047
- DialogContext = React20.createContext(null);
4047
+ DialogContext = React21.createContext(null);
4048
4048
  }
4049
4049
  });
4050
4050
 
@@ -4059,7 +4059,7 @@ var Input;
4059
4059
  var init_input = __esm({
4060
4060
  "src/ui/input.tsx"() {
4061
4061
  init_utils();
4062
- Input = React20.forwardRef(
4062
+ Input = React21.forwardRef(
4063
4063
  ({ className, type, ...props }, ref) => {
4064
4064
  return /* @__PURE__ */ jsx(
4065
4065
  "input",
@@ -4079,7 +4079,7 @@ var Label;
4079
4079
  var init_label = __esm({
4080
4080
  "src/ui/label.tsx"() {
4081
4081
  init_utils();
4082
- Label = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4082
+ Label = React21.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
4083
4083
  "label",
4084
4084
  {
4085
4085
  ref,
@@ -4094,6 +4094,37 @@ var init_label = __esm({
4094
4094
  Label.displayName = "Label";
4095
4095
  }
4096
4096
  });
4097
+ var Flex;
4098
+ var init_flex = __esm({
4099
+ "src/ui/flex.tsx"() {
4100
+ init_utils();
4101
+ Flex = React21.forwardRef(
4102
+ ({ className, align, justify, direction, wrap, gap, style, ...props }, ref) => {
4103
+ const isStandardGap = typeof gap === "number" && [0.5, 1, 1.5, 2, 3, 4, 5].includes(gap);
4104
+ const gapClass = isStandardGap ? `editor-gap-${gap.toString().replace(".", "-")}` : void 0;
4105
+ const gapStyle = !isStandardGap && typeof gap === "number" ? { gap: `${gap * 0.25}rem` } : !isStandardGap && typeof gap !== "undefined" ? { gap } : void 0;
4106
+ return /* @__PURE__ */ jsx(
4107
+ "div",
4108
+ {
4109
+ ref,
4110
+ className: cn(
4111
+ "editor-flex",
4112
+ align && `editor-items-${align}`,
4113
+ justify && `editor-justify-${justify}`,
4114
+ direction && `editor-flex-${direction}`,
4115
+ wrap && `editor-flex-${wrap}`,
4116
+ gapClass,
4117
+ className
4118
+ ),
4119
+ style: { ...gapStyle, ...style },
4120
+ ...props
4121
+ }
4122
+ );
4123
+ }
4124
+ );
4125
+ Flex.displayName = "Flex";
4126
+ }
4127
+ });
4097
4128
  function Tabs({
4098
4129
  defaultValue,
4099
4130
  value: controlledValue,
@@ -4102,7 +4133,7 @@ function Tabs({
4102
4133
  className,
4103
4134
  ...props
4104
4135
  }) {
4105
- const [uncontrolledValue, setUncontrolledValue] = React20.useState(defaultValue || "");
4136
+ const [uncontrolledValue, setUncontrolledValue] = React21.useState(defaultValue || "");
4106
4137
  const value = controlledValue ?? uncontrolledValue;
4107
4138
  const setValue = onValueChange ?? setUncontrolledValue;
4108
4139
  return /* @__PURE__ */ jsx(TabsContext.Provider, { value: { value, onValueChange: setValue }, children: /* @__PURE__ */ jsx("div", { className: cn(className), ...props, children }) });
@@ -4121,7 +4152,7 @@ function TabsList({ className, children, ...props }) {
4121
4152
  );
4122
4153
  }
4123
4154
  function TabsTrigger({ value, className, children, ...props }) {
4124
- const context = React20.useContext(TabsContext);
4155
+ const context = React21.useContext(TabsContext);
4125
4156
  const isSelected = context?.value === value;
4126
4157
  return /* @__PURE__ */ jsx(
4127
4158
  "button",
@@ -4139,7 +4170,7 @@ function TabsTrigger({ value, className, children, ...props }) {
4139
4170
  );
4140
4171
  }
4141
4172
  function TabsContent({ value, className, children, ...props }) {
4142
- const context = React20.useContext(TabsContext);
4173
+ const context = React21.useContext(TabsContext);
4143
4174
  const isSelected = context?.value === value;
4144
4175
  if (!isSelected) return null;
4145
4176
  return /* @__PURE__ */ jsx(
@@ -4158,7 +4189,7 @@ var TabsContext;
4158
4189
  var init_tabs = __esm({
4159
4190
  "src/ui/tabs.tsx"() {
4160
4191
  init_utils();
4161
- TabsContext = React20.createContext(null);
4192
+ TabsContext = React21.createContext(null);
4162
4193
  }
4163
4194
  });
4164
4195
  function useEditorUploads() {
@@ -4185,27 +4216,27 @@ function Collapsible({
4185
4216
  className,
4186
4217
  ...props
4187
4218
  }) {
4188
- const [uncontrolledOpen, setUncontrolledOpen] = React20.useState(false);
4219
+ const [uncontrolledOpen, setUncontrolledOpen] = React21.useState(false);
4189
4220
  const open = controlledOpen ?? uncontrolledOpen;
4190
4221
  const setOpen = onOpenChange ?? setUncontrolledOpen;
4191
4222
  return /* @__PURE__ */ jsx(CollapsibleContext.Provider, { value: { open, setOpen }, children: /* @__PURE__ */ jsx("div", { className: cn("editor-collapsible", className), "data-state": open ? "open" : "closed", ...props, children }) });
4192
4223
  }
4193
4224
  function CollapsibleTrigger({ children, asChild, ...props }) {
4194
- const context = React20.useContext(CollapsibleContext);
4225
+ const context = React21.useContext(CollapsibleContext);
4195
4226
  if (!context) throw new Error("CollapsibleTrigger must be used within Collapsible");
4196
4227
  const handleClick = (e) => {
4197
4228
  context.setOpen(!context.open);
4198
- if (React20.isValidElement(children)) {
4229
+ if (React21.isValidElement(children)) {
4199
4230
  children.props.onClick?.(e);
4200
4231
  }
4201
4232
  };
4202
- if (asChild && React20.isValidElement(children)) {
4203
- return React20.cloneElement(children, { onClick: handleClick, ...props });
4233
+ if (asChild && React21.isValidElement(children)) {
4234
+ return React21.cloneElement(children, { onClick: handleClick, ...props });
4204
4235
  }
4205
4236
  return /* @__PURE__ */ jsx("button", { type: "button", onClick: handleClick, ...props, children });
4206
4237
  }
4207
4238
  function CollapsibleContent({ children, className, ...props }) {
4208
- const context = React20.useContext(CollapsibleContext);
4239
+ const context = React21.useContext(CollapsibleContext);
4209
4240
  if (!context) throw new Error("CollapsibleContent must be used within Collapsible");
4210
4241
  if (!context.open) return null;
4211
4242
  return /* @__PURE__ */ jsx("div", { className: cn("editor-overflow-hidden", className), ...props, children });
@@ -4214,7 +4245,7 @@ var CollapsibleContext;
4214
4245
  var init_collapsible = __esm({
4215
4246
  "src/ui/collapsible.tsx"() {
4216
4247
  init_utils();
4217
- CollapsibleContext = React20.createContext(null);
4248
+ CollapsibleContext = React21.createContext(null);
4218
4249
  }
4219
4250
  });
4220
4251
  function InsertImageUriDialogBody({
@@ -4329,7 +4360,7 @@ function ImagePickerFolderTree({
4329
4360
  }) {
4330
4361
  const hasContent = folder.images.length > 0 || folder.subfolders.length > 0;
4331
4362
  const isOpen = openFolders.has(folder.path);
4332
- const handleOpenChange = React20.useCallback(
4363
+ const handleOpenChange = React21.useCallback(
4333
4364
  (open) => {
4334
4365
  if (open) {
4335
4366
  setOpenFolders((prev) => {
@@ -4409,11 +4440,11 @@ function InsertImageUploadsDialogBody({
4409
4440
  const [openFolders, setOpenFolders] = useState(/* @__PURE__ */ new Set());
4410
4441
  const { folderTree, isLoading } = useEditorUploads();
4411
4442
  const isDisabled = !selectedImage;
4412
- const handleImageSelect = React20.useCallback((imageUrl, originalName) => {
4443
+ const handleImageSelect = React21.useCallback((imageUrl, originalName) => {
4413
4444
  setSelectedImage(imageUrl);
4414
4445
  setAltText((prev) => prev || originalName);
4415
4446
  }, []);
4416
- const handleConfirm = React20.useCallback(() => {
4447
+ const handleConfirm = React21.useCallback(() => {
4417
4448
  if (selectedImage) {
4418
4449
  let imageUrl = selectedImage;
4419
4450
  if (imageUrl.startsWith("/api/uploads")) {
@@ -4424,7 +4455,7 @@ function InsertImageUploadsDialogBody({
4424
4455
  onClick({ altText: altText || "", src: imageUrl });
4425
4456
  }
4426
4457
  }, [selectedImage, altText, onClick]);
4427
- React20.useEffect(() => {
4458
+ React21.useEffect(() => {
4428
4459
  const handleDoubleClickConfirm = () => {
4429
4460
  setTimeout(() => {
4430
4461
  handleConfirm();
@@ -4435,7 +4466,7 @@ function InsertImageUploadsDialogBody({
4435
4466
  document.removeEventListener("confirm-image-insert", handleDoubleClickConfirm);
4436
4467
  };
4437
4468
  }, [handleConfirm]);
4438
- React20.useEffect(() => {
4469
+ React21.useEffect(() => {
4439
4470
  if (folderTree && folderTree.subfolders.length > 0) {
4440
4471
  setOpenFolders(new Set(folderTree.subfolders.map((f) => f.path)));
4441
4472
  }
@@ -4443,7 +4474,7 @@ function InsertImageUploadsDialogBody({
4443
4474
  return /* @__PURE__ */ jsxs("div", { className: "editor-form-grid", children: [
4444
4475
  /* @__PURE__ */ jsxs("div", { className: "editor-form-item", children: [
4445
4476
  /* @__PURE__ */ jsx(Label, { children: "Ch\u1ECDn h\xECnh \u1EA3nh t\u1EEB th\u01B0 vi\u1EC7n" }),
4446
- isLoading ? /* @__PURE__ */ jsx("div", { className: "editor-flex-center-justify-py-8", children: /* @__PURE__ */ jsx(Loader2, { className: "editor-loader" }) }) : !folderTree || folderTree.subfolders.length === 0 && folderTree.images.length === 0 ? /* @__PURE__ */ jsx("div", { className: "editor-empty-state", children: /* @__PURE__ */ jsx(TypographySpanSmallMuted, { children: "Ch\u01B0a c\xF3 h\xECnh \u1EA3nh n\xE0o \u0111\u01B0\u1EE3c upload" }) }) : /* @__PURE__ */ jsxs("div", { className: "editor-scroll-area editor-flex editor-flex-col editor-gap-1", children: [
4477
+ isLoading ? /* @__PURE__ */ jsx(Flex, { align: "center", justify: "center", className: "editor-py-8", children: /* @__PURE__ */ jsx(Loader2, { className: "editor-loader" }) }) : !folderTree || folderTree.subfolders.length === 0 && folderTree.images.length === 0 ? /* @__PURE__ */ jsx("div", { className: "editor-empty-state", children: /* @__PURE__ */ jsx(TypographySpanSmallMuted, { children: "Ch\u01B0a c\xF3 h\xECnh \u1EA3nh n\xE0o \u0111\u01B0\u1EE3c upload" }) }) : /* @__PURE__ */ jsxs("div", { className: "editor-scroll-area editor-flex editor-flex-col editor-gap-1", children: [
4447
4478
  folderTree.images.length > 0 && /* @__PURE__ */ jsxs("div", { className: "editor-mb-3", children: [
4448
4479
  /* @__PURE__ */ jsx(TypographySpanSmallMuted, { className: "editor-mb-2 editor-px-1", children: "Root" }),
4449
4480
  /* @__PURE__ */ jsx("div", { className: "editor-image-grid editor-gap-2", children: folderTree.images.map((image) => /* @__PURE__ */ jsx(
@@ -4711,6 +4742,7 @@ var init_images_plugin = __esm({
4711
4742
  init_dialog();
4712
4743
  init_input();
4713
4744
  init_label();
4745
+ init_flex();
4714
4746
  init_tabs();
4715
4747
  init_uploads_context();
4716
4748
  init_collapsible();
@@ -5037,7 +5069,7 @@ var init_image_placeholder = __esm({
5037
5069
  }
5038
5070
  });
5039
5071
  function ContentEditable({
5040
- placeholder: placeholder2,
5072
+ placeholder,
5041
5073
  className,
5042
5074
  placeholderClassName,
5043
5075
  placeholderDefaults = true
@@ -5051,8 +5083,8 @@ function ContentEditable({
5051
5083
  !isReadOnlyOrReview && "min-h-72 px-8 py-4",
5052
5084
  className
5053
5085
  ),
5054
- "aria-placeholder": placeholder2,
5055
- "aria-label": placeholder2 || "Editor n\u1ED9i dung",
5086
+ "aria-placeholder": placeholder,
5087
+ "aria-label": placeholder || "Editor n\u1ED9i dung",
5056
5088
  placeholder: /* @__PURE__ */ jsx(
5057
5089
  "div",
5058
5090
  {
@@ -5061,7 +5093,7 @@ function ContentEditable({
5061
5093
  "text-muted-foreground pointer-events-none select-none",
5062
5094
  placeholderDefaults && !isReadOnlyOrReview && "absolute top-0 left-0 overflow-hidden px-8 py-[18px] text-ellipsis"
5063
5095
  ),
5064
- children: placeholder2
5096
+ children: placeholder
5065
5097
  }
5066
5098
  )
5067
5099
  }
@@ -5695,7 +5727,7 @@ function $isImageNode(node) {
5695
5727
  var ImageComponent2, WHITESPACE_REGEX, ImageNode;
5696
5728
  var init_image_node = __esm({
5697
5729
  "src/nodes/image-node.tsx"() {
5698
- ImageComponent2 = React20.lazy(() => Promise.resolve().then(() => (init_image_component(), image_component_exports)));
5730
+ ImageComponent2 = React21.lazy(() => Promise.resolve().then(() => (init_image_component(), image_component_exports)));
5699
5731
  WHITESPACE_REGEX = /[\u200B\u00A0\s]+/g;
5700
5732
  ImageNode = class _ImageNode extends DecoratorNode {
5701
5733
  __src;
@@ -6457,7 +6489,7 @@ var Separator;
6457
6489
  var init_separator = __esm({
6458
6490
  "src/ui/separator.tsx"() {
6459
6491
  init_utils();
6460
- Separator = React20.forwardRef(({ className, orientation = "horizontal", ...props }, ref) => /* @__PURE__ */ jsx(
6492
+ Separator = React21.forwardRef(({ className, orientation = "horizontal", ...props }, ref) => /* @__PURE__ */ jsx(
6461
6493
  "div",
6462
6494
  {
6463
6495
  ref,
@@ -6474,34 +6506,6 @@ var init_separator = __esm({
6474
6506
  Separator.displayName = "Separator";
6475
6507
  }
6476
6508
  });
6477
- var Flex;
6478
- var init_flex = __esm({
6479
- "src/ui/flex.tsx"() {
6480
- init_utils();
6481
- Flex = React20.forwardRef(
6482
- ({ className, align, justify, direction, wrap, gap, style, ...props }, ref) => {
6483
- const gapStyle = typeof gap === "number" ? { gap: `${gap * 0.25}rem` } : typeof gap !== "undefined" ? { gap } : void 0;
6484
- return /* @__PURE__ */ jsx(
6485
- "div",
6486
- {
6487
- ref,
6488
- className: cn(
6489
- "editor-flex",
6490
- align && `editor-items-${align}`,
6491
- justify && `editor-justify-${justify}`,
6492
- direction && `editor-flex-${direction}`,
6493
- wrap && `editor-flex-${wrap}`,
6494
- className
6495
- ),
6496
- style: { ...gapStyle, ...style },
6497
- ...props
6498
- }
6499
- );
6500
- }
6501
- );
6502
- Flex.displayName = "Flex";
6503
- }
6504
- });
6505
6509
  function textEncoder() {
6506
6510
  if (window.TextEncoder === void 0) {
6507
6511
  return null;
@@ -6977,7 +6981,7 @@ var ScrollArea, ScrollBar;
6977
6981
  var init_scroll_area = __esm({
6978
6982
  "src/ui/scroll-area.tsx"() {
6979
6983
  init_utils();
6980
- ScrollArea = React20.forwardRef(
6984
+ ScrollArea = React21.forwardRef(
6981
6985
  ({ className, children, ...props }, ref) => /* @__PURE__ */ jsx(
6982
6986
  "div",
6983
6987
  {
@@ -7159,9 +7163,9 @@ var init_code_button = __esm({
7159
7163
  }
7160
7164
  });
7161
7165
  function Select({ value, onValueChange, children, disabled }) {
7162
- const [open, setOpen] = React20.useState(false);
7163
- const triggerRef = React20.useRef(null);
7164
- const contextValue = React20.useMemo(() => ({
7166
+ const [open, setOpen] = React21.useState(false);
7167
+ const triggerRef = React21.useRef(null);
7168
+ const contextValue = React21.useMemo(() => ({
7165
7169
  value,
7166
7170
  onValueChange,
7167
7171
  open,
@@ -7172,7 +7176,7 @@ function Select({ value, onValueChange, children, disabled }) {
7172
7176
  return /* @__PURE__ */ jsx(SelectContext.Provider, { value: contextValue, children });
7173
7177
  }
7174
7178
  function SelectTrigger({ className, children, size = "default", ...props }) {
7175
- const context = React20.useContext(SelectContext);
7179
+ const context = React21.useContext(SelectContext);
7176
7180
  if (!context) throw new Error("SelectTrigger must be used within Select");
7177
7181
  const { triggerRef, disabled, open, setOpen } = context;
7178
7182
  return /* @__PURE__ */ jsxs(
@@ -7195,16 +7199,16 @@ function SelectTrigger({ className, children, size = "default", ...props }) {
7195
7199
  }
7196
7200
  );
7197
7201
  }
7198
- function SelectValue({ placeholder: placeholder2 }) {
7199
- const context = React20.useContext(SelectContext);
7202
+ function SelectValue({ placeholder }) {
7203
+ const context = React21.useContext(SelectContext);
7200
7204
  if (!context) throw new Error("SelectValue must be used within Select");
7201
- return /* @__PURE__ */ jsx("span", { children: context.value || placeholder2 });
7205
+ return /* @__PURE__ */ jsx("span", { children: context.value || placeholder });
7202
7206
  }
7203
7207
  function SelectContent({ className, children, ...props }) {
7204
- const context = React20.useContext(SelectContext);
7205
- const [position, setPosition] = React20.useState({ top: 0, left: 0, width: 0 });
7206
- const contentRef = React20.useRef(null);
7207
- React20.useEffect(() => {
7208
+ const context = React21.useContext(SelectContext);
7209
+ const [position, setPosition] = React21.useState({ top: 0, left: 0, width: 0 });
7210
+ const contentRef = React21.useRef(null);
7211
+ React21.useEffect(() => {
7208
7212
  if (context?.open && context.triggerRef.current) {
7209
7213
  const rect = context.triggerRef.current.getBoundingClientRect();
7210
7214
  setPosition({
@@ -7246,7 +7250,7 @@ function SelectContent({ className, children, ...props }) {
7246
7250
  );
7247
7251
  }
7248
7252
  function SelectItem({ value, children, className, ...props }) {
7249
- const context = React20.useContext(SelectContext);
7253
+ const context = React21.useContext(SelectContext);
7250
7254
  if (!context) throw new Error("SelectItem must be used within Select");
7251
7255
  const isSelected = context.value === value;
7252
7256
  return /* @__PURE__ */ jsxs(
@@ -7276,7 +7280,7 @@ var SelectContext;
7276
7280
  var init_select = __esm({
7277
7281
  "src/ui/select.tsx"() {
7278
7282
  init_utils();
7279
- SelectContext = React20.createContext(null);
7283
+ SelectContext = React21.createContext(null);
7280
7284
  }
7281
7285
  });
7282
7286
  function getCodeLanguageOptions() {
@@ -7505,7 +7509,7 @@ var Command, CommandList, CommandGroup, CommandItem;
7505
7509
  var init_command = __esm({
7506
7510
  "src/ui/command.tsx"() {
7507
7511
  init_utils();
7508
- Command = React20.forwardRef(
7512
+ Command = React21.forwardRef(
7509
7513
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
7510
7514
  "div",
7511
7515
  {
@@ -7516,7 +7520,7 @@ var init_command = __esm({
7516
7520
  )
7517
7521
  );
7518
7522
  Command.displayName = "Command";
7519
- CommandList = React20.forwardRef(
7523
+ CommandList = React21.forwardRef(
7520
7524
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
7521
7525
  "div",
7522
7526
  {
@@ -7527,7 +7531,7 @@ var init_command = __esm({
7527
7531
  )
7528
7532
  );
7529
7533
  CommandList.displayName = "CommandList";
7530
- CommandGroup = React20.forwardRef(
7534
+ CommandGroup = React21.forwardRef(
7531
7535
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
7532
7536
  "div",
7533
7537
  {
@@ -7538,7 +7542,7 @@ var init_command = __esm({
7538
7542
  )
7539
7543
  );
7540
7544
  CommandGroup.displayName = "CommandGroup";
7541
- CommandItem = React20.forwardRef(({ className, onSelect, ...props }, ref) => /* @__PURE__ */ jsx(
7545
+ CommandItem = React21.forwardRef(({ className, onSelect, ...props }, ref) => /* @__PURE__ */ jsx(
7542
7546
  "div",
7543
7547
  {
7544
7548
  ref,
@@ -7874,6 +7878,98 @@ var init_component_picker_menu_plugin = __esm({
7874
7878
  );
7875
7879
  }
7876
7880
  });
7881
+ var NumberInput;
7882
+ var init_number_input = __esm({
7883
+ "src/ui/number-input.tsx"() {
7884
+ "use client";
7885
+ init_utils();
7886
+ init_button();
7887
+ init_input();
7888
+ NumberInput = React21.forwardRef(
7889
+ ({ value, onValueChange, min = 0, max = 100, step = 1, unit = "px", className, ...props }, ref) => {
7890
+ const timerRef = React21.useRef(null);
7891
+ const intervalRef = React21.useRef(null);
7892
+ const valueRef = React21.useRef(value);
7893
+ React21.useEffect(() => {
7894
+ valueRef.current = value;
7895
+ }, [value]);
7896
+ const updateValue = React21.useCallback((delta) => {
7897
+ onValueChange(Math.min(Math.max(valueRef.current + delta, min), max));
7898
+ }, [onValueChange, min, max]);
7899
+ const startLongPress = (delta) => {
7900
+ updateValue(delta);
7901
+ timerRef.current = setTimeout(() => {
7902
+ intervalRef.current = setInterval(() => {
7903
+ updateValue(delta);
7904
+ }, 50);
7905
+ }, 300);
7906
+ };
7907
+ const stopLongPress = React21.useCallback(() => {
7908
+ if (timerRef.current) clearTimeout(timerRef.current);
7909
+ if (intervalRef.current) clearInterval(intervalRef.current);
7910
+ }, []);
7911
+ const handleBlur = () => {
7912
+ onValueChange(Math.min(Math.max(value, min), max));
7913
+ };
7914
+ React21.useEffect(() => {
7915
+ return () => stopLongPress();
7916
+ }, [stopLongPress]);
7917
+ return /* @__PURE__ */ jsxs("div", { className: cn("editor-number-input-container", className), children: [
7918
+ /* @__PURE__ */ jsx(
7919
+ Button,
7920
+ {
7921
+ variant: "ghost",
7922
+ size: "icon",
7923
+ className: "editor-number-input-btn",
7924
+ onMouseDown: () => startLongPress(-step),
7925
+ onMouseUp: stopLongPress,
7926
+ onMouseLeave: stopLongPress,
7927
+ onTouchStart: () => startLongPress(-step),
7928
+ onTouchEnd: stopLongPress,
7929
+ tabIndex: -1,
7930
+ children: /* @__PURE__ */ jsx(Minus, { size: 14 })
7931
+ }
7932
+ ),
7933
+ /* @__PURE__ */ jsxs("div", { className: "editor-number-input-wrapper", children: [
7934
+ /* @__PURE__ */ jsx(
7935
+ Input,
7936
+ {
7937
+ ...props,
7938
+ ref,
7939
+ type: "number",
7940
+ value,
7941
+ onBlur: handleBlur,
7942
+ onChange: (e) => {
7943
+ const val = parseInt(e.target.value, 10);
7944
+ if (!isNaN(val)) onValueChange(val);
7945
+ else onValueChange(0);
7946
+ },
7947
+ className: "editor-number-input-field"
7948
+ }
7949
+ ),
7950
+ unit && /* @__PURE__ */ jsx("span", { className: "editor-number-input-unit", children: unit })
7951
+ ] }),
7952
+ /* @__PURE__ */ jsx(
7953
+ Button,
7954
+ {
7955
+ variant: "ghost",
7956
+ size: "icon",
7957
+ className: "editor-number-input-btn",
7958
+ onMouseDown: () => startLongPress(step),
7959
+ onMouseUp: stopLongPress,
7960
+ onMouseLeave: stopLongPress,
7961
+ onTouchStart: () => startLongPress(step),
7962
+ onTouchEnd: stopLongPress,
7963
+ tabIndex: -1,
7964
+ children: /* @__PURE__ */ jsx(Plus, { size: 14 })
7965
+ }
7966
+ )
7967
+ ] });
7968
+ }
7969
+ );
7970
+ NumberInput.displayName = "NumberInput";
7971
+ }
7972
+ });
7877
7973
  var Slot;
7878
7974
  var init_slot = __esm({
7879
7975
  "src/ui/slot.tsx"() {
@@ -7881,11 +7977,11 @@ var init_slot = __esm({
7881
7977
  }
7882
7978
  });
7883
7979
  function Popover({ children, open: controlledOpen, defaultOpen = false, onOpenChange, modal = false }) {
7884
- const [uncontrolledOpen, setUncontrolledOpen] = React20.useState(defaultOpen);
7885
- const triggerRef = React20.useRef(null);
7980
+ const [uncontrolledOpen, setUncontrolledOpen] = React21.useState(defaultOpen);
7981
+ const triggerRef = React21.useRef(null);
7886
7982
  const open = controlledOpen ?? uncontrolledOpen;
7887
7983
  const setOpen = onOpenChange ?? setUncontrolledOpen;
7888
- const contextValue = React20.useMemo(() => ({
7984
+ const contextValue = React21.useMemo(() => ({
7889
7985
  open,
7890
7986
  setOpen,
7891
7987
  triggerRef,
@@ -7894,17 +7990,17 @@ function Popover({ children, open: controlledOpen, defaultOpen = false, onOpenCh
7894
7990
  return /* @__PURE__ */ jsx(PopoverContext.Provider, { value: contextValue, children });
7895
7991
  }
7896
7992
  function PopoverTrigger({ children, asChild, ...props }) {
7897
- const context = React20.useContext(PopoverContext);
7993
+ const context = React21.useContext(PopoverContext);
7898
7994
  if (!context) throw new Error("PopoverTrigger must be used within Popover");
7899
7995
  const { triggerRef, open, setOpen } = context;
7900
7996
  const handleClick = (e) => {
7901
7997
  setOpen(!open);
7902
- if (React20.isValidElement(children)) {
7998
+ if (React21.isValidElement(children)) {
7903
7999
  children.props.onClick?.(e);
7904
8000
  }
7905
8001
  };
7906
- if (asChild && React20.isValidElement(children)) {
7907
- return React20.cloneElement(children, {
8002
+ if (asChild && React21.isValidElement(children)) {
8003
+ return React21.cloneElement(children, {
7908
8004
  ref: triggerRef,
7909
8005
  onClick: handleClick,
7910
8006
  ...props
@@ -7922,10 +8018,10 @@ function PopoverTrigger({ children, asChild, ...props }) {
7922
8018
  );
7923
8019
  }
7924
8020
  function PopoverContent({ children, className, align = "center", sideOffset = 4, ...props }) {
7925
- const context = React20.useContext(PopoverContext);
7926
- const [position, setPosition] = React20.useState({ top: 0, left: 0 });
7927
- const contentRef = React20.useRef(null);
7928
- React20.useEffect(() => {
8021
+ const context = React21.useContext(PopoverContext);
8022
+ const [position, setPosition] = React21.useState({ top: 0, left: 0 });
8023
+ const contentRef = React21.useRef(null);
8024
+ React21.useEffect(() => {
7929
8025
  if (context?.open && context.triggerRef.current) {
7930
8026
  const rect = context.triggerRef.current.getBoundingClientRect();
7931
8027
  let left = rect.left;
@@ -7975,7 +8071,7 @@ var PopoverContext;
7975
8071
  var init_popover = __esm({
7976
8072
  "src/ui/popover.tsx"() {
7977
8073
  init_utils();
7978
- PopoverContext = React20.createContext(null);
8074
+ PopoverContext = React21.createContext(null);
7979
8075
  }
7980
8076
  });
7981
8077
  function setRef(ref, value) {
@@ -8011,7 +8107,7 @@ function composeRefs(...refs) {
8011
8107
  };
8012
8108
  }
8013
8109
  function useComposedRefs(...refs) {
8014
- return React20.useCallback(
8110
+ return React21.useCallback(
8015
8111
  (value) => {
8016
8112
  composeRefs(...refs)(value);
8017
8113
  },
@@ -8029,19 +8125,19 @@ function VisuallyHiddenInput(props) {
8029
8125
  style,
8030
8126
  ...inputProps
8031
8127
  } = props;
8032
- const isCheckInput = React20.useMemo(
8128
+ const isCheckInput = React21.useMemo(
8033
8129
  () => type === "checkbox" || type === "radio" || type === "switch",
8034
8130
  [type]
8035
8131
  );
8036
- const inputRef = React20.useRef(null);
8037
- const prevValueRef = React20.useRef({
8132
+ const inputRef = React21.useRef(null);
8133
+ const prevValueRef = React21.useRef({
8038
8134
  value: isCheckInput ? checked : value,
8039
8135
  previous: isCheckInput ? checked : value
8040
8136
  });
8041
- const [prevValue, setPrevValue] = React20.useState(
8137
+ const [prevValue, setPrevValue] = React21.useState(
8042
8138
  isCheckInput ? checked : value
8043
8139
  );
8044
- React20.useEffect(() => {
8140
+ React21.useEffect(() => {
8045
8141
  const currentValue = isCheckInput ? checked : value;
8046
8142
  if (prevValueRef.current.value !== currentValue) {
8047
8143
  prevValueRef.current.previous = prevValueRef.current.value;
@@ -8049,8 +8145,8 @@ function VisuallyHiddenInput(props) {
8049
8145
  setPrevValue(prevValueRef.current.previous);
8050
8146
  }
8051
8147
  }, [isCheckInput, value, checked]);
8052
- const [controlSize, setControlSize] = React20.useState({});
8053
- React20.useLayoutEffect(() => {
8148
+ const [controlSize, setControlSize] = React21.useState({});
8149
+ React21.useLayoutEffect(() => {
8054
8150
  if (!control) {
8055
8151
  setControlSize({});
8056
8152
  return;
@@ -8082,7 +8178,7 @@ function VisuallyHiddenInput(props) {
8082
8178
  resizeObserver.disconnect();
8083
8179
  };
8084
8180
  }, [control]);
8085
- React20.useEffect(() => {
8181
+ React21.useEffect(() => {
8086
8182
  const input = inputRef.current;
8087
8183
  if (!input) return;
8088
8184
  const inputProto = window.HTMLInputElement.prototype;
@@ -8098,7 +8194,7 @@ function VisuallyHiddenInput(props) {
8098
8194
  input.dispatchEvent(event);
8099
8195
  }
8100
8196
  }, [prevValue, value, checked, bubbles, isCheckInput]);
8101
- const composedStyle = React20.useMemo(() => {
8197
+ const composedStyle = React21.useMemo(() => {
8102
8198
  return {
8103
8199
  ...style,
8104
8200
  ...controlSize.width !== void 0 && controlSize.height !== void 0 ? controlSize : {},
@@ -8410,11 +8506,11 @@ function parseColorString(value) {
8410
8506
  return null;
8411
8507
  }
8412
8508
  function useDirection(dirProp) {
8413
- const contextDir = React20.useContext(DirectionContext);
8509
+ const contextDir = React21.useContext(DirectionContext);
8414
8510
  return dirProp ?? contextDir ?? "ltr";
8415
8511
  }
8416
8512
  function useLazyRef(fn) {
8417
- const ref = React20.useRef(null);
8513
+ const ref = React21.useRef(null);
8418
8514
  if (ref.current === null) {
8419
8515
  ref.current = fn();
8420
8516
  }
@@ -8488,7 +8584,7 @@ function createColorPickerStore(listenersRef, stateRef, callbacks) {
8488
8584
  return store;
8489
8585
  }
8490
8586
  function useColorPickerStoreContext(consumerName) {
8491
- const context = React20.useContext(ColorPickerStoreContext);
8587
+ const context = React21.useContext(ColorPickerStoreContext);
8492
8588
  if (!context) {
8493
8589
  throw new Error(
8494
8590
  `\`${consumerName}\` must be used within \`ColorPickerRoot\``
@@ -8498,14 +8594,14 @@ function useColorPickerStoreContext(consumerName) {
8498
8594
  }
8499
8595
  function useColorPickerStore(selector) {
8500
8596
  const store = useColorPickerStoreContext("useColorPickerStoreSelector");
8501
- const getSnapshot = React20.useCallback(
8597
+ const getSnapshot = React21.useCallback(
8502
8598
  () => selector(store.getState()),
8503
8599
  [store, selector]
8504
8600
  );
8505
- return React20.useSyncExternalStore(store.subscribe, getSnapshot, getSnapshot);
8601
+ return React21.useSyncExternalStore(store.subscribe, getSnapshot, getSnapshot);
8506
8602
  }
8507
8603
  function useColorPickerContext(consumerName) {
8508
- const context = React20.useContext(ColorPickerContext);
8604
+ const context = React21.useContext(ColorPickerContext);
8509
8605
  if (!context) {
8510
8606
  throw new Error(
8511
8607
  `\`${consumerName}\` must be used within \`ColorPickerRoot\``
@@ -8532,12 +8628,12 @@ function ColorPickerRootImpl(props) {
8532
8628
  } = props;
8533
8629
  const store = useColorPickerStoreContext("ColorPickerRootImpl");
8534
8630
  const dir = useDirection(dirProp);
8535
- const [formTrigger, setFormTrigger] = React20.useState(
8631
+ const [formTrigger, setFormTrigger] = React21.useState(
8536
8632
  null
8537
8633
  );
8538
8634
  const composedRef = useComposedRefs(ref, (node) => setFormTrigger(node));
8539
8635
  const isFormControl = formTrigger ? !!formTrigger.closest("form") : true;
8540
- React20.useEffect(() => {
8636
+ React21.useEffect(() => {
8541
8637
  if (valueProp !== void 0) {
8542
8638
  const color = parseColorString(valueProp);
8543
8639
  if (color) {
@@ -8547,12 +8643,12 @@ function ColorPickerRootImpl(props) {
8547
8643
  }
8548
8644
  }
8549
8645
  }, [valueProp, store]);
8550
- React20.useEffect(() => {
8646
+ React21.useEffect(() => {
8551
8647
  if (openProp !== void 0) {
8552
8648
  store.setOpen(openProp);
8553
8649
  }
8554
8650
  }, [openProp, store]);
8555
- const contextValue = React20.useMemo(
8651
+ const contextValue = React21.useMemo(
8556
8652
  () => ({
8557
8653
  dir,
8558
8654
  disabled,
@@ -8564,7 +8660,7 @@ function ColorPickerRootImpl(props) {
8564
8660
  );
8565
8661
  const value = useColorPickerStore((state) => rgbToHex(state.color));
8566
8662
  const open = useColorPickerStore((state) => state.open);
8567
- const onPopoverOpenChange = React20.useCallback(
8663
+ const onPopoverOpenChange = React21.useCallback(
8568
8664
  (newOpen) => {
8569
8665
  store.setOpen(newOpen);
8570
8666
  onOpenChange?.(newOpen);
@@ -8650,10 +8746,10 @@ function ColorPickerArea(props) {
8650
8746
  const context = useColorPickerContext("ColorPickerArea");
8651
8747
  const store = useColorPickerStoreContext("ColorPickerArea");
8652
8748
  const hsv = useColorPickerStore((state) => state.hsv);
8653
- const isDraggingRef = React20.useRef(false);
8654
- const areaRef = React20.useRef(null);
8749
+ const isDraggingRef = React21.useRef(false);
8750
+ const areaRef = React21.useRef(null);
8655
8751
  const composedRef = useComposedRefs(ref, areaRef);
8656
- const updateColorFromPosition = React20.useCallback(
8752
+ const updateColorFromPosition = React21.useCallback(
8657
8753
  (clientX, clientY) => {
8658
8754
  if (!areaRef.current) return;
8659
8755
  const rect = areaRef.current.getBoundingClientRect();
@@ -8670,7 +8766,7 @@ function ColorPickerArea(props) {
8670
8766
  },
8671
8767
  [hsv, store]
8672
8768
  );
8673
- const onPointerDown = React20.useCallback(
8769
+ const onPointerDown = React21.useCallback(
8674
8770
  (event) => {
8675
8771
  if (context.disabled) return;
8676
8772
  event.preventDefault();
@@ -8680,7 +8776,7 @@ function ColorPickerArea(props) {
8680
8776
  },
8681
8777
  [context.disabled, updateColorFromPosition]
8682
8778
  );
8683
- const onPointerMove = React20.useCallback(
8779
+ const onPointerMove = React21.useCallback(
8684
8780
  (event) => {
8685
8781
  if (isDraggingRef.current) {
8686
8782
  updateColorFromPosition(event.clientX, event.clientY);
@@ -8688,7 +8784,7 @@ function ColorPickerArea(props) {
8688
8784
  },
8689
8785
  [updateColorFromPosition]
8690
8786
  );
8691
- const onPointerUp = React20.useCallback((event) => {
8787
+ const onPointerUp = React21.useCallback((event) => {
8692
8788
  isDraggingRef.current = false;
8693
8789
  areaRef.current?.releasePointerCapture(event.pointerId);
8694
8790
  }, []);
@@ -8758,7 +8854,7 @@ function ColorPickerHueSlider(props) {
8758
8854
  const context = useColorPickerContext("ColorPickerHueSlider");
8759
8855
  const store = useColorPickerStoreContext("ColorPickerHueSlider");
8760
8856
  const hsv = useColorPickerStore((state) => state.hsv);
8761
- const onValueChange = React20.useCallback(
8857
+ const onValueChange = React21.useCallback(
8762
8858
  (values) => {
8763
8859
  const newHsv = {
8764
8860
  h: values[0] ?? 0,
@@ -8798,7 +8894,7 @@ function ColorPickerAlphaSlider(props) {
8798
8894
  const store = useColorPickerStoreContext("ColorPickerAlphaSlider");
8799
8895
  const color = useColorPickerStore((state) => state.color);
8800
8896
  const hsv = useColorPickerStore((state) => state.hsv);
8801
- const onValueChange = React20.useCallback(
8897
+ const onValueChange = React21.useCallback(
8802
8898
  (values) => {
8803
8899
  const alpha = (values[0] ?? 0) / 100;
8804
8900
  const newColor = { ...color, a: alpha };
@@ -8857,7 +8953,7 @@ function ColorPickerEyeDropper(props) {
8857
8953
  const context = useColorPickerContext("ColorPickerEyeDropper");
8858
8954
  const store = useColorPickerStoreContext("ColorPickerEyeDropper");
8859
8955
  const color = useColorPickerStore((state) => state.color);
8860
- const onEyeDropper = React20.useCallback(async () => {
8956
+ const onEyeDropper = React21.useCallback(async () => {
8861
8957
  if (!window.EyeDropper) return;
8862
8958
  try {
8863
8959
  const eyeDropper = new window.EyeDropper();
@@ -8894,7 +8990,7 @@ function ColorPickerFormatSelect(props) {
8894
8990
  const context = useColorPickerContext("ColorPickerFormatSelector");
8895
8991
  const store = useColorPickerStoreContext("ColorPickerFormatSelector");
8896
8992
  const format = useColorPickerStore((state) => state.format);
8897
- const onFormatChange = React20.useCallback(
8993
+ const onFormatChange = React21.useCallback(
8898
8994
  (value) => {
8899
8995
  if (colorFormats.includes(value)) {
8900
8996
  store.setFormat(value);
@@ -8931,7 +9027,7 @@ function ColorPickerInput(props) {
8931
9027
  const color = useColorPickerStore((state) => state.color);
8932
9028
  const format = useColorPickerStore((state) => state.format);
8933
9029
  const hsv = useColorPickerStore((state) => state.hsv);
8934
- const onColorChange = React20.useCallback(
9030
+ const onColorChange = React21.useCallback(
8935
9031
  (newColor) => {
8936
9032
  const newHsv = rgbToHsv(newColor);
8937
9033
  store.setColor(newColor);
@@ -9013,7 +9109,7 @@ function HexInput(props) {
9013
9109
  } = props;
9014
9110
  const hexValue = rgbToHex(color);
9015
9111
  const alphaValue = Math.round((color?.a ?? 1) * 100);
9016
- const onHexChange = React20.useCallback(
9112
+ const onHexChange = React21.useCallback(
9017
9113
  (event) => {
9018
9114
  const value = event.target.value;
9019
9115
  const parsedColor = parseColorString(value);
@@ -9023,7 +9119,7 @@ function HexInput(props) {
9023
9119
  },
9024
9120
  [color, onColorChange]
9025
9121
  );
9026
- const onAlphaChange = React20.useCallback(
9122
+ const onAlphaChange = React21.useCallback(
9027
9123
  (event) => {
9028
9124
  const value = Number.parseInt(event.target.value, 10);
9029
9125
  if (!Number.isNaN(value) && value >= 0 && value <= 100) {
@@ -9100,7 +9196,7 @@ function RgbInput(props) {
9100
9196
  const gValue = Math.round(color?.g ?? 0);
9101
9197
  const bValue = Math.round(color?.b ?? 0);
9102
9198
  const alphaValue = Math.round((color?.a ?? 1) * 100);
9103
- const onChannelChange = React20.useCallback(
9199
+ const onChannelChange = React21.useCallback(
9104
9200
  (channel, max, isAlpha = false) => (event) => {
9105
9201
  const value = Number.parseInt(event.target.value, 10);
9106
9202
  if (!Number.isNaN(value) && value >= 0 && value <= max) {
@@ -9197,9 +9293,9 @@ function HslInput(props) {
9197
9293
  className,
9198
9294
  ...inputProps
9199
9295
  } = props;
9200
- const hsl = React20.useMemo(() => rgbToHsl(color), [color]);
9296
+ const hsl = React21.useMemo(() => rgbToHsl(color), [color]);
9201
9297
  const alphaValue = Math.round((color?.a ?? 1) * 100);
9202
- const onHslChannelChange = React20.useCallback(
9298
+ const onHslChannelChange = React21.useCallback(
9203
9299
  (channel, max) => (event) => {
9204
9300
  const value = Number.parseInt(event.target.value, 10);
9205
9301
  if (!Number.isNaN(value) && value >= 0 && value <= max) {
@@ -9210,7 +9306,7 @@ function HslInput(props) {
9210
9306
  },
9211
9307
  [hsl, color, onColorChange]
9212
9308
  );
9213
- const onAlphaChange = React20.useCallback(
9309
+ const onAlphaChange = React21.useCallback(
9214
9310
  (event) => {
9215
9311
  const value = Number.parseInt(event.target.value, 10);
9216
9312
  if (!Number.isNaN(value) && value >= 0 && value <= 100) {
@@ -9307,7 +9403,7 @@ function HsbInput(props) {
9307
9403
  ...inputProps
9308
9404
  } = props;
9309
9405
  const alphaValue = Math.round((hsv?.a ?? 1) * 100);
9310
- const onHsvChannelChange = React20.useCallback(
9406
+ const onHsvChannelChange = React21.useCallback(
9311
9407
  (channel, max) => (event) => {
9312
9408
  const value = Number.parseInt(event.target.value, 10);
9313
9409
  if (!Number.isNaN(value) && value >= 0 && value <= max) {
@@ -9318,7 +9414,7 @@ function HsbInput(props) {
9318
9414
  },
9319
9415
  [hsv, onColorChange]
9320
9416
  );
9321
- const onAlphaChange = React20.useCallback(
9417
+ const onAlphaChange = React21.useCallback(
9322
9418
  (event) => {
9323
9419
  const value = Number.parseInt(event.target.value, 10);
9324
9420
  if (!Number.isNaN(value) && value >= 0 && value <= 100) {
@@ -9411,7 +9507,7 @@ function ColorPickerPresets(props) {
9411
9507
  const context = useColorPickerContext("ColorPickerPresets");
9412
9508
  const store = useColorPickerStoreContext("ColorPickerPresets");
9413
9509
  const color = useColorPickerStore((state) => state.color);
9414
- const onPresetClick = React20.useCallback(
9510
+ const onPresetClick = React21.useCallback(
9415
9511
  (hex, alpha) => {
9416
9512
  const nextAlpha = alpha ?? (color?.a ?? 1);
9417
9513
  const newColor = hexToRgb(hex, nextAlpha);
@@ -9472,14 +9568,14 @@ var init_color_picker = __esm({
9472
9568
  // --muted in light theme is #F5F5F5, /50 -> alpha 0.5
9473
9569
  { label: "bg-muted/50", value: "#F5F5F5", alpha: 0.5 }
9474
9570
  ];
9475
- DirectionContext = React20.createContext(void 0);
9476
- ColorPickerStoreContext = React20.createContext(
9571
+ DirectionContext = React21.createContext(void 0);
9572
+ ColorPickerStoreContext = React21.createContext(
9477
9573
  null
9478
9574
  );
9479
- ColorPickerContext = React20.createContext(
9575
+ ColorPickerContext = React21.createContext(
9480
9576
  null
9481
9577
  );
9482
- ColorPickerRoot = React20.memo(function ColorPickerRoot2(props) {
9578
+ ColorPickerRoot = React21.memo(function ColorPickerRoot2(props) {
9483
9579
  const {
9484
9580
  value: valueProp,
9485
9581
  defaultValue = "#000000",
@@ -9497,7 +9593,7 @@ var init_color_picker = __esm({
9497
9593
  required,
9498
9594
  ...rootProps
9499
9595
  } = props;
9500
- const initialColor = React20.useMemo(() => {
9596
+ const initialColor = React21.useMemo(() => {
9501
9597
  const colorString = valueProp ?? defaultValue;
9502
9598
  const color = parseColorString(colorString) ?? hexToRgb(defaultValue);
9503
9599
  return {
@@ -9516,7 +9612,7 @@ var init_color_picker = __esm({
9516
9612
  ]);
9517
9613
  const stateRef = useLazyRef(() => initialColor);
9518
9614
  const listenersRef = useLazyRef(() => /* @__PURE__ */ new Set());
9519
- const storeCallbacks = React20.useMemo(
9615
+ const storeCallbacks = React21.useMemo(
9520
9616
  () => ({
9521
9617
  onColorChange: onValueChange,
9522
9618
  onOpenChange,
@@ -9524,7 +9620,7 @@ var init_color_picker = __esm({
9524
9620
  }),
9525
9621
  [onValueChange, onOpenChange, onFormatChange]
9526
9622
  );
9527
- const store = React20.useMemo(
9623
+ const store = React21.useMemo(
9528
9624
  () => createColorPickerStore(listenersRef, stateRef, storeCallbacks),
9529
9625
  [listenersRef, stateRef, storeCallbacks]
9530
9626
  );
@@ -9557,13 +9653,15 @@ function InsertLayoutDialog({
9557
9653
  const [backgroundColor, setBackgroundColor] = useState(
9558
9654
  initialValues?.itemBackgroundColor ?? "#ffffff"
9559
9655
  );
9560
- const [paddingPx, setPaddingPx] = useState(initialValues?.itemPaddingPx ?? 12);
9656
+ const [paddingXPx, setPaddingXPx] = useState(initialValues?.itemPaddingXPx ?? 12);
9657
+ const [paddingYPx, setPaddingYPx] = useState(initialValues?.itemPaddingYPx ?? 12);
9561
9658
  const [borderRadiusPx, setBorderRadiusPx] = useState(
9562
9659
  initialValues?.itemBorderRadiusPx ?? 8
9563
9660
  );
9564
9661
  const layoutRef = useRef(layout);
9565
9662
  const backgroundColorRef = useRef(backgroundColor);
9566
- const paddingPxRef = useRef(paddingPx);
9663
+ const paddingXPxRef = useRef(paddingXPx);
9664
+ const paddingYPxRef = useRef(paddingYPx);
9567
9665
  const borderRadiusPxRef = useRef(borderRadiusPx);
9568
9666
  useEffect(() => {
9569
9667
  layoutRef.current = layout;
@@ -9572,8 +9670,11 @@ function InsertLayoutDialog({
9572
9670
  backgroundColorRef.current = backgroundColor;
9573
9671
  }, [backgroundColor]);
9574
9672
  useEffect(() => {
9575
- paddingPxRef.current = paddingPx;
9576
- }, [paddingPx]);
9673
+ paddingXPxRef.current = paddingXPx;
9674
+ }, [paddingXPx]);
9675
+ useEffect(() => {
9676
+ paddingYPxRef.current = paddingYPx;
9677
+ }, [paddingYPx]);
9577
9678
  useEffect(() => {
9578
9679
  borderRadiusPxRef.current = borderRadiusPx;
9579
9680
  }, [borderRadiusPx]);
@@ -9581,10 +9682,15 @@ function InsertLayoutDialog({
9581
9682
  backgroundColorRef.current = value;
9582
9683
  setBackgroundColor(value);
9583
9684
  };
9584
- const onPaddingChange = (next) => {
9685
+ const onPaddingXChange = (next) => {
9686
+ const value = Math.min(Math.max(next, 0), 64);
9687
+ paddingXPxRef.current = value;
9688
+ setPaddingXPx(value);
9689
+ };
9690
+ const onPaddingYChange = (next) => {
9585
9691
  const value = Math.min(Math.max(next, 0), 64);
9586
- paddingPxRef.current = value;
9587
- setPaddingPx(value);
9692
+ paddingYPxRef.current = value;
9693
+ setPaddingYPx(value);
9588
9694
  };
9589
9695
  const onBorderRadiusChange = (next) => {
9590
9696
  const value = Math.min(Math.max(next, 0), 64);
@@ -9596,7 +9702,8 @@ function InsertLayoutDialog({
9596
9702
  const values = {
9597
9703
  template: layoutRef.current,
9598
9704
  itemBackgroundColor: backgroundColorRef.current,
9599
- itemPaddingPx: paddingPxRef.current,
9705
+ itemPaddingXPx: paddingXPxRef.current,
9706
+ itemPaddingYPx: paddingYPxRef.current,
9600
9707
  itemBorderRadiusPx: borderRadiusPxRef.current
9601
9708
  };
9602
9709
  logger.info("[Layout] Submit dialog values", {
@@ -9611,13 +9718,13 @@ function InsertLayoutDialog({
9611
9718
  activeEditor.dispatchCommand(INSERT_LAYOUT_COMMAND, values);
9612
9719
  onClose();
9613
9720
  };
9614
- return /* @__PURE__ */ jsxs(Fragment, { children: [
9721
+ return /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 4, children: [
9615
9722
  /* @__PURE__ */ jsxs(Select, { onValueChange: setLayout, value: layout, children: [
9616
9723
  /* @__PURE__ */ jsx(SelectTrigger, { className: "editor-input-lg editor-w-full", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: buttonLabel }) }),
9617
9724
  /* @__PURE__ */ jsx(SelectContent, { className: "editor-w-full", children: LAYOUTS.map(({ label, value }) => /* @__PURE__ */ jsx(SelectItem, { value, children: label }, value)) })
9618
9725
  ] }),
9619
9726
  /* @__PURE__ */ jsxs("div", { className: "editor-layout-dialog-grid", children: [
9620
- /* @__PURE__ */ jsxs("div", { className: "editor-layout-dialog-group", children: [
9727
+ /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 1.5, children: [
9621
9728
  /* @__PURE__ */ jsx("div", { className: "editor-text-xs-muted", children: "Background" }),
9622
9729
  /* @__PURE__ */ jsxs(
9623
9730
  ColorPickerRoot,
@@ -9663,47 +9770,39 @@ function InsertLayoutDialog({
9663
9770
  }
9664
9771
  )
9665
9772
  ] }),
9666
- /* @__PURE__ */ jsxs("div", { className: "editor-layout-dialog-group", children: [
9667
- /* @__PURE__ */ jsx("div", { className: "editor-text-xs-muted", children: "Padding (px)" }),
9773
+ /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 1.5, children: [
9774
+ /* @__PURE__ */ jsx("div", { className: "editor-text-xs-muted", children: "Padding X (px)" }),
9668
9775
  /* @__PURE__ */ jsx(
9669
- Input,
9776
+ NumberInput,
9670
9777
  {
9671
- type: "number",
9672
9778
  min: 0,
9673
9779
  max: 64,
9674
- step: 1,
9675
- value: paddingPx,
9676
- onChange: (event) => {
9677
- const next = Number.parseInt(event.target.value, 10);
9678
- if (Number.isFinite(next)) {
9679
- onPaddingChange(next);
9680
- } else {
9681
- onPaddingChange(0);
9682
- }
9683
- },
9684
- className: "editor-input-lg editor-w-full"
9780
+ value: paddingXPx,
9781
+ onValueChange: onPaddingXChange
9782
+ }
9783
+ )
9784
+ ] }),
9785
+ /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 1.5, children: [
9786
+ /* @__PURE__ */ jsx("div", { className: "editor-text-xs-muted", children: "Padding Y (px)" }),
9787
+ /* @__PURE__ */ jsx(
9788
+ NumberInput,
9789
+ {
9790
+ min: 0,
9791
+ max: 64,
9792
+ value: paddingYPx,
9793
+ onValueChange: onPaddingYChange
9685
9794
  }
9686
9795
  )
9687
9796
  ] }),
9688
- /* @__PURE__ */ jsxs("div", { className: "editor-layout-dialog-group", children: [
9797
+ /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 1.5, children: [
9689
9798
  /* @__PURE__ */ jsx("div", { className: "editor-text-xs-muted", children: "Border radius (px)" }),
9690
9799
  /* @__PURE__ */ jsx(
9691
- Input,
9800
+ NumberInput,
9692
9801
  {
9693
- type: "number",
9694
9802
  min: 0,
9695
9803
  max: 64,
9696
- step: 1,
9697
9804
  value: borderRadiusPx,
9698
- onChange: (event) => {
9699
- const next = Number.parseInt(event.target.value, 10);
9700
- if (Number.isFinite(next)) {
9701
- onBorderRadiusChange(next);
9702
- } else {
9703
- onBorderRadiusChange(0);
9704
- }
9705
- },
9706
- className: "editor-input-lg editor-w-full"
9805
+ onValueChange: onBorderRadiusChange
9707
9806
  }
9708
9807
  )
9709
9808
  ] })
@@ -9754,23 +9853,32 @@ function LayoutPlugin() {
9754
9853
  if (!value) {
9755
9854
  return void 0;
9756
9855
  }
9757
- const match = value.match(/^(\d+)px$/i);
9758
- if (!match?.[1]) {
9759
- return void 0;
9760
- }
9761
- const parsed = Number.parseInt(match[1], 10);
9762
- return Number.isFinite(parsed) ? parsed : void 0;
9856
+ const values = value.replace(/!important/gi, "").trim().split(/\s+/);
9857
+ const parsedValues = values.map((v) => {
9858
+ const match = v.match(/^(\d+)px/i);
9859
+ if (!match?.[1]) return null;
9860
+ const parsed = Number.parseInt(match[1], 10);
9861
+ return Number.isFinite(parsed) ? parsed : null;
9862
+ }).filter((v) => v !== null);
9863
+ if (parsedValues.length === 0) return void 0;
9864
+ return parsedValues;
9763
9865
  };
9764
9866
  const buildLayoutItemStyle = ({
9765
9867
  itemBackgroundColor,
9766
- itemPaddingPx,
9868
+ itemPaddingXPx,
9869
+ itemPaddingYPx,
9767
9870
  itemBorderRadiusPx
9768
9871
  }) => {
9769
9872
  const itemStyles = [];
9770
9873
  if (itemBackgroundColor.trim()) {
9771
9874
  itemStyles.push(`background-color: ${itemBackgroundColor.trim()}`);
9772
9875
  }
9773
- itemStyles.push(`padding: ${Math.min(Math.max(itemPaddingPx, 0), 64)}px`);
9876
+ itemStyles.push(
9877
+ `padding: ${Math.min(Math.max(itemPaddingYPx, 0), 64)}px ${Math.min(
9878
+ Math.max(itemPaddingXPx, 0),
9879
+ 64
9880
+ )}px`
9881
+ );
9774
9882
  itemStyles.push(
9775
9883
  `border-radius: ${Math.min(Math.max(itemBorderRadiusPx, 0), 64)}px`
9776
9884
  );
@@ -9783,7 +9891,10 @@ function LayoutPlugin() {
9783
9891
  return;
9784
9892
  }
9785
9893
  const background = values.itemBackgroundColor.trim();
9786
- const padding = `${Math.min(Math.max(values.itemPaddingPx, 0), 64)}px`;
9894
+ const padding = `${Math.min(Math.max(values.itemPaddingYPx, 0), 64)}px ${Math.min(
9895
+ Math.max(values.itemPaddingXPx, 0),
9896
+ 64
9897
+ )}px`;
9787
9898
  const borderRadius = `${Math.min(Math.max(values.itemBorderRadiusPx, 0), 64)}px`;
9788
9899
  if (background) {
9789
9900
  element.style.setProperty("background-color", background);
@@ -9834,14 +9945,17 @@ function LayoutPlugin() {
9834
9945
  return;
9835
9946
  }
9836
9947
  const style = layoutItem.getStyle();
9948
+ const paddingValues = extractNumericStyle(style, "padding");
9949
+ const borderRadiusValues = extractNumericStyle(style, "border-radius");
9837
9950
  payload = {
9838
9951
  containerKey: parentContainer.getKey(),
9839
9952
  layoutItemKey: layoutItem.getKey(),
9840
9953
  values: {
9841
9954
  template: parentContainer.getTemplateColumns(),
9842
9955
  itemBackgroundColor: extractStyleValue(style, "background-color") ?? "#ffffff",
9843
- itemPaddingPx: extractNumericStyle(style, "padding") ?? 12,
9844
- itemBorderRadiusPx: extractNumericStyle(style, "border-radius") ?? 8
9956
+ itemPaddingXPx: paddingValues && paddingValues.length > 1 ? paddingValues[1] : paddingValues?.[0] ?? 12,
9957
+ itemPaddingYPx: paddingValues?.[0] ?? 12,
9958
+ itemBorderRadiusPx: borderRadiusValues?.[0] ?? 8
9845
9959
  }
9846
9960
  };
9847
9961
  logger.debug("[Layout] Resolved payload from target", payload);
@@ -9954,11 +10068,13 @@ function LayoutPlugin() {
9954
10068
  editor.update(() => {
9955
10069
  const template = typeof payload === "string" ? payload : payload.template;
9956
10070
  const itemBackgroundColor = typeof payload === "string" ? void 0 : payload.itemBackgroundColor?.trim();
9957
- const itemPaddingPx = typeof payload === "string" ? void 0 : typeof payload.itemPaddingPx === "number" && Number.isFinite(payload.itemPaddingPx) ? Math.min(Math.max(payload.itemPaddingPx, 0), 64) : void 0;
10071
+ const itemPaddingXPx = typeof payload === "string" ? void 0 : typeof payload.itemPaddingXPx === "number" && Number.isFinite(payload.itemPaddingXPx) ? Math.min(Math.max(payload.itemPaddingXPx, 0), 64) : void 0;
10072
+ const itemPaddingYPx = typeof payload === "string" ? void 0 : typeof payload.itemPaddingYPx === "number" && Number.isFinite(payload.itemPaddingYPx) ? Math.min(Math.max(payload.itemPaddingYPx, 0), 64) : void 0;
9958
10073
  const itemBorderRadiusPx = typeof payload === "string" ? void 0 : typeof payload.itemBorderRadiusPx === "number" && Number.isFinite(payload.itemBorderRadiusPx) ? Math.min(Math.max(payload.itemBorderRadiusPx, 0), 64) : void 0;
9959
10074
  const itemStyle = buildLayoutItemStyle({
9960
10075
  itemBackgroundColor: itemBackgroundColor ?? "#ffffff",
9961
- itemPaddingPx: itemPaddingPx ?? 12,
10076
+ itemPaddingXPx: itemPaddingXPx ?? 12,
10077
+ itemPaddingYPx: itemPaddingYPx ?? 12,
9962
10078
  itemBorderRadiusPx: itemBorderRadiusPx ?? 8
9963
10079
  });
9964
10080
  const container = $createLayoutContainerNode(template);
@@ -10029,9 +10145,9 @@ var init_layout_plugin = __esm({
10029
10145
  init_layout_container_node();
10030
10146
  init_layout_item_node();
10031
10147
  init_button();
10148
+ init_number_input();
10032
10149
  init_select();
10033
10150
  init_color_picker();
10034
- init_input();
10035
10151
  init_flex();
10036
10152
  init_use_modal();
10037
10153
  init_logger();
@@ -10068,7 +10184,7 @@ function applyListColor(editor) {
10068
10184
  function ListColorPlugin() {
10069
10185
  const [editor] = useLexicalComposerContext();
10070
10186
  const [modal, showModal] = useEditorModal();
10071
- React20.useEffect(() => {
10187
+ React21.useEffect(() => {
10072
10188
  const applyColor = (color, listKey) => {
10073
10189
  listColorStore.set(listKey, color);
10074
10190
  editor.update(() => {
@@ -10114,7 +10230,7 @@ function ListColorPlugin() {
10114
10230
  const fromAttr = listEl.getAttribute("data-list-color");
10115
10231
  const initialColor = fromStore || fromVar || fromAttr || "#000000";
10116
10232
  function ListColorModalContent({ onClose }) {
10117
- const [color, setColor] = React20.useState(initialColor);
10233
+ const [color, setColor] = React21.useState(initialColor);
10118
10234
  return /* @__PURE__ */ jsx("div", { className: "editor-list-color-dialog", children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 4, children: [
10119
10235
  /* @__PURE__ */ jsx("div", { className: "editor-text-xs-muted", children: "Ch\u1ECDn m\xE0u cho bullet ho\u1EB7c s\u1ED1 th\u1EE9 t\u1EF1 c\u1EE7a list." }),
10120
10236
  /* @__PURE__ */ jsx(
@@ -28570,10 +28686,10 @@ var ToggleGroupContext, ToggleGroup, ToggleGroupItem;
28570
28686
  var init_toggle_group = __esm({
28571
28687
  "src/ui/toggle-group.tsx"() {
28572
28688
  init_utils();
28573
- ToggleGroupContext = React20.createContext(null);
28574
- ToggleGroup = React20.forwardRef(
28689
+ ToggleGroupContext = React21.createContext(null);
28690
+ ToggleGroup = React21.forwardRef(
28575
28691
  ({ className, type = "single", value, onValueChange, children, size, variant, ...props }, ref) => {
28576
- const contextValue = React20.useMemo(() => ({
28692
+ const contextValue = React21.useMemo(() => ({
28577
28693
  type,
28578
28694
  value: value || (type === "multiple" ? [] : ""),
28579
28695
  onValueChange: (val) => {
@@ -28590,8 +28706,8 @@ var init_toggle_group = __esm({
28590
28706
  }
28591
28707
  );
28592
28708
  ToggleGroup.displayName = "ToggleGroup";
28593
- ToggleGroupItem = React20.forwardRef(({ className, value, onClick, size: itemSize, variant: itemVariant, ...props }, ref) => {
28594
- const context = React20.useContext(ToggleGroupContext);
28709
+ ToggleGroupItem = React21.forwardRef(({ className, value, onClick, size: itemSize, variant: itemVariant, ...props }, ref) => {
28710
+ const context = React21.useContext(ToggleGroupContext);
28595
28711
  const size = itemSize || context?.size || "default";
28596
28712
  if (!context) {
28597
28713
  return /* @__PURE__ */ jsx(
@@ -32187,7 +32303,7 @@ var Toggle;
32187
32303
  var init_toggle = __esm({
32188
32304
  "src/ui/toggle.tsx"() {
32189
32305
  init_utils();
32190
- Toggle = React20.forwardRef(({ className, pressed, onPressedChange, variant = "default", size = "default", ...props }, ref) => /* @__PURE__ */ jsx(
32306
+ Toggle = React21.forwardRef(({ className, pressed, onPressedChange, variant = "default", size = "default", ...props }, ref) => /* @__PURE__ */ jsx(
32191
32307
  "button",
32192
32308
  {
32193
32309
  ref,
@@ -32839,7 +32955,8 @@ __export(plugins_exports, {
32839
32955
  Plugins: () => Plugins
32840
32956
  });
32841
32957
  function Plugins({
32842
- readOnly = false
32958
+ readOnly = false,
32959
+ placeholder = ""
32843
32960
  }) {
32844
32961
  const [floatingAnchorElem, setFloatingAnchorElem] = useState(null);
32845
32962
  const [isLinkEditMode, setIsLinkEditMode] = useState(false);
@@ -33047,9 +33164,9 @@ function Plugins({
33047
33164
  ] })
33048
33165
  ] }),
33049
33166
  !readOnly && /* @__PURE__ */ jsx(ActionsPlugin, { children: /* @__PURE__ */ jsxs("div", { className: "editor-actions-bar", children: [
33050
- /* @__PURE__ */ jsx("div", { className: "editor-flex-shrink-0", children: /* @__PURE__ */ jsx(CounterCharacterPlugin, { charset: "UTF-16" }) }),
33167
+ /* @__PURE__ */ jsx(Flex, { align: "center", className: "editor-flex-shrink-0", children: /* @__PURE__ */ jsx(CounterCharacterPlugin, { charset: "UTF-16" }) }),
33051
33168
  /* @__PURE__ */ jsx("div", { className: "editor-flex-1" }),
33052
- /* @__PURE__ */ jsxs("div", { className: "editor-flex-shrink-0 editor-flex-end", children: [
33169
+ /* @__PURE__ */ jsxs(Flex, { align: "center", justify: "end", gap: 1, wrap: "nowrap", className: "editor-flex-shrink-0", children: [
33053
33170
  /* @__PURE__ */ jsx(SpeechToTextPlugin, {}),
33054
33171
  /* @__PURE__ */ jsx(ShareContentPlugin, {}),
33055
33172
  /* @__PURE__ */ jsx(ImportExportPlugin, {}),
@@ -33079,7 +33196,6 @@ function Plugins({
33079
33196
  ] }) })
33080
33197
  ] });
33081
33198
  }
33082
- var placeholder;
33083
33199
  var init_plugins = __esm({
33084
33200
  "src/editor-x/plugins.tsx"() {
33085
33201
  "use client";
@@ -33168,7 +33284,7 @@ var init_plugins = __esm({
33168
33284
  init_markdown_tweet_transformer();
33169
33285
  init_markdown_list_transformer();
33170
33286
  init_separator();
33171
- placeholder = "Press / for commands...";
33287
+ init_flex();
33172
33288
  }
33173
33289
  });
33174
33290
 
@@ -33312,7 +33428,8 @@ function Editor({
33312
33428
  editorSerializedState,
33313
33429
  onChange,
33314
33430
  onSerializedChange,
33315
- readOnly = false
33431
+ readOnly = false,
33432
+ placeholder = ""
33316
33433
  }) {
33317
33434
  const { ref: editorRef, width: editorWidth } = useElementSize();
33318
33435
  const editorMaxWidth = editorWidth || void 0;
@@ -33366,7 +33483,7 @@ function Editor({
33366
33483
  ...editorSerializedState ? { editorState: JSON.stringify(editorSerializedState) } : {}
33367
33484
  },
33368
33485
  children: /* @__PURE__ */ jsxs(TooltipProvider, { children: [
33369
- /* @__PURE__ */ jsx(Plugins2, { readOnly }),
33486
+ /* @__PURE__ */ jsx(Plugins2, { readOnly, placeholder }),
33370
33487
  !readOnly && /* @__PURE__ */ jsx(
33371
33488
  OnChangePlugin,
33372
33489
  {
@@ -33391,7 +33508,8 @@ function LexicalEditor11({
33391
33508
  value,
33392
33509
  onChange,
33393
33510
  readOnly = false,
33394
- className
33511
+ className,
33512
+ placeholder = ""
33395
33513
  }) {
33396
33514
  const [editorState, setEditorState] = useState(() => {
33397
33515
  if (value && typeof value === "object" && value !== null) {
@@ -33466,7 +33584,8 @@ function LexicalEditor11({
33466
33584
  {
33467
33585
  editorSerializedState: editorState,
33468
33586
  onSerializedChange: handleSerializedChange,
33469
- readOnly
33587
+ readOnly,
33588
+ placeholder
33470
33589
  }
33471
33590
  ) });
33472
33591
  }