@postxl/ui-components 1.6.3 → 1.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -4660,6 +4660,60 @@ function isValidJson(str) {
4660
4660
  return false;
4661
4661
  }
4662
4662
  }
4663
+ function JsonEditorWithLineNumbers({ value, onChange, onSave }) {
4664
+ const textareaRef = React$31.useRef(null);
4665
+ const gutterRef = React$31.useRef(null);
4666
+ const lineCount = React$31.useMemo(() => {
4667
+ if (!value) return 1;
4668
+ return value.split("\n").length;
4669
+ }, [value]);
4670
+ const gutterMinWidth = React$31.useMemo(() => {
4671
+ const digits = String(lineCount).length;
4672
+ return `calc(${digits}ch + 16px)`;
4673
+ }, [lineCount]);
4674
+ const onScroll = React$31.useCallback(() => {
4675
+ if (textareaRef.current && gutterRef.current) gutterRef.current.scrollTop = textareaRef.current.scrollTop;
4676
+ }, []);
4677
+ const onKeyDown = React$31.useCallback((e) => {
4678
+ if (e.key === "Tab") {
4679
+ e.preventDefault();
4680
+ const textarea = e.currentTarget;
4681
+ const start = textarea.selectionStart;
4682
+ const end = textarea.selectionEnd;
4683
+ const newValue = value.substring(0, start) + " " + value.substring(end);
4684
+ onChange(newValue);
4685
+ requestAnimationFrame(() => {
4686
+ textarea.selectionStart = textarea.selectionEnd = start + 2;
4687
+ });
4688
+ }
4689
+ if (e.key === "s" && (e.metaKey || e.ctrlKey)) {
4690
+ e.preventDefault();
4691
+ onSave?.();
4692
+ }
4693
+ }, [
4694
+ value,
4695
+ onChange,
4696
+ onSave
4697
+ ]);
4698
+ return /* @__PURE__ */ jsxs("div", {
4699
+ className: "relative flex min-h-[200px] max-h-[50vh] rounded-md border border-input overflow-hidden",
4700
+ children: [/* @__PURE__ */ jsx("div", {
4701
+ ref: gutterRef,
4702
+ "aria-hidden": "true",
4703
+ style: { minWidth: gutterMinWidth },
4704
+ className: "shrink-0 overflow-hidden bg-muted px-2 py-2 text-right font-mono text-sm leading-[1.43] text-muted-foreground select-none border-r border-input",
4705
+ children: Array.from({ length: lineCount }, (_, i) => /* @__PURE__ */ jsx("div", { children: i + 1 }, i))
4706
+ }), /* @__PURE__ */ jsx("textarea", {
4707
+ ref: textareaRef,
4708
+ value,
4709
+ onChange: (e) => onChange(e.target.value),
4710
+ onKeyDown,
4711
+ onScroll,
4712
+ className: "flex-1 resize-none bg-transparent p-2 font-mono text-sm leading-[1.43] outline-none",
4713
+ spellCheck: false
4714
+ })]
4715
+ });
4716
+ }
4663
4717
  function JsonCell({ cell, table, rowIndex, columnId, isFocused, isSelected }) {
4664
4718
  const rawValue = cell.getValue();
4665
4719
  const [dialogOpen, setDialogOpen] = React$31.useState(false);
@@ -4778,11 +4832,10 @@ function JsonCell({ cell, table, rowIndex, columnId, isFocused, isSelected }) {
4778
4832
  className: "max-w-2xl max-h-[80vh]",
4779
4833
  children: [
4780
4834
  /* @__PURE__ */ jsx(DialogHeader, { children: /* @__PURE__ */ jsxs(DialogTitle, { children: [headerLabel, " (JSON)"] }) }),
4781
- /* @__PURE__ */ jsx(Textarea, {
4835
+ /* @__PURE__ */ jsx(JsonEditorWithLineNumbers, {
4782
4836
  value: editValue,
4783
- onChange: (e) => setEditValue(e.target.value),
4784
- className: "min-h-[200px] max-h-[50vh] font-mono text-sm resize-y",
4785
- spellCheck: false
4837
+ onChange: setEditValue,
4838
+ onSave
4786
4839
  }),
4787
4840
  jsonParseError && /* @__PURE__ */ jsx("p", {
4788
4841
  className: "text-sm text-destructive",