@sigx/runtime-dom 0.2.3 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/directives.d.ts +55 -0
- package/dist/directives.d.ts.map +1 -0
- package/dist/index.d.ts +6 -63
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +51 -2
- package/dist/index.js.map +1 -0
- package/dist/internals.d.ts +5 -2
- package/dist/internals.d.ts.map +1 -1
- package/dist/internals.js +2 -2
- package/dist/model-processor.d.ts +8 -0
- package/dist/model-processor.d.ts.map +1 -0
- package/dist/nodeOps.d.ts +10 -0
- package/dist/nodeOps.d.ts.map +1 -0
- package/dist/patchProp.d.ts +9 -0
- package/dist/patchProp.d.ts.map +1 -0
- package/dist/{src-BvXBxpbX.js → render-BWNQH1pJ.js} +91 -180
- package/dist/render-BWNQH1pJ.js.map +1 -0
- package/dist/render.d.ts +26 -0
- package/dist/render.d.ts.map +1 -0
- package/package.json +4 -4
- package/dist/src-BvXBxpbX.js.map +0 -1
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Directive runtime for DOM (element-level use:* directives)
|
|
3
|
+
*
|
|
4
|
+
* Handles the built-in directive registry, directive lifecycle hooks
|
|
5
|
+
* (created, mounted, updated, unmounted), and event handler cleanup.
|
|
6
|
+
*/
|
|
7
|
+
import { type DirectiveDefinition } from '@sigx/runtime-core';
|
|
8
|
+
import type { AppContext } from '@sigx/runtime-core';
|
|
9
|
+
/**
|
|
10
|
+
* A directive definition narrowed to DOM elements.
|
|
11
|
+
* Use this type when defining directives for the DOM renderer.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { defineDirective, type DOMDirective } from 'sigx';
|
|
16
|
+
*
|
|
17
|
+
* const tooltip = defineDirective<string, HTMLElement>({
|
|
18
|
+
* mounted(el, { value }) {
|
|
19
|
+
* el.title = value; // el is HTMLElement, fully typed
|
|
20
|
+
* }
|
|
21
|
+
* });
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export type DOMDirective<T = any> = DirectiveDefinition<T, HTMLElement>;
|
|
25
|
+
/**
|
|
26
|
+
* Register a built-in directive so it can be used with the shorthand syntax:
|
|
27
|
+
* `<div use:show={value}>` instead of `<div use:show={[show, value]}>`.
|
|
28
|
+
* @internal
|
|
29
|
+
*/
|
|
30
|
+
export declare function registerBuiltInDirective(name: string, def: DirectiveDefinition): void;
|
|
31
|
+
/**
|
|
32
|
+
* Look up a registered built-in directive by name.
|
|
33
|
+
* Used by SSR renderer to resolve `use:<name>={value}` shorthand.
|
|
34
|
+
* @internal
|
|
35
|
+
*/
|
|
36
|
+
export declare function resolveBuiltInDirective(name: string): DirectiveDefinition | undefined;
|
|
37
|
+
/**
|
|
38
|
+
* Process a `use:*` prop in patchProp.
|
|
39
|
+
* Handles directive created and updated lifecycle hooks.
|
|
40
|
+
* @internal
|
|
41
|
+
*/
|
|
42
|
+
export declare function patchDirective(el: Element, name: string, prevValue: any, nextValue: any, appContext: AppContext | null): void;
|
|
43
|
+
/**
|
|
44
|
+
* Called after an element is inserted into the DOM.
|
|
45
|
+
* Invokes `mounted` hooks for all directives on the element.
|
|
46
|
+
* @internal
|
|
47
|
+
*/
|
|
48
|
+
export declare function onElementMounted(el: Element): void;
|
|
49
|
+
/**
|
|
50
|
+
* Called before an element is removed from the DOM.
|
|
51
|
+
* Invokes `unmounted` hooks for all directives on the element.
|
|
52
|
+
* @internal
|
|
53
|
+
*/
|
|
54
|
+
export declare function onElementUnmounted(el: Element): void;
|
|
55
|
+
//# sourceMappingURL=directives.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"directives.d.ts","sourceRoot":"","sources":["../src/directives.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAe,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC3E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,YAAY,CAAC,CAAC,GAAG,GAAG,IAAI,mBAAmB,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;AAUxE;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,mBAAmB,GAAG,IAAI,CAErF;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS,CAErF;AA+BD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,UAAU,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI,CAoE7H;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI,CASlD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI,CA0BpD"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,69 +1,12 @@
|
|
|
1
1
|
import './jsx';
|
|
2
2
|
import './types';
|
|
3
3
|
import './directives/show-jsx-types';
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* ```ts
|
|
13
|
-
* import { defineDirective, type DOMDirective } from 'sigx';
|
|
14
|
-
*
|
|
15
|
-
* const tooltip = defineDirective<string, HTMLElement>({
|
|
16
|
-
* mounted(el, { value }) {
|
|
17
|
-
* el.title = value; // el is HTMLElement, fully typed
|
|
18
|
-
* }
|
|
19
|
-
* });
|
|
20
|
-
* ```
|
|
21
|
-
*/
|
|
22
|
-
export type DOMDirective<T = any> = DirectiveDefinition<T, HTMLElement>;
|
|
23
|
-
/**
|
|
24
|
-
* Register a built-in directive so it can be used with the shorthand syntax:
|
|
25
|
-
* `<div use:show={value}>` instead of `<div use:show={[show, value]}>`.
|
|
26
|
-
* @internal
|
|
27
|
-
*/
|
|
28
|
-
export declare function registerBuiltInDirective(name: string, def: DirectiveDefinition): void;
|
|
29
|
-
/**
|
|
30
|
-
* Look up a registered built-in directive by name.
|
|
31
|
-
* Used by SSR renderer to resolve `use:<name>={value}` shorthand.
|
|
32
|
-
* @internal
|
|
33
|
-
*/
|
|
34
|
-
export declare function resolveBuiltInDirective(name: string): DirectiveDefinition | undefined;
|
|
35
|
-
/**
|
|
36
|
-
* Process a `use:*` prop in patchProp.
|
|
37
|
-
* Handles directive created and updated lifecycle hooks.
|
|
38
|
-
* @internal
|
|
39
|
-
*/
|
|
40
|
-
declare function patchDirective(el: Element, name: string, prevValue: any, nextValue: any, appContext: AppContext | null): void;
|
|
41
|
-
/**
|
|
42
|
-
* Called after an element is inserted into the DOM.
|
|
43
|
-
* Invokes `mounted` hooks for all directives on the element.
|
|
44
|
-
* @internal
|
|
45
|
-
*/
|
|
46
|
-
declare function onElementMounted(el: Element): void;
|
|
47
|
-
declare function patchProp(dom: Element, key: string, prevValue: any, nextValue: any, isSVG?: boolean): void;
|
|
48
|
-
declare const nodeOps: RendererOptions<Node, Element>;
|
|
49
|
-
/**
|
|
50
|
-
* Render a SignalX element to a DOM container.
|
|
51
|
-
* Supports both Element references and CSS selectors.
|
|
52
|
-
*
|
|
53
|
-
* @example
|
|
54
|
-
* ```tsx
|
|
55
|
-
* import { render } from 'sigx';
|
|
56
|
-
*
|
|
57
|
-
* // Using CSS selector
|
|
58
|
-
* render(<App />, "#app");
|
|
59
|
-
*
|
|
60
|
-
* // Using element reference
|
|
61
|
-
* render(<App />, document.getElementById('app')!);
|
|
62
|
-
* ```
|
|
63
|
-
*/
|
|
64
|
-
export declare const render: (element: JSXElement, container: string | Element, appContext?: AppContext | undefined) => void;
|
|
65
|
-
export declare const patch: import("@sigx/runtime-core/internals").RendererPatchFn<Node, Element>, mount: import("@sigx/runtime-core/internals").RendererMountFn<Node, Element>, unmount: import("@sigx/runtime-core/internals").RendererUnmountFn<Node, Element>, mountComponent: import("@sigx/runtime-core/internals").RendererMountComponentFn<Node, Element>;
|
|
66
|
-
export { patchProp, patchDirective, onElementMounted, nodeOps };
|
|
4
|
+
import './model-processor.js';
|
|
5
|
+
export { render, patch, mount, unmount, mountComponent } from './render.js';
|
|
6
|
+
export { patchProp } from './patchProp.js';
|
|
7
|
+
export { patchDirective, onElementMounted, registerBuiltInDirective, resolveBuiltInDirective } from './directives.js';
|
|
8
|
+
export type { DOMDirective } from './directives.js';
|
|
9
|
+
export { nodeOps } from './nodeOps.js';
|
|
67
10
|
export { Portal, supportsMoveBefore, moveNode } from './Portal.js';
|
|
68
11
|
export { show } from './directives/show.js';
|
|
69
12
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,OAAO,CAAC;AAEf,OAAO,SAAS,CAAC;AAEjB,OAAO,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,OAAO,CAAC;AAEf,OAAO,SAAS,CAAC;AAEjB,OAAO,6BAA6B,CAAC;AAGrC,OAAO,sBAAsB,CAAC;AAG9B,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AACtH,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,OAAO,EAAE,MAAM,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGnE,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,51 @@
|
|
|
1
|
-
import { a as e, c as t, d as n,
|
|
2
|
-
|
|
1
|
+
import { a as e, c as t, d as n, i as r, l as i, n as a, o, r as s, s as c, t as l, u } from "./render-BWNQH1pJ.js";
|
|
2
|
+
import { Fragment as d, component as f, defineDirective as p, jsx as m } from "@sigx/runtime-core";
|
|
3
|
+
import { normalizeSubTree as h } from "@sigx/runtime-core/internals";
|
|
4
|
+
import { effect as g } from "@sigx/reactivity";
|
|
5
|
+
//#region src/Portal.tsx
|
|
6
|
+
function _() {
|
|
7
|
+
return typeof Node < "u" && "moveBefore" in Node.prototype;
|
|
8
|
+
}
|
|
9
|
+
function v(e, t, n = null) {
|
|
10
|
+
_() ? e.moveBefore(t, n) : e.insertBefore(t, n);
|
|
11
|
+
}
|
|
12
|
+
function y(e) {
|
|
13
|
+
return e === void 0 ? document.body : typeof e == "string" ? document.querySelector(e) || (console.warn(`Portal: Target "${e}" not found, falling back to document.body`), document.body) : e;
|
|
14
|
+
}
|
|
15
|
+
var b = f(({ props: t, slots: n, onMounted: r, onUnmounted: i }) => {
|
|
16
|
+
let a = null, o = null, c = null;
|
|
17
|
+
return r(() => {
|
|
18
|
+
if (t.disabled) return;
|
|
19
|
+
let e = y(t.to);
|
|
20
|
+
a = document.createElement("div"), a.setAttribute("data-sigx-portal", ""), v(e, a), c = g(() => {
|
|
21
|
+
let e = n.default();
|
|
22
|
+
if (!a) return;
|
|
23
|
+
let t = h(e);
|
|
24
|
+
o ? s(o, t, a) : l(t, a), o = t;
|
|
25
|
+
});
|
|
26
|
+
}), i(() => {
|
|
27
|
+
c &&= (c(), null), o && a && (e(o, a), o = null), a && a.parentNode && a.parentNode.removeChild(a), a = null;
|
|
28
|
+
}), () => t.disabled ? m(d, { children: n.default() }) : null;
|
|
29
|
+
}, { name: "Portal" }), x = Symbol("sigx.show.originalDisplay"), S = p({
|
|
30
|
+
mounted(e, { value: t }) {
|
|
31
|
+
let n = e, r = n.style.display === "none" ? "" : n.style.display;
|
|
32
|
+
n[x] = r, n.style.display = t ? r : "none";
|
|
33
|
+
},
|
|
34
|
+
updated(e, { value: t, oldValue: n }) {
|
|
35
|
+
if (t !== n) {
|
|
36
|
+
let n = e;
|
|
37
|
+
n.style.display = t ? n[x] ?? "" : "none";
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
unmounted(e) {
|
|
41
|
+
let t = e, n = t[x];
|
|
42
|
+
n !== void 0 && (t.style.display = n);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
//#endregion
|
|
46
|
+
//#region src/index.ts
|
|
47
|
+
i("show", S);
|
|
48
|
+
//#endregion
|
|
49
|
+
export { b as Portal, l as mount, a as mountComponent, v as moveNode, o as nodeOps, c as onElementMounted, s as patch, t as patchDirective, n as patchProp, i as registerBuiltInDirective, r as render, u as resolveBuiltInDirective, S as show, _ as supportsMoveBefore, e as unmount };
|
|
50
|
+
|
|
51
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/Portal.tsx","../src/directives/show.ts","../src/index.ts"],"sourcesContent":["/**\r\n * Portal component for rendering children to a different DOM location.\r\n * \r\n * Uses the `moveBefore` API (Chrome 133+) when available for state-preserving\r\n * DOM moves. Falls back to `insertBefore` for older browsers.\r\n * \r\n * @example\r\n * ```tsx\r\n * import { Portal } from '@sigx/runtime-dom';\r\n * \r\n * // Render to document.body (default)\r\n * <Portal>\r\n * <div class=\"modal\">Modal content</div>\r\n * </Portal>\r\n * \r\n * // Render to a specific container\r\n * <Portal to={document.getElementById('modal-root')}>\r\n * <div class=\"modal\">Modal content</div>\r\n * </Portal>\r\n * \r\n * // Render to a container by selector\r\n * <Portal to=\"#modal-root\">\r\n * <div class=\"modal\">Modal content</div>\r\n * </Portal>\r\n * ```\r\n */\r\n\r\nimport { component, Fragment, VNode, jsx, type Define } from '@sigx/runtime-core';\r\nimport { normalizeSubTree } from '@sigx/runtime-core/internals';\r\nimport { effect } from '@sigx/reactivity';\r\nimport { mount, unmount, patch } from './render.js';\r\n\r\n/**\r\n * Check if the browser supports the moveBefore API.\r\n * moveBefore allows moving DOM nodes without losing state (iframes, videos, focus, etc.)\r\n */\r\nexport function supportsMoveBefore(): boolean {\r\n return typeof Node !== 'undefined' && 'moveBefore' in Node.prototype;\r\n}\r\n\r\n/**\r\n * Move or insert a node into a parent, using moveBefore when available\r\n * for state-preserving moves.\r\n * \r\n * @param parent - The target parent element\r\n * @param node - The node to move/insert\r\n * @param anchor - Optional reference node to insert before\r\n */\r\nexport function moveNode(\r\n parent: Element,\r\n node: Node,\r\n anchor: Node | null = null\r\n): void {\r\n if (supportsMoveBefore()) {\r\n // Use moveBefore for state-preserving move (Chrome 133+)\r\n (parent as any).moveBefore(node, anchor);\r\n } else {\r\n // Fallback to insertBefore (causes state reset for iframes, etc.)\r\n parent.insertBefore(node, anchor);\r\n }\r\n}\r\n\r\n/**\r\n * Resolve a portal target from a string selector or Element.\r\n * Returns document.body as fallback.\r\n */\r\nfunction resolveTarget(target: string | Element | undefined): Element {\r\n if (target === undefined) {\r\n return document.body;\r\n }\r\n \r\n if (typeof target === 'string') {\r\n const resolved = document.querySelector(target);\r\n if (!resolved) {\r\n console.warn(`Portal: Target \"${target}\" not found, falling back to document.body`);\r\n return document.body;\r\n }\r\n return resolved;\r\n }\r\n \r\n return target;\r\n}\r\n\r\ntype PortalProps = Define.Prop<'to', string | Element> & Define.Prop<'disabled', boolean>;\r\n\r\n/**\r\n * Portal component - renders children to a different DOM location.\r\n * \r\n * Props:\r\n * - `to` - Target container (Element or CSS selector string). Defaults to document.body.\r\n * - `disabled` - When true, renders children in place instead of portaling\r\n * - `children` - Content to render in the portal\r\n * \r\n * Features:\r\n * - Uses `moveBefore` API (Chrome 133+) for state-preserving DOM moves\r\n * - Preserves iframe content, video playback, focus, and CSS animations\r\n * - Falls back to `insertBefore` for older browsers\r\n */\r\nexport const Portal = component<PortalProps>(({ props, slots, onMounted, onUnmounted }) => {\r\n // Container element for portal content\r\n let portalContainer: HTMLDivElement | null = null;\r\n let mountedVNode: VNode | null = null;\r\n let cleanupEffect: (() => void) | null = null;\r\n\r\n onMounted(() => {\r\n if (props.disabled) {\r\n return;\r\n }\r\n\r\n // Resolve target container\r\n const targetContainer = resolveTarget(props.to);\r\n\r\n // Create a container div for the portal content\r\n portalContainer = document.createElement('div');\r\n portalContainer.setAttribute('data-sigx-portal', '');\r\n\r\n // Use moveBefore when available for state-preserving move\r\n moveNode(targetContainer, portalContainer);\r\n\r\n // Set up reactive effect to render children into portal container\r\n const stopEffect = effect(() => {\r\n const children = slots.default();\r\n \r\n if (!portalContainer) return;\r\n \r\n // Normalize children to a proper VNode using the shared utility\r\n const vnode = normalizeSubTree(children);\r\n\r\n if (mountedVNode) {\r\n // Patch existing content\r\n patch(mountedVNode, vnode, portalContainer);\r\n } else {\r\n // Initial mount\r\n mount(vnode, portalContainer);\r\n }\r\n \r\n mountedVNode = vnode;\r\n });\r\n\r\n cleanupEffect = stopEffect;\r\n });\r\n\r\n onUnmounted(() => {\r\n // Stop the reactive effect\r\n if (cleanupEffect) {\r\n cleanupEffect();\r\n cleanupEffect = null;\r\n }\r\n\r\n // Unmount the portal content\r\n if (mountedVNode && portalContainer) {\r\n unmount(mountedVNode, portalContainer);\r\n mountedVNode = null;\r\n }\r\n\r\n // Remove the portal container from the DOM\r\n if (portalContainer && portalContainer.parentNode) {\r\n portalContainer.parentNode.removeChild(portalContainer);\r\n }\r\n portalContainer = null;\r\n });\r\n\r\n return () => {\r\n // When disabled, render children in place using jsx function\r\n if (props.disabled) {\r\n const children = slots.default();\r\n return jsx(Fragment, { children });\r\n }\r\n\r\n // When portal is active, render nothing in place\r\n // Children are rendered into the portal container via the effect\r\n return null;\r\n };\r\n}, { name: 'Portal' });\r\n","/**\r\n * Built-in `show` directive — toggles element visibility via `display` CSS property.\r\n *\r\n * Unlike conditional rendering (ternary in JSX), `use:show` keeps the element in the DOM\r\n * and only toggles its `display` style. This is useful when toggling is frequent and you\r\n * want to preserve element state (e.g., scroll position, input focus).\r\n *\r\n * @example\r\n * ```tsx\r\n * // Shorthand — directive resolved automatically:\r\n * <div use:show={isVisible}>Content</div>\r\n *\r\n * // Explicit tuple form:\r\n * import { show } from 'sigx';\r\n * <div use:show={[show, isVisible]}>Content</div>\r\n * ```\r\n */\r\n\r\nimport { defineDirective } from '@sigx/runtime-core';\r\n\r\n/** Symbol key for storing the original display value on elements. */\r\nconst ORIGINAL_DISPLAY = Symbol('sigx.show.originalDisplay');\r\n\r\n/** HTMLElement with the show directive's original display property. */\r\ninterface ShowElement extends HTMLElement {\r\n [ORIGINAL_DISPLAY]?: string;\r\n}\r\n\r\nexport const show = defineDirective<boolean, HTMLElement>({\r\n mounted(el, { value }) {\r\n const showEl = el as ShowElement;\r\n // Save the original display value now that all props have been applied\r\n const saved = showEl.style.display === 'none' ? '' : showEl.style.display;\r\n showEl[ORIGINAL_DISPLAY] = saved;\r\n showEl.style.display = value ? saved : 'none';\r\n },\r\n\r\n updated(el, { value, oldValue }) {\r\n if (value !== oldValue) {\r\n const showEl = el as ShowElement;\r\n showEl.style.display = value ? showEl[ORIGINAL_DISPLAY] ?? '' : 'none';\r\n }\r\n },\r\n\r\n unmounted(el) {\r\n const showEl = el as ShowElement;\r\n // Restore original display on cleanup\r\n const original = showEl[ORIGINAL_DISPLAY];\r\n if (original !== undefined) {\r\n showEl.style.display = original;\r\n }\r\n }\r\n});\r\n","// Import JSX types (global augmentation)\r\nimport './jsx';\r\n// Import type augmentation for @sigx/runtime-core\r\nimport './types';\r\n// Import JSX type augmentation for built-in directives (IntelliSense for use:show, etc.)\r\nimport './directives/show-jsx-types';\r\n\r\n// Platform setup (side effects)\r\nimport './model-processor.js';\r\n\r\n// Re-export public API from focused modules\r\nexport { render, patch, mount, unmount, mountComponent } from './render.js';\r\nexport { patchProp } from './patchProp.js';\r\nexport { patchDirective, onElementMounted, registerBuiltInDirective, resolveBuiltInDirective } from './directives.js';\r\nexport type { DOMDirective } from './directives.js';\r\nexport { nodeOps } from './nodeOps.js';\r\n\r\n// Export Portal component and moveBefore utilities\r\nexport { Portal, supportsMoveBefore, moveNode } from './Portal.js';\r\n\r\n// Export built-in directives\r\nexport { show } from './directives/show.js';\r\n\r\n// Register built-in directives so use:show={value} works without importing\r\nimport { show as _showDirective } from './directives/show.js';\r\nimport { registerBuiltInDirective as _register } from './directives.js';\r\n_register('show', _showDirective);\r\n"],"mappings":";;;;;AAoCA,SAAgB,IAA8B;AAC1C,QAAO,OAAO,OAAS,OAAe,gBAAgB,KAAK;;AAW/D,SAAgB,EACZ,GACA,GACA,IAAsB,MAClB;AACJ,CAAI,GAAoB,GAEnB,EAAe,WAAW,GAAM,EAAO,GAGxC,EAAO,aAAa,GAAM,EAAO;;AAQzC,SAAS,EAAc,GAA+C;AAclE,QAbI,MAAW,KAAA,IACJ,SAAS,OAGhB,OAAO,KAAW,WACD,SAAS,cAAc,EAAO,KAE3C,QAAQ,KAAK,mBAAmB,EAAO,4CAA4C,EAC5E,SAAS,QAKjB;;AAkBX,IAAa,IAAS,GAAwB,EAAE,UAAO,UAAO,cAAW,qBAAkB;CAEvF,IAAI,IAAyC,MACzC,IAA6B,MAC7B,IAAqC;AA4DzC,QA1DA,QAAgB;AACZ,MAAI,EAAM,SACN;EAIJ,IAAM,IAAkB,EAAc,EAAM,GAAG;AA6B/C,EA1BA,IAAkB,SAAS,cAAc,MAAM,EAC/C,EAAgB,aAAa,oBAAoB,GAAG,EAGpD,EAAS,GAAiB,EAAgB,EAsB1C,IAnBmB,QAAa;GAC5B,IAAM,IAAW,EAAM,SAAS;AAEhC,OAAI,CAAC,EAAiB;GAGtB,IAAM,IAAQ,EAAiB,EAAS;AAUxC,GARI,IAEA,EAAM,GAAc,GAAO,EAAgB,GAG3C,EAAM,GAAO,EAAgB,EAGjC,IAAe;IACjB;GAGJ,EAEF,QAAkB;AAiBd,EAfA,AAEI,OADA,GAAe,EACC,OAIhB,KAAgB,MAChB,EAAQ,GAAc,EAAgB,EACtC,IAAe,OAIf,KAAmB,EAAgB,cACnC,EAAgB,WAAW,YAAY,EAAgB,EAE3D,IAAkB;GACpB,QAIM,EAAM,WAEC,EAAI,GAAU,EAAE,UADN,EAAM,SAAS,EACC,CAAC,GAK/B;GAEZ,EAAE,MAAM,UAAU,CAAC,ECxJhB,IAAmB,OAAO,4BAA4B,EAO/C,IAAO,EAAsC;CACtD,QAAQ,GAAI,EAAE,YAAS;EACnB,IAAM,IAAS,GAET,IAAQ,EAAO,MAAM,YAAY,SAAS,KAAK,EAAO,MAAM;AAElE,EADA,EAAO,KAAoB,GAC3B,EAAO,MAAM,UAAU,IAAQ,IAAQ;;CAG3C,QAAQ,GAAI,EAAE,UAAO,eAAY;AAC7B,MAAI,MAAU,GAAU;GACpB,IAAM,IAAS;AACf,KAAO,MAAM,UAAU,IAAQ,EAAO,MAAqB,KAAK;;;CAIxE,UAAU,GAAI;EACV,IAAM,IAAS,GAET,IAAW,EAAO;AACxB,EAAI,MAAa,KAAA,MACb,EAAO,MAAM,UAAU;;CAGlC,CAAC;;;AC1BF,EAAU,QAAQ,EAAe"}
|
package/dist/internals.d.ts
CHANGED
|
@@ -7,6 +7,9 @@
|
|
|
7
7
|
*
|
|
8
8
|
* @internal
|
|
9
9
|
*/
|
|
10
|
-
export { patch, mount, unmount, mountComponent
|
|
11
|
-
export {
|
|
10
|
+
export { patch, mount, unmount, mountComponent } from './render.js';
|
|
11
|
+
export { patchProp } from './patchProp.js';
|
|
12
|
+
export { patchDirective, onElementMounted } from './directives.js';
|
|
13
|
+
export { nodeOps } from './nodeOps.js';
|
|
14
|
+
export { registerBuiltInDirective, resolveBuiltInDirective } from './directives.js';
|
|
12
15
|
//# sourceMappingURL=internals.d.ts.map
|
package/dist/internals.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internals.d.ts","sourceRoot":"","sources":["../src/internals.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,cAAc,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"internals.d.ts","sourceRoot":"","sources":["../src/internals.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGpE,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,OAAO,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/internals.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as e, c as t, d as n,
|
|
2
|
-
export { c as mount, i as mountComponent,
|
|
1
|
+
import { a as e, c as t, d as n, l as r, n as i, o as a, r as o, s, t as c, u as l } from "./render-BWNQH1pJ.js";
|
|
2
|
+
export { c as mount, i as mountComponent, a as nodeOps, s as onElementMounted, o as patch, t as patchDirective, n as patchProp, r as registerBuiltInDirective, l as resolveBuiltInDirective, e as unmount };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform-specific model processor for DOM form elements.
|
|
3
|
+
*
|
|
4
|
+
* Registers smart two-way binding behavior for checkboxes (boolean and array modes),
|
|
5
|
+
* radio buttons, text inputs, textareas, and select elements (single and multi-select).
|
|
6
|
+
*/
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=model-processor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-processor.d.ts","sourceRoot":"","sources":["../src/model-processor.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DOM node operations and SVG support.
|
|
3
|
+
*
|
|
4
|
+
* Provides the complete RendererOptions implementation for the DOM platform,
|
|
5
|
+
* including element creation, insertion, removal, text manipulation,
|
|
6
|
+
* focus preservation, and SVG namespace handling.
|
|
7
|
+
*/
|
|
8
|
+
import type { RendererOptions } from '@sigx/runtime-core/internals';
|
|
9
|
+
export declare const nodeOps: RendererOptions<Node, Element>;
|
|
10
|
+
//# sourceMappingURL=nodeOps.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nodeOps.d.ts","sourceRoot":"","sources":["../src/nodeOps.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AA6BpE,eAAO,MAAM,OAAO,EAAE,eAAe,CAAC,IAAI,EAAE,OAAO,CAoDlD,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DOM property patching logic.
|
|
3
|
+
*
|
|
4
|
+
* Handles setting/updating all element properties including styles,
|
|
5
|
+
* event handlers, className, SVG attributes, form element values,
|
|
6
|
+
* and custom property bindings.
|
|
7
|
+
*/
|
|
8
|
+
export declare function patchProp(dom: Element, key: string, prevValue: any, nextValue: any, isSVG?: boolean): void;
|
|
9
|
+
//# sourceMappingURL=patchProp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patchProp.d.ts","sourceRoot":"","sources":["../src/patchProp.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,wBAAgB,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE,OAAO,QA4MnG"}
|
|
@@ -1,164 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { createRenderer as
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
function f() {
|
|
6
|
-
return typeof Node < "u" && "moveBefore" in Node.prototype;
|
|
7
|
-
}
|
|
8
|
-
function p(e, t, n = null) {
|
|
9
|
-
f() ? e.moveBefore(t, n) : e.insertBefore(t, n);
|
|
10
|
-
}
|
|
11
|
-
function m(e) {
|
|
12
|
-
return e === void 0 ? document.body : typeof e == "string" ? document.querySelector(e) || (console.warn(`Portal: Target "${e}" not found, falling back to document.body`), document.body) : e;
|
|
13
|
-
}
|
|
14
|
-
var h = t(({ props: t, slots: n, onMounted: r, onUnmounted: a }) => {
|
|
15
|
-
let o = null, s = null, l = null;
|
|
16
|
-
return r(() => {
|
|
17
|
-
if (t.disabled) return;
|
|
18
|
-
let e = m(t.to);
|
|
19
|
-
o = document.createElement("div"), o.setAttribute("data-sigx-portal", ""), p(e, o), l = d(() => {
|
|
20
|
-
let e = n.default();
|
|
21
|
-
if (!o) return;
|
|
22
|
-
let t = c(e);
|
|
23
|
-
s ? j(s, t, o) : M(t, o), s = t;
|
|
24
|
-
});
|
|
25
|
-
}), a(() => {
|
|
26
|
-
l &&= (l(), null), s && o && (N(s, o), s = null), o && o.parentNode && o.parentNode.removeChild(o), o = null;
|
|
27
|
-
}), () => t.disabled ? i(e, { children: n.default() }) : null;
|
|
28
|
-
}, { name: "Portal" }), g = Symbol("sigx.show.originalDisplay"), _ = n({
|
|
29
|
-
mounted(e, { value: t }) {
|
|
30
|
-
let n = e, r = n.style.display === "none" ? "" : n.style.display;
|
|
31
|
-
n[g] = r, n.style.display = t ? r : "none";
|
|
32
|
-
},
|
|
33
|
-
updated(e, { value: t, oldValue: n }) {
|
|
34
|
-
if (t !== n) {
|
|
35
|
-
let n = e;
|
|
36
|
-
n.style.display = t ? n[g] ?? "" : "none";
|
|
37
|
-
}
|
|
38
|
-
},
|
|
39
|
-
unmounted(e) {
|
|
40
|
-
let t = e, n = t[g];
|
|
41
|
-
n !== void 0 && (t.style.display = n);
|
|
42
|
-
}
|
|
43
|
-
}), v = /* @__PURE__ */ new Map();
|
|
44
|
-
function y(e, t) {
|
|
45
|
-
v.set(e, t);
|
|
46
|
-
}
|
|
47
|
-
function b(e) {
|
|
48
|
-
return v.get(e);
|
|
49
|
-
}
|
|
50
|
-
var x = Symbol.for("sigx.directives");
|
|
51
|
-
function S(e) {
|
|
52
|
-
let t = e[x];
|
|
53
|
-
return t || (t = /* @__PURE__ */ new Map(), e[x] = t), t;
|
|
54
|
-
}
|
|
55
|
-
function C(e, t, n, i, a) {
|
|
56
|
-
let o = S(e);
|
|
57
|
-
if (i == null) {
|
|
58
|
-
o.delete(t);
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
let s, c;
|
|
62
|
-
if (r(i)) s = i, c = void 0;
|
|
63
|
-
else if (Array.isArray(i) && i.length >= 1 && r(i[0])) s = i[0], c = i[1];
|
|
64
|
-
else {
|
|
65
|
-
let e = v.get(t);
|
|
66
|
-
if (e) s = e, c = i;
|
|
67
|
-
else {
|
|
68
|
-
let e = a?.directives.get(t);
|
|
69
|
-
if (e) s = e, c = i;
|
|
70
|
-
else {
|
|
71
|
-
console.warn(`[sigx] Directive "use:${t}" could not be resolved. Make sure to register it via app.directive('${t}', definition) or pass a directive definition directly.`);
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
let l = o.get(t);
|
|
77
|
-
if (l) {
|
|
78
|
-
let t = l.value;
|
|
79
|
-
l.def = s, l.value = c, s.updated && c !== t && s.updated(e, {
|
|
80
|
-
value: c,
|
|
81
|
-
oldValue: t
|
|
82
|
-
});
|
|
83
|
-
} else {
|
|
84
|
-
let n = {
|
|
85
|
-
def: s,
|
|
86
|
-
value: c
|
|
87
|
-
};
|
|
88
|
-
o.set(t, n), s.created && s.created(e, { value: c });
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
function w(e) {
|
|
92
|
-
let t = e[x];
|
|
93
|
-
if (t) for (let [, n] of t) n.def.mounted && n.def.mounted(e, { value: n.value });
|
|
94
|
-
}
|
|
95
|
-
function T(e) {
|
|
96
|
-
let t = e[x];
|
|
97
|
-
if (t) {
|
|
98
|
-
for (let [, n] of t) n.def.unmounted && n.def.unmounted(e, { value: n.value }), n.cleanup && n.cleanup();
|
|
99
|
-
t.clear(), delete e[x];
|
|
100
|
-
}
|
|
101
|
-
let n = "__sigx_event_handlers", r = e[n];
|
|
102
|
-
if (r) {
|
|
103
|
-
for (let [t, n] of r) e.removeEventListener(t, n);
|
|
104
|
-
r.clear(), delete e[n];
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
var E = "http://www.w3.org/2000/svg";
|
|
108
|
-
u((e, t, [n, r], i) => {
|
|
109
|
-
let a = (e) => {
|
|
110
|
-
let t = n[`onUpdate:${r}`];
|
|
111
|
-
typeof t == "function" ? t(e) : n[r] = e;
|
|
112
|
-
};
|
|
113
|
-
if (e === "input" && i.type === "checkbox") {
|
|
114
|
-
let e = n[r];
|
|
115
|
-
if (Array.isArray(e)) {
|
|
116
|
-
t.checked = e.includes(i.value);
|
|
117
|
-
let o = t["onUpdate:modelValue"];
|
|
118
|
-
t["onUpdate:modelValue"] = (e) => {
|
|
119
|
-
let t = i.value, s = n[r];
|
|
120
|
-
e ? s.includes(t) || a([...s, t]) : a(s.filter((e) => e !== t)), o && o(e);
|
|
121
|
-
};
|
|
122
|
-
} else {
|
|
123
|
-
t.checked = e;
|
|
124
|
-
let n = t["onUpdate:modelValue"];
|
|
125
|
-
t["onUpdate:modelValue"] = (e) => {
|
|
126
|
-
a(e), n && n(e);
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
return !0;
|
|
130
|
-
}
|
|
131
|
-
if (e === "input" && i.type === "radio") {
|
|
132
|
-
t.checked = n[r] === i.value;
|
|
133
|
-
let e = t["onUpdate:modelValue"];
|
|
134
|
-
return t["onUpdate:modelValue"] = (t) => {
|
|
135
|
-
t && a(i.value), e && e(t);
|
|
136
|
-
}, !0;
|
|
137
|
-
}
|
|
138
|
-
if (e === "input") {
|
|
139
|
-
t.value = n[r] ?? "";
|
|
140
|
-
let e = t["onUpdate:modelValue"];
|
|
141
|
-
return t["onUpdate:modelValue"] = (t) => {
|
|
142
|
-
a(t), e && e(t);
|
|
143
|
-
}, !0;
|
|
144
|
-
}
|
|
145
|
-
if (e === "textarea") {
|
|
146
|
-
t.value = n[r] ?? "";
|
|
147
|
-
let e = t["onUpdate:modelValue"];
|
|
148
|
-
return t["onUpdate:modelValue"] = (t) => {
|
|
149
|
-
a(t), e && e(t);
|
|
150
|
-
}, !0;
|
|
151
|
-
}
|
|
152
|
-
if (e === "select") {
|
|
153
|
-
i.multiple && Array.isArray(n[r]) ? t.value = n[r] : t.value = n[r] ?? "";
|
|
154
|
-
let e = t["onUpdate:modelValue"];
|
|
155
|
-
return t["onUpdate:modelValue"] = (t) => {
|
|
156
|
-
a(t), e && e(t);
|
|
157
|
-
}, !0;
|
|
158
|
-
}
|
|
159
|
-
return !1;
|
|
160
|
-
});
|
|
161
|
-
function D(e, t, n, r, i) {
|
|
1
|
+
import { isDirective as e, mountTargetNotFoundError as t, renderTargetNotFoundError as n } from "@sigx/runtime-core";
|
|
2
|
+
import { createRenderer as r, setDefaultMount as i } from "@sigx/runtime-core/internals";
|
|
3
|
+
//#region src/patchProp.ts
|
|
4
|
+
function a(e, t, n, r, i) {
|
|
162
5
|
if (!e) return;
|
|
163
6
|
let a = e.tagName.toLowerCase(), o = i ?? e instanceof SVGElement, s = n, c = r;
|
|
164
7
|
if (!(t === "children" || t === "key" || t === "ref")) if (t === "style") {
|
|
@@ -229,7 +72,75 @@ function D(e, t, n, r, i) {
|
|
|
229
72
|
}
|
|
230
73
|
else a.includes("-") && !t.includes("-") ? e[t] = c : c === !0 ? e.setAttribute(t, "") : c === !1 || c == null ? e.removeAttribute(t) : e.setAttribute(t, String(c));
|
|
231
74
|
}
|
|
232
|
-
|
|
75
|
+
//#endregion
|
|
76
|
+
//#region src/directives.ts
|
|
77
|
+
var o = /* @__PURE__ */ new Map();
|
|
78
|
+
function s(e, t) {
|
|
79
|
+
o.set(e, t);
|
|
80
|
+
}
|
|
81
|
+
function c(e) {
|
|
82
|
+
return o.get(e);
|
|
83
|
+
}
|
|
84
|
+
var l = Symbol.for("sigx.directives");
|
|
85
|
+
function u(e) {
|
|
86
|
+
let t = e[l];
|
|
87
|
+
return t || (t = /* @__PURE__ */ new Map(), e[l] = t), t;
|
|
88
|
+
}
|
|
89
|
+
function d(t, n, r, i, a) {
|
|
90
|
+
let s = u(t);
|
|
91
|
+
if (i == null) {
|
|
92
|
+
s.delete(n);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
let c, l;
|
|
96
|
+
if (e(i)) c = i, l = void 0;
|
|
97
|
+
else if (Array.isArray(i) && i.length >= 1 && e(i[0])) c = i[0], l = i[1];
|
|
98
|
+
else {
|
|
99
|
+
let e = o.get(n);
|
|
100
|
+
if (e) c = e, l = i;
|
|
101
|
+
else {
|
|
102
|
+
let e = a?.directives.get(n);
|
|
103
|
+
if (e) c = e, l = i;
|
|
104
|
+
else {
|
|
105
|
+
console.warn(`[sigx] Directive "use:${n}" could not be resolved. Make sure to register it via app.directive('${n}', definition) or pass a directive definition directly.`);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
let d = s.get(n);
|
|
111
|
+
if (d) {
|
|
112
|
+
let e = d.value;
|
|
113
|
+
d.def = c, d.value = l, c.updated && l !== e && c.updated(t, {
|
|
114
|
+
value: l,
|
|
115
|
+
oldValue: e
|
|
116
|
+
});
|
|
117
|
+
} else {
|
|
118
|
+
let e = {
|
|
119
|
+
def: c,
|
|
120
|
+
value: l
|
|
121
|
+
};
|
|
122
|
+
s.set(n, e), c.created && c.created(t, { value: l });
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
function f(e) {
|
|
126
|
+
let t = e[l];
|
|
127
|
+
if (t) for (let [, n] of t) n.def.mounted && n.def.mounted(e, { value: n.value });
|
|
128
|
+
}
|
|
129
|
+
function p(e) {
|
|
130
|
+
let t = e[l];
|
|
131
|
+
if (t) {
|
|
132
|
+
for (let [, n] of t) n.def.unmounted && n.def.unmounted(e, { value: n.value }), n.cleanup && n.cleanup();
|
|
133
|
+
t.clear(), delete e[l];
|
|
134
|
+
}
|
|
135
|
+
let n = "__sigx_event_handlers", r = e[n];
|
|
136
|
+
if (r) {
|
|
137
|
+
for (let [t, n] of r) e.removeEventListener(t, n);
|
|
138
|
+
r.clear(), delete e[n];
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
//#endregion
|
|
142
|
+
//#region src/nodeOps.ts
|
|
143
|
+
var m = "http://www.w3.org/2000/svg", h = {
|
|
233
144
|
insert: (e, t, n) => {
|
|
234
145
|
n && n.parentNode !== t && (n = null), t.insertBefore(e, n || null);
|
|
235
146
|
},
|
|
@@ -238,7 +149,7 @@ var O = {
|
|
|
238
149
|
t && t.removeChild(e);
|
|
239
150
|
},
|
|
240
151
|
createElement: (e, t, n) => {
|
|
241
|
-
if (t) return document.createElementNS(
|
|
152
|
+
if (t) return document.createElementNS(m, e);
|
|
242
153
|
let r = n ? { is: n } : void 0;
|
|
243
154
|
return document.createElement(e, r);
|
|
244
155
|
},
|
|
@@ -278,23 +189,23 @@ var O = {
|
|
|
278
189
|
})), e.focus({ preventScroll: !0 });
|
|
279
190
|
}
|
|
280
191
|
},
|
|
281
|
-
patchProp:
|
|
282
|
-
patchDirective:
|
|
283
|
-
onElementMounted:
|
|
284
|
-
onElementUnmounted:
|
|
285
|
-
},
|
|
286
|
-
let
|
|
287
|
-
if (!
|
|
288
|
-
return
|
|
289
|
-
}, { patch:
|
|
290
|
-
|
|
291
|
-
let
|
|
292
|
-
if (!
|
|
293
|
-
return
|
|
294
|
-
|
|
192
|
+
patchProp: a,
|
|
193
|
+
patchDirective: d,
|
|
194
|
+
onElementMounted: f,
|
|
195
|
+
onElementUnmounted: p
|
|
196
|
+
}, g = r(h), _ = (e, t, r) => {
|
|
197
|
+
let i = typeof t == "string" ? document.querySelector(t) : t;
|
|
198
|
+
if (!i) throw n(String(t));
|
|
199
|
+
return g.render(e, i, r);
|
|
200
|
+
}, { patch: v, mount: y, unmount: b, mountComponent: x } = g;
|
|
201
|
+
i((e, n, r) => {
|
|
202
|
+
let i = typeof n == "string" ? document.querySelector(n) : n;
|
|
203
|
+
if (!i) throw t(String(n));
|
|
204
|
+
return _(e, i, r), () => {
|
|
205
|
+
_(null, i);
|
|
295
206
|
};
|
|
296
|
-
})
|
|
207
|
+
});
|
|
297
208
|
//#endregion
|
|
298
|
-
export {
|
|
209
|
+
export { b as a, d as c, a as d, _ as i, s as l, x as n, h as o, v as r, f as s, y as t, c as u };
|
|
299
210
|
|
|
300
|
-
//# sourceMappingURL=
|
|
211
|
+
//# sourceMappingURL=render-BWNQH1pJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-BWNQH1pJ.js","names":[],"sources":["../src/patchProp.ts","../src/directives.ts","../src/nodeOps.ts","../src/render.ts"],"sourcesContent":["/**\r\n * DOM property patching logic.\r\n *\r\n * Handles setting/updating all element properties including styles,\r\n * event handlers, className, SVG attributes, form element values,\r\n * and custom property bindings.\r\n */\r\n\r\nexport function patchProp(dom: Element, key: string, prevValue: any, nextValue: any, isSVG?: boolean) {\r\n // Guard: skip if dom is null (shouldn't happen but protects against edge cases)\r\n if (!dom) return;\r\n const tagName = dom.tagName.toLowerCase();\r\n \r\n // Detect SVG context: either passed explicitly or detect from element type\r\n // This ensures SVG attributes are handled correctly even if renderer doesn't pass isSVG\r\n const isSvgElement = isSVG ?? (dom instanceof SVGElement);\r\n \r\n const _oldProps = prevValue ? { [key]: prevValue } : {};\r\n const _newProps = nextValue ? { [key]: nextValue } : {};\r\n\r\n // This is a simplified version of updateProps that handles a single prop\r\n // But the original updateProps handled all props at once.\r\n // The renderer calls patchProp for each key.\r\n\r\n // Logic adapted from original updateProps\r\n const oldValue = prevValue;\r\n const newValue = nextValue;\r\n\r\n if (key === 'children' || key === 'key' || key === 'ref') return;\r\n\r\n if (key === 'style') {\r\n const el = dom as HTMLElement;\r\n if (typeof newValue === 'object' && newValue !== null) {\r\n const styleObj = newValue as Record<string, string | number | null | undefined>;\r\n // Remove old style properties not present in the new style object\r\n if (typeof oldValue === 'object' && oldValue !== null) {\r\n for (const oldKey in oldValue as Record<string, any>) {\r\n if (!(oldKey in styleObj)) {\r\n if (oldKey.startsWith('--')) {\r\n el.style.removeProperty(oldKey);\r\n } else {\r\n (el.style as any)[oldKey] = '';\r\n }\r\n }\r\n }\r\n }\r\n for (const styleKey in styleObj) {\r\n const val = styleObj[styleKey];\r\n if (val == null || val === '') {\r\n if (styleKey.startsWith('--')) {\r\n el.style.removeProperty(styleKey);\r\n } else {\r\n (el.style as any)[styleKey] = '';\r\n }\r\n } else {\r\n if (styleKey.startsWith('--')) {\r\n el.style.setProperty(styleKey, String(val));\r\n } else {\r\n (el.style as any)[styleKey] = val;\r\n }\r\n }\r\n }\r\n } else if (newValue) {\r\n el.style.cssText = String(newValue);\r\n } else {\r\n el.style.cssText = '';\r\n }\r\n } else if (key.startsWith('on')) {\r\n if (key === 'onUpdate:modelValue' && (tagName === 'input' || tagName === 'textarea' || tagName === 'select')) {\r\n const el = dom as HTMLElement;\r\n if (oldValue) {\r\n const wrapper = (oldValue as any).__sigx_model_handler;\r\n if (wrapper) {\r\n el.removeEventListener('input', wrapper);\r\n el.removeEventListener('change', wrapper);\r\n }\r\n }\r\n\r\n if (newValue) {\r\n const handler = (e: Event) => {\r\n const target = e.target as HTMLInputElement;\r\n let val: any;\r\n\r\n if (target.type === 'checkbox' || target.type === 'radio') {\r\n val = target.checked;\r\n } else if (target.type === 'number') {\r\n val = target.valueAsNumber;\r\n } else if (tagName === 'select' && (dom as HTMLSelectElement).multiple) {\r\n val = Array.from((dom as HTMLSelectElement).selectedOptions).map(o => o.value);\r\n } else {\r\n val = target.value;\r\n }\r\n\r\n (newValue as Function)(val);\r\n };\r\n (newValue as any).__sigx_model_handler = handler;\r\n\r\n const inputType = (dom as HTMLInputElement).type;\r\n if (tagName === 'select' || (tagName === 'input' && (inputType === 'checkbox' || inputType === 'radio'))) {\r\n el.addEventListener('change', handler);\r\n } else {\r\n el.addEventListener('input', handler);\r\n }\r\n }\r\n return;\r\n }\r\n\r\n const eventName = key.slice(2).toLowerCase();\r\n // Store handlers on the DOM element to properly track them across re-renders\r\n // Using a Map keyed by event name to ensure we remove the correct wrapper\r\n const handlersKey = '__sigx_event_handlers';\r\n let handlers = (dom as any)[handlersKey] as Map<string, EventListener> | undefined;\r\n if (!handlers) {\r\n handlers = new Map();\r\n (dom as any)[handlersKey] = handlers;\r\n }\r\n\r\n // Remove old handler if exists\r\n const oldHandler = handlers.get(eventName);\r\n if (oldHandler) {\r\n dom.removeEventListener(eventName, oldHandler);\r\n handlers.delete(eventName);\r\n }\r\n\r\n // Add new handler\r\n if (newValue) {\r\n const handler = (e: Event) => {\r\n if (e instanceof CustomEvent) {\r\n (newValue as Function)(e.detail);\r\n } else {\r\n (newValue as Function)(e);\r\n }\r\n };\r\n handlers.set(eventName, handler);\r\n dom.addEventListener(eventName, handler as EventListener);\r\n }\r\n } else if (key === 'className') {\r\n // For SVG, use setAttribute to preserve case (class works on both)\r\n dom.setAttribute('class', String(newValue));\r\n } else if (key.startsWith('.')) {\r\n const propName = key.slice(1);\r\n (dom as any)[propName] = newValue;\r\n } else if (key.startsWith('prop:')) {\r\n const propName = key.slice(5);\r\n (dom as any)[propName] = newValue;\r\n } else if (isSvgElement) {\r\n // SVG elements: use setAttribute to preserve case-sensitive attribute names\r\n // SVG attributes like viewBox, preserveAspectRatio, etc. are case-sensitive\r\n if (key === 'innerHTML' || key === 'textContent') {\r\n // These can be set as properties even on SVG\r\n (dom as any)[key] = newValue ?? '';\r\n } else if (key.startsWith('xlink:')) {\r\n // xlink: attributes need special namespace handling\r\n const xlinkNS = 'http://www.w3.org/1999/xlink';\r\n if (newValue == null) {\r\n dom.removeAttributeNS(xlinkNS, key.slice(6));\r\n } else {\r\n dom.setAttributeNS(xlinkNS, key, String(newValue));\r\n }\r\n } else {\r\n // Standard SVG attribute - use setAttribute to preserve case\r\n if (newValue === true) dom.setAttribute(key, '');\r\n else if (newValue === false || newValue == null) dom.removeAttribute(key);\r\n else dom.setAttribute(key, String(newValue));\r\n }\r\n } else {\r\n if ((tagName === 'input' || tagName === 'textarea' || tagName === 'select') &&\r\n (key === 'value' || key === 'checked')) {\r\n if (tagName === 'select' && key === 'value') {\r\n // Defer setting select value until options are mounted\r\n queueMicrotask(() => {\r\n if (Array.isArray(newValue)) {\r\n // Multi-select: set selected on each matching option\r\n const values = newValue as string[];\r\n const options = (dom as HTMLSelectElement).options;\r\n for (let i = 0; i < options.length; i++) {\r\n options[i].selected = values.includes(options[i].value);\r\n }\r\n } else {\r\n (dom as HTMLSelectElement).value = String(newValue ?? '');\r\n }\r\n });\r\n return;\r\n }\r\n\r\n if (key === 'checked' && tagName === 'input') {\r\n (dom as HTMLInputElement).checked = Boolean(newValue);\r\n } else if (key === 'value') {\r\n (dom as HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement).value = String(newValue ?? '');\r\n }\r\n } else if (key in dom) {\r\n // Skip undefined/null to avoid DOM coercing to 0 for numeric props like maxLength\r\n if (newValue == null) {\r\n // Remove attribute if it exists\r\n if (dom.hasAttribute?.(key)) {\r\n dom.removeAttribute(key);\r\n }\r\n } else {\r\n try {\r\n (dom as Record<string, any>)[key] = newValue;\r\n } catch {\r\n dom.setAttribute(key, String(newValue));\r\n }\r\n }\r\n } else if (tagName.includes('-') && !key.includes('-')) {\r\n (dom as Record<string, any>)[key] = newValue;\r\n } else {\r\n if (newValue === true) dom.setAttribute(key, '');\r\n else if (newValue === false || newValue == null) dom.removeAttribute(key);\r\n else dom.setAttribute(key, String(newValue));\r\n }\r\n }\r\n}\r\n","/**\r\n * Directive runtime for DOM (element-level use:* directives)\r\n *\r\n * Handles the built-in directive registry, directive lifecycle hooks\r\n * (created, mounted, updated, unmounted), and event handler cleanup.\r\n */\r\n\r\nimport { isDirective, type DirectiveDefinition } from '@sigx/runtime-core';\r\nimport type { AppContext } from '@sigx/runtime-core';\r\n\r\n/**\r\n * A directive definition narrowed to DOM elements.\r\n * Use this type when defining directives for the DOM renderer.\r\n *\r\n * @example\r\n * ```ts\r\n * import { defineDirective, type DOMDirective } from 'sigx';\r\n *\r\n * const tooltip = defineDirective<string, HTMLElement>({\r\n * mounted(el, { value }) {\r\n * el.title = value; // el is HTMLElement, fully typed\r\n * }\r\n * });\r\n * ```\r\n */\r\nexport type DOMDirective<T = any> = DirectiveDefinition<T, HTMLElement>;\r\n\r\n/**\r\n * Registry of built-in directives by name.\r\n * When a `use:<name>` prop receives a plain value (not a DirectiveDefinition),\r\n * the runtime looks up the directive by name here.\r\n * @internal\r\n */\r\nconst builtInDirectives = new Map<string, DirectiveDefinition>();\r\n\r\n/**\r\n * Register a built-in directive so it can be used with the shorthand syntax:\r\n * `<div use:show={value}>` instead of `<div use:show={[show, value]}>`.\r\n * @internal\r\n */\r\nexport function registerBuiltInDirective(name: string, def: DirectiveDefinition): void {\r\n builtInDirectives.set(name, def);\r\n}\r\n\r\n/**\r\n * Look up a registered built-in directive by name.\r\n * Used by SSR renderer to resolve `use:<name>={value}` shorthand.\r\n * @internal\r\n */\r\nexport function resolveBuiltInDirective(name: string): DirectiveDefinition | undefined {\r\n return builtInDirectives.get(name);\r\n}\r\n\r\n/**\r\n * Symbol key to store directive state on DOM elements.\r\n * @internal\r\n */\r\nconst DIRECTIVE_STATE = Symbol.for('sigx.directives');\r\n\r\n/**\r\n * Per-directive state stored on a DOM element.\r\n * @internal\r\n */\r\ninterface DirectiveState {\r\n def: DirectiveDefinition;\r\n value: any;\r\n cleanup?: () => void;\r\n}\r\n\r\n/**\r\n * Get or create the directive state map on a DOM element.\r\n * @internal\r\n */\r\nfunction getDirectiveMap(el: Element): Map<string, DirectiveState> {\r\n let map = (el as any)[DIRECTIVE_STATE] as Map<string, DirectiveState> | undefined;\r\n if (!map) {\r\n map = new Map();\r\n (el as any)[DIRECTIVE_STATE] = map;\r\n }\r\n return map;\r\n}\r\n\r\n/**\r\n * Process a `use:*` prop in patchProp.\r\n * Handles directive created and updated lifecycle hooks.\r\n * @internal\r\n */\r\nexport function patchDirective(el: Element, name: string, prevValue: any, nextValue: any, appContext: AppContext | null): void {\r\n const dirMap = getDirectiveMap(el);\r\n\r\n if (nextValue == null) {\r\n // Directive removed — unmounted will be called via onElementUnmounted\r\n dirMap.delete(name);\r\n return;\r\n }\r\n\r\n // Extract directive definition and binding value from the prop value:\r\n // - use:name={directiveDef} → def=directiveDef, value=undefined\r\n // - use:name={[directiveDef, value]} → def=directiveDef[0], value=directiveDef[1]\r\n let def: DirectiveDefinition;\r\n let value: any;\r\n\r\n if (isDirective(nextValue)) {\r\n def = nextValue;\r\n value = undefined;\r\n } else if (\r\n Array.isArray(nextValue) &&\r\n nextValue.length >= 1 &&\r\n isDirective(nextValue[0])\r\n ) {\r\n def = nextValue[0];\r\n value = nextValue[1];\r\n } else {\r\n // Not an explicit directive — try to resolve by name:\r\n // 1. Built-in directives (always available, e.g., 'show')\r\n // 2. App-registered custom directives (via app.directive())\r\n const builtIn = builtInDirectives.get(name);\r\n if (builtIn) {\r\n def = builtIn;\r\n value = nextValue;\r\n } else {\r\n const custom = appContext?.directives.get(name);\r\n if (custom) {\r\n def = custom;\r\n value = nextValue;\r\n } else {\r\n console.warn(\r\n `[sigx] Directive \"use:${name}\" could not be resolved. ` +\r\n `Make sure to register it via app.directive('${name}', definition) or pass a directive definition directly.`\r\n );\r\n return;\r\n }\r\n }\r\n }\r\n\r\n const existing = dirMap.get(name);\r\n\r\n if (!existing) {\r\n // First time — call created hook\r\n const state: DirectiveState = { def, value };\r\n dirMap.set(name, state);\r\n\r\n if (def.created) {\r\n def.created(el, { value });\r\n }\r\n } else {\r\n // Update — call updated hook\r\n const oldValue = existing.value;\r\n existing.def = def;\r\n existing.value = value;\r\n\r\n if (def.updated && value !== oldValue) {\r\n def.updated(el, { value, oldValue });\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Called after an element is inserted into the DOM.\r\n * Invokes `mounted` hooks for all directives on the element.\r\n * @internal\r\n */\r\nexport function onElementMounted(el: Element): void {\r\n const map = (el as any)[DIRECTIVE_STATE] as Map<string, DirectiveState> | undefined;\r\n if (!map) return;\r\n\r\n for (const [, state] of map) {\r\n if (state.def.mounted) {\r\n state.def.mounted(el, { value: state.value });\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Called before an element is removed from the DOM.\r\n * Invokes `unmounted` hooks for all directives on the element.\r\n * @internal\r\n */\r\nexport function onElementUnmounted(el: Element): void {\r\n // Clean up directive state\r\n const map = (el as any)[DIRECTIVE_STATE] as Map<string, DirectiveState> | undefined;\r\n if (map) {\r\n for (const [, state] of map) {\r\n if (state.def.unmounted) {\r\n state.def.unmounted(el, { value: state.value });\r\n }\r\n if (state.cleanup) {\r\n state.cleanup();\r\n }\r\n }\r\n map.clear();\r\n delete (el as any)[DIRECTIVE_STATE];\r\n }\r\n\r\n // Clean up event handlers to prevent memory leaks\r\n const handlersKey = '__sigx_event_handlers';\r\n const handlers = (el as any)[handlersKey] as Map<string, EventListener> | undefined;\r\n if (handlers) {\r\n for (const [eventName, handler] of handlers) {\r\n el.removeEventListener(eventName, handler);\r\n }\r\n handlers.clear();\r\n delete (el as any)[handlersKey];\r\n }\r\n}\r\n","/**\r\n * DOM node operations and SVG support.\r\n *\r\n * Provides the complete RendererOptions implementation for the DOM platform,\r\n * including element creation, insertion, removal, text manipulation,\r\n * focus preservation, and SVG namespace handling.\r\n */\r\n\r\nimport type { RendererOptions } from '@sigx/runtime-core/internals';\r\nimport { patchProp } from './patchProp.js';\r\nimport { patchDirective, onElementMounted, onElementUnmounted } from './directives.js';\r\n\r\n// SVG namespace for createElementNS\r\nconst svgNS = 'http://www.w3.org/2000/svg';\r\n\r\n// SVG elements that should be created with createElementNS\r\n// Based on https://developer.mozilla.org/en-US/docs/Web/SVG/Element\r\nconst svgElements = new Set([\r\n 'svg', 'animate', 'animateMotion', 'animateTransform', 'circle', 'clipPath',\r\n 'defs', 'desc', 'ellipse', 'feBlend', 'feColorMatrix', 'feComponentTransfer',\r\n 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap',\r\n 'feDistantLight', 'feDropShadow', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG',\r\n 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode', 'feMorphology',\r\n 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile',\r\n 'feTurbulence', 'filter', 'foreignObject', 'g', 'image', 'line', 'linearGradient',\r\n 'marker', 'mask', 'metadata', 'mpath', 'path', 'pattern', 'polygon', 'polyline',\r\n 'radialGradient', 'rect', 'set', 'stop', 'switch', 'symbol', 'text', 'textPath',\r\n 'title', 'tspan', 'use', 'view'\r\n]);\r\n\r\n/**\r\n * Check if a tag is an SVG element\r\n */\r\nfunction _isSvgTag(tag: string): boolean {\r\n return svgElements.has(tag);\r\n}\r\n\r\nexport const nodeOps: RendererOptions<Node, Element> = {\r\n insert: (child, parent, anchor) => {\r\n if (anchor && anchor.parentNode !== parent) anchor = null;\r\n parent.insertBefore(child, anchor || null);\r\n },\r\n remove: (child) => {\r\n const parent = child.parentNode;\r\n if (parent) {\r\n parent.removeChild(child);\r\n }\r\n },\r\n createElement: (tag, isSVG, isCustomizedBuiltIn) => {\r\n if (isSVG) {\r\n return document.createElementNS(svgNS, tag);\r\n }\r\n const is = isCustomizedBuiltIn ? { is: isCustomizedBuiltIn } : undefined;\r\n return document.createElement(tag, is);\r\n },\r\n createText: (text) => document.createTextNode(text),\r\n createComment: (text) => document.createComment(text),\r\n setText: (node, text) => {\r\n node.nodeValue = text;\r\n },\r\n setElementText: (el, text) => {\r\n el.textContent = text;\r\n },\r\n parentNode: (node) => node.parentNode as Element,\r\n nextSibling: (node) => node.nextSibling,\r\n querySelector: (selector) => document.querySelector(selector),\r\n setScopeId: (el, id) => el.setAttribute(id, ''),\r\n cloneNode: (node) => node.cloneNode(true),\r\n getActiveElement: () => document.activeElement as Element | null,\r\n restoreFocus: (el) => {\r\n if (el instanceof HTMLElement || el instanceof SVGElement) {\r\n // Use preventScroll to avoid layout thrashing.\r\n // Suppress focus/blur events to prevent re-triggering reactive updates.\r\n const suppressEvent = (e: Event) => { e.stopImmediatePropagation(); };\r\n el.addEventListener('focus', suppressEvent, { capture: true, once: true });\r\n el.addEventListener('focusin', suppressEvent, { capture: true, once: true });\r\n // Also suppress blur on the element that will lose focus\r\n const current = document.activeElement;\r\n if (current instanceof HTMLElement) {\r\n current.addEventListener('blur', suppressEvent, { capture: true, once: true });\r\n current.addEventListener('focusout', suppressEvent, { capture: true, once: true });\r\n }\r\n el.focus({ preventScroll: true });\r\n }\r\n },\r\n patchProp,\r\n patchDirective,\r\n onElementMounted,\r\n onElementUnmounted\r\n};\r\n","/**\r\n * DOM renderer creation and render API.\r\n *\r\n * Creates the platform-specific renderer from nodeOps and exports\r\n * the public render function and low-level renderer primitives.\r\n */\r\n\r\nimport { createRenderer, setDefaultMount } from '@sigx/runtime-core/internals';\r\nimport type { JSXElement } from '@sigx/runtime-core';\r\nimport type { AppContext } from '@sigx/runtime-core';\r\nimport { renderTargetNotFoundError, mountTargetNotFoundError } from '@sigx/runtime-core';\r\nimport { nodeOps } from './nodeOps.js';\r\n\r\nconst renderer = createRenderer(nodeOps);\r\n\r\n/**\r\n * Render a SignalX element to a DOM container.\r\n * Supports both Element references and CSS selectors.\r\n * \r\n * @example\r\n * ```tsx\r\n * import { render } from 'sigx';\r\n * \r\n * // Using CSS selector\r\n * render(<App />, \"#app\");\r\n * \r\n * // Using element reference\r\n * render(<App />, document.getElementById('app')!);\r\n * ```\r\n */\r\nexport const render = (element: JSXElement, container: Element | string, appContext?: AppContext): void => {\r\n const target = typeof container === 'string'\r\n ? document.querySelector(container)\r\n : container;\r\n\r\n if (!target) {\r\n throw renderTargetNotFoundError(String(container));\r\n }\r\n\r\n return renderer.render(element, target as Element, appContext);\r\n};\r\n\r\n// Export primitives for SSR plugins and hydration\r\nexport const { patch, mount, unmount, mountComponent } = renderer;\r\n\r\n// Set up the default mount function for this platform\r\nsetDefaultMount((component: any, container: HTMLElement | Element | ShadowRoot | string, appContext?: AppContext): (() => void) => {\r\n const target = typeof container === 'string'\r\n ? document.querySelector(container)\r\n : container;\r\n\r\n if (!target) {\r\n throw mountTargetNotFoundError(String(container));\r\n }\r\n\r\n render(component, target as Element, appContext);\r\n\r\n return () => {\r\n render(null, target as Element);\r\n };\r\n});\r\n"],"mappings":"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"}
|
package/dist/render.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DOM renderer creation and render API.
|
|
3
|
+
*
|
|
4
|
+
* Creates the platform-specific renderer from nodeOps and exports
|
|
5
|
+
* the public render function and low-level renderer primitives.
|
|
6
|
+
*/
|
|
7
|
+
import type { JSXElement } from '@sigx/runtime-core';
|
|
8
|
+
import type { AppContext } from '@sigx/runtime-core';
|
|
9
|
+
/**
|
|
10
|
+
* Render a SignalX element to a DOM container.
|
|
11
|
+
* Supports both Element references and CSS selectors.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* import { render } from 'sigx';
|
|
16
|
+
*
|
|
17
|
+
* // Using CSS selector
|
|
18
|
+
* render(<App />, "#app");
|
|
19
|
+
*
|
|
20
|
+
* // Using element reference
|
|
21
|
+
* render(<App />, document.getElementById('app')!);
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export declare const render: (element: JSXElement, container: string | Element, appContext?: AppContext | undefined) => void;
|
|
25
|
+
export declare const patch: import("@sigx/runtime-core/internals").RendererPatchFn<Node, Element>, mount: import("@sigx/runtime-core/internals").RendererMountFn<Node, Element>, unmount: import("@sigx/runtime-core/internals").RendererUnmountFn<Node, Element>, mountComponent: import("@sigx/runtime-core/internals").RendererMountComponentFn<Node, Element>;
|
|
26
|
+
//# sourceMappingURL=render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAMrD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,MAAM,iGAUlB,CAAC;AAGF,eAAO,MAAQ,KAAK,yEAAE,KAAK,yEAAE,OAAO,2EAAE,cAAc,gFAAa,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sigx/runtime-dom",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"description": "DOM runtime for SignalX",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -37,13 +37,13 @@
|
|
|
37
37
|
"node": "^20.19.0 || >=22.12.0"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@sigx/
|
|
41
|
-
"@sigx/
|
|
40
|
+
"@sigx/runtime-core": "^0.2.4",
|
|
41
|
+
"@sigx/reactivity": "^0.2.4"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"typescript": "^5.9.3",
|
|
45
45
|
"vite": "^8.0.3",
|
|
46
|
-
"@sigx/vite": "^0.2.
|
|
46
|
+
"@sigx/vite": "^0.2.4"
|
|
47
47
|
},
|
|
48
48
|
"scripts": {
|
|
49
49
|
"build": "vite build && tsgo --emitDeclarationOnly",
|
package/dist/src-BvXBxpbX.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"src-BvXBxpbX.js","names":[],"sources":["../src/Portal.tsx","../src/directives/show.ts","../src/index.ts"],"sourcesContent":["/**\r\n * Portal component for rendering children to a different DOM location.\r\n * \r\n * Uses the `moveBefore` API (Chrome 133+) when available for state-preserving\r\n * DOM moves. Falls back to `insertBefore` for older browsers.\r\n * \r\n * @example\r\n * ```tsx\r\n * import { Portal } from '@sigx/runtime-dom';\r\n * \r\n * // Render to document.body (default)\r\n * <Portal>\r\n * <div class=\"modal\">Modal content</div>\r\n * </Portal>\r\n * \r\n * // Render to a specific container\r\n * <Portal to={document.getElementById('modal-root')}>\r\n * <div class=\"modal\">Modal content</div>\r\n * </Portal>\r\n * \r\n * // Render to a container by selector\r\n * <Portal to=\"#modal-root\">\r\n * <div class=\"modal\">Modal content</div>\r\n * </Portal>\r\n * ```\r\n */\r\n\r\nimport { component, Fragment, VNode, jsx, type Define } from '@sigx/runtime-core';\r\nimport { normalizeSubTree } from '@sigx/runtime-core/internals';\r\nimport { effect } from '@sigx/reactivity';\r\nimport { mount, unmount, patch } from './index.js';\r\n\r\n/**\r\n * Check if the browser supports the moveBefore API.\r\n * moveBefore allows moving DOM nodes without losing state (iframes, videos, focus, etc.)\r\n */\r\nexport function supportsMoveBefore(): boolean {\r\n return typeof Node !== 'undefined' && 'moveBefore' in Node.prototype;\r\n}\r\n\r\n/**\r\n * Move or insert a node into a parent, using moveBefore when available\r\n * for state-preserving moves.\r\n * \r\n * @param parent - The target parent element\r\n * @param node - The node to move/insert\r\n * @param anchor - Optional reference node to insert before\r\n */\r\nexport function moveNode(\r\n parent: Element,\r\n node: Node,\r\n anchor: Node | null = null\r\n): void {\r\n if (supportsMoveBefore()) {\r\n // Use moveBefore for state-preserving move (Chrome 133+)\r\n (parent as any).moveBefore(node, anchor);\r\n } else {\r\n // Fallback to insertBefore (causes state reset for iframes, etc.)\r\n parent.insertBefore(node, anchor);\r\n }\r\n}\r\n\r\n/**\r\n * Resolve a portal target from a string selector or Element.\r\n * Returns document.body as fallback.\r\n */\r\nfunction resolveTarget(target: string | Element | undefined): Element {\r\n if (target === undefined) {\r\n return document.body;\r\n }\r\n \r\n if (typeof target === 'string') {\r\n const resolved = document.querySelector(target);\r\n if (!resolved) {\r\n console.warn(`Portal: Target \"${target}\" not found, falling back to document.body`);\r\n return document.body;\r\n }\r\n return resolved;\r\n }\r\n \r\n return target;\r\n}\r\n\r\ntype PortalProps = Define.Prop<'to', string | Element> & Define.Prop<'disabled', boolean>;\r\n\r\n/**\r\n * Portal component - renders children to a different DOM location.\r\n * \r\n * Props:\r\n * - `to` - Target container (Element or CSS selector string). Defaults to document.body.\r\n * - `disabled` - When true, renders children in place instead of portaling\r\n * - `children` - Content to render in the portal\r\n * \r\n * Features:\r\n * - Uses `moveBefore` API (Chrome 133+) for state-preserving DOM moves\r\n * - Preserves iframe content, video playback, focus, and CSS animations\r\n * - Falls back to `insertBefore` for older browsers\r\n */\r\nexport const Portal = component<PortalProps>(({ props, slots, onMounted, onUnmounted }) => {\r\n // Container element for portal content\r\n let portalContainer: HTMLDivElement | null = null;\r\n let mountedVNode: VNode | null = null;\r\n let cleanupEffect: (() => void) | null = null;\r\n\r\n onMounted(() => {\r\n if (props.disabled) {\r\n return;\r\n }\r\n\r\n // Resolve target container\r\n const targetContainer = resolveTarget(props.to);\r\n\r\n // Create a container div for the portal content\r\n portalContainer = document.createElement('div');\r\n portalContainer.setAttribute('data-sigx-portal', '');\r\n\r\n // Use moveBefore when available for state-preserving move\r\n moveNode(targetContainer, portalContainer);\r\n\r\n // Set up reactive effect to render children into portal container\r\n const stopEffect = effect(() => {\r\n const children = slots.default();\r\n \r\n if (!portalContainer) return;\r\n \r\n // Normalize children to a proper VNode using the shared utility\r\n const vnode = normalizeSubTree(children);\r\n\r\n if (mountedVNode) {\r\n // Patch existing content\r\n patch(mountedVNode, vnode, portalContainer);\r\n } else {\r\n // Initial mount\r\n mount(vnode, portalContainer);\r\n }\r\n \r\n mountedVNode = vnode;\r\n });\r\n\r\n cleanupEffect = stopEffect;\r\n });\r\n\r\n onUnmounted(() => {\r\n // Stop the reactive effect\r\n if (cleanupEffect) {\r\n cleanupEffect();\r\n cleanupEffect = null;\r\n }\r\n\r\n // Unmount the portal content\r\n if (mountedVNode && portalContainer) {\r\n unmount(mountedVNode, portalContainer);\r\n mountedVNode = null;\r\n }\r\n\r\n // Remove the portal container from the DOM\r\n if (portalContainer && portalContainer.parentNode) {\r\n portalContainer.parentNode.removeChild(portalContainer);\r\n }\r\n portalContainer = null;\r\n });\r\n\r\n return () => {\r\n // When disabled, render children in place using jsx function\r\n if (props.disabled) {\r\n const children = slots.default();\r\n return jsx(Fragment, { children });\r\n }\r\n\r\n // When portal is active, render nothing in place\r\n // Children are rendered into the portal container via the effect\r\n return null;\r\n };\r\n}, { name: 'Portal' });\r\n","/**\r\n * Built-in `show` directive — toggles element visibility via `display` CSS property.\r\n *\r\n * Unlike conditional rendering (ternary in JSX), `use:show` keeps the element in the DOM\r\n * and only toggles its `display` style. This is useful when toggling is frequent and you\r\n * want to preserve element state (e.g., scroll position, input focus).\r\n *\r\n * @example\r\n * ```tsx\r\n * // Shorthand — directive resolved automatically:\r\n * <div use:show={isVisible}>Content</div>\r\n *\r\n * // Explicit tuple form:\r\n * import { show } from 'sigx';\r\n * <div use:show={[show, isVisible]}>Content</div>\r\n * ```\r\n */\r\n\r\nimport { defineDirective } from '@sigx/runtime-core';\r\n\r\n/** Symbol key for storing the original display value on elements. */\r\nconst ORIGINAL_DISPLAY = Symbol('sigx.show.originalDisplay');\r\n\r\n/** HTMLElement with the show directive's original display property. */\r\ninterface ShowElement extends HTMLElement {\r\n [ORIGINAL_DISPLAY]?: string;\r\n}\r\n\r\nexport const show = defineDirective<boolean, HTMLElement>({\r\n mounted(el, { value }) {\r\n const showEl = el as ShowElement;\r\n // Save the original display value now that all props have been applied\r\n const saved = showEl.style.display === 'none' ? '' : showEl.style.display;\r\n showEl[ORIGINAL_DISPLAY] = saved;\r\n showEl.style.display = value ? saved : 'none';\r\n },\r\n\r\n updated(el, { value, oldValue }) {\r\n if (value !== oldValue) {\r\n const showEl = el as ShowElement;\r\n showEl.style.display = value ? showEl[ORIGINAL_DISPLAY] ?? '' : 'none';\r\n }\r\n },\r\n\r\n unmounted(el) {\r\n const showEl = el as ShowElement;\r\n // Restore original display on cleanup\r\n const original = showEl[ORIGINAL_DISPLAY];\r\n if (original !== undefined) {\r\n showEl.style.display = original;\r\n }\r\n }\r\n});\r\n","// Import JSX types (global augmentation)\r\nimport './jsx';\r\n// Import type augmentation for @sigx/runtime-core\r\nimport './types';\r\n// Import JSX type augmentation for built-in directives (IntelliSense for use:show, etc.)\r\nimport './directives/show-jsx-types';\r\nimport { setPlatformModelProcessor, createRenderer, setDefaultMount } from '@sigx/runtime-core/internals';\r\nimport type { RendererOptions } from '@sigx/runtime-core/internals';\r\nimport { isDirective, type DirectiveDefinition, type JSXElement } from '@sigx/runtime-core';\r\nimport type { AppContext } from '@sigx/runtime-core';\r\nimport { renderTargetNotFoundError, mountTargetNotFoundError } from '@sigx/runtime-core';\r\n\r\n/**\r\n * A directive definition narrowed to DOM elements.\r\n * Use this type when defining directives for the DOM renderer.\r\n *\r\n * @example\r\n * ```ts\r\n * import { defineDirective, type DOMDirective } from 'sigx';\r\n *\r\n * const tooltip = defineDirective<string, HTMLElement>({\r\n * mounted(el, { value }) {\r\n * el.title = value; // el is HTMLElement, fully typed\r\n * }\r\n * });\r\n * ```\r\n */\r\nexport type DOMDirective<T = any> = DirectiveDefinition<T, HTMLElement>;\r\n\r\n// ============================================================================\r\n// Directive Runtime for DOM (element-level use:* directives)\r\n// ============================================================================\r\n\r\n/**\r\n * Registry of built-in directives by name.\r\n * When a `use:<name>` prop receives a plain value (not a DirectiveDefinition),\r\n * the runtime looks up the directive by name here.\r\n * @internal\r\n */\r\nconst builtInDirectives = new Map<string, DirectiveDefinition>();\r\n\r\n/**\r\n * Register a built-in directive so it can be used with the shorthand syntax:\r\n * `<div use:show={value}>` instead of `<div use:show={[show, value]}>`.\r\n * @internal\r\n */\r\nexport function registerBuiltInDirective(name: string, def: DirectiveDefinition): void {\r\n builtInDirectives.set(name, def);\r\n}\r\n\r\n/**\r\n * Look up a registered built-in directive by name.\r\n * Used by SSR renderer to resolve `use:<name>={value}` shorthand.\r\n * @internal\r\n */\r\nexport function resolveBuiltInDirective(name: string): DirectiveDefinition | undefined {\r\n return builtInDirectives.get(name);\r\n}\r\n\r\n/**\r\n * Symbol key to store directive state on DOM elements.\r\n * @internal\r\n */\r\nconst DIRECTIVE_STATE = Symbol.for('sigx.directives');\r\n\r\n/**\r\n * Per-directive state stored on a DOM element.\r\n * @internal\r\n */\r\ninterface DirectiveState {\r\n def: DirectiveDefinition;\r\n value: any;\r\n cleanup?: () => void;\r\n}\r\n\r\n/**\r\n * Get or create the directive state map on a DOM element.\r\n * @internal\r\n */\r\nfunction getDirectiveMap(el: Element): Map<string, DirectiveState> {\r\n let map = (el as any)[DIRECTIVE_STATE] as Map<string, DirectiveState> | undefined;\r\n if (!map) {\r\n map = new Map();\r\n (el as any)[DIRECTIVE_STATE] = map;\r\n }\r\n return map;\r\n}\r\n\r\n/**\r\n * Process a `use:*` prop in patchProp.\r\n * Handles directive created and updated lifecycle hooks.\r\n * @internal\r\n */\r\nfunction patchDirective(el: Element, name: string, prevValue: any, nextValue: any, appContext: AppContext | null): void {\r\n const dirMap = getDirectiveMap(el);\r\n\r\n if (nextValue == null) {\r\n // Directive removed — unmounted will be called via onElementUnmounted\r\n dirMap.delete(name);\r\n return;\r\n }\r\n\r\n // Extract directive definition and binding value from the prop value:\r\n // - use:name={directiveDef} → def=directiveDef, value=undefined\r\n // - use:name={[directiveDef, value]} → def=directiveDef[0], value=directiveDef[1]\r\n let def: DirectiveDefinition;\r\n let value: any;\r\n\r\n if (isDirective(nextValue)) {\r\n def = nextValue;\r\n value = undefined;\r\n } else if (\r\n Array.isArray(nextValue) &&\r\n nextValue.length >= 1 &&\r\n isDirective(nextValue[0])\r\n ) {\r\n def = nextValue[0];\r\n value = nextValue[1];\r\n } else {\r\n // Not an explicit directive — try to resolve by name:\r\n // 1. Built-in directives (always available, e.g., 'show')\r\n // 2. App-registered custom directives (via app.directive())\r\n const builtIn = builtInDirectives.get(name);\r\n if (builtIn) {\r\n def = builtIn;\r\n value = nextValue;\r\n } else {\r\n const custom = appContext?.directives.get(name);\r\n if (custom) {\r\n def = custom;\r\n value = nextValue;\r\n } else {\r\n console.warn(\r\n `[sigx] Directive \"use:${name}\" could not be resolved. ` +\r\n `Make sure to register it via app.directive('${name}', definition) or pass a directive definition directly.`\r\n );\r\n return;\r\n }\r\n }\r\n }\r\n\r\n const existing = dirMap.get(name);\r\n\r\n if (!existing) {\r\n // First time — call created hook\r\n const state: DirectiveState = { def, value };\r\n dirMap.set(name, state);\r\n\r\n if (def.created) {\r\n def.created(el, { value });\r\n }\r\n } else {\r\n // Update — call updated hook\r\n const oldValue = existing.value;\r\n existing.def = def;\r\n existing.value = value;\r\n\r\n if (def.updated && value !== oldValue) {\r\n def.updated(el, { value, oldValue });\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Called after an element is inserted into the DOM.\r\n * Invokes `mounted` hooks for all directives on the element.\r\n * @internal\r\n */\r\nfunction onElementMounted(el: Element): void {\r\n const map = (el as any)[DIRECTIVE_STATE] as Map<string, DirectiveState> | undefined;\r\n if (!map) return;\r\n\r\n for (const [, state] of map) {\r\n if (state.def.mounted) {\r\n state.def.mounted(el, { value: state.value });\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Called before an element is removed from the DOM.\r\n * Invokes `unmounted` hooks for all directives on the element.\r\n * @internal\r\n */\r\nfunction onElementUnmounted(el: Element): void {\r\n // Clean up directive state\r\n const map = (el as any)[DIRECTIVE_STATE] as Map<string, DirectiveState> | undefined;\r\n if (map) {\r\n for (const [, state] of map) {\r\n if (state.def.unmounted) {\r\n state.def.unmounted(el, { value: state.value });\r\n }\r\n if (state.cleanup) {\r\n state.cleanup();\r\n }\r\n }\r\n map.clear();\r\n delete (el as any)[DIRECTIVE_STATE];\r\n }\r\n\r\n // Clean up event handlers to prevent memory leaks\r\n const handlersKey = '__sigx_event_handlers';\r\n const handlers = (el as any)[handlersKey] as Map<string, EventListener> | undefined;\r\n if (handlers) {\r\n for (const [eventName, handler] of handlers) {\r\n el.removeEventListener(eventName, handler);\r\n }\r\n handlers.clear();\r\n delete (el as any)[handlersKey];\r\n }\r\n}\r\n\r\n// SVG namespace for createElementNS\r\nconst svgNS = 'http://www.w3.org/2000/svg';\r\n\r\n// SVG elements that should be created with createElementNS\r\n// Based on https://developer.mozilla.org/en-US/docs/Web/SVG/Element\r\nconst svgElements = new Set([\r\n 'svg', 'animate', 'animateMotion', 'animateTransform', 'circle', 'clipPath',\r\n 'defs', 'desc', 'ellipse', 'feBlend', 'feColorMatrix', 'feComponentTransfer',\r\n 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap',\r\n 'feDistantLight', 'feDropShadow', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG',\r\n 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode', 'feMorphology',\r\n 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile',\r\n 'feTurbulence', 'filter', 'foreignObject', 'g', 'image', 'line', 'linearGradient',\r\n 'marker', 'mask', 'metadata', 'mpath', 'path', 'pattern', 'polygon', 'polyline',\r\n 'radialGradient', 'rect', 'set', 'stop', 'switch', 'symbol', 'text', 'textPath',\r\n 'title', 'tspan', 'use', 'view'\r\n]);\r\n\r\n/**\r\n * Check if a tag is an SVG element\r\n */\r\nfunction _isSvgTag(tag: string): boolean {\r\n return svgElements.has(tag);\r\n}\r\n\r\n// Register DOM-specific model processor for intrinsic elements (checkbox, radio, etc.)\r\nsetPlatformModelProcessor((type, props, [stateObj, key], originalProps) => {\r\n // Helper to set value - uses onUpdate handler if available (for props model forwarding)\r\n const setValue = (v: any) => {\r\n const updateHandler = stateObj[`onUpdate:${key}`];\r\n if (typeof updateHandler === 'function') {\r\n updateHandler(v);\r\n } else {\r\n stateObj[key] = v;\r\n }\r\n };\r\n\r\n // Smart mapping for checkbox\r\n if (type === 'input' && originalProps.type === 'checkbox') {\r\n const val = stateObj[key];\r\n\r\n if (Array.isArray(val)) {\r\n // Array Checkbox (Multi-select)\r\n props.checked = val.includes(originalProps.value);\r\n\r\n const existingHandler = props['onUpdate:modelValue'];\r\n props['onUpdate:modelValue'] = (checked: boolean) => {\r\n const currentVal = originalProps.value;\r\n const currentArr = stateObj[key] as any[];\r\n if (checked) {\r\n if (!currentArr.includes(currentVal)) {\r\n setValue([...currentArr, currentVal]);\r\n }\r\n } else {\r\n setValue(currentArr.filter((i: any) => i !== currentVal));\r\n }\r\n if (existingHandler) existingHandler(checked);\r\n };\r\n } else {\r\n // Boolean Checkbox\r\n props.checked = val;\r\n const existingHandler = props['onUpdate:modelValue'];\r\n props['onUpdate:modelValue'] = (v: any) => {\r\n setValue(v);\r\n if (existingHandler) existingHandler(v);\r\n };\r\n }\r\n return true; // Handled\r\n }\r\n\r\n // Radio Button\r\n if (type === 'input' && originalProps.type === 'radio') {\r\n props.checked = stateObj[key] === originalProps.value;\r\n const existingHandler = props['onUpdate:modelValue'];\r\n props['onUpdate:modelValue'] = (checked: boolean) => {\r\n if (checked) setValue(originalProps.value);\r\n if (existingHandler) existingHandler(checked);\r\n };\r\n return true; // Handled\r\n }\r\n\r\n // Text input (default input type)\r\n if (type === 'input') {\r\n props.value = stateObj[key] ?? '';\r\n const existingHandler = props['onUpdate:modelValue'];\r\n props['onUpdate:modelValue'] = (v: any) => {\r\n setValue(v);\r\n if (existingHandler) existingHandler(v);\r\n };\r\n return true; // Handled\r\n }\r\n\r\n // Textarea\r\n if (type === 'textarea') {\r\n props.value = stateObj[key] ?? '';\r\n const existingHandler = props['onUpdate:modelValue'];\r\n props['onUpdate:modelValue'] = (v: any) => {\r\n setValue(v);\r\n if (existingHandler) existingHandler(v);\r\n };\r\n return true; // Handled\r\n }\r\n\r\n // Select\r\n if (type === 'select') {\r\n if (originalProps.multiple && Array.isArray(stateObj[key])) {\r\n // Multi-select: pass array as value, patchProp will set option.selected\r\n props.value = stateObj[key];\r\n } else {\r\n props.value = stateObj[key] ?? '';\r\n }\r\n const existingHandler = props['onUpdate:modelValue'];\r\n props['onUpdate:modelValue'] = (v: any) => {\r\n setValue(v);\r\n if (existingHandler) existingHandler(v);\r\n };\r\n return true; // Handled\r\n }\r\n\r\n // Not handled - use generic fallback\r\n return false;\r\n});\r\n\r\nfunction patchProp(dom: Element, key: string, prevValue: any, nextValue: any, isSVG?: boolean) {\r\n // Guard: skip if dom is null (shouldn't happen but protects against edge cases)\r\n if (!dom) return;\r\n const tagName = dom.tagName.toLowerCase();\r\n \r\n // Detect SVG context: either passed explicitly or detect from element type\r\n // This ensures SVG attributes are handled correctly even if renderer doesn't pass isSVG\r\n const isSvgElement = isSVG ?? (dom instanceof SVGElement);\r\n \r\n const _oldProps = prevValue ? { [key]: prevValue } : {};\r\n const _newProps = nextValue ? { [key]: nextValue } : {};\r\n\r\n // This is a simplified version of updateProps that handles a single prop\r\n // But the original updateProps handled all props at once.\r\n // The renderer calls patchProp for each key.\r\n\r\n // Logic adapted from original updateProps\r\n const oldValue = prevValue;\r\n const newValue = nextValue;\r\n\r\n if (key === 'children' || key === 'key' || key === 'ref') return;\r\n\r\n if (key === 'style') {\r\n const el = dom as HTMLElement;\r\n if (typeof newValue === 'object' && newValue !== null) {\r\n const styleObj = newValue as Record<string, string | number | null | undefined>;\r\n // Remove old style properties not present in the new style object\r\n if (typeof oldValue === 'object' && oldValue !== null) {\r\n for (const oldKey in oldValue as Record<string, any>) {\r\n if (!(oldKey in styleObj)) {\r\n if (oldKey.startsWith('--')) {\r\n el.style.removeProperty(oldKey);\r\n } else {\r\n (el.style as any)[oldKey] = '';\r\n }\r\n }\r\n }\r\n }\r\n for (const styleKey in styleObj) {\r\n const val = styleObj[styleKey];\r\n if (val == null || val === '') {\r\n if (styleKey.startsWith('--')) {\r\n el.style.removeProperty(styleKey);\r\n } else {\r\n (el.style as any)[styleKey] = '';\r\n }\r\n } else {\r\n if (styleKey.startsWith('--')) {\r\n el.style.setProperty(styleKey, String(val));\r\n } else {\r\n (el.style as any)[styleKey] = val;\r\n }\r\n }\r\n }\r\n } else if (newValue) {\r\n el.style.cssText = String(newValue);\r\n } else {\r\n el.style.cssText = '';\r\n }\r\n } else if (key.startsWith('on')) {\r\n if (key === 'onUpdate:modelValue' && (tagName === 'input' || tagName === 'textarea' || tagName === 'select')) {\r\n const el = dom as HTMLElement;\r\n if (oldValue) {\r\n const wrapper = (oldValue as any).__sigx_model_handler;\r\n if (wrapper) {\r\n el.removeEventListener('input', wrapper);\r\n el.removeEventListener('change', wrapper);\r\n }\r\n }\r\n\r\n if (newValue) {\r\n const handler = (e: Event) => {\r\n const target = e.target as HTMLInputElement;\r\n let val: any;\r\n\r\n if (target.type === 'checkbox' || target.type === 'radio') {\r\n val = target.checked;\r\n } else if (target.type === 'number') {\r\n val = target.valueAsNumber;\r\n } else if (tagName === 'select' && (dom as HTMLSelectElement).multiple) {\r\n val = Array.from((dom as HTMLSelectElement).selectedOptions).map(o => o.value);\r\n } else {\r\n val = target.value;\r\n }\r\n\r\n (newValue as Function)(val);\r\n };\r\n (newValue as any).__sigx_model_handler = handler;\r\n\r\n const inputType = (dom as HTMLInputElement).type;\r\n if (tagName === 'select' || (tagName === 'input' && (inputType === 'checkbox' || inputType === 'radio'))) {\r\n el.addEventListener('change', handler);\r\n } else {\r\n el.addEventListener('input', handler);\r\n }\r\n }\r\n return;\r\n }\r\n\r\n const eventName = key.slice(2).toLowerCase();\r\n // Store handlers on the DOM element to properly track them across re-renders\r\n // Using a Map keyed by event name to ensure we remove the correct wrapper\r\n const handlersKey = '__sigx_event_handlers';\r\n let handlers = (dom as any)[handlersKey] as Map<string, EventListener> | undefined;\r\n if (!handlers) {\r\n handlers = new Map();\r\n (dom as any)[handlersKey] = handlers;\r\n }\r\n\r\n // Remove old handler if exists\r\n const oldHandler = handlers.get(eventName);\r\n if (oldHandler) {\r\n dom.removeEventListener(eventName, oldHandler);\r\n handlers.delete(eventName);\r\n }\r\n\r\n // Add new handler\r\n if (newValue) {\r\n const handler = (e: Event) => {\r\n if (e instanceof CustomEvent) {\r\n (newValue as Function)(e.detail);\r\n } else {\r\n (newValue as Function)(e);\r\n }\r\n };\r\n handlers.set(eventName, handler);\r\n dom.addEventListener(eventName, handler as EventListener);\r\n }\r\n } else if (key === 'className') {\r\n // For SVG, use setAttribute to preserve case (class works on both)\r\n dom.setAttribute('class', String(newValue));\r\n } else if (key.startsWith('.')) {\r\n const propName = key.slice(1);\r\n (dom as any)[propName] = newValue;\r\n } else if (key.startsWith('prop:')) {\r\n const propName = key.slice(5);\r\n (dom as any)[propName] = newValue;\r\n } else if (isSvgElement) {\r\n // SVG elements: use setAttribute to preserve case-sensitive attribute names\r\n // SVG attributes like viewBox, preserveAspectRatio, etc. are case-sensitive\r\n if (key === 'innerHTML' || key === 'textContent') {\r\n // These can be set as properties even on SVG\r\n (dom as any)[key] = newValue ?? '';\r\n } else if (key.startsWith('xlink:')) {\r\n // xlink: attributes need special namespace handling\r\n const xlinkNS = 'http://www.w3.org/1999/xlink';\r\n if (newValue == null) {\r\n dom.removeAttributeNS(xlinkNS, key.slice(6));\r\n } else {\r\n dom.setAttributeNS(xlinkNS, key, String(newValue));\r\n }\r\n } else {\r\n // Standard SVG attribute - use setAttribute to preserve case\r\n if (newValue === true) dom.setAttribute(key, '');\r\n else if (newValue === false || newValue == null) dom.removeAttribute(key);\r\n else dom.setAttribute(key, String(newValue));\r\n }\r\n } else {\r\n if ((tagName === 'input' || tagName === 'textarea' || tagName === 'select') &&\r\n (key === 'value' || key === 'checked')) {\r\n if (tagName === 'select' && key === 'value') {\r\n // Defer setting select value until options are mounted\r\n queueMicrotask(() => {\r\n if (Array.isArray(newValue)) {\r\n // Multi-select: set selected on each matching option\r\n const values = newValue as string[];\r\n const options = (dom as HTMLSelectElement).options;\r\n for (let i = 0; i < options.length; i++) {\r\n options[i].selected = values.includes(options[i].value);\r\n }\r\n } else {\r\n (dom as HTMLSelectElement).value = String(newValue ?? '');\r\n }\r\n });\r\n return;\r\n }\r\n\r\n if (key === 'checked' && tagName === 'input') {\r\n (dom as HTMLInputElement).checked = Boolean(newValue);\r\n } else if (key === 'value') {\r\n (dom as HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement).value = String(newValue ?? '');\r\n }\r\n } else if (key in dom) {\r\n // Skip undefined/null to avoid DOM coercing to 0 for numeric props like maxLength\r\n if (newValue == null) {\r\n // Remove attribute if it exists\r\n if (dom.hasAttribute?.(key)) {\r\n dom.removeAttribute(key);\r\n }\r\n } else {\r\n try {\r\n (dom as Record<string, any>)[key] = newValue;\r\n } catch {\r\n dom.setAttribute(key, String(newValue));\r\n }\r\n }\r\n } else if (tagName.includes('-') && !key.includes('-')) {\r\n (dom as Record<string, any>)[key] = newValue;\r\n } else {\r\n if (newValue === true) dom.setAttribute(key, '');\r\n else if (newValue === false || newValue == null) dom.removeAttribute(key);\r\n else dom.setAttribute(key, String(newValue));\r\n }\r\n }\r\n}\r\n\r\nconst nodeOps: RendererOptions<Node, Element> = {\r\n insert: (child, parent, anchor) => {\r\n if (anchor && anchor.parentNode !== parent) anchor = null;\r\n parent.insertBefore(child, anchor || null);\r\n },\r\n remove: (child) => {\r\n const parent = child.parentNode;\r\n if (parent) {\r\n parent.removeChild(child);\r\n }\r\n },\r\n createElement: (tag, isSVG, isCustomizedBuiltIn) => {\r\n if (isSVG) {\r\n return document.createElementNS(svgNS, tag);\r\n }\r\n const is = isCustomizedBuiltIn ? { is: isCustomizedBuiltIn } : undefined;\r\n return document.createElement(tag, is);\r\n },\r\n createText: (text) => document.createTextNode(text),\r\n createComment: (text) => document.createComment(text),\r\n setText: (node, text) => {\r\n node.nodeValue = text;\r\n },\r\n setElementText: (el, text) => {\r\n el.textContent = text;\r\n },\r\n parentNode: (node) => node.parentNode as Element,\r\n nextSibling: (node) => node.nextSibling,\r\n querySelector: (selector) => document.querySelector(selector),\r\n setScopeId: (el, id) => el.setAttribute(id, ''),\r\n cloneNode: (node) => node.cloneNode(true),\r\n getActiveElement: () => document.activeElement as Element | null,\r\n restoreFocus: (el) => {\r\n if (el instanceof HTMLElement || el instanceof SVGElement) {\r\n // Use preventScroll to avoid layout thrashing.\r\n // Suppress focus/blur events to prevent re-triggering reactive updates.\r\n const suppressEvent = (e: Event) => { e.stopImmediatePropagation(); };\r\n el.addEventListener('focus', suppressEvent, { capture: true, once: true });\r\n el.addEventListener('focusin', suppressEvent, { capture: true, once: true });\r\n // Also suppress blur on the element that will lose focus\r\n const current = document.activeElement;\r\n if (current instanceof HTMLElement) {\r\n current.addEventListener('blur', suppressEvent, { capture: true, once: true });\r\n current.addEventListener('focusout', suppressEvent, { capture: true, once: true });\r\n }\r\n el.focus({ preventScroll: true });\r\n }\r\n },\r\n patchProp,\r\n patchDirective,\r\n onElementMounted,\r\n onElementUnmounted\r\n};\r\n\r\nconst renderer = createRenderer(nodeOps);\r\n\r\n/**\r\n * Render a SignalX element to a DOM container.\r\n * Supports both Element references and CSS selectors.\r\n * \r\n * @example\r\n * ```tsx\r\n * import { render } from 'sigx';\r\n * \r\n * // Using CSS selector\r\n * render(<App />, \"#app\");\r\n * \r\n * // Using element reference\r\n * render(<App />, document.getElementById('app')!);\r\n * ```\r\n */\r\nexport const render = (element: JSXElement, container: Element | string, appContext?: AppContext): void => {\r\n const target = typeof container === 'string'\r\n ? document.querySelector(container)\r\n : container;\r\n\r\n if (!target) {\r\n throw renderTargetNotFoundError(String(container));\r\n }\r\n\r\n return renderer.render(element, target as Element, appContext);\r\n};\r\n\r\n// Export primitives for SSR plugins and hydration\r\nexport const { patch, mount, unmount, mountComponent } = renderer;\r\nexport { patchProp, patchDirective, onElementMounted, nodeOps };\r\n\r\n// Set up the default mount function for this platform\r\nsetDefaultMount((component: any, container: HTMLElement | Element | ShadowRoot | string, appContext?: AppContext): (() => void) => {\r\n const target = typeof container === 'string'\r\n ? document.querySelector(container)\r\n : container;\r\n\r\n if (!target) {\r\n throw mountTargetNotFoundError(String(container));\r\n }\r\n\r\n render(component, target as Element, appContext);\r\n\r\n return () => {\r\n render(null, target as Element);\r\n };\r\n});\r\n\r\n// Export Portal component and moveBefore utilities\r\nexport { Portal, supportsMoveBefore, moveNode } from './Portal.js';\r\n\r\n// Export built-in directives\r\nexport { show } from './directives/show.js';\r\n\r\n// Register built-in directives so use:show={value} works without importing\r\nimport { show as _showDirective } from './directives/show.js';\r\nregisterBuiltInDirective('show', _showDirective);\r\n"],"mappings":"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"}
|