@skygraph/react 0.5.2 → 0.5.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.
Files changed (51) hide show
  1. package/README.md +70 -70
  2. package/dist/{Table-BmesoMje.d.ts → Table-CAay8MmA.d.ts} +8 -1
  3. package/dist/{Table-CpKMOH2x.d.cts → Table-CMKo6Pc3.d.cts} +8 -1
  4. package/dist/{chunk-ZJF6SJLP.js → chunk-45YW5VSP.js} +44 -10
  5. package/dist/chunk-45YW5VSP.js.map +1 -0
  6. package/dist/{chunk-NXB3VAVF.js → chunk-7AA2JPZB.js} +148 -61
  7. package/dist/chunk-7AA2JPZB.js.map +1 -0
  8. package/dist/{chunk-Z5UGF7EO.js → chunk-EFDB2ENB.js} +87 -25
  9. package/dist/chunk-EFDB2ENB.js.map +1 -0
  10. package/dist/{chunk-UO6VJC3C.js → chunk-KGFFQGCM.js} +3 -3
  11. package/dist/{chunk-FSV73JI4.js → chunk-PEX2UTNG.js} +2 -2
  12. package/dist/chunk-VLRLCHEL.js +184 -0
  13. package/dist/chunk-VLRLCHEL.js.map +1 -0
  14. package/dist/{chunk-MLEBVELO.js → chunk-Y6XZ5TLD.js} +93 -47
  15. package/dist/chunk-Y6XZ5TLD.js.map +1 -0
  16. package/dist/{chunk-GJDDPZH7.js → chunk-ZJC2QUWA.js} +12 -12
  17. package/dist/chunk-ZJC2QUWA.js.map +1 -0
  18. package/dist/datagrid.cjs +76 -21
  19. package/dist/datagrid.cjs.map +1 -1
  20. package/dist/datagrid.js +3 -3
  21. package/dist/devtools.cjs +11 -11
  22. package/dist/devtools.cjs.map +1 -1
  23. package/dist/devtools.js +1 -1
  24. package/dist/form.cjs +168 -86
  25. package/dist/form.cjs.map +1 -1
  26. package/dist/form.d.cts +1 -1
  27. package/dist/form.d.ts +1 -1
  28. package/dist/form.js +3 -3
  29. package/dist/index.cjs +1549 -1021
  30. package/dist/index.cjs.map +1 -1
  31. package/dist/index.d.cts +157 -7
  32. package/dist/index.d.ts +157 -7
  33. package/dist/index.js +444 -231
  34. package/dist/index.js.map +1 -1
  35. package/dist/table.cjs +344 -221
  36. package/dist/table.cjs.map +1 -1
  37. package/dist/table.d.cts +1 -1
  38. package/dist/table.d.ts +1 -1
  39. package/dist/table.js +4 -4
  40. package/dist/tree.cjs.map +1 -1
  41. package/dist/tree.js +3 -3
  42. package/package.json +2 -2
  43. package/dist/chunk-2OCEO636.js +0 -91
  44. package/dist/chunk-2OCEO636.js.map +0 -1
  45. package/dist/chunk-GJDDPZH7.js.map +0 -1
  46. package/dist/chunk-MLEBVELO.js.map +0 -1
  47. package/dist/chunk-NXB3VAVF.js.map +0 -1
  48. package/dist/chunk-Z5UGF7EO.js.map +0 -1
  49. package/dist/chunk-ZJF6SJLP.js.map +0 -1
  50. /package/dist/{chunk-UO6VJC3C.js.map → chunk-KGFFQGCM.js.map} +0 -0
  51. /package/dist/{chunk-FSV73JI4.js.map → chunk-PEX2UTNG.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/devtools.ts","../src/hooks/useHistory.ts","../src/components/devtools/HistoryPanel.tsx"],"sourcesContent":["export { useHistory } from './hooks/useHistory'\nexport type { UseHistoryReturn } from './hooks/useHistory'\nexport { HistoryPanel } from './components/devtools/HistoryPanel'\nexport type { HistoryPanelProps } from './components/devtools/HistoryPanel'\n","import { useState, useCallback, useEffect, useRef, useMemo } from 'react'\nimport type { Core } from '@skygraph/core'\nimport { createHistory } from '@skygraph/core'\nimport type { HistoryPlugin, HistoryOptions } from '@skygraph/core'\n\nexport interface UseHistoryReturn {\n history: HistoryPlugin\n canUndo: boolean\n canRedo: boolean\n cursor: number\n entries: HistoryPlugin['entries']\n undo: () => void\n redo: () => void\n jumpTo: (index: number) => void\n clear: () => void\n}\n\nexport function useHistory(core: Core, options?: HistoryOptions): UseHistoryReturn {\n const [, forceUpdate] = useState(0)\n const historyRef = useRef<HistoryPlugin | null>(null)\n const optionsRef = useRef(options)\n\n if (!historyRef.current) {\n historyRef.current = createHistory(core, optionsRef.current)\n }\n\n const tick = useCallback(() => forceUpdate((n) => n + 1), [])\n\n const undo = useCallback(() => {\n historyRef.current!.undo()\n tick()\n }, [tick])\n\n const redo = useCallback(() => {\n historyRef.current!.redo()\n tick()\n }, [tick])\n\n const jumpTo = useCallback(\n (index: number) => {\n historyRef.current!.jumpTo(index)\n tick()\n },\n [tick],\n )\n\n const clear = useCallback(() => {\n historyRef.current!.clear()\n tick()\n }, [tick])\n\n useEffect(() => {\n return () => {\n historyRef.current?.destroy()\n }\n }, [])\n\n const h = historyRef.current\n\n return useMemo(\n () => ({\n history: h,\n canUndo: h.canUndo,\n canRedo: h.canRedo,\n cursor: h.cursor,\n entries: h.entries,\n undo,\n redo,\n jumpTo,\n clear,\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [h, h.cursor, h.entries.length, undo, redo, jumpTo, clear],\n )\n}\n","import React, { useState } from 'react'\nimport type { UseHistoryReturn } from '../../hooks/useHistory'\nimport type { BaseComponentProps } from '../../types'\n\n/** Props for the devtools time-travel history panel (base layout props come from `BaseComponentProps`). */\nexport interface HistoryPanelProps extends BaseComponentProps {\n /** History controller from `useHistory` (entries, cursor, undo/redo, jump, clear). */\n history: UseHistoryReturn\n}\n\nconst styles: Record<string, React.CSSProperties> = {\n root: {\n fontFamily: 'ui-monospace, \"Cascadia Code\", \"Fira Code\", monospace',\n fontSize: 12,\n border: '1px solid var(--sg-border, #d9d9d9)',\n borderRadius: 8,\n background: 'var(--sg-bg-elevated, #fff)',\n overflow: 'hidden',\n },\n header: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '8px 12px',\n borderBottom: '1px solid var(--sg-border, #d9d9d9)',\n fontWeight: 600,\n fontSize: 13,\n },\n controls: {\n display: 'flex',\n gap: 4,\n },\n btn: {\n padding: '2px 8px',\n border: '1px solid var(--sg-border, #d9d9d9)',\n borderRadius: 4,\n background: 'var(--sg-bg, #fafafa)',\n cursor: 'pointer',\n fontSize: 11,\n },\n btnDisabled: {\n opacity: 0.4,\n cursor: 'not-allowed',\n },\n list: {\n maxHeight: 300,\n overflowY: 'auto' as const,\n margin: 0,\n padding: 0,\n listStyle: 'none',\n },\n entry: {\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n padding: '4px 12px',\n cursor: 'pointer',\n borderBottom: '1px solid var(--sg-border-light, #f0f0f0)',\n transition: 'background 0.15s',\n },\n entryActive: {\n background: 'var(--sg-primary-bg, #e6f4ff)',\n fontWeight: 600,\n },\n entryFuture: {\n opacity: 0.5,\n },\n badge: {\n display: 'inline-block',\n padding: '1px 6px',\n borderRadius: 4,\n fontSize: 10,\n background: 'var(--sg-primary-bg, #e6f4ff)',\n color: 'var(--sg-primary, #1677ff)',\n },\n patches: {\n padding: '4px 12px 8px 32px',\n background: 'var(--sg-bg-subtle, #fafafa)',\n fontSize: 11,\n lineHeight: 1.6,\n },\n empty: {\n padding: '24px 12px',\n textAlign: 'center' as const,\n color: 'var(--sg-text-tertiary, #999)',\n },\n}\n\n/**\n * Time-travel UI listing history entries with undo/redo controls and expandable patch details.\n */\nexport function HistoryPanel({ history, className, style }: HistoryPanelProps) {\n const { entries, cursor, canUndo, canRedo, undo, redo, jumpTo, clear } = history\n const [expanded, setExpanded] = useState<number | null>(null)\n\n return (\n <div className={className} style={{ ...styles.root, ...style }}>\n <div style={styles.header}>\n <span>Time-Travel ({entries.length})</span>\n <div style={styles.controls}>\n <button\n style={{ ...styles.btn, ...(canUndo ? {} : styles.btnDisabled) }}\n disabled={!canUndo}\n onClick={undo}\n >\n Undo\n </button>\n <button\n style={{ ...styles.btn, ...(canRedo ? {} : styles.btnDisabled) }}\n disabled={!canRedo}\n onClick={redo}\n >\n Redo\n </button>\n <button style={styles.btn} onClick={clear}>\n Clear\n </button>\n </div>\n </div>\n\n {entries.length === 0 ? (\n <div style={styles.empty}>No history yet</div>\n ) : (\n <ul style={styles.list}>\n {entries.map((entry, i) => {\n const isCurrent = i === cursor\n const isFuture = i > cursor\n\n return (\n <li key={i}>\n <div\n style={{\n ...styles.entry,\n ...(isCurrent ? styles.entryActive : {}),\n ...(isFuture ? styles.entryFuture : {}),\n }}\n onClick={() => jumpTo(i)}\n onDoubleClick={() => setExpanded(expanded === i ? null : i)}\n >\n <span style={styles.badge}>{i}</span>\n <span>\n {entry.patches.length} write{entry.patches.length !== 1 ? 's' : ''}\n </span>\n <span style={{ marginLeft: 'auto', fontSize: 10, opacity: 0.6 }}>\n {formatTime(entry.timestamp)}\n </span>\n </div>\n\n {expanded === i && (\n <div style={styles.patches}>\n {entry.patches.map((p, pi) => (\n <div key={pi}>\n <code>{p.path}</code>:{' '}\n <span style={{ opacity: 0.5 }}>{formatValue(p.oldValue)}</span>\n {' → '}\n <span>{formatValue(p.value)}</span>\n </div>\n ))}\n </div>\n )}\n </li>\n )\n })}\n </ul>\n )}\n </div>\n )\n}\n\nfunction formatTime(ts: number): string {\n const d = new Date(ts)\n return d.toLocaleTimeString(undefined, {\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n })\n}\n\nfunction formatValue(v: unknown): string {\n if (v === undefined) return 'undefined'\n if (v === null) return 'null'\n if (typeof v === 'string') return `\"${v}\"`\n try {\n return JSON.stringify(v)\n } catch {\n return String(v)\n }\n}\n"],"mappings":"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","names":["import_react"]}
1
+ {"version":3,"sources":["../src/devtools.ts","../src/hooks/useHistory.ts","../src/components/devtools/HistoryPanel.tsx"],"sourcesContent":["export { useHistory } from './hooks/useHistory'\nexport type { UseHistoryReturn } from './hooks/useHistory'\nexport { HistoryPanel } from './components/devtools/HistoryPanel'\nexport type { HistoryPanelProps } from './components/devtools/HistoryPanel'\n","import { useState, useCallback, useEffect, useRef, useMemo } from 'react'\nimport type { Core } from '@skygraph/core'\nimport { createHistory } from '@skygraph/core'\nimport type { HistoryPlugin, HistoryOptions } from '@skygraph/core'\n\nexport interface UseHistoryReturn {\n history: HistoryPlugin\n canUndo: boolean\n canRedo: boolean\n cursor: number\n entries: HistoryPlugin['entries']\n undo: () => void\n redo: () => void\n jumpTo: (index: number) => void\n clear: () => void\n}\n\nexport function useHistory(core: Core, options?: HistoryOptions): UseHistoryReturn {\n const [, forceUpdate] = useState(0)\n const historyRef = useRef<HistoryPlugin | null>(null)\n const optionsRef = useRef(options)\n\n if (!historyRef.current) {\n historyRef.current = createHistory(core, optionsRef.current)\n }\n\n const tick = useCallback(() => forceUpdate((n) => n + 1), [])\n\n const undo = useCallback(() => {\n historyRef.current!.undo()\n tick()\n }, [tick])\n\n const redo = useCallback(() => {\n historyRef.current!.redo()\n tick()\n }, [tick])\n\n const jumpTo = useCallback(\n (index: number) => {\n historyRef.current!.jumpTo(index)\n tick()\n },\n [tick],\n )\n\n const clear = useCallback(() => {\n historyRef.current!.clear()\n tick()\n }, [tick])\n\n useEffect(() => {\n return () => {\n historyRef.current?.destroy()\n }\n }, [])\n\n const h = historyRef.current\n\n return useMemo(\n () => ({\n history: h,\n canUndo: h.canUndo,\n canRedo: h.canRedo,\n cursor: h.cursor,\n entries: h.entries,\n undo,\n redo,\n jumpTo,\n clear,\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [h, h.cursor, h.entries.length, undo, redo, jumpTo, clear],\n )\n}\n","import React, { useState } from 'react'\nimport type { UseHistoryReturn } from '../../hooks/useHistory'\nimport type { BaseComponentProps } from '../../types'\n\n/** Props for the devtools time-travel history panel (base layout props come from `BaseComponentProps`). */\nexport interface HistoryPanelProps extends BaseComponentProps {\n /** History controller from `useHistory` (entries, cursor, undo/redo, jump, clear). */\n history: UseHistoryReturn\n}\n\nconst styles: Record<string, React.CSSProperties> = {\n root: {\n fontFamily: 'ui-monospace, \"Cascadia Code\", \"Fira Code\", monospace',\n fontSize: 12,\n border: '1px solid var(--sg-color-border, #d9d9d9)',\n borderRadius: 8,\n background: 'var(--sg-color-bg-elevated, #fff)',\n overflow: 'hidden',\n },\n header: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '8px 12px',\n borderBottom: '1px solid var(--sg-color-border, #d9d9d9)',\n fontWeight: 600,\n fontSize: 13,\n },\n controls: {\n display: 'flex',\n gap: 4,\n },\n btn: {\n padding: '2px 8px',\n border: '1px solid var(--sg-color-border, #d9d9d9)',\n borderRadius: 4,\n background: 'var(--sg-color-bg-secondary, #fafafa)',\n cursor: 'pointer',\n fontSize: 11,\n },\n btnDisabled: {\n opacity: 0.4,\n cursor: 'not-allowed',\n },\n list: {\n maxHeight: 300,\n overflowY: 'auto' as const,\n margin: 0,\n padding: 0,\n listStyle: 'none',\n },\n entry: {\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n padding: '4px 12px',\n cursor: 'pointer',\n borderBottom: '1px solid var(--sg-color-border-secondary, #f0f0f0)',\n transition: 'background 0.15s',\n },\n entryActive: {\n background: 'var(--sg-color-primary-bg, #e6f4ff)',\n fontWeight: 600,\n },\n entryFuture: {\n opacity: 0.5,\n },\n badge: {\n display: 'inline-block',\n padding: '1px 6px',\n borderRadius: 4,\n fontSize: 10,\n background: 'var(--sg-color-primary-bg, #e6f4ff)',\n color: 'var(--sg-color-primary, #1677ff)',\n },\n patches: {\n padding: '4px 12px 8px 32px',\n background: 'var(--sg-color-bg-secondary, #fafafa)',\n fontSize: 11,\n lineHeight: 1.6,\n },\n empty: {\n padding: '24px 12px',\n textAlign: 'center' as const,\n color: 'var(--sg-color-text-tertiary, #999)',\n },\n}\n\n/**\n * Time-travel UI listing history entries with undo/redo controls and expandable patch details.\n */\nexport function HistoryPanel({ history, className, style }: HistoryPanelProps) {\n const { entries, cursor, canUndo, canRedo, undo, redo, jumpTo, clear } = history\n const [expanded, setExpanded] = useState<number | null>(null)\n\n return (\n <div className={className} style={{ ...styles.root, ...style }}>\n <div style={styles.header}>\n <span>Time-Travel ({entries.length})</span>\n <div style={styles.controls}>\n <button\n style={{ ...styles.btn, ...(canUndo ? {} : styles.btnDisabled) }}\n disabled={!canUndo}\n onClick={undo}\n >\n Undo\n </button>\n <button\n style={{ ...styles.btn, ...(canRedo ? {} : styles.btnDisabled) }}\n disabled={!canRedo}\n onClick={redo}\n >\n Redo\n </button>\n <button style={styles.btn} onClick={clear}>\n Clear\n </button>\n </div>\n </div>\n\n {entries.length === 0 ? (\n <div style={styles.empty}>No history yet</div>\n ) : (\n <ul style={styles.list}>\n {entries.map((entry, i) => {\n const isCurrent = i === cursor\n const isFuture = i > cursor\n\n return (\n <li key={i}>\n <div\n style={{\n ...styles.entry,\n ...(isCurrent ? styles.entryActive : {}),\n ...(isFuture ? styles.entryFuture : {}),\n }}\n onClick={() => jumpTo(i)}\n onDoubleClick={() => setExpanded(expanded === i ? null : i)}\n >\n <span style={styles.badge}>{i}</span>\n <span>\n {entry.patches.length} write{entry.patches.length !== 1 ? 's' : ''}\n </span>\n <span style={{ marginLeft: 'auto', fontSize: 10, opacity: 0.6 }}>\n {formatTime(entry.timestamp)}\n </span>\n </div>\n\n {expanded === i && (\n <div style={styles.patches}>\n {entry.patches.map((p, pi) => (\n <div key={pi}>\n <code>{p.path}</code>:{' '}\n <span style={{ opacity: 0.5 }}>{formatValue(p.oldValue)}</span>\n {' → '}\n <span>{formatValue(p.value)}</span>\n </div>\n ))}\n </div>\n )}\n </li>\n )\n })}\n </ul>\n )}\n </div>\n )\n}\n\nfunction formatTime(ts: number): string {\n const d = new Date(ts)\n return d.toLocaleTimeString(undefined, {\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n })\n}\n\nfunction formatValue(v: unknown): string {\n if (v === undefined) return 'undefined'\n if (v === null) return 'null'\n if (typeof v === 'string') return `\"${v}\"`\n try {\n return JSON.stringify(v)\n } catch {\n return String(v)\n }\n}\n"],"mappings":"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","names":["import_react"]}
package/dist/devtools.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  HistoryPanel,
3
3
  useHistory
4
- } from "./chunk-GJDDPZH7.js";
4
+ } from "./chunk-ZJC2QUWA.js";
5
5
  export {
6
6
  HistoryPanel,
7
7
  useHistory
package/dist/form.cjs CHANGED
@@ -421,7 +421,10 @@ function Form({
421
421
  }
422
422
 
423
423
  // src/components/complex/Field.tsx
424
- var import_react13 = require("react");
424
+ var import_react14 = require("react");
425
+
426
+ // src/components/ui/Input.tsx
427
+ var import_react10 = __toESM(require("react"), 1);
425
428
 
426
429
  // src/components/ui/Spin.tsx
427
430
  var import_react9 = __toESM(require("react"), 1);
@@ -498,9 +501,14 @@ function Input({
498
501
  size: sizeProp,
499
502
  disabled: disabledProp,
500
503
  loading,
504
+ allowClear = false,
505
+ status,
506
+ prefix,
507
+ suffix,
501
508
  onChange,
502
509
  onBlur,
503
510
  onFocus,
511
+ onClear,
504
512
  "aria-invalid": ariaInvalid,
505
513
  "aria-required": ariaRequired,
506
514
  "aria-describedby": ariaDescribedBy,
@@ -512,45 +520,73 @@ function Input({
512
520
  const config = useConfig();
513
521
  const size = sizeProp ?? config.size ?? "middle";
514
522
  const disabled = disabledProp ?? config.disabled ?? false;
523
+ const [internalValue, setInternalValue] = import_react10.default.useState(defaultValue ?? "");
524
+ const currentValue = value ?? internalValue;
525
+ const isControlled = value !== void 0;
515
526
  const wrapperClasses = unstyled ? className ?? "" : [
516
527
  "sg-input-wrapper",
517
528
  `sg-input-wrapper-${size}`,
518
529
  loading ? "sg-input-wrapper-loading" : "",
519
530
  readOnly ? "sg-input-wrapper-readonly" : "",
531
+ status ? `sg-input-wrapper-status-${status}` : "",
520
532
  className
521
533
  ].filter(Boolean).join(" ");
522
534
  const inputClasses = unstyled ? "" : [
523
535
  "sg-input",
524
536
  `sg-input-${size}`,
525
- readOnly ? "sg-input-readonly" : ""
537
+ readOnly ? "sg-input-readonly" : "",
538
+ status ? `sg-input-status-${status}` : ""
526
539
  ].filter(Boolean).join(" ");
540
+ const clearLabel = config.locale?.input?.clear ?? "Clear";
541
+ const showClear = allowClear && !disabled && !readOnly && !loading && currentValue !== "";
542
+ const handleChange = (e) => {
543
+ if (!isControlled) setInternalValue(e.target.value);
544
+ onChange?.(e.target.value);
545
+ };
546
+ const handleClear = () => {
547
+ if (!isControlled) setInternalValue("");
548
+ onChange?.("");
549
+ onClear?.();
550
+ };
551
+ const resolvedAriaInvalid = ariaInvalid ?? (status === "error" ? true : void 0);
527
552
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: wrapperClasses, style, children: [
553
+ prefix && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "sg-input-prefix", children: prefix }),
528
554
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
529
555
  "input",
530
556
  {
531
557
  id,
532
558
  type,
533
559
  className: inputClasses,
534
- value,
535
- defaultValue,
560
+ value: currentValue,
536
561
  placeholder,
537
562
  disabled: disabled || loading,
538
563
  readOnly,
539
- "aria-invalid": ariaInvalid,
564
+ "aria-invalid": resolvedAriaInvalid,
540
565
  "aria-required": ariaRequired,
541
566
  "aria-readonly": readOnly || void 0,
542
567
  "aria-describedby": ariaDescribedBy,
543
- onChange: (e) => onChange?.(e.target.value),
568
+ onChange: handleChange,
544
569
  onBlur,
545
570
  onFocus
546
571
  }
547
572
  ),
548
- loading && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Spin, { size: "small", unstyled })
573
+ showClear && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
574
+ "button",
575
+ {
576
+ type: "button",
577
+ className: "sg-input-clear",
578
+ "aria-label": clearLabel,
579
+ onClick: handleClear,
580
+ children: "\xD7"
581
+ }
582
+ ),
583
+ loading && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Spin, { size: "small", unstyled }),
584
+ suffix && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "sg-input-suffix", children: suffix })
549
585
  ] });
550
586
  }
551
587
 
552
588
  // src/components/ui/Textarea.tsx
553
- var import_react10 = __toESM(require("react"), 1);
589
+ var import_react11 = __toESM(require("react"), 1);
554
590
  var import_jsx_runtime6 = require("react/jsx-runtime");
555
591
  function Textarea({
556
592
  value,
@@ -576,7 +612,7 @@ function Textarea({
576
612
  const config = useConfig();
577
613
  const disabled = disabledProp ?? config.disabled;
578
614
  const size = sizeProp ?? config.size ?? "middle";
579
- const [internalValue, setInternalValue] = import_react10.default.useState(value ?? defaultValue ?? "");
615
+ const [internalValue, setInternalValue] = import_react11.default.useState(value ?? defaultValue ?? "");
580
616
  const currentValue = value ?? internalValue;
581
617
  const handleChange = (e) => {
582
618
  const v = e.target.value;
@@ -613,10 +649,10 @@ function Textarea({
613
649
  }
614
650
 
615
651
  // src/components/ui/Tooltip.tsx
616
- var import_react12 = require("react");
652
+ var import_react13 = require("react");
617
653
 
618
654
  // src/components/ui/Transition.tsx
619
- var import_react11 = __toESM(require("react"), 1);
655
+ var import_react12 = __toESM(require("react"), 1);
620
656
  function Transition({
621
657
  visible,
622
658
  name = "sg-fade",
@@ -630,20 +666,20 @@ function Transition({
630
666
  children,
631
667
  unmountOnExit = true
632
668
  }) {
633
- const [mounted, setMounted] = (0, import_react11.useState)(visible);
634
- const [phase, setPhase] = (0, import_react11.useState)(visible ? "idle" : "idle");
635
- const nodeRef = (0, import_react11.useRef)(null);
636
- const timerRef = (0, import_react11.useRef)(void 0);
637
- const prevVisible = (0, import_react11.useRef)(visible);
638
- const getEnterClasses = (0, import_react11.useCallback)(() => {
669
+ const [mounted, setMounted] = (0, import_react12.useState)(visible);
670
+ const [phase, setPhase] = (0, import_react12.useState)(visible ? "idle" : "idle");
671
+ const nodeRef = (0, import_react12.useRef)(null);
672
+ const timerRef = (0, import_react12.useRef)(void 0);
673
+ const prevVisible = (0, import_react12.useRef)(visible);
674
+ const getEnterClasses = (0, import_react12.useCallback)(() => {
639
675
  if (enterFrom && enterTo) return { from: enterFrom, active: `${name}-enter-active`, to: enterTo };
640
676
  return { from: `${name}-enter-from`, active: `${name}-enter-active`, to: `${name}-enter-to` };
641
677
  }, [name, enterFrom, enterTo]);
642
- const getLeaveClasses = (0, import_react11.useCallback)(() => {
678
+ const getLeaveClasses = (0, import_react12.useCallback)(() => {
643
679
  if (leaveFrom && leaveTo) return { from: leaveFrom, active: `${name}-leave-active`, to: leaveTo };
644
680
  return { from: `${name}-leave-from`, active: `${name}-leave-active`, to: `${name}-leave-to` };
645
681
  }, [name, leaveFrom, leaveTo]);
646
- (0, import_react11.useEffect)(() => {
682
+ (0, import_react12.useEffect)(() => {
647
683
  if (visible === prevVisible.current) return;
648
684
  prevVisible.current = visible;
649
685
  clearTimeout(timerRef.current);
@@ -669,7 +705,7 @@ function Transition({
669
705
  }, duration);
670
706
  }
671
707
  }, [visible, duration, unmountOnExit, onAfterEnter, onAfterLeave]);
672
- (0, import_react11.useEffect)(() => {
708
+ (0, import_react12.useEffect)(() => {
673
709
  return () => clearTimeout(timerRef.current);
674
710
  }, []);
675
711
  if (!mounted && unmountOnExit) return null;
@@ -690,7 +726,7 @@ function Transition({
690
726
  transitionClass = `${leaveC.to} ${leaveC.active}`;
691
727
  break;
692
728
  }
693
- return import_react11.default.cloneElement(children, {
729
+ return import_react12.default.cloneElement(children, {
694
730
  ref: nodeRef,
695
731
  className: [children.props.className, transitionClass].filter(Boolean).join(" ")
696
732
  });
@@ -705,10 +741,10 @@ function Tooltip({
705
741
  className,
706
742
  unstyled
707
743
  }) {
708
- const [visible, setVisible] = (0, import_react12.useState)(false);
709
- const ref = (0, import_react12.useRef)(null);
710
- const tooltipId = (0, import_react12.useId)();
711
- const triggerWithAria = (0, import_react12.isValidElement)(children) ? (0, import_react12.cloneElement)(children, {
744
+ const [visible, setVisible] = (0, import_react13.useState)(false);
745
+ const ref = (0, import_react13.useRef)(null);
746
+ const tooltipId = (0, import_react13.useId)();
747
+ const triggerWithAria = (0, import_react13.isValidElement)(children) ? (0, import_react13.cloneElement)(children, {
712
748
  "aria-describedby": visible ? [children.props["aria-describedby"], tooltipId].filter(Boolean).join(" ") : children.props["aria-describedby"],
713
749
  onFocus: (e) => {
714
750
  setVisible(true);
@@ -786,6 +822,7 @@ function Field({
786
822
  noStyle,
787
823
  normalize,
788
824
  getValueFromEvent: _getValueFromEvent,
825
+ valuePropName,
789
826
  validateFirst,
790
827
  validateStatus: manualStatus,
791
828
  hasFeedback,
@@ -800,12 +837,12 @@ function Field({
800
837
  const formLocale = useConfig().locale?.form;
801
838
  const requiredMarker = formLocale?.required ?? "*";
802
839
  const optionalMarker = formLocale?.optional ?? "(optional)";
803
- const autoId = (0, import_react13.useId)();
840
+ const autoId = (0, import_react14.useId)();
804
841
  const fieldId = `sg-field-${autoId.replace(/:/g, "")}-${name.replace(/\./g, "-")}`;
805
842
  const helpId = `${fieldId}-help`;
806
843
  const field = useField(core, form, name);
807
- const prevValueRef = (0, import_react13.useRef)(field.value);
808
- (0, import_react13.useEffect)(() => {
844
+ const prevValueRef = (0, import_react14.useRef)(field.value);
845
+ (0, import_react14.useEffect)(() => {
809
846
  const allRules = [...rules];
810
847
  if (required) {
811
848
  allRules.unshift({ required: true });
@@ -826,6 +863,18 @@ function Field({
826
863
  prevValueRef.current = normalized;
827
864
  field.onChange(normalized);
828
865
  } : field.onChange;
866
+ const valueProp = valuePropName ?? "value";
867
+ const extractValue = (...args) => {
868
+ if (_getValueFromEvent) return _getValueFromEvent(...args);
869
+ const first = args[0];
870
+ if (first !== null && typeof first === "object" && "target" in first) {
871
+ const target = first.target;
872
+ if (target && typeof target === "object" && "value" in target) {
873
+ return valueProp === "checked" ? target.checked : target.value;
874
+ }
875
+ }
876
+ return first;
877
+ };
829
878
  const effectiveStatus = manualStatus ?? field.status;
830
879
  const hasErrors = field.errors.length > 0;
831
880
  const hasWarnings = field.warnings.length > 0;
@@ -861,6 +910,34 @@ function Field({
861
910
  ] });
862
911
  }
863
912
  if (children) {
913
+ if ((0, import_react14.isValidElement)(children)) {
914
+ const childProps = children.props;
915
+ const childOnChange = childProps.onChange;
916
+ const childOnBlur = childProps.onBlur;
917
+ const injected = {
918
+ [valueProp]: field.value,
919
+ onChange: (...args) => {
920
+ wrappedOnChange(extractValue(...args));
921
+ childOnChange?.(...args);
922
+ },
923
+ onBlur: (...args) => {
924
+ field.onBlur();
925
+ childOnBlur?.(...args);
926
+ }
927
+ };
928
+ if (childProps.id === void 0) injected.id = fieldId;
929
+ if (childProps.disabled === void 0 && disabled) injected.disabled = true;
930
+ if (childProps["aria-describedby"] === void 0 && describedBy) {
931
+ injected["aria-describedby"] = describedBy;
932
+ }
933
+ if (childProps["aria-invalid"] === void 0 && hasErrors) {
934
+ injected["aria-invalid"] = true;
935
+ }
936
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
937
+ (0, import_react14.cloneElement)(children, injected),
938
+ feedbackIcon
939
+ ] });
940
+ }
864
941
  return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
865
942
  children,
866
943
  feedbackIcon
@@ -1035,7 +1112,7 @@ function SubmitButton({
1035
1112
  }
1036
1113
 
1037
1114
  // src/components/complex/FormList.tsx
1038
- var import_react14 = __toESM(require("react"), 1);
1115
+ var import_react15 = __toESM(require("react"), 1);
1039
1116
  var import_jsx_runtime11 = require("react/jsx-runtime");
1040
1117
  var listUid = 0;
1041
1118
  function genKey() {
@@ -1043,15 +1120,15 @@ function genKey() {
1043
1120
  }
1044
1121
  function FormList({ name, initialValue, draggable, children }) {
1045
1122
  const { core, form } = useFormContext();
1046
- import_react14.default.useEffect(() => {
1123
+ import_react15.default.useEffect(() => {
1047
1124
  if (initialValue && !Array.isArray(core.get(name))) {
1048
1125
  core.set(name, initialValue);
1049
1126
  }
1050
1127
  }, []);
1051
1128
  const listValue = useWatch(core, name);
1052
1129
  const items = Array.isArray(listValue) ? listValue : [];
1053
- const [keys, setKeys] = (0, import_react14.useState)(() => items.map(() => genKey()));
1054
- import_react14.default.useEffect(() => {
1130
+ const [keys, setKeys] = (0, import_react15.useState)(() => items.map(() => genKey()));
1131
+ import_react15.default.useEffect(() => {
1055
1132
  setKeys((prev) => {
1056
1133
  if (prev.length === items.length) return prev;
1057
1134
  if (items.length > prev.length) {
@@ -1060,11 +1137,11 @@ function FormList({ name, initialValue, draggable, children }) {
1060
1137
  return prev.slice(0, items.length);
1061
1138
  });
1062
1139
  }, [items.length]);
1063
- const fields = (0, import_react14.useMemo)(
1140
+ const fields = (0, import_react15.useMemo)(
1064
1141
  () => keys.slice(0, items.length).map((key, index) => ({ key, index })),
1065
1142
  [keys, items.length]
1066
1143
  );
1067
- const add = (0, import_react14.useCallback)(
1144
+ const add = (0, import_react15.useCallback)(
1068
1145
  (defaultValue, insertIndex) => {
1069
1146
  form.listAdd(name, defaultValue, insertIndex);
1070
1147
  setKeys((prev) => {
@@ -1079,7 +1156,7 @@ function FormList({ name, initialValue, draggable, children }) {
1079
1156
  },
1080
1157
  [form, name]
1081
1158
  );
1082
- const remove = (0, import_react14.useCallback)(
1159
+ const remove = (0, import_react15.useCallback)(
1083
1160
  (index) => {
1084
1161
  form.listRemove(name, index);
1085
1162
  setKeys((prev) => {
@@ -1092,7 +1169,7 @@ function FormList({ name, initialValue, draggable, children }) {
1092
1169
  },
1093
1170
  [form, name]
1094
1171
  );
1095
- const move = (0, import_react14.useCallback)(
1172
+ const move = (0, import_react15.useCallback)(
1096
1173
  (from, to) => {
1097
1174
  form.listMove(name, from, to);
1098
1175
  setKeys((prev) => {
@@ -1104,20 +1181,20 @@ function FormList({ name, initialValue, draggable, children }) {
1104
1181
  },
1105
1182
  [form, name]
1106
1183
  );
1107
- const replace = (0, import_react14.useCallback)(
1184
+ const replace = (0, import_react15.useCallback)(
1108
1185
  (values) => {
1109
1186
  form.listReplace(name, values);
1110
1187
  setKeys(values.map(() => genKey()));
1111
1188
  },
1112
1189
  [form, name]
1113
1190
  );
1114
- const operation = (0, import_react14.useMemo)(
1191
+ const operation = (0, import_react15.useMemo)(
1115
1192
  () => ({ add, remove, move, replace }),
1116
1193
  [add, remove, move, replace]
1117
1194
  );
1118
- const meta = (0, import_react14.useMemo)(() => ({ errors: form.getFieldErrors(name) }), [form, name]);
1119
- const dragIdx = (0, import_react14.useRef)(-1);
1120
- const dragOverIdx = (0, import_react14.useRef)(-1);
1195
+ const meta = (0, import_react15.useMemo)(() => ({ errors: form.getFieldErrors(name) }), [form, name]);
1196
+ const dragIdx = (0, import_react15.useRef)(-1);
1197
+ const dragOverIdx = (0, import_react15.useRef)(-1);
1121
1198
  if (!draggable) {
1122
1199
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_jsx_runtime11.Fragment, { children: children(fields, operation, meta) });
1123
1200
  }
@@ -1149,7 +1226,7 @@ function FormList({ name, initialValue, draggable, children }) {
1149
1226
  }
1150
1227
 
1151
1228
  // src/components/complex/AutoField/AutoField.tsx
1152
- var import_react15 = require("react");
1229
+ var import_react16 = require("react");
1153
1230
  var import_jsx_runtime12 = require("react/jsx-runtime");
1154
1231
  function AutoField(props) {
1155
1232
  const {
@@ -1172,7 +1249,7 @@ function AutoField(props) {
1172
1249
  const { form } = useFormContext();
1173
1250
  const value = form.getValue(name);
1174
1251
  const meta = form.getFieldState(name);
1175
- const inferredType = (0, import_react15.useMemo)(() => {
1252
+ const inferredType = (0, import_react16.useMemo)(() => {
1176
1253
  if (forcedType) return forcedType;
1177
1254
  if (options && options.length > 0) return "select";
1178
1255
  if (typeof value === "boolean") return "boolean";
@@ -1189,20 +1266,10 @@ function AutoField(props) {
1189
1266
  const errorId = `${name}-error`;
1190
1267
  const hasErrors = meta.errors.length > 0;
1191
1268
  const hasWarnings = meta.warnings.length > 0;
1192
- const wrapperStyle = {
1193
- display: "flex",
1194
- flexDirection: "column",
1195
- gap: 4,
1196
- ...style
1197
- };
1198
- const inputStyle = {
1199
- padding: "6px 12px",
1200
- border: `1px solid ${hasErrors ? "var(--sg-error, #ff4d4f)" : hasWarnings ? "var(--sg-warning, #faad14)" : "var(--sg-border, #d9d9d9)"}`,
1201
- borderRadius: "var(--sg-radius, 6px)",
1202
- fontSize: 14,
1203
- outline: "none",
1204
- background: disabled ? "var(--sg-bg-disabled, #f5f5f5)" : "var(--sg-bg, #fff)"
1205
- };
1269
+ const inputClass = [
1270
+ "sg-autofield-input",
1271
+ hasErrors ? "sg-autofield-input-error" : hasWarnings ? "sg-autofield-input-warning" : ""
1272
+ ].filter(Boolean).join(" ");
1206
1273
  function renderInput() {
1207
1274
  switch (inferredType) {
1208
1275
  case "boolean":
@@ -1233,7 +1300,7 @@ function AutoField(props) {
1233
1300
  min,
1234
1301
  max,
1235
1302
  step,
1236
- style: inputStyle,
1303
+ className: inputClass,
1237
1304
  "aria-invalid": hasErrors,
1238
1305
  "aria-describedby": hasErrors ? errorId : void 0
1239
1306
  }
@@ -1247,7 +1314,7 @@ function AutoField(props) {
1247
1314
  onBlur: () => form.onFieldBlur(name),
1248
1315
  placeholder,
1249
1316
  disabled,
1250
- style: { ...inputStyle, minHeight: 80, resize: "vertical" },
1317
+ className: `${inputClass} sg-autofield-input-textarea`,
1251
1318
  "aria-invalid": hasErrors,
1252
1319
  "aria-describedby": hasErrors ? errorId : void 0
1253
1320
  }
@@ -1259,7 +1326,7 @@ function AutoField(props) {
1259
1326
  value: value == null ? "" : String(value),
1260
1327
  onChange: (e) => handleChange(e.target.value),
1261
1328
  disabled,
1262
- style: inputStyle,
1329
+ className: inputClass,
1263
1330
  "aria-invalid": hasErrors,
1264
1331
  "aria-describedby": hasErrors ? errorId : void 0,
1265
1332
  children: [
@@ -1279,27 +1346,34 @@ function AutoField(props) {
1279
1346
  handleChange(selected);
1280
1347
  },
1281
1348
  disabled,
1282
- style: { ...inputStyle, minHeight: 80 },
1349
+ className: `${inputClass} sg-autofield-input-multiple`,
1283
1350
  "aria-invalid": hasErrors,
1284
1351
  "aria-describedby": hasErrors ? errorId : void 0,
1285
1352
  children: options?.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("option", { value: opt.value, children: opt.label }, opt.value))
1286
1353
  }
1287
1354
  );
1288
1355
  case "radio":
1289
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { role: "radiogroup", style: { display: "flex", gap: 12, flexWrap: "wrap" }, children: options?.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { style: { display: "flex", alignItems: "center", gap: 4, cursor: "pointer" }, children: [
1290
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1291
- "input",
1292
- {
1293
- type: "radio",
1294
- name,
1295
- value: opt.value,
1296
- checked: value === opt.value,
1297
- onChange: () => handleChange(opt.value),
1298
- disabled
1299
- }
1300
- ),
1301
- opt.label
1302
- ] }, opt.value)) });
1356
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { role: "radiogroup", style: { display: "flex", gap: 12, flexWrap: "wrap" }, children: options?.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
1357
+ "label",
1358
+ {
1359
+ style: { display: "flex", alignItems: "center", gap: 4, cursor: "pointer" },
1360
+ children: [
1361
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1362
+ "input",
1363
+ {
1364
+ type: "radio",
1365
+ name,
1366
+ value: opt.value,
1367
+ checked: value === opt.value,
1368
+ onChange: () => handleChange(opt.value),
1369
+ disabled
1370
+ }
1371
+ ),
1372
+ opt.label
1373
+ ]
1374
+ },
1375
+ opt.value
1376
+ )) });
1303
1377
  case "date":
1304
1378
  return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1305
1379
  "input",
@@ -1308,7 +1382,7 @@ function AutoField(props) {
1308
1382
  value: value == null ? "" : String(value),
1309
1383
  onChange: (e) => handleChange(e.target.value),
1310
1384
  disabled,
1311
- style: inputStyle,
1385
+ className: inputClass,
1312
1386
  "aria-invalid": hasErrors,
1313
1387
  "aria-describedby": hasErrors ? errorId : void 0
1314
1388
  }
@@ -1321,7 +1395,7 @@ function AutoField(props) {
1321
1395
  value: value == null ? "" : String(value),
1322
1396
  onChange: (e) => handleChange(e.target.value),
1323
1397
  disabled,
1324
- style: inputStyle,
1398
+ className: inputClass,
1325
1399
  "aria-invalid": hasErrors,
1326
1400
  "aria-describedby": hasErrors ? errorId : void 0
1327
1401
  }
@@ -1336,7 +1410,7 @@ function AutoField(props) {
1336
1410
  onBlur: () => form.onFieldBlur(name),
1337
1411
  placeholder,
1338
1412
  disabled,
1339
- style: inputStyle,
1413
+ className: inputClass,
1340
1414
  "aria-invalid": hasErrors,
1341
1415
  "aria-describedby": hasErrors ? errorId : void 0
1342
1416
  }
@@ -1349,7 +1423,7 @@ function AutoField(props) {
1349
1423
  value: value == null ? "#000000" : String(value),
1350
1424
  onChange: (e) => handleChange(e.target.value),
1351
1425
  disabled,
1352
- style: { ...inputStyle, padding: 2, width: 48, height: 32 }
1426
+ className: `${inputClass} sg-autofield-input-color`
1353
1427
  }
1354
1428
  );
1355
1429
  case "slider":
@@ -1383,7 +1457,7 @@ function AutoField(props) {
1383
1457
  border: "none",
1384
1458
  cursor: disabled ? "default" : "pointer",
1385
1459
  fontSize: 20,
1386
- color: i < currentRate ? "var(--sg-warning, #faad14)" : "var(--sg-border, #d9d9d9)",
1460
+ color: i < currentRate ? "var(--sg-color-warning, #faad14)" : "var(--sg-color-border, #d9d9d9)",
1387
1461
  padding: 0
1388
1462
  },
1389
1463
  "aria-label": `${i + 1} star${i !== 0 ? "s" : ""}`,
@@ -1404,7 +1478,7 @@ function AutoField(props) {
1404
1478
  if (files) handleChange(multiple ? Array.from(files) : files[0] ?? null);
1405
1479
  },
1406
1480
  disabled,
1407
- style: inputStyle
1481
+ className: inputClass
1408
1482
  }
1409
1483
  );
1410
1484
  case "email":
@@ -1420,18 +1494,26 @@ function AutoField(props) {
1420
1494
  onBlur: () => form.onFieldBlur(name),
1421
1495
  placeholder,
1422
1496
  disabled,
1423
- style: inputStyle,
1497
+ className: inputClass,
1424
1498
  "aria-invalid": hasErrors,
1425
1499
  "aria-describedby": hasErrors ? errorId : void 0
1426
1500
  }
1427
1501
  );
1428
1502
  }
1429
1503
  }
1430
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: `sg-autofield ${className ?? ""}`, style: wrapperStyle, children: [
1431
- inferredType !== "boolean" && inferredType !== "switch" && label && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("label", { style: { fontWeight: 500, fontSize: 14 }, children: label }),
1504
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: `sg-autofield ${className ?? ""}`, style, children: [
1505
+ inferredType !== "boolean" && inferredType !== "switch" && label && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("label", { className: "sg-autofield-label", children: label }),
1432
1506
  renderInput(),
1433
- hasErrors && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { id: errorId, role: "alert", style: { color: "var(--sg-error, #ff4d4f)", fontSize: 12 }, children: meta.errors.join("; ") }),
1434
- hasWarnings && !hasErrors && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { style: { color: "var(--sg-warning, #faad14)", fontSize: 12 }, children: meta.warnings.join("; ") })
1507
+ hasErrors && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1508
+ "span",
1509
+ {
1510
+ id: errorId,
1511
+ role: "alert",
1512
+ style: { color: "var(--sg-color-error, #ff4d4f)", fontSize: 12 },
1513
+ children: meta.errors.join("; ")
1514
+ }
1515
+ ),
1516
+ hasWarnings && !hasErrors && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { style: { color: "var(--sg-color-warning, #faad14)", fontSize: 12 }, children: meta.warnings.join("; ") })
1435
1517
  ] });
1436
1518
  }
1437
1519