@jbpark/live-editor 3.0.2 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.ko.md +3 -2
  2. package/README.md +3 -2
  3. package/dist/{ast-D6R-dsk0.js → ast-Bx2Avo4d.js} +416 -177
  4. package/dist/ast-Bx2Avo4d.js.map +1 -0
  5. package/dist/{boundary-BF7iZp6e.js → boundary-BTP1nfG6.js} +2 -2
  6. package/dist/{boundary-BF7iZp6e.js.map → boundary-BTP1nfG6.js.map} +1 -1
  7. package/dist/{context-DH70wj9d.js → context-649REFsj.js} +2 -2
  8. package/dist/{context-DH70wj9d.js.map → context-649REFsj.js.map} +1 -1
  9. package/dist/{core-CTsQ9LiQ.js → core-D3q5rpuz.js} +2 -2
  10. package/dist/{core-CTsQ9LiQ.js.map → core-D3q5rpuz.js.map} +1 -1
  11. package/dist/dnd/index.d.ts +2 -2
  12. package/dist/dnd/index.js +2 -2
  13. package/dist/{dnd-C4iBiSkv.js → dnd-DTT37EbA.js} +487 -449
  14. package/dist/dnd-DTT37EbA.js.map +1 -0
  15. package/dist/document-C6bNHl7l.js.map +1 -1
  16. package/dist/editor/index.d.ts +1 -1
  17. package/dist/editor/index.js +2 -2
  18. package/dist/{editor-C0lphNg6.js → editor-LzqHe_-F.js} +3 -3
  19. package/dist/editor-LzqHe_-F.js.map +1 -0
  20. package/dist/error/index.js +2 -2
  21. package/dist/{error-lsJey-it.js → error-CO0EbMlA.js} +2 -2
  22. package/dist/{error-lsJey-it.js.map → error-CO0EbMlA.js.map} +1 -1
  23. package/dist/{index-Ck3akHag.d.ts → index-Ba8jGXSM.d.ts} +3 -2
  24. package/dist/{index-Bqc5kUAG.d.ts → index-DswWDEXZ.d.ts} +27 -3
  25. package/dist/{index-GuEiafMN.d.ts → index-DxbG789f.d.ts} +25 -2
  26. package/dist/index.d.ts +2 -2
  27. package/dist/index.js +5 -5
  28. package/dist/preview/index.js +1 -1
  29. package/dist/{preview-CNVXyDgY.js → preview-CWT0lgwq.js} +6 -6
  30. package/dist/preview-CWT0lgwq.js.map +1 -0
  31. package/dist/provider/index.js +1 -1
  32. package/dist/{use-dynamic-tailwind-C0Onss1A.js → use-dynamic-tailwind-DAhKGsY4.js} +70 -78
  33. package/dist/use-dynamic-tailwind-DAhKGsY4.js.map +1 -0
  34. package/dist/utils/ast/index.d.ts +2 -2
  35. package/dist/utils/ast/index.js +2 -2
  36. package/dist/utils/index.js +1 -1
  37. package/dist/{utils-BwEgY5pe.js → utils-WyxPYZGh.js} +12 -10
  38. package/dist/{utils-BwEgY5pe.js.map → utils-WyxPYZGh.js.map} +1 -1
  39. package/package.json +3 -2
  40. package/dist/ast-D6R-dsk0.js.map +0 -1
  41. package/dist/dnd-C4iBiSkv.js.map +0 -1
  42. package/dist/editor-C0lphNg6.js.map +0 -1
  43. package/dist/preview-CNVXyDgY.js.map +0 -1
  44. package/dist/use-dynamic-tailwind-C0Onss1A.js.map +0 -1
@@ -1,2 +1,2 @@
1
- import { a as Props, i as Core, n as EditorRenderData, r as Props$1, t as Editor } from "../index-Ck3akHag.js";
1
+ import { a as Props, i as Core, n as EditorRenderData, r as Props$1, t as Editor } from "../index-Ba8jGXSM.js";
2
2
  export { Core, type Props as CoreProps, type EditorRenderData, type Props$1 as Props, Editor as default };
@@ -1,3 +1,3 @@
1
- import { t as Core } from "../core-CTsQ9LiQ.js";
2
- import { t as Editor } from "../editor-C0lphNg6.js";
1
+ import { t as Core } from "../core-D3q5rpuz.js";
2
+ import { t as Editor } from "../editor-LzqHe_-F.js";
3
3
  export { Core, Editor as default };
@@ -1,6 +1,6 @@
1
1
  import { y as DEFAULT_TEMPLATE } from "./document-C6bNHl7l.js";
2
2
  import { i as usePreview, r as useError } from "./states-Ci1AvoQ9.js";
3
- import { n as useFormatCode, t as Core } from "./core-CTsQ9LiQ.js";
3
+ import { n as useFormatCode, t as Core } from "./core-D3q5rpuz.js";
4
4
  import { useCallback, useEffect } from "react";
5
5
  import { jsx } from "react/jsx-runtime";
6
6
  import { useDebouncedValue } from "@jbpark/use-hooks";
@@ -8,7 +8,7 @@ import { useDebouncedValue } from "@jbpark/use-hooks";
8
8
  const Editor$1 = ({ defaultValue, value: _value, debounce = 1e3, onChange: _onChange, renderEditor, fragment, prettierOptions, ...props }) => {
9
9
  const { setCode } = usePreview();
10
10
  const { setError } = useError();
11
- const value = _value.trim() === "" ? defaultValue || DEFAULT_TEMPLATE : _value;
11
+ const value = _value === void 0 ? defaultValue ?? DEFAULT_TEMPLATE : _value;
12
12
  const onChange = useCallback((value) => {
13
13
  _onChange?.(value);
14
14
  }, [_onChange]);
@@ -48,4 +48,4 @@ Editor.Core = Core;
48
48
  //#endregion
49
49
  export { Editor as t };
50
50
 
51
- //# sourceMappingURL=editor-C0lphNg6.js.map
51
+ //# sourceMappingURL=editor-LzqHe_-F.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editor-LzqHe_-F.js","names":["Editor","EditorImpl"],"sources":["../src/components/editor/editor.tsx","../src/components/editor/index.ts"],"sourcesContent":["import { useCallback, useEffect } from 'react';\n\nimport { useDebouncedValue } from '@jbpark/use-hooks';\n\nimport { useError, usePreview } from '~/components/context/states';\nimport { DEFAULT_TEMPLATE } from '~/constants';\n\nimport Core, { type Props as CoreProps } from './core';\nimport { useFormatCode } from './use-format-code';\n\nexport interface EditorRenderData {\n value: string;\n onChange: (value: string) => void;\n // Same prettier-based formatting Core's own Cmd+S uses - reused rather\n // than reimplemented, so a custom editor can offer equivalent\n // format-on-save behavior without duplicating the prettier wiring.\n formatCode: (code: string) => Promise<string>;\n}\n\nexport interface Props extends Omit<CoreProps, 'value' | 'onSave' | 'onError'> {\n value?: string;\n defaultValue?: string;\n debounce?: number;\n // Full replacement for the built-in CodeMirror editor. Editor still owns\n // syncing `value` to the shared preview code (debounced), regardless of\n // which UI renders it - only the editing surface itself is customizable.\n renderEditor?: (data: EditorRenderData) => React.ReactNode;\n}\n\nconst Editor = ({\n defaultValue,\n value: _value,\n debounce = 1000,\n onChange: _onChange,\n renderEditor,\n fragment,\n prettierOptions,\n ...props\n}: Props) => {\n const { setCode } = usePreview();\n const { setError } = useError();\n\n const value =\n _value === undefined ? (defaultValue ?? DEFAULT_TEMPLATE) : _value;\n\n const onChange = useCallback(\n (value: string) => {\n _onChange?.(value);\n },\n [_onChange],\n );\n\n const onSave = useCallback(\n (formattedCode: string) => {\n setCode(formattedCode);\n },\n [setCode],\n );\n\n const onError = useCallback(\n (error: string | null) => {\n setError(error);\n },\n [setError],\n );\n\n const formatCode = useFormatCode({ fragment, prettierOptions });\n\n const debouncedValue = useDebouncedValue(value, debounce);\n\n useEffect(() => {\n setCode(debouncedValue);\n }, [debouncedValue, setCode]);\n\n if (renderEditor) {\n return renderEditor({ value, onChange, formatCode });\n }\n\n return (\n <Core\n value={value}\n onChange={onChange}\n onSave={onSave}\n onError={onError}\n fragment={fragment}\n prettierOptions={prettierOptions}\n {...props}\n />\n );\n};\n\nexport default Editor;\n","import Core, { type Props as CoreProps } from './core';\nimport EditorImpl, { type EditorRenderData, type Props } from './editor';\n\ntype EditorComponent = typeof EditorImpl & { Core: typeof Core };\n\nconst Editor = EditorImpl as EditorComponent;\n\nEditor.Core = Core;\n\nexport { Core };\nexport type { Props, CoreProps, EditorRenderData };\nexport default Editor;\n"],"mappings":";;;;;;;AA6BA,MAAMA,YAAU,EACd,cACA,OAAO,QACP,WAAW,KACX,UAAU,WACV,cACA,UACA,iBACA,GAAG,YACQ;CACX,MAAM,EAAE,YAAY,WAAW;CAC/B,MAAM,EAAE,aAAa,SAAS;CAE9B,MAAM,QACJ,WAAW,KAAA,IAAa,gBAAgB,mBAAoB;CAE9D,MAAM,WAAW,aACd,UAAkB;EACjB,YAAY,KAAK;CACnB,GACA,CAAC,SAAS,CACZ;CAEA,MAAM,SAAS,aACZ,kBAA0B;EACzB,QAAQ,aAAa;CACvB,GACA,CAAC,OAAO,CACV;CAEA,MAAM,UAAU,aACb,UAAyB;EACxB,SAAS,KAAK;CAChB,GACA,CAAC,QAAQ,CACX;CAEA,MAAM,aAAa,cAAc;EAAE;EAAU;CAAgB,CAAC;CAE9D,MAAM,iBAAiB,kBAAkB,OAAO,QAAQ;CAExD,gBAAgB;EACd,QAAQ,cAAc;CACxB,GAAG,CAAC,gBAAgB,OAAO,CAAC;CAE5B,IAAI,cACF,OAAO,aAAa;EAAE;EAAO;EAAU;CAAW,CAAC;CAGrD,OACE,oBAAC,MAAD;EACS;EACG;EACF;EACC;EACC;EACO;EACjB,GAAI;CACL,CAAA;AAEL;;;ACpFA,MAAM,SAASC;AAEf,OAAO,OAAO"}
@@ -1,3 +1,3 @@
1
- import { t as ErrorBoundary } from "../boundary-BF7iZp6e.js";
2
- import { n as Runtime, r as Guard, t as Error } from "../error-lsJey-it.js";
1
+ import { t as ErrorBoundary } from "../boundary-BTP1nfG6.js";
2
+ import { n as Runtime, r as Guard, t as Error } from "../error-CO0EbMlA.js";
3
3
  export { ErrorBoundary, Guard as ErrorGuard, Runtime as ErrorRuntime, Error as default };
@@ -1,5 +1,5 @@
1
1
  import { r as useError } from "./states-Ci1AvoQ9.js";
2
- import { n as Error$1, t as ErrorBoundary } from "./boundary-BF7iZp6e.js";
2
+ import { n as Error$1, t as ErrorBoundary } from "./boundary-BTP1nfG6.js";
3
3
  import { useEffect, useRef, useState } from "react";
4
4
  import { jsx } from "react/jsx-runtime";
5
5
  import { useEventListener } from "@jbpark/use-hooks";
@@ -79,4 +79,4 @@ Error.Guard = Guard;
79
79
  //#endregion
80
80
  export { Runtime as n, Guard as r, Error as t };
81
81
 
82
- //# sourceMappingURL=error-lsJey-it.js.map
82
+ //# sourceMappingURL=error-CO0EbMlA.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"error-lsJey-it.js","names":["ErrorComponent","Error","ErrorImpl","ErrorRuntime","ErrorGuard"],"sources":["../src/components/error/guard.tsx","../src/components/error/runtime.tsx","../src/components/error/index.ts"],"sourcesContent":["import { useEffect, useRef, useState } from 'react';\n\nimport { useEventListener } from '@jbpark/use-hooks';\n\nimport ErrorComponent from './error';\n\nexport interface Props {\n children: React.ReactNode;\n onError?: (error: Error) => void;\n}\n\nconst Guard = ({ children, onError }: Props) => {\n const [error, setError] = useState<string | null>(null);\n\n const containerRef = useRef<HTMLDivElement>(null);\n const errorHandled = useRef(false);\n\n useEventListener(\n 'error',\n event => {\n if (errorHandled.current) {\n return;\n }\n\n errorHandled.current = true;\n\n const errorMessage =\n event.error?.message || event.message || 'Unknown error';\n\n console.error('⚡ [Guard] Event handler error:', errorMessage);\n\n event.preventDefault();\n\n setError(errorMessage);\n onError?.(event.error || new window.Error(errorMessage));\n\n setTimeout(() => {\n errorHandled.current = false;\n }, 100);\n },\n { capture: true },\n );\n\n useEffect(() => {\n const container = containerRef.current;\n\n if (!container) {\n return;\n }\n\n const handleUnhandledRejection = (event: PromiseRejectionEvent) => {\n if (errorHandled.current) {\n return;\n }\n\n errorHandled.current = true;\n\n const errorMessage = event.reason?.message || 'Promise rejection';\n\n event.preventDefault();\n setError(errorMessage);\n onError?.(event.reason || new window.Error(errorMessage));\n\n setTimeout(() => {\n errorHandled.current = false;\n }, 100);\n };\n\n window.addEventListener(\n 'unhandledrejection',\n handleUnhandledRejection,\n true,\n );\n\n return () => {\n window.removeEventListener(\n 'unhandledrejection',\n handleUnhandledRejection,\n true,\n );\n };\n }, [onError]);\n\n if (error) {\n return (\n <ErrorComponent\n title=\"Runtime Error\"\n message={error}\n className=\"m-4\"\n onReset={() => {\n setError(null);\n errorHandled.current = false;\n }}\n />\n );\n }\n\n return <div ref={containerRef}>{children}</div>;\n};\n\nexport default Guard;\n","import { useEffect } from 'react';\n\nimport { useEventListener } from '@jbpark/use-hooks';\n\nimport { useError } from '~/components/context/states';\n\nimport Error from './error';\n\nexport interface Props extends React.ComponentPropsWithRef<'div'> {\n open?: boolean;\n reset?: () => void;\n}\n\nconst Runtime = ({ open = true, reset }: Props) => {\n const { error: message, setError } = useError();\n\n useEventListener('error', e => {\n setError(e.message);\n e.preventDefault();\n });\n\n useEffect(() => {\n return () => setError(null);\n }, [setError]);\n\n if (!open) {\n return null;\n }\n\n return <Error message={message} onReset={reset} title=\"Runtime Error\" />;\n};\n\nexport default Runtime;\n","import ErrorBoundary from './boundary';\nimport ErrorImpl, { type Props } from './error';\nimport ErrorGuard from './guard';\nimport ErrorRuntime from './runtime';\n\ntype ErrorComponent = typeof ErrorImpl & {\n Boundary: typeof ErrorBoundary;\n Runtime: typeof ErrorRuntime;\n Guard: typeof ErrorGuard;\n};\n\nconst Error = ErrorImpl as ErrorComponent;\n\nError.Boundary = ErrorBoundary;\nError.Runtime = ErrorRuntime;\nError.Guard = ErrorGuard;\n\nexport { ErrorBoundary, ErrorRuntime, ErrorGuard };\nexport type { Props };\nexport default Error;\n"],"mappings":";;;;;;AAWA,MAAM,SAAS,EAAE,UAAU,cAAqB;CAC9C,MAAM,CAAC,OAAO,YAAY,SAAwB,IAAI;CAEtD,MAAM,eAAe,OAAuB,IAAI;CAChD,MAAM,eAAe,OAAO,KAAK;CAEjC,iBACE,UACA,UAAS;EACP,IAAI,aAAa,SACf;EAGF,aAAa,UAAU;EAEvB,MAAM,eACJ,MAAM,OAAO,WAAW,MAAM,WAAW;EAE3C,QAAQ,MAAM,kCAAkC,YAAY;EAE5D,MAAM,eAAe;EAErB,SAAS,YAAY;EACrB,UAAU,MAAM,SAAS,IAAI,OAAO,MAAM,YAAY,CAAC;EAEvD,iBAAiB;GACf,aAAa,UAAU;EACzB,GAAG,GAAG;CACR,GACA,EAAE,SAAS,KAAK,CAClB;CAEA,gBAAgB;EAGd,IAAI,CAFc,aAAa,SAG7B;EAGF,MAAM,4BAA4B,UAAiC;GACjE,IAAI,aAAa,SACf;GAGF,aAAa,UAAU;GAEvB,MAAM,eAAe,MAAM,QAAQ,WAAW;GAE9C,MAAM,eAAe;GACrB,SAAS,YAAY;GACrB,UAAU,MAAM,UAAU,IAAI,OAAO,MAAM,YAAY,CAAC;GAExD,iBAAiB;IACf,aAAa,UAAU;GACzB,GAAG,GAAG;EACR;EAEA,OAAO,iBACL,sBACA,0BACA,IACF;EAEA,aAAa;GACX,OAAO,oBACL,sBACA,0BACA,IACF;EACF;CACF,GAAG,CAAC,OAAO,CAAC;CAEZ,IAAI,OACF,OACE,oBAACA,SAAD;EACE,OAAM;EACN,SAAS;EACT,WAAU;EACV,eAAe;GACb,SAAS,IAAI;GACb,aAAa,UAAU;EACzB;CACD,CAAA;CAIL,OAAO,oBAAC,OAAD;EAAK,KAAK;EAAe;CAAc,CAAA;AAChD;;;ACrFA,MAAM,WAAW,EAAE,OAAO,MAAM,YAAmB;CACjD,MAAM,EAAE,OAAO,SAAS,aAAa,SAAS;CAE9C,iBAAiB,UAAS,MAAK;EAC7B,SAAS,EAAE,OAAO;EAClB,EAAE,eAAe;CACnB,CAAC;CAED,gBAAgB;EACd,aAAa,SAAS,IAAI;CAC5B,GAAG,CAAC,QAAQ,CAAC;CAEb,IAAI,CAAC,MACH,OAAO;CAGT,OAAO,oBAACC,SAAD;EAAgB;EAAS,SAAS;EAAO,OAAM;CAAiB,CAAA;AACzE;;;ACnBA,MAAM,QAAQC;AAEd,MAAM,WAAW;AACjB,MAAM,UAAUC;AAChB,MAAM,QAAQC"}
1
+ {"version":3,"file":"error-CO0EbMlA.js","names":["ErrorComponent","Error","ErrorImpl","ErrorRuntime","ErrorGuard"],"sources":["../src/components/error/guard.tsx","../src/components/error/runtime.tsx","../src/components/error/index.ts"],"sourcesContent":["import { useEffect, useRef, useState } from 'react';\n\nimport { useEventListener } from '@jbpark/use-hooks';\n\nimport ErrorComponent from './error';\n\nexport interface Props {\n children: React.ReactNode;\n onError?: (error: Error) => void;\n}\n\nconst Guard = ({ children, onError }: Props) => {\n const [error, setError] = useState<string | null>(null);\n\n const containerRef = useRef<HTMLDivElement>(null);\n const errorHandled = useRef(false);\n\n useEventListener(\n 'error',\n event => {\n if (errorHandled.current) {\n return;\n }\n\n errorHandled.current = true;\n\n const errorMessage =\n event.error?.message || event.message || 'Unknown error';\n\n console.error('⚡ [Guard] Event handler error:', errorMessage);\n\n event.preventDefault();\n\n setError(errorMessage);\n onError?.(event.error || new window.Error(errorMessage));\n\n setTimeout(() => {\n errorHandled.current = false;\n }, 100);\n },\n { capture: true },\n );\n\n useEffect(() => {\n const container = containerRef.current;\n\n if (!container) {\n return;\n }\n\n const handleUnhandledRejection = (event: PromiseRejectionEvent) => {\n if (errorHandled.current) {\n return;\n }\n\n errorHandled.current = true;\n\n const errorMessage = event.reason?.message || 'Promise rejection';\n\n event.preventDefault();\n setError(errorMessage);\n onError?.(event.reason || new window.Error(errorMessage));\n\n setTimeout(() => {\n errorHandled.current = false;\n }, 100);\n };\n\n window.addEventListener(\n 'unhandledrejection',\n handleUnhandledRejection,\n true,\n );\n\n return () => {\n window.removeEventListener(\n 'unhandledrejection',\n handleUnhandledRejection,\n true,\n );\n };\n }, [onError]);\n\n if (error) {\n return (\n <ErrorComponent\n title=\"Runtime Error\"\n message={error}\n className=\"m-4\"\n onReset={() => {\n setError(null);\n errorHandled.current = false;\n }}\n />\n );\n }\n\n return <div ref={containerRef}>{children}</div>;\n};\n\nexport default Guard;\n","import { useEffect } from 'react';\n\nimport { useEventListener } from '@jbpark/use-hooks';\n\nimport { useError } from '~/components/context/states';\n\nimport Error from './error';\n\nexport interface Props extends React.ComponentPropsWithRef<'div'> {\n open?: boolean;\n reset?: () => void;\n}\n\nconst Runtime = ({ open = true, reset }: Props) => {\n const { error: message, setError } = useError();\n\n useEventListener('error', e => {\n setError(e.message);\n e.preventDefault();\n });\n\n useEffect(() => {\n return () => setError(null);\n }, [setError]);\n\n if (!open) {\n return null;\n }\n\n return <Error message={message} onReset={reset} title=\"Runtime Error\" />;\n};\n\nexport default Runtime;\n","import ErrorBoundary from './boundary';\nimport ErrorImpl, { type Props } from './error';\nimport ErrorGuard from './guard';\nimport ErrorRuntime from './runtime';\n\ntype ErrorComponent = typeof ErrorImpl & {\n Boundary: typeof ErrorBoundary;\n Runtime: typeof ErrorRuntime;\n Guard: typeof ErrorGuard;\n};\n\nconst Error = ErrorImpl as ErrorComponent;\n\nError.Boundary = ErrorBoundary;\nError.Runtime = ErrorRuntime;\nError.Guard = ErrorGuard;\n\nexport { ErrorBoundary, ErrorRuntime, ErrorGuard };\nexport type { Props };\nexport default Error;\n"],"mappings":";;;;;;AAWA,MAAM,SAAS,EAAE,UAAU,cAAqB;CAC9C,MAAM,CAAC,OAAO,YAAY,SAAwB,IAAI;CAEtD,MAAM,eAAe,OAAuB,IAAI;CAChD,MAAM,eAAe,OAAO,KAAK;CAEjC,iBACE,UACA,UAAS;EACP,IAAI,aAAa,SACf;EAGF,aAAa,UAAU;EAEvB,MAAM,eACJ,MAAM,OAAO,WAAW,MAAM,WAAW;EAE3C,QAAQ,MAAM,kCAAkC,YAAY;EAE5D,MAAM,eAAe;EAErB,SAAS,YAAY;EACrB,UAAU,MAAM,SAAS,IAAI,OAAO,MAAM,YAAY,CAAC;EAEvD,iBAAiB;GACf,aAAa,UAAU;EACzB,GAAG,GAAG;CACR,GACA,EAAE,SAAS,KAAK,CAClB;CAEA,gBAAgB;EAGd,IAAI,CAFc,aAAa,SAG7B;EAGF,MAAM,4BAA4B,UAAiC;GACjE,IAAI,aAAa,SACf;GAGF,aAAa,UAAU;GAEvB,MAAM,eAAe,MAAM,QAAQ,WAAW;GAE9C,MAAM,eAAe;GACrB,SAAS,YAAY;GACrB,UAAU,MAAM,UAAU,IAAI,OAAO,MAAM,YAAY,CAAC;GAExD,iBAAiB;IACf,aAAa,UAAU;GACzB,GAAG,GAAG;EACR;EAEA,OAAO,iBACL,sBACA,0BACA,IACF;EAEA,aAAa;GACX,OAAO,oBACL,sBACA,0BACA,IACF;EACF;CACF,GAAG,CAAC,OAAO,CAAC;CAEZ,IAAI,OACF,OACE,oBAACA,SAAD;EACE,OAAM;EACN,SAAS;EACT,WAAU;EACV,eAAe;GACb,SAAS,IAAI;GACb,aAAa,UAAU;EACzB;CACD,CAAA;CAIL,OAAO,oBAAC,OAAD;EAAK,KAAK;EAAe;CAAc,CAAA;AAChD;;;ACrFA,MAAM,WAAW,EAAE,OAAO,MAAM,YAAmB;CACjD,MAAM,EAAE,OAAO,SAAS,aAAa,SAAS;CAE9C,iBAAiB,UAAS,MAAK;EAC7B,SAAS,EAAE,OAAO;EAClB,EAAE,eAAe;CACnB,CAAC;CAED,gBAAgB;EACd,aAAa,SAAS,IAAI;CAC5B,GAAG,CAAC,QAAQ,CAAC;CAEb,IAAI,CAAC,MACH,OAAO;CAGT,OAAO,oBAACC,SAAD;EAAgB;EAAS,SAAS;EAAO,OAAM;CAAiB,CAAA;AACzE;;;ACnBA,MAAM,QAAQC;AAEd,MAAM,WAAW;AACjB,MAAM,UAAUC;AAChB,MAAM,QAAQC"}
@@ -20,7 +20,8 @@ interface EditorRenderData {
20
20
  onChange: (value: string) => void;
21
21
  formatCode: (code: string) => Promise<string>;
22
22
  }
23
- interface Props extends Omit<Props$1, 'onSave' | 'onError'> {
23
+ interface Props extends Omit<Props$1, 'value' | 'onSave' | 'onError'> {
24
+ value?: string;
24
25
  defaultValue?: string;
25
26
  debounce?: number;
26
27
  renderEditor?: (data: EditorRenderData) => React.ReactNode;
@@ -34,4 +35,4 @@ type EditorComponent = typeof Editor$1 & {
34
35
  declare const Editor: EditorComponent;
35
36
  //#endregion
36
37
  export { Props$1 as a, Core as i, EditorRenderData as n, Props as r, Editor as t };
37
- //# sourceMappingURL=index-Ck3akHag.d.ts.map
38
+ //# sourceMappingURL=index-Ba8jGXSM.d.ts.map
@@ -1,5 +1,5 @@
1
1
  import { v as Section } from "./document-J9Lo9p81.js";
2
- import { B as BindingOption, H as BindingRenderMap, U as BindingType } from "./index-GuEiafMN.js";
2
+ import { G as BindingRenderMap, K as BindingType, U as BindingOption, q as DataAttrNode } from "./index-DxbG789f.js";
3
3
  import { t as FrameProps } from "./index-DpDU1IAw.js";
4
4
  import { useMultiSelect } from "@jbpark/use-hooks";
5
5
  import { LucideIcon } from "lucide-react";
@@ -147,6 +147,30 @@ interface ItemsEditorOptions {
147
147
  }
148
148
  declare const useItemsEditor: (value: string, { render, onChange, onNodeChange }?: ItemsEditorOptions) => ItemsEditor;
149
149
  //#endregion
150
+ //#region src/components/dnd/panel/use-children-editor.d.ts
151
+ interface ChildrenEditorOptions {
152
+ onChange?: (value: string) => void;
153
+ }
154
+ declare const useChildrenEditor: (items: DataAttrNode[], { onChange }?: ChildrenEditorOptions) => {
155
+ items: DataAttrNode[];
156
+ selection: {
157
+ readonly selected: Set<number>;
158
+ readonly isSelected: (index: number) => boolean;
159
+ readonly toggle: (index: number, shiftKey?: boolean) => void;
160
+ readonly clear: () => void;
161
+ readonly replace: (indices: Set<number>) => void;
162
+ };
163
+ actions: {
164
+ move: (from: number, to: number) => void;
165
+ remove: (index: number) => void;
166
+ add: () => void;
167
+ duplicateSelected: () => void;
168
+ moveSelected: (direction: "up" | "down") => void;
169
+ removeSelected: () => void;
170
+ };
171
+ };
172
+ type ChildrenEditor = ReturnType<typeof useChildrenEditor>;
173
+ //#endregion
150
174
  //#region src/components/dnd/index.d.ts
151
175
  type DndComponent = typeof Dnd$1 & {
152
176
  DraggableItem: typeof DraggableItem;
@@ -158,5 +182,5 @@ type DndComponent = typeof Dnd$1 & {
158
182
  };
159
183
  declare const Dnd: DndComponent;
160
184
  //#endregion
161
- export { Props as A, DraggableItem as C, DndPanel as D, DndPalette as E, PanelBinding as O, Panel as S, DraggableItemProps as T, Canvas as _, ItemsEditorNestedElement as a, Layout as b, useItemsEditor as c, Field as d, FieldProps as f, useDndPanel as g, useDndPalette as h, ItemsEditorItem as i, PanelNodeChange as k, ICON_MAP as l, useDndLayout as m, ItemsEditor as n, ItemsEditorNestedGroup as o, DndLayout as p, ItemsEditorActions as r, ItemsEditorOptions as s, Dnd as t, ICON_OPTIONS as u, DndLayoutProps as v, DraggableItemDragState as w, Palette as x, DndRegionProps as y };
162
- //# sourceMappingURL=index-Bqc5kUAG.d.ts.map
185
+ export { DndPanel as A, Layout as C, DraggableItemDragState as D, DraggableItem as E, PanelNodeChange as M, Props as N, DraggableItemProps as O, DndRegionProps as S, Panel as T, useDndLayout as _, ItemsEditor as a, Canvas as b, ItemsEditorNestedElement as c, useItemsEditor as d, ICON_MAP as f, DndLayout as g, FieldProps as h, useChildrenEditor as i, PanelBinding as j, DndPalette as k, ItemsEditorNestedGroup as l, Field as m, ChildrenEditor as n, ItemsEditorActions as o, ICON_OPTIONS as p, ChildrenEditorOptions as r, ItemsEditorItem as s, Dnd as t, ItemsEditorOptions as u, useDndPalette as v, Palette as w, DndLayoutProps as x, useDndPanel as y };
186
+ //# sourceMappingURL=index-DswWDEXZ.d.ts.map
@@ -12,6 +12,7 @@ interface DataAttrNode {
12
12
  dataAttributes: Attribute[];
13
13
  textContent: string;
14
14
  rawChildren?: string;
15
+ source?: string;
15
16
  loc?: {
16
17
  start: {
17
18
  line: number;
@@ -151,6 +152,28 @@ declare const bulkUpdate: (raw: string, entries: {
151
152
  property?: string;
152
153
  }[]) => UpdateResult;
153
154
  //#endregion
155
+ //#region src/utils/ast/children.d.ts
156
+ type ChildrenAction = {
157
+ type: 'move';
158
+ from: number;
159
+ to: number;
160
+ } | {
161
+ type: 'move-selected';
162
+ indices: number[];
163
+ direction: 'up' | 'down';
164
+ } | {
165
+ type: 'remove' | 'duplicate';
166
+ indices: number[];
167
+ } | {
168
+ type: 'append';
169
+ };
170
+ interface ChildrenEdit {
171
+ kind: 'children-edit';
172
+ expected: string[];
173
+ action: ChildrenAction;
174
+ }
175
+ declare const getChildrenSignatures: (nodes: DataAttrNode[]) => string[];
176
+ //#endregion
154
177
  //#region node_modules/.pnpm/@babel+parser@7.29.8/node_modules/@babel/parser/typings/babel-parser.d.ts
155
178
  declare class Position {
156
179
  line: number;
@@ -189,5 +212,5 @@ interface ValidationResult {
189
212
  }
190
213
  declare const validateBindingValue: (binding: BindingItem, value: unknown) => ValidationResult;
191
214
  //#endregion
192
- export { flattenEditableValue as A, BindingOption as B, EditablePathSegment as C, createNodeFromValue as D, arrayExpressionToCode as E, getCurrentValue as F, EditableNodeValueType as G, BindingRenderMap as H, getStructuredValue as I, ExtractedNodeValue as K, parseBinding as L, parseValue as M, setEditableValue as N, extractNodeValue as O, findEditableChildren as P, parseBindingExpression as R, generateCode as S, EditableValueEntry as T, BindingType as U, BindingRenderLeaf as V, DataAttrNode as W, moveArrayItems as _, replaceIds as a, updateArrayItemProperty as b, bulkUpdate as c, extract as d, ArrayItem as f, moveArrayItem as g, duplicateArrayItems as h, fillIds as i, parseArrayExpression as j, extractObjectProperties as k, update as l, appendArrayItem as m, validateBindingValue as n, UpdateFailure as o, ItemKind as p, NodeValueType as q, clone as r, UpdateResult as s, ValidationResult as t, clearExtractCache as u, parseItems as v, EditablePrimitive as w, updateArrayItemValue as x, removeArrayItems as y, BindingItem as z };
193
- //# sourceMappingURL=index-GuEiafMN.d.ts.map
215
+ export { createNodeFromValue as A, parseBinding as B, updateArrayItemProperty as C, EditablePrimitive as D, EditablePathSegment as E, parseValue as F, BindingRenderMap as G, BindingItem as H, setEditableValue as I, EditableNodeValueType as J, BindingType as K, findEditableChildren as L, extractObjectProperties as M, flattenEditableValue as N, EditableValueEntry as O, parseArrayExpression as P, getCurrentValue as R, removeArrayItems as S, generateCode as T, BindingOption as U, parseBindingExpression as V, BindingRenderLeaf as W, NodeValueType as X, ExtractedNodeValue as Y, appendArrayItem as _, replaceIds as a, moveArrayItems as b, getChildrenSignatures as c, bulkUpdate as d, update as f, ItemKind as g, ArrayItem as h, fillIds as i, extractNodeValue as j, arrayExpressionToCode as k, UpdateFailure as l, extract as m, validateBindingValue as n, ChildrenAction as o, clearExtractCache as p, DataAttrNode as q, clone as r, ChildrenEdit as s, ValidationResult as t, UpdateResult as u, duplicateArrayItems as v, updateArrayItemValue as w, parseItems as x, moveArrayItem as y, getStructuredValue as z };
216
+ //# sourceMappingURL=index-DxbG789f.d.ts.map
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { v as Section } from "./document-J9Lo9p81.js";
2
2
  import { t as FrameProps } from "./index-DpDU1IAw.js";
3
- import { A as Props, D as DndPanel, E as DndPalette, O as PanelBinding, S as Panel, T as DraggableItemProps, _ as Canvas, b as Layout, f as FieldProps, i as ItemsEditorItem, k as PanelNodeChange, n as ItemsEditor, p as DndLayout, s as ItemsEditorOptions, t as Dnd, x as Palette } from "./index-Bqc5kUAG.js";
4
- import { a as Props$2, n as EditorRenderData, r as Props$1, t as Editor } from "./index-Ck3akHag.js";
3
+ import { A as DndPanel, C as Layout, M as PanelNodeChange, N as Props, O as DraggableItemProps, T as Panel, a as ItemsEditor, b as Canvas, g as DndLayout, h as FieldProps, j as PanelBinding, k as DndPalette, s as ItemsEditorItem, t as Dnd, u as ItemsEditorOptions, w as Palette } from "./index-DswWDEXZ.js";
4
+ import { a as Props$2, n as EditorRenderData, r as Props$1, t as Editor } from "./index-Ba8jGXSM.js";
5
5
  import { a as Props$5, n as Props$4, o as Props$3, s as ErrorBoundary, t as Error } from "./index-CCynrS6c.js";
6
6
  import { n as Props$6, t as Preview } from "./index-lgHdCda5.js";
7
7
  //#region src/index.d.ts
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
- import { t as ContextProvider } from "./context-DH70wj9d.js";
2
- import { t as Dnd } from "./dnd-C4iBiSkv.js";
3
- import { t as Editor } from "./editor-C0lphNg6.js";
4
- import { t as Error } from "./error-lsJey-it.js";
5
- import { t as Preview } from "./preview-CNVXyDgY.js";
1
+ import { t as ContextProvider } from "./context-649REFsj.js";
2
+ import { t as Dnd } from "./dnd-DTT37EbA.js";
3
+ import { t as Editor } from "./editor-LzqHe_-F.js";
4
+ import { t as Error } from "./error-CO0EbMlA.js";
5
+ import { t as Preview } from "./preview-CWT0lgwq.js";
6
6
  import { jsx } from "react/jsx-runtime";
7
7
  //#region src/index.tsx
8
8
  const App = ({ children }) => {
@@ -1,2 +1,2 @@
1
- import { t as Preview } from "../preview-CNVXyDgY.js";
1
+ import { t as Preview } from "../preview-CWT0lgwq.js";
2
2
  export { Preview as default };
@@ -1,16 +1,16 @@
1
- import { r as cn } from "./utils-BwEgY5pe.js";
1
+ import { r as cn } from "./utils-WyxPYZGh.js";
2
2
  import { i as usePreview, r as useError } from "./states-Ci1AvoQ9.js";
3
- import { n as useCompiledModule, r as Frame, t as useDynamicTailwind } from "./use-dynamic-tailwind-C0Onss1A.js";
4
- import { t as Error } from "./error-lsJey-it.js";
3
+ import { n as useCompiledModule, r as Frame, t as useDynamicTailwind } from "./use-dynamic-tailwind-DAhKGsY4.js";
4
+ import { t as Error } from "./error-CO0EbMlA.js";
5
5
  import { useMemo } from "react";
6
6
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
7
7
  //#region src/components/preview/client.tsx
8
- const Client = ({ code: _code = "", className, showError, props = {}, modules = {}, frame, dynamicTailwind = false, provider }) => {
8
+ const Client = ({ code: _code, className, showError, props = {}, modules = {}, frame, dynamicTailwind = false, provider }) => {
9
9
  const { code } = usePreview();
10
10
  const { error, setError } = useError();
11
11
  const isError = !!showError && !!error;
12
12
  const classNames = cn(isError && "hidden", className);
13
- const effectiveCode = _code || code;
13
+ const effectiveCode = _code === void 0 ? code : _code;
14
14
  const module = useCompiledModule(effectiveCode, modules);
15
15
  const { ref: contentRef, css: dynamicCSS } = useDynamicTailwind(effectiveCode, dynamicTailwind);
16
16
  const componentProps = useMemo(() => ({ ...props }), [props]);
@@ -79,4 +79,4 @@ const Preview = ({ code, props = {}, modules = {}, dynamicTailwind = false, prov
79
79
  //#endregion
80
80
  export { Preview as t };
81
81
 
82
- //# sourceMappingURL=preview-CNVXyDgY.js.map
82
+ //# sourceMappingURL=preview-CWT0lgwq.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview-CWT0lgwq.js","names":["LiveError"],"sources":["../src/components/preview/client.tsx","../src/components/preview/preview.tsx"],"sourcesContent":["'use client';\n\nimport { useMemo } from 'react';\n\nimport { useError, usePreview } from '~/components/context/states';\nimport LiveError from '~/components/error';\nimport Frame, { type FrameProps } from '~/components/frame';\nimport { cn } from '~/utils';\n\nimport { type Props } from './preview';\nimport { useCompiledModule } from './use-compiled-module';\nimport { useDynamicTailwind } from './use-dynamic-tailwind';\n\nconst Client = ({\n code: _code,\n className,\n showError,\n props = {},\n modules = {},\n frame,\n dynamicTailwind = false,\n provider,\n}: Props) => {\n const { code } = usePreview();\n const { error, setError } = useError();\n const isError = !!showError && !!error;\n\n const classNames = cn(isError && 'hidden', className);\n\n const effectiveCode = _code === undefined ? code : _code;\n\n const module = useCompiledModule(effectiveCode, modules);\n\n // Attached to the wrapper below; scans the rendered DOM so classes coming\n // from an imported component are picked up too. See the hook for details.\n const { ref: contentRef, css: dynamicCSS } = useDynamicTailwind(\n effectiveCode,\n dynamicTailwind,\n );\n\n const componentProps = useMemo(\n () => ({\n ...props,\n }),\n [props],\n );\n\n const renderProvider = (component: React.ReactNode) => {\n return provider ? provider(component) : component;\n };\n\n if (module && module.error) {\n return (\n <>\n <div className={cn('relative h-full w-full', classNames)}>\n <LiveError message={module.error} title=\"Compile Error\" />\n </div>\n <LiveError.Runtime open={isError} />\n </>\n );\n }\n\n const Component = module?.exports?.default;\n\n if (!Component) {\n return null;\n }\n\n return (\n <>\n {frame ? (\n <div className={cn('h-full w-full', classNames)}>\n <Frame {...(frame as FrameProps)}>\n {container => (\n <div ref={contentRef} style={{ display: 'contents' }}>\n <LiveError.Boundary\n resetKeys={[effectiveCode]}\n onError={(e: Error) => setError(e.message)}\n >\n {renderProvider(\n <LiveError.Guard onError={e => setError(e.message)}>\n <Component {...componentProps} container={container} />\n {dynamicTailwind && dynamicCSS && (\n <style>{dynamicCSS}</style>\n )}\n </LiveError.Guard>,\n )}\n </LiveError.Boundary>\n </div>\n )}\n </Frame>\n </div>\n ) : (\n <div\n ref={contentRef}\n className={cn(\n 'relative h-full w-full overflow-x-hidden overflow-y-auto',\n classNames,\n )}\n style={{\n isolation: 'isolate',\n transform: 'translateZ(0)',\n containerType: 'inline-size',\n }}\n >\n <LiveError.Boundary\n resetKeys={[effectiveCode]}\n onError={e => setError(e.message)}\n >\n {renderProvider(\n <LiveError.Guard onError={e => setError(e.message)}>\n <Component {...componentProps} />\n {dynamicTailwind && dynamicCSS && <style>{dynamicCSS}</style>}\n </LiveError.Guard>,\n )}\n </LiveError.Boundary>\n </div>\n )}\n <LiveError.Runtime open={isError} />\n </>\n );\n};\n\nexport default Client;\n","import type React from 'react';\n\nimport type { FrameProps } from '../frame';\nimport Client from './client';\n\nexport interface Props extends React.ComponentPropsWithRef<'div'> {\n code?: string;\n showError?: boolean;\n props?: Record<string, unknown>;\n container?: HTMLElement | null;\n frame?: boolean | FrameProps;\n modules?: Record<string, unknown>;\n dynamicTailwind?: boolean;\n provider?: (children: React.ReactNode) => React.ReactNode;\n}\n\n// A thin wrapper around Client, which does the actual compiling, error\n// handling, and frame wrapping. This used to have its own duplicate\n// compile-and-render branch for the `code` prop that never wrapped its\n// output in <Frame>, so `frame` was silently ignored whenever `code` was\n// passed — see #187. Client already handles `code` (falling back to\n// context when absent) and `frame`, so there is only one render path now.\nconst Preview = ({\n code,\n props = {},\n modules = {},\n dynamicTailwind = false,\n provider,\n ...restProps\n}: Props) => {\n return (\n <Client\n code={code}\n props={props}\n modules={modules}\n dynamicTailwind={dynamicTailwind}\n provider={provider}\n {...restProps}\n />\n );\n};\n\nexport default Preview;\n"],"mappings":";;;;;;;AAaA,MAAM,UAAU,EACd,MAAM,OACN,WACA,WACA,QAAQ,CAAC,GACT,UAAU,CAAC,GACX,OACA,kBAAkB,OAClB,eACW;CACX,MAAM,EAAE,SAAS,WAAW;CAC5B,MAAM,EAAE,OAAO,aAAa,SAAS;CACrC,MAAM,UAAU,CAAC,CAAC,aAAa,CAAC,CAAC;CAEjC,MAAM,aAAa,GAAG,WAAW,UAAU,SAAS;CAEpD,MAAM,gBAAgB,UAAU,KAAA,IAAY,OAAO;CAEnD,MAAM,SAAS,kBAAkB,eAAe,OAAO;CAIvD,MAAM,EAAE,KAAK,YAAY,KAAK,eAAe,mBAC3C,eACA,eACF;CAEA,MAAM,iBAAiB,eACd,EACL,GAAG,MACL,IACA,CAAC,KAAK,CACR;CAEA,MAAM,kBAAkB,cAA+B;EACrD,OAAO,WAAW,SAAS,SAAS,IAAI;CAC1C;CAEA,IAAI,UAAU,OAAO,OACnB,OACE,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,OAAD;EAAK,WAAW,GAAG,0BAA0B,UAAU;EACrD,UAAA,oBAACA,OAAD;GAAW,SAAS,OAAO;GAAO,OAAM;EAAiB,CAAA;CACtD,CAAA,GACL,oBAACA,MAAU,SAAX,EAAmB,MAAM,QAAU,CAAA,CACnC,EAAA,CAAA;CAIN,MAAM,YAAY,QAAQ,SAAS;CAEnC,IAAI,CAAC,WACH,OAAO;CAGT,OACE,qBAAA,UAAA,EAAA,UAAA,CACG,QACC,oBAAC,OAAD;EAAK,WAAW,GAAG,iBAAiB,UAAU;EAC5C,UAAA,oBAAC,OAAD;GAAO,GAAK;GACT,WAAA,cACC,oBAAC,OAAD;IAAK,KAAK;IAAY,OAAO,EAAE,SAAS,WAAW;IACjD,UAAA,oBAACA,MAAU,UAAX;KACE,WAAW,CAAC,aAAa;KACzB,UAAU,MAAa,SAAS,EAAE,OAAO;KAExC,UAAA,eACC,qBAACA,MAAU,OAAX;MAAiB,UAAS,MAAK,SAAS,EAAE,OAAO;MAAjD,UAAA,CACE,oBAAC,WAAD;OAAW,GAAI;OAA2B;MAAY,CAAA,GACrD,mBAAmB,cAClB,oBAAC,SAAD,EAAA,UAAQ,WAAkB,CAAA,CAEb;KACnB,CAAA,CAAA;IACkB,CAAA;GACjB,CAAA;EAEF,CAAA;CACJ,CAAA,IAEL,oBAAC,OAAD;EACE,KAAK;EACL,WAAW,GACT,4DACA,UACF;EACA,OAAO;GACL,WAAW;GACX,WAAW;GACX,eAAe;EACjB;EAEA,UAAA,oBAACA,MAAU,UAAX;GACE,WAAW,CAAC,aAAa;GACzB,UAAS,MAAK,SAAS,EAAE,OAAO;GAE/B,UAAA,eACC,qBAACA,MAAU,OAAX;IAAiB,UAAS,MAAK,SAAS,EAAE,OAAO;IAAjD,UAAA,CACE,oBAAC,WAAD,EAAW,GAAI,eAAiB,CAAA,GAC/B,mBAAmB,cAAc,oBAAC,SAAD,EAAA,UAAQ,WAAkB,CAAA,CAC7C;GACnB,CAAA,CAAA;EACkB,CAAA;CACjB,CAAA,GAEP,oBAACA,MAAU,SAAX,EAAmB,MAAM,QAAU,CAAA,CACnC,EAAA,CAAA;AAEN;;;ACnGA,MAAM,WAAW,EACf,MACA,QAAQ,CAAC,GACT,UAAU,CAAC,GACX,kBAAkB,OAClB,UACA,GAAG,gBACQ;CACX,OACE,oBAAC,QAAD;EACQ;EACC;EACE;EACQ;EACP;EACV,GAAI;CACL,CAAA;AAEL"}
@@ -1,2 +1,2 @@
1
- import { t as ContextProvider } from "../context-DH70wj9d.js";
1
+ import { t as ContextProvider } from "../context-649REFsj.js";
2
2
  export { ContextProvider as default };
@@ -1,4 +1,4 @@
1
- import { i as compile, l as getCachedScriptBlob, t as baseModules } from "./utils-BwEgY5pe.js";
1
+ import { i as compile, l as getCachedScriptBlob, t as baseModules } from "./utils-WyxPYZGh.js";
2
2
  import { t as generateTailwindCSSFromDOM } from "./tailwind-CbjdLyVX.js";
3
3
  import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
4
4
  import { jsx } from "react/jsx-runtime";
@@ -24,6 +24,63 @@ const estimatePositionedElementHeight = (offsetHeight, transform, probeHeight) =
24
24
  return Math.min(offsetY + offsetHeight, probeHeight);
25
25
  };
26
26
  //#endregion
27
+ //#region src/components/frame/style-sync.ts
28
+ const SYNCED_STYLE_ATTR = "data-live-editor-synced-style";
29
+ const createStyleSyncManager = () => ({ clones: /* @__PURE__ */ new Map() });
30
+ const isDocument = (target) => target.nodeType === Node.DOCUMENT_NODE;
31
+ const sourceStyles = (document) => Array.from(document.head.querySelectorAll("link[rel=\"stylesheet\"], style"));
32
+ const copyAttributes = (source, clone, transformStyle) => {
33
+ Array.from(clone.attributes).forEach((attribute) => {
34
+ if (attribute.name !== SYNCED_STYLE_ATTR && !source.hasAttribute(attribute.name)) clone.removeAttribute(attribute.name);
35
+ });
36
+ Array.from(source.attributes).forEach((attribute) => {
37
+ clone.setAttribute(attribute.name, attribute.value);
38
+ });
39
+ if (source.tagName === "LINK" && clone.tagName === "LINK") clone.disabled = source.disabled;
40
+ clone.textContent = source.tagName === "STYLE" ? transformStyle(source.textContent || "") : source.textContent;
41
+ };
42
+ const createClone = (source, target, transformStyle) => {
43
+ const clone = (isDocument(target) ? target : target.ownerDocument).createElement(source.tagName.toLowerCase());
44
+ clone.setAttribute(SYNCED_STYLE_ATTR, "");
45
+ copyAttributes(source, clone, transformStyle);
46
+ return clone;
47
+ };
48
+ const targetContainer = (target) => isDocument(target) ? target.head : target;
49
+ const isSyncedStyle = (node) => {
50
+ const element = node;
51
+ return (element.tagName === "LINK" || element.tagName === "STYLE") && element.hasAttribute(SYNCED_STYLE_ATTR);
52
+ };
53
+ const removeClone = (clone) => {
54
+ clone.remove();
55
+ };
56
+ const reconcileStyles = (sourceDocument, target, manager, enabled, transformStyle = (content) => content) => {
57
+ if (!enabled) {
58
+ manager.clones.forEach(removeClone);
59
+ manager.clones.clear();
60
+ return;
61
+ }
62
+ const sources = sourceStyles(sourceDocument);
63
+ const sourceSet = new Set(sources);
64
+ const container = targetContainer(target);
65
+ manager.clones.forEach((clone, source) => {
66
+ if (!sourceSet.has(source)) {
67
+ removeClone(clone);
68
+ manager.clones.delete(source);
69
+ }
70
+ });
71
+ let previous = null;
72
+ sources.forEach((source) => {
73
+ let clone = manager.clones.get(source);
74
+ if (!clone) {
75
+ clone = createClone(source, target, transformStyle);
76
+ manager.clones.set(source, clone);
77
+ } else copyAttributes(source, clone, transformStyle);
78
+ const nextSibling = previous ? previous.nextSibling : Array.from(container.childNodes).find(isSyncedStyle) ?? null;
79
+ if (clone !== nextSibling) container.insertBefore(clone, nextSibling);
80
+ previous = clone;
81
+ });
82
+ };
83
+ //#endregion
27
84
  //#region src/components/frame/viewport-units.ts
28
85
  const UNIT_MAP = {
29
86
  vh: "cqh",
@@ -60,44 +117,11 @@ const IFrame = ({ title = "Live Preview", sandbox, style = {}, scripts = EMPTY_S
60
117
  const prevStyleCountRef = useRef(0);
61
118
  const prevStylesheetCountRef = useRef(0);
62
119
  const shouldAutoHeight = autoHeight && style.height == null;
63
- const styleManagerRef = useRef({
64
- copiedLinks: /* @__PURE__ */ new Set(),
65
- copiedStyles: /* @__PURE__ */ new Set()
66
- });
120
+ const styleManagerRef = useRef(createStyleSyncManager());
67
121
  const applyStyle = useCallback(() => {
68
122
  const doc = iframeRef.current?.contentDocument;
69
- if (!doc || !syncStyle) return;
70
- const manager = styleManagerRef.current;
71
- const links = document.querySelectorAll("link[rel=\"stylesheet\"]");
72
- const newLinks = Array.from(links).map((link) => link.href).filter((href) => !manager.copiedLinks.has(href));
73
- if (newLinks.length) {
74
- const fragment = doc.createDocumentFragment();
75
- newLinks.forEach((href) => {
76
- const link = doc.createElement("link");
77
- link.rel = "stylesheet";
78
- link.href = href;
79
- fragment.appendChild(link);
80
- manager.copiedLinks.add(href);
81
- });
82
- doc.head.appendChild(fragment);
83
- }
84
- const styles = document.querySelectorAll("style");
85
- const newStyles = Array.from(styles).map((style) => style.textContent || "").filter((content) => {
86
- if (!content) return false;
87
- const hash = content.length + content.slice(0, 50);
88
- if (manager.copiedStyles.has(hash)) return false;
89
- manager.copiedStyles.add(hash);
90
- return true;
91
- });
92
- if (newStyles.length) {
93
- const fragment = doc.createDocumentFragment();
94
- newStyles.forEach((content) => {
95
- const style = doc.createElement("style");
96
- style.textContent = convertViewportUnits(content);
97
- fragment.appendChild(style);
98
- });
99
- doc.head.appendChild(fragment);
100
- }
123
+ if (!doc) return;
124
+ reconcileStyles(document, doc, styleManagerRef.current, syncStyle, convertViewportUnits);
101
125
  }, [syncStyle]);
102
126
  const applyStyleTimeoutRef = useRef(void 0);
103
127
  const debouncedApplyStyle = useCallback(() => {
@@ -111,8 +135,7 @@ const IFrame = ({ title = "Live Preview", sandbox, style = {}, scripts = EMPTY_S
111
135
  enabled: syncStyle,
112
136
  childList: true,
113
137
  subtree: true,
114
- attributes: true,
115
- attributeFilter: ["href"]
138
+ attributes: true
116
139
  });
117
140
  useEffect(() => {
118
141
  const $iframe = iframeRef.current;
@@ -316,56 +339,25 @@ const Shadow = ({ syncStyle = false, children }) => {
316
339
  const renderTargetRef = useRef(null);
317
340
  const [renderTarget, setRenderTarget] = useState(null);
318
341
  const [hostContainer, setHostContainer] = useState(null);
319
- const styleManagerRef = useRef({
320
- copiedLinks: /* @__PURE__ */ new Set(),
321
- copiedStyles: /* @__PURE__ */ new Set()
322
- });
342
+ const styleManagerRef = useRef(createStyleSyncManager());
323
343
  const applyStyle = useCallback(() => {
324
344
  const shadowRoot = shadowRootRef.current;
325
- if (!shadowRoot || !syncStyle) return;
326
- const manager = styleManagerRef.current;
327
- const links = document.querySelectorAll("link[rel=\"stylesheet\"]");
328
- const newLinks = Array.from(links).map((link) => link.href).filter((href) => !manager.copiedLinks.has(href));
329
- if (newLinks.length) {
330
- const fragment = document.createDocumentFragment();
331
- newLinks.forEach((href) => {
332
- const link = document.createElement("link");
333
- link.rel = "stylesheet";
334
- link.href = href;
335
- fragment.appendChild(link);
336
- manager.copiedLinks.add(href);
337
- });
338
- shadowRoot.appendChild(fragment);
339
- }
340
- const styleTags = document.querySelectorAll("style");
341
- const newStyles = Array.from(styleTags).map((style) => style.textContent || "").filter((content) => {
342
- if (!content) return false;
343
- const hash = content.length + content.slice(0, 50);
344
- if (manager.copiedStyles.has(hash)) return false;
345
- manager.copiedStyles.add(hash);
346
- return true;
347
- });
348
- if (newStyles.length) {
349
- const fragment = document.createDocumentFragment();
350
- newStyles.forEach((content) => {
351
- const style = document.createElement("style");
352
- style.textContent = content;
353
- fragment.appendChild(style);
354
- });
355
- shadowRoot.appendChild(fragment);
356
- }
345
+ if (!shadowRoot) return;
346
+ reconcileStyles(document, shadowRoot, styleManagerRef.current, syncStyle);
357
347
  }, [syncStyle]);
358
348
  const applyStyleTimeoutRef = useRef(void 0);
359
349
  const debouncedApplyStyle = useCallback(() => {
360
350
  clearTimeout(applyStyleTimeoutRef.current);
361
351
  applyStyleTimeoutRef.current = window.setTimeout(applyStyle, 50);
362
352
  }, [applyStyle]);
353
+ useEffect(() => {
354
+ return () => clearTimeout(applyStyleTimeoutRef.current);
355
+ }, []);
363
356
  useMutationObserver(document.head, debouncedApplyStyle, {
364
357
  enabled: syncStyle,
365
358
  childList: true,
366
359
  subtree: true,
367
- attributes: true,
368
- attributeFilter: ["href"]
360
+ attributes: true
369
361
  });
370
362
  useLayoutEffect(() => {
371
363
  if (!hostRef.current) return;
@@ -456,4 +448,4 @@ const useDynamicTailwind = (code, enabled) => {
456
448
  //#endregion
457
449
  export { useCompiledModule as n, Frame as r, useDynamicTailwind as t };
458
450
 
459
- //# sourceMappingURL=use-dynamic-tailwind-C0Onss1A.js.map
451
+ //# sourceMappingURL=use-dynamic-tailwind-DAhKGsY4.js.map