@editframe/react 0.38.1 → 0.39.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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TimelineRoot.js","names":["TimelineRoot: React.FC<TimelineRootProps>"],"sources":["../../src/components/TimelineRoot.tsx"],"sourcesContent":["import * as React from \"react\";\nimport * as ReactDOM from \"react-dom/client\";\nimport { flushSync } from \"react-dom\";\nimport { useEffect, useRef } from \"react\";\nimport {\n registerCloneFactory,\n unregisterCloneFactory,\n type EFTimegroup,\n} from \"@editframe/elements\";\n\ninterface TimelineRootProps {\n /**\n * Unique identifier used for playback control targeting (Preview, Scrubber, TogglePlay).\n * Also passed as `id` prop to the component for clone rendering.\n */\n id: string;\n /**\n * React component that renders the timeline content (must include a Timegroup at root).\n */\n component: React.ComponentType<Record<string, unknown>>;\n /** Optional CSS class name for the container */\n className?: string;\n /** Optional inline styles for the container */\n style?: React.CSSProperties;\n /** Optional children to render alongside the component (e.g., Configuration wrapper) */\n children?: React.ReactNode;\n}\n\n/**\n * TimelineRoot - Factory wrapper for React-based timelines.\n *\n * This component enables proper clone rendering by registering a clone factory\n * for the managed ef-timegroup element. When render clones are needed\n * (for exports, thumbnails, etc.), the factory mounts a fresh React component\n * tree — producing a fully functional second instance with all hooks, state,\n * and effects running.\n *\n * This is necessary because React DOM cannot be cloned via cloneNode() —\n * cloned elements are dead HTML without React's fiber tree behind them.\n * The factory pattern ensures each clone is a real React mount.\n *\n * @example\n * ```tsx\n * const MyTimeline = () => (\n * <Timegroup mode=\"sequence\">\n * <MyScenes />\n * </Timegroup>\n * );\n *\n * <TimelineRoot id=\"root\" component={MyTimeline} />\n * ```\n */\nexport const TimelineRoot: React.FC<TimelineRootProps> = ({\n id,\n component: Component,\n className,\n style,\n children,\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const componentRef = useRef(Component);\n componentRef.current = Component;\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n // Find the root timegroup rendered by Component\n const timegroup = container.querySelector(\"ef-timegroup\") as EFTimegroup;\n if (!timegroup) {\n throw new Error(\n \"[TimelineRoot] No ef-timegroup found in component. \" +\n \"Ensure your component renders a Timegroup.\",\n );\n }\n\n // Register a clone factory for this element.\n // When createRenderClone is called, it will use this factory\n // to mount a fresh React tree instead of cloning dead DOM.\n registerCloneFactory(timegroup, (cloneContainer: HTMLElement) => {\n const root = ReactDOM.createRoot(cloneContainer);\n const Comp = componentRef.current;\n flushSync(() => {\n root.render(<Comp id={id} />);\n });\n\n const newTimegroup = cloneContainer.querySelector(\n \"ef-timegroup\",\n ) as EFTimegroup | null;\n if (!newTimegroup) {\n throw new Error(\n \"[TimelineRoot] Clone factory did not produce an ef-timegroup. \" +\n \"Ensure your component renders a Timegroup.\",\n );\n }\n\n return {\n timegroup: newTimegroup,\n cleanup: () => {\n
|
|
1
|
+
{"version":3,"file":"TimelineRoot.js","names":["TimelineRoot: React.FC<TimelineRootProps>"],"sources":["../../src/components/TimelineRoot.tsx"],"sourcesContent":["import * as React from \"react\";\nimport * as ReactDOM from \"react-dom/client\";\nimport { flushSync } from \"react-dom\";\nimport { useEffect, useRef } from \"react\";\nimport {\n registerCloneFactory,\n unregisterCloneFactory,\n type EFTimegroup,\n} from \"@editframe/elements\";\n\ninterface TimelineRootProps {\n /**\n * Unique identifier used for playback control targeting (Preview, Scrubber, TogglePlay).\n * Also passed as `id` prop to the component for clone rendering.\n */\n id: string;\n /**\n * React component that renders the timeline content (must include a Timegroup at root).\n */\n component: React.ComponentType<Record<string, unknown>>;\n /** Optional CSS class name for the container */\n className?: string;\n /** Optional inline styles for the container */\n style?: React.CSSProperties;\n /** Optional children to render alongside the component (e.g., Configuration wrapper) */\n children?: React.ReactNode;\n}\n\n/**\n * TimelineRoot - Factory wrapper for React-based timelines.\n *\n * This component enables proper clone rendering by registering a clone factory\n * for the managed ef-timegroup element. When render clones are needed\n * (for exports, thumbnails, etc.), the factory mounts a fresh React component\n * tree — producing a fully functional second instance with all hooks, state,\n * and effects running.\n *\n * This is necessary because React DOM cannot be cloned via cloneNode() —\n * cloned elements are dead HTML without React's fiber tree behind them.\n * The factory pattern ensures each clone is a real React mount.\n *\n * @example\n * ```tsx\n * const MyTimeline = () => (\n * <Timegroup mode=\"sequence\">\n * <MyScenes />\n * </Timegroup>\n * );\n *\n * <TimelineRoot id=\"root\" component={MyTimeline} />\n * ```\n */\nexport const TimelineRoot: React.FC<TimelineRootProps> = ({\n id,\n component: Component,\n className,\n style,\n children,\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const componentRef = useRef(Component);\n componentRef.current = Component;\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n // Find the root timegroup rendered by Component\n const timegroup = container.querySelector(\"ef-timegroup\") as EFTimegroup;\n if (!timegroup) {\n throw new Error(\n \"[TimelineRoot] No ef-timegroup found in component. \" +\n \"Ensure your component renders a Timegroup.\",\n );\n }\n\n // Register a clone factory for this element.\n // When createRenderClone is called, it will use this factory\n // to mount a fresh React tree instead of cloning dead DOM.\n registerCloneFactory(timegroup, (cloneContainer: HTMLElement) => {\n const root = ReactDOM.createRoot(cloneContainer);\n const Comp = componentRef.current;\n flushSync(() => {\n root.render(<Comp id={id} />);\n });\n\n const newTimegroup = cloneContainer.querySelector(\n \"ef-timegroup\",\n ) as EFTimegroup | null;\n if (!newTimegroup) {\n throw new Error(\n \"[TimelineRoot] Clone factory did not produce an ef-timegroup. \" +\n \"Ensure your component renders a Timegroup.\",\n );\n }\n\n return {\n timegroup: newTimegroup,\n cleanup: () => {\n root.unmount();\n },\n };\n });\n\n return () => {\n unregisterCloneFactory(timegroup);\n };\n }, [id]);\n\n return (\n <div\n ref={containerRef}\n className={className}\n style={{ display: \"contents\", ...style }}\n >\n {children}\n <Component id={id} />\n </div>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoDA,MAAaA,gBAA6C,EACxD,IACA,WAAW,WACX,WACA,OACA,eACI;CACJ,MAAM,eAAe,OAAuB,KAAK;CACjD,MAAM,eAAe,OAAO,UAAU;AACtC,cAAa,UAAU;AAEvB,iBAAgB;EACd,MAAM,YAAY,aAAa;AAC/B,MAAI,CAAC,UAAW;EAGhB,MAAM,YAAY,UAAU,cAAc,eAAe;AACzD,MAAI,CAAC,UACH,OAAM,IAAI,MACR,gGAED;AAMH,uBAAqB,YAAY,mBAAgC;GAC/D,MAAM,OAAO,SAAS,WAAW,eAAe;GAChD,MAAM,OAAO,aAAa;AAC1B,mBAAgB;AACd,SAAK,OAAO,oBAAC,QAAS,KAAM,CAAC;KAC7B;GAEF,MAAM,eAAe,eAAe,cAClC,eACD;AACD,OAAI,CAAC,aACH,OAAM,IAAI,MACR,2GAED;AAGH,UAAO;IACL,WAAW;IACX,eAAe;AACb,UAAK,SAAS;;IAEjB;IACD;AAEF,eAAa;AACX,0BAAuB,UAAU;;IAElC,CAAC,GAAG,CAAC;AAER,QACE,qBAAC;EACC,KAAK;EACM;EACX,OAAO;GAAE,SAAS;GAAY,GAAG;GAAO;aAEvC,UACD,oBAAC,aAAc,KAAM;GACjB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@editframe/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.39.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"author": "",
|
|
40
40
|
"license": "UNLICENSED",
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@editframe/elements": "0.
|
|
42
|
+
"@editframe/elements": "0.39.0",
|
|
43
43
|
"@lit/task": "^1.0.1",
|
|
44
44
|
"@react-three/fiber": "^9.5.0",
|
|
45
45
|
"@react-three/offscreen": "^0.0.8",
|