foldkit 0.146.0 → 0.148.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.
- package/README.md +5 -2
- package/dist/buildToken.d.ts +3 -0
- package/dist/buildToken.d.ts.map +1 -0
- package/dist/buildToken.js +21 -0
- package/dist/controlledDomState.d.ts +25 -0
- package/dist/controlledDomState.d.ts.map +1 -0
- package/dist/controlledDomState.js +240 -0
- package/dist/cssStyleProperties.d.ts +6 -0
- package/dist/cssStyleProperties.d.ts.map +1 -0
- package/dist/cssStyleProperties.js +91 -0
- package/dist/customElement/index.d.ts.map +1 -1
- package/dist/customElement/index.js +23 -0
- package/dist/domReflection.d.ts +73 -0
- package/dist/domReflection.d.ts.map +1 -0
- package/dist/domReflection.js +557 -0
- package/dist/experimental/index.d.ts +1 -0
- package/dist/experimental/index.d.ts.map +1 -1
- package/dist/experimental/index.js +1 -0
- package/dist/experimental/machine/machine.d.ts +22 -3
- package/dist/experimental/machine/machine.d.ts.map +1 -1
- package/dist/experimental/machine/machine.js +8 -0
- package/dist/experimental/server/entry.d.ts +73 -0
- package/dist/experimental/server/entry.d.ts.map +1 -0
- package/dist/experimental/server/entry.js +41 -0
- package/dist/experimental/server/host.d.ts +136 -0
- package/dist/experimental/server/host.d.ts.map +1 -0
- package/dist/experimental/server/host.js +359 -0
- package/dist/experimental/server/index.d.ts +5 -0
- package/dist/experimental/server/index.d.ts.map +1 -0
- package/dist/experimental/server/index.js +4 -0
- package/dist/experimental/server/public.d.ts +3 -0
- package/dist/experimental/server/public.d.ts.map +1 -0
- package/dist/experimental/server/public.js +1 -0
- package/dist/experimental/server/serialize.d.ts +43 -0
- package/dist/experimental/server/serialize.d.ts.map +1 -0
- package/dist/experimental/server/serialize.js +786 -0
- package/dist/experimental/server/server.d.ts +242 -0
- package/dist/experimental/server/server.d.ts.map +1 -0
- package/dist/experimental/server/server.js +946 -0
- package/dist/experimental/server/template.d.ts +53 -0
- package/dist/experimental/server/template.d.ts.map +1 -0
- package/dist/experimental/server/template.js +617 -0
- package/dist/html/index.d.ts +5 -0
- package/dist/html/index.d.ts.map +1 -1
- package/dist/html/index.js +474 -33
- package/dist/hydrate.d.ts +4 -0
- package/dist/hydrate.d.ts.map +1 -0
- package/dist/hydrate.js +850 -0
- package/dist/hydrationMarker.d.ts +10 -0
- package/dist/hydrationMarker.d.ts.map +1 -0
- package/dist/hydrationMarker.js +9 -0
- package/dist/hydrationMarkers.d.ts +15 -0
- package/dist/hydrationMarkers.d.ts.map +1 -0
- package/dist/hydrationMarkers.js +70 -0
- package/dist/nativeInnerHtml.d.ts +13 -0
- package/dist/nativeInnerHtml.d.ts.map +1 -0
- package/dist/nativeInnerHtml.js +30 -0
- package/dist/propertyProvenance.d.ts +33 -0
- package/dist/propertyProvenance.d.ts.map +1 -0
- package/dist/propertyProvenance.js +78 -0
- package/dist/propsModule.d.ts.map +1 -1
- package/dist/propsModule.js +149 -15
- package/dist/runtime/public.d.ts +2 -2
- package/dist/runtime/public.d.ts.map +1 -1
- package/dist/runtime/public.js +1 -1
- package/dist/runtime/runtime.d.ts +99 -36
- package/dist/runtime/runtime.d.ts.map +1 -1
- package/dist/runtime/runtime.js +412 -71
- package/dist/snabbdom/attributes.d.ts.map +1 -1
- package/dist/snabbdom/attributes.js +65 -37
- package/dist/snabbdom/h.d.ts +1 -0
- package/dist/snabbdom/h.d.ts.map +1 -1
- package/dist/snabbdom/h.js +85 -4
- package/dist/snabbdom/style.d.ts.map +1 -1
- package/dist/snabbdom/style.js +53 -34
- package/dist/snabbdom/tovnode.d.ts.map +1 -1
- package/dist/snabbdom/tovnode.js +5 -1
- package/dist/tagName.d.ts +6 -0
- package/dist/tagName.d.ts.map +1 -0
- package/dist/tagName.js +11 -0
- package/dist/test/apps/attributes.d.ts +1 -0
- package/dist/test/apps/attributes.d.ts.map +1 -1
- package/dist/test/apps/attributes.js +8 -1
- package/dist/test/apps/login.js +1 -1
- package/dist/test/matchers.d.ts.map +1 -1
- package/dist/test/matchers.js +2 -1
- package/dist/test/scene.d.ts.map +1 -1
- package/dist/test/scene.js +2 -1
- package/dist/vdom.d.ts.map +1 -1
- package/dist/vdom.js +25 -1
- package/package.json +9 -2
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
---
|
|
20
20
|
|
|
21
|
-
Foldkit is a TypeScript frontend framework built on [Effect](https://effect.website/) and architected like [Elm](https://guide.elm-lang.org/architecture/). One Model, one update function, one way to do things. No hooks, no local state, no hidden mutations. It's all in on Effect with no escape hatch, though a program doesn't have to own the whole page: [`Runtime.embed`](https://foldkit.dev/core/embedding) runs a Foldkit widget inside any existing app, React included.
|
|
21
|
+
Foldkit is a TypeScript frontend framework built on [Effect](https://effect.website/) and architected like [Elm](https://guide.elm-lang.org/architecture/). One Model, one update function, one way to do things. No hooks, no local state, no hidden mutations. It's all in on Effect with no escape hatch, though a program doesn't have to own the whole page: [`Runtime.embed`](https://foldkit.dev/core/embedding) runs a Foldkit widget inside any existing app, React included. The same program also [renders on the server](https://foldkit.dev/core/server-rendering), at build time or per request, and hydrates in place.
|
|
22
22
|
|
|
23
23
|
Your Model is a [Schema](https://effect.website/docs/schema/introduction/) and side effects are values you return, not callbacks you fire. If you know Effect, Foldkit feels natural. If you're new to it, Foldkit is a good way in. Coming from React? [Start here](https://foldkit.dev/react/coming-from-react), or read the [same pixel-art editor built in both frameworks](https://foldkit.dev/react/foldkit-vs-react-side-by-side).
|
|
24
24
|
|
|
@@ -27,7 +27,7 @@ Your Model is a [Schema](https://effect.website/docs/schema/introduction/) and s
|
|
|
27
27
|
|
|
28
28
|
## Get Started
|
|
29
29
|
|
|
30
|
-
`create-foldkit-app` scaffolds a complete setup with Tailwind, TypeScript, [Oxlint](https://foldkit.dev/tooling/oxlint-plugin), Prettier, and the Vite plugin for state-preserving HMR,
|
|
30
|
+
`create-foldkit-app` scaffolds a complete setup with Tailwind, TypeScript, [Oxlint](https://foldkit.dev/tooling/oxlint-plugin), Prettier, and the Vite plugin for state-preserving HMR. Pick a rendering mode (browser-only SPA, static generation, or server rendering) and, for a SPA, the example to start from.
|
|
31
31
|
|
|
32
32
|
```bash
|
|
33
33
|
npx create-foldkit-app@latest
|
|
@@ -137,6 +137,7 @@ A complete system, not a collection of libraries you stitch together. Each of th
|
|
|
137
137
|
- **UI Components**: Accessible, keyboard-friendly primitives in the `@foldkit/ui` package.
|
|
138
138
|
- **Field Validation**: Per-field validation state modeled as a discriminated union.
|
|
139
139
|
- **Virtual DOM**: Declarative views with lazy memoization and keyed diffing, powered by [Snabbdom](https://github.com/snabbdom/snabbdom).
|
|
140
|
+
- **Server Rendering**: The same program rendered to HTML at build time (SSG) or per request (SSR), then hydrated in place.
|
|
140
141
|
- **DevTools**: In-browser overlay for inspecting Messages, Model, and Commands, with time-travel.
|
|
141
142
|
- **DevTools MCP**: Expose a running app to AI agents over the Model Context Protocol.
|
|
142
143
|
- **Crash View and Reporting**: A custom fallback UI when the update loop throws, plus a report callback.
|
|
@@ -169,6 +170,8 @@ Some of what you can build with Foldkit. [See all example apps on foldkit.dev](h
|
|
|
169
170
|
- **[Kanban](https://foldkit.dev/example-apps/kanban)**: Drag-and-drop kanban board with cross-column reordering and keyboard navigation
|
|
170
171
|
- **[Pixel Art](https://foldkit.dev/example-apps/pixel-art)**: Grid-based pixel editor with painting, erasing, and palette selection
|
|
171
172
|
- **[UI Showcase](https://foldkit.dev/example-apps/ui-showcase)**: Interactive showcase of every Foldkit UI component
|
|
173
|
+
- **[Static Site Generation](https://foldkit.dev/example-apps/ssg)**: Build-time prerendering with client hydration
|
|
174
|
+
- **[Server-Side Rendering](https://foldkit.dev/example-apps/ssr)**: Per-request rendering on an Effect HttpServer with cookie-derived Flags
|
|
172
175
|
- **[Typing Game](https://github.com/foldkit/foldkit/tree/main/packages/typing-game)**: Multiplayer typing game with Effect RPC backend ([play it live](https://typingterminal.com))
|
|
173
176
|
|
|
174
177
|
## License
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildToken.d.ts","sourceRoot":"","sources":["../src/buildToken.ts"],"names":[],"mappings":"AAoBA,kEAAkE;AAClE,eAAO,MAAM,yBAAyB,uBAAuB,CAAA"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// The build id names the deployment a page came from. `renderToString` stamps it
|
|
2
|
+
// on the rendered root and `Runtime.hydrate` compares it before adopting
|
|
3
|
+
// anything, so a page from one deployment is never reconciled against a client
|
|
4
|
+
// from another.
|
|
5
|
+
//
|
|
6
|
+
// View identities cannot answer that question on their own. They move when the
|
|
7
|
+
// view they name changes, but what a view renders also depends on the constants
|
|
8
|
+
// it imports, the configuration it reads, and the arguments its caller passes. A
|
|
9
|
+
// component whose own source is untouched renders something different when its
|
|
10
|
+
// caller changes, and its identity is the one that wins on the element, so the
|
|
11
|
+
// DOM state on a stale page could otherwise be carried into a view that now
|
|
12
|
+
// means something else.
|
|
13
|
+
//
|
|
14
|
+
// Both sides are given the id explicitly rather than reading it from a
|
|
15
|
+
// compile-time constant inside this package. Vite externalizes an installed
|
|
16
|
+
// dependency from a server build, where a define never reaches it, so a
|
|
17
|
+
// framework-internal read is silently absent in exactly the production shape
|
|
18
|
+
// that matters. Application code is always transformed, so the entries read
|
|
19
|
+
// `import.meta.env.FOLDKIT_BUILD_ID` and pass what they find.
|
|
20
|
+
/** The attribute a hydratable render stamps the build id onto. */
|
|
21
|
+
export const HYDRATION_BUILD_ATTRIBUTE = 'data-foldkit-build';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { VNode } from './snabbdom/vnode.js';
|
|
2
|
+
/** Synchronizes the default state that parsed HTML necessarily creates for a
|
|
3
|
+
* controlled property.
|
|
4
|
+
*
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
export declare const synchronizeControlledDefault: (element: Element, propertyName: string, value: unknown) => void;
|
|
8
|
+
/** Clears default state owned by a controlled property that left a vnode.
|
|
9
|
+
*
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
export declare const clearControlledDefault: (element: Element, propertyName: string) => void;
|
|
13
|
+
export declare const restoreUncontrolledContent: (element: Element, vnode: VNode) => void;
|
|
14
|
+
/** Restores live state after a controlled property gives ownership to a raw
|
|
15
|
+
* attribute when that property has separate current and default state.
|
|
16
|
+
*
|
|
17
|
+
* @internal
|
|
18
|
+
*/
|
|
19
|
+
export declare const restoreControlledStateFromRawAttribute: (element: Element, propertyName: string) => void;
|
|
20
|
+
/** Live and default properties jointly owned by a controlled vnode property.
|
|
21
|
+
*
|
|
22
|
+
* @internal
|
|
23
|
+
*/
|
|
24
|
+
export declare const controlledStatePropertyNames: (element: Element, properties: Readonly<Record<string, unknown>> | undefined) => ReadonlyArray<string>;
|
|
25
|
+
//# sourceMappingURL=controlledDomState.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controlledDomState.d.ts","sourceRoot":"","sources":["../src/controlledDomState.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAoBhD;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,GACvC,SAAS,OAAO,EAChB,cAAc,MAAM,EACpB,OAAO,OAAO,KACb,IAqDF,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,sBAAsB,GACjC,SAAS,OAAO,EAChB,cAAc,MAAM,KACnB,IA0CF,CAAA;AAsFD,eAAO,MAAM,0BAA0B,GACrC,SAAS,OAAO,EAChB,OAAO,KAAK,KACX,IAYF,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,sCAAsC,GACjD,SAAS,OAAO,EAChB,cAAc,MAAM,KACnB,IA0BF,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,4BAA4B,GACvC,SAAS,OAAO,EAChB,YAAY,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,KACxD,aAAa,CAAC,MAAM,CAuBtB,CAAA"}
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { HTML_NAMESPACE, htmlAttributeValue } from './domReflection.js';
|
|
2
|
+
import { isClientOnlyProperty } from './propertyProvenance.js';
|
|
3
|
+
import { tagNameFromSelector } from './tagName.js';
|
|
4
|
+
const htmlTagName = (element) => element.namespaceURI === null || element.namespaceURI === HTML_NAMESPACE
|
|
5
|
+
? element.localName
|
|
6
|
+
: undefined;
|
|
7
|
+
const setBooleanDefaultAttribute = (element, name, value) => {
|
|
8
|
+
if (value && !element.hasAttribute(name)) {
|
|
9
|
+
element.setAttribute(name, '');
|
|
10
|
+
}
|
|
11
|
+
else if (!value && element.hasAttribute(name)) {
|
|
12
|
+
element.removeAttribute(name);
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
/** Synchronizes the default state that parsed HTML necessarily creates for a
|
|
16
|
+
* controlled property.
|
|
17
|
+
*
|
|
18
|
+
* @internal
|
|
19
|
+
*/
|
|
20
|
+
export const synchronizeControlledDefault = (element, propertyName, value) => {
|
|
21
|
+
const tagName = htmlTagName(element);
|
|
22
|
+
if (propertyName === 'value' &&
|
|
23
|
+
(tagName === 'input' || tagName === 'textarea' || tagName === 'output')) {
|
|
24
|
+
const nextValue = String(value);
|
|
25
|
+
if (Reflect.get(element, 'defaultValue') !== nextValue) {
|
|
26
|
+
Reflect.set(element, 'defaultValue', nextValue);
|
|
27
|
+
}
|
|
28
|
+
if (tagName === 'input') {
|
|
29
|
+
if (element.getAttribute('value') !== nextValue) {
|
|
30
|
+
element.setAttribute('value', nextValue);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if (propertyName === 'checked' && tagName === 'input') {
|
|
36
|
+
const isChecked = Boolean(value);
|
|
37
|
+
if (Reflect.get(element, 'defaultChecked') !== isChecked) {
|
|
38
|
+
Reflect.set(element, 'defaultChecked', isChecked);
|
|
39
|
+
}
|
|
40
|
+
setBooleanDefaultAttribute(element, 'checked', isChecked);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (propertyName === 'selected' && tagName === 'option') {
|
|
44
|
+
const isSelected = Boolean(value);
|
|
45
|
+
if (Reflect.get(element, 'defaultSelected') !== isSelected) {
|
|
46
|
+
Reflect.set(element, 'defaultSelected', isSelected);
|
|
47
|
+
}
|
|
48
|
+
setBooleanDefaultAttribute(element, 'selected', isSelected);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (propertyName === 'muted' &&
|
|
52
|
+
(tagName === 'audio' || tagName === 'video')) {
|
|
53
|
+
const isMuted = Boolean(value);
|
|
54
|
+
if (Reflect.get(element, 'defaultMuted') !== isMuted) {
|
|
55
|
+
Reflect.set(element, 'defaultMuted', isMuted);
|
|
56
|
+
}
|
|
57
|
+
setBooleanDefaultAttribute(element, 'muted', isMuted);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (propertyName === 'value' && tagName === 'select') {
|
|
61
|
+
for (const option of element.querySelectorAll('option')) {
|
|
62
|
+
if (option.defaultSelected !== option.selected) {
|
|
63
|
+
option.defaultSelected = option.selected;
|
|
64
|
+
}
|
|
65
|
+
setBooleanDefaultAttribute(option, 'selected', option.selected);
|
|
66
|
+
}
|
|
67
|
+
Reflect.set(element, 'value', value);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
/** Clears default state owned by a controlled property that left a vnode.
|
|
71
|
+
*
|
|
72
|
+
* @internal
|
|
73
|
+
*/
|
|
74
|
+
export const clearControlledDefault = (element, propertyName) => {
|
|
75
|
+
const tagName = htmlTagName(element);
|
|
76
|
+
if (propertyName === 'value' &&
|
|
77
|
+
(tagName === 'input' || tagName === 'textarea' || tagName === 'output')) {
|
|
78
|
+
Reflect.set(element, 'defaultValue', '');
|
|
79
|
+
if (tagName === 'input') {
|
|
80
|
+
element.removeAttribute('value');
|
|
81
|
+
Reflect.set(element, 'value', '');
|
|
82
|
+
}
|
|
83
|
+
else if (tagName === 'output') {
|
|
84
|
+
Reflect.set(element, 'value', '');
|
|
85
|
+
}
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
if (propertyName === 'checked' && tagName === 'input') {
|
|
89
|
+
Reflect.set(element, 'defaultChecked', false);
|
|
90
|
+
element.removeAttribute('checked');
|
|
91
|
+
Reflect.set(element, 'checked', false);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (propertyName === 'selected' && tagName === 'option') {
|
|
95
|
+
Reflect.set(element, 'defaultSelected', false);
|
|
96
|
+
element.removeAttribute('selected');
|
|
97
|
+
Reflect.set(element, 'selected', false);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
if (propertyName === 'muted' &&
|
|
101
|
+
(tagName === 'audio' || tagName === 'video')) {
|
|
102
|
+
Reflect.set(element, 'defaultMuted', false);
|
|
103
|
+
element.removeAttribute('muted');
|
|
104
|
+
Reflect.set(element, 'muted', false);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
if (propertyName === 'value' && tagName === 'select') {
|
|
108
|
+
for (const option of element.querySelectorAll('option')) {
|
|
109
|
+
option.defaultSelected = false;
|
|
110
|
+
option.removeAttribute('selected');
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
const optionOwnershipOf = (vnode) => {
|
|
115
|
+
const props = vnode.data?.props;
|
|
116
|
+
const hasSelectedProperty = props !== undefined && Object.hasOwn(props, 'selected');
|
|
117
|
+
const isSelectedClientOnly = isClientOnlyProperty(props, 'selected');
|
|
118
|
+
const rawSelected = htmlAttributeValue(vnode.data?.attrs, 'selected') !== undefined;
|
|
119
|
+
return {
|
|
120
|
+
defaultSelected: hasSelectedProperty && !isSelectedClientOnly
|
|
121
|
+
? Boolean(props['selected'])
|
|
122
|
+
: rawSelected,
|
|
123
|
+
selected: hasSelectedProperty ? Boolean(props['selected']) : undefined,
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
const collectOptionOwnership = (vnode, collected) => {
|
|
127
|
+
if (vnode.sel !== undefined &&
|
|
128
|
+
tagNameFromSelector(vnode.sel).toLowerCase() === 'option') {
|
|
129
|
+
collected.push(optionOwnershipOf(vnode));
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
for (const child of vnode.children ?? []) {
|
|
133
|
+
if (typeof child !== 'string') {
|
|
134
|
+
collectOptionOwnership(child, collected);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
const restoreUncontrolledSelect = (element, vnode) => {
|
|
139
|
+
const isContentPropertyOwned = vnode.data?.props !== undefined &&
|
|
140
|
+
Object.hasOwn(vnode.data.props, 'innerHTML');
|
|
141
|
+
const ownership = [];
|
|
142
|
+
if (!isContentPropertyOwned) {
|
|
143
|
+
collectOptionOwnership(vnode, ownership);
|
|
144
|
+
const ownershipIterator = ownership.values();
|
|
145
|
+
for (const option of Array.from(element.options)) {
|
|
146
|
+
const nextOwnership = ownershipIterator.next().value;
|
|
147
|
+
const isDefaultSelected = nextOwnership?.defaultSelected ?? false;
|
|
148
|
+
if (option.defaultSelected !== isDefaultSelected) {
|
|
149
|
+
option.defaultSelected = isDefaultSelected;
|
|
150
|
+
}
|
|
151
|
+
setBooleanDefaultAttribute(option, 'selected', isDefaultSelected);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
const probe = element.cloneNode(true);
|
|
155
|
+
if (!(probe instanceof HTMLSelectElement)) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
for (let index = 0; index < element.options.length; index += 1) {
|
|
159
|
+
const option = element.options.item(index);
|
|
160
|
+
const probeOption = probe.options.item(index);
|
|
161
|
+
if (option !== null && probeOption !== null) {
|
|
162
|
+
option.selected = probeOption.selected;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
const ownershipIterator = ownership.values();
|
|
166
|
+
for (const option of Array.from(element.options)) {
|
|
167
|
+
const selected = ownershipIterator.next().value?.selected;
|
|
168
|
+
if (selected !== undefined) {
|
|
169
|
+
option.selected = selected;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
export const restoreUncontrolledContent = (element, vnode) => {
|
|
174
|
+
if (element instanceof HTMLTextAreaElement) {
|
|
175
|
+
element.value = element.defaultValue;
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
if (element instanceof HTMLOutputElement) {
|
|
179
|
+
element.defaultValue = element.textContent ?? '';
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
if (element instanceof HTMLSelectElement) {
|
|
183
|
+
restoreUncontrolledSelect(element, vnode);
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
/** Restores live state after a controlled property gives ownership to a raw
|
|
187
|
+
* attribute when that property has separate current and default state.
|
|
188
|
+
*
|
|
189
|
+
* @internal
|
|
190
|
+
*/
|
|
191
|
+
export const restoreControlledStateFromRawAttribute = (element, propertyName) => {
|
|
192
|
+
const tagName = htmlTagName(element);
|
|
193
|
+
if (propertyName === 'value' && tagName === 'input') {
|
|
194
|
+
const value = Reflect.get(element, 'defaultValue');
|
|
195
|
+
Reflect.set(element, 'value', Reflect.get(element, 'type') === 'file' ? '' : value);
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
if (propertyName === 'checked' && tagName === 'input') {
|
|
199
|
+
Reflect.set(element, 'checked', Reflect.get(element, 'defaultChecked'));
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
if (propertyName === 'selected' && tagName === 'option') {
|
|
203
|
+
Reflect.set(element, 'selected', Reflect.get(element, 'defaultSelected'));
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
if (propertyName === 'muted' &&
|
|
207
|
+
(tagName === 'audio' || tagName === 'video')) {
|
|
208
|
+
Reflect.set(element, 'muted', Reflect.get(element, 'defaultMuted'));
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
/** Live and default properties jointly owned by a controlled vnode property.
|
|
213
|
+
*
|
|
214
|
+
* @internal
|
|
215
|
+
*/
|
|
216
|
+
export const controlledStatePropertyNames = (element, properties) => {
|
|
217
|
+
if (properties === undefined) {
|
|
218
|
+
return [];
|
|
219
|
+
}
|
|
220
|
+
const tagName = htmlTagName(element);
|
|
221
|
+
const names = [];
|
|
222
|
+
if ('value' in properties) {
|
|
223
|
+
if (tagName === 'input' || tagName === 'textarea' || tagName === 'output') {
|
|
224
|
+
names.push('value', 'defaultValue');
|
|
225
|
+
}
|
|
226
|
+
else if (tagName === 'select') {
|
|
227
|
+
names.push('value', 'selectedIndex');
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
if ('checked' in properties && tagName === 'input') {
|
|
231
|
+
names.push('checked', 'defaultChecked');
|
|
232
|
+
}
|
|
233
|
+
if ('selected' in properties && tagName === 'option') {
|
|
234
|
+
names.push('selected', 'defaultSelected');
|
|
235
|
+
}
|
|
236
|
+
if ('muted' in properties && (tagName === 'audio' || tagName === 'video')) {
|
|
237
|
+
names.push('muted', 'defaultMuted');
|
|
238
|
+
}
|
|
239
|
+
return names;
|
|
240
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cssStyleProperties.d.ts","sourceRoot":"","sources":["../src/cssStyleProperties.ts"],"names":[],"mappings":"AAuFA;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,WAAW,CAAC,MAAM,CAEpD,CAAA"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
const CSS_STYLE_PROPERTY_SOURCE = `
|
|
2
|
+
accentColor alignContent alignItems alignSelf alignmentBaseline all anchorName anchorScope
|
|
3
|
+
animation animationComposition animationDelay animationDirection animationDuration animationFillMode
|
|
4
|
+
animationIterationCount animationName animationPlayState animationRange animationRangeEnd
|
|
5
|
+
animationRangeStart animationTimeline animationTimingFunction appearance aspectRatio backdropFilter
|
|
6
|
+
backfaceVisibility background backgroundAttachment backgroundBlendMode backgroundClip backgroundColor
|
|
7
|
+
backgroundImage backgroundOrigin backgroundPosition backgroundPositionX backgroundPositionY
|
|
8
|
+
backgroundRepeat backgroundSize baselineShift baselineSource blockSize border borderBlock
|
|
9
|
+
borderBlockColor borderBlockEnd borderBlockEndColor borderBlockEndStyle borderBlockEndWidth
|
|
10
|
+
borderBlockStart borderBlockStartColor borderBlockStartStyle borderBlockStartWidth borderBlockStyle
|
|
11
|
+
borderBlockWidth borderBottom borderBottomColor borderBottomLeftRadius borderBottomRightRadius
|
|
12
|
+
borderBottomStyle borderBottomWidth borderCollapse borderColor borderEndEndRadius borderEndStartRadius
|
|
13
|
+
borderImage borderImageOutset borderImageRepeat borderImageSlice borderImageSource borderImageWidth
|
|
14
|
+
borderInline borderInlineColor borderInlineEnd borderInlineEndColor borderInlineEndStyle
|
|
15
|
+
borderInlineEndWidth borderInlineStart borderInlineStartColor borderInlineStartStyle
|
|
16
|
+
borderInlineStartWidth borderInlineStyle borderInlineWidth borderLeft borderLeftColor borderLeftStyle
|
|
17
|
+
borderLeftWidth borderRadius borderRight borderRightColor borderRightStyle borderRightWidth
|
|
18
|
+
borderSpacing borderStartEndRadius borderStartStartRadius borderStyle borderTop borderTopColor
|
|
19
|
+
borderTopLeftRadius borderTopRightRadius borderTopStyle borderTopWidth borderWidth bottom
|
|
20
|
+
boxDecorationBreak boxShadow boxSizing breakAfter breakBefore breakInside captionSide caretColor clear
|
|
21
|
+
clip clipPath clipRule color colorInterpolation colorInterpolationFilters colorScheme columnCount
|
|
22
|
+
columnFill columnGap columnRule columnRuleColor columnRuleStyle columnRuleWidth columnSpan columnWidth
|
|
23
|
+
columns contain containIntrinsicBlockSize containIntrinsicHeight containIntrinsicInlineSize
|
|
24
|
+
containIntrinsicSize containIntrinsicWidth container containerName containerType content
|
|
25
|
+
contentVisibility counterIncrement counterReset counterSet cssFloat cursor cx cy d direction display
|
|
26
|
+
dominantBaseline dynamicRangeLimit emptyCells fieldSizing fill fillOpacity fillRule filter flex
|
|
27
|
+
flexBasis flexDirection flexFlow flexGrow flexShrink flexWrap float floodColor floodOpacity font
|
|
28
|
+
fontFamily fontFeatureSettings fontKerning fontLanguageOverride fontOpticalSizing fontPalette fontSize
|
|
29
|
+
fontSizeAdjust fontStretch fontStyle fontSynthesis fontSynthesisSmallCaps fontSynthesisStyle
|
|
30
|
+
fontSynthesisWeight fontVariant fontVariantAlternates fontVariantCaps fontVariantEastAsian
|
|
31
|
+
fontVariantEmoji fontVariantLigatures fontVariantNumeric fontVariantPosition fontVariationSettings
|
|
32
|
+
fontWeight forcedColorAdjust gap grid gridArea gridAutoColumns gridAutoFlow gridAutoRows gridColumn
|
|
33
|
+
gridColumnEnd gridColumnGap gridColumnStart gridGap gridRow gridRowEnd gridRowGap gridRowStart
|
|
34
|
+
gridTemplate gridTemplateAreas gridTemplateColumns gridTemplateRows height hyphenateCharacter
|
|
35
|
+
hyphenateLimitChars hyphens imageOrientation imageRendering inlineSize inset insetBlock insetBlockEnd
|
|
36
|
+
insetBlockStart insetInline insetInlineEnd insetInlineStart isolation justifyContent justifyItems
|
|
37
|
+
justifySelf left letterSpacing lightingColor lineBreak lineHeight listStyle listStyleImage
|
|
38
|
+
listStylePosition listStyleType margin marginBlock marginBlockEnd marginBlockStart marginBottom
|
|
39
|
+
marginInline marginInlineEnd marginInlineStart marginLeft marginRight marginTop marker markerEnd markerMid
|
|
40
|
+
markerStart mask maskClip maskComposite maskImage maskMode maskOrigin maskPosition maskRepeat maskSize
|
|
41
|
+
maskType mathDepth mathShift mathStyle maxBlockSize maxHeight maxInlineSize maxWidth minBlockSize
|
|
42
|
+
minHeight minInlineSize minWidth mixBlendMode objectFit objectPosition offset offsetAnchor
|
|
43
|
+
offsetDistance offsetPath offsetPosition offsetRotate opacity order orphans outline outlineColor
|
|
44
|
+
outlineOffset outlineStyle outlineWidth overflow overflowAnchor overflowBlock overflowClipMargin
|
|
45
|
+
overflowInline overflowWrap overflowX overflowY overscrollBehavior overscrollBehaviorBlock
|
|
46
|
+
overscrollBehaviorInline overscrollBehaviorX overscrollBehaviorY padding paddingBlock paddingBlockEnd
|
|
47
|
+
paddingBlockStart paddingBottom paddingInline paddingInlineEnd paddingInlineStart paddingLeft paddingRight
|
|
48
|
+
paddingTop page pageBreakAfter pageBreakBefore pageBreakInside paintOrder perspective perspectiveOrigin
|
|
49
|
+
placeContent placeItems placeSelf pointerEvents position positionAnchor positionArea positionTry
|
|
50
|
+
positionTryFallbacks positionTryOrder positionVisibility printColorAdjust quotes r resize right rotate
|
|
51
|
+
rowGap rubyAlign rubyPosition rx ry scale scrollBehavior scrollMargin scrollMarginBlock
|
|
52
|
+
scrollMarginBlockEnd scrollMarginBlockStart scrollMarginBottom scrollMarginInline scrollMarginInlineEnd
|
|
53
|
+
scrollMarginInlineStart scrollMarginLeft scrollMarginRight scrollMarginTop scrollPadding
|
|
54
|
+
scrollPaddingBlock scrollPaddingBlockEnd scrollPaddingBlockStart scrollPaddingBottom scrollPaddingInline
|
|
55
|
+
scrollPaddingInlineEnd scrollPaddingInlineStart scrollPaddingLeft scrollPaddingRight scrollPaddingTop
|
|
56
|
+
scrollSnapAlign scrollSnapStop scrollSnapType scrollTimeline scrollTimelineAxis scrollTimelineName
|
|
57
|
+
scrollbarColor scrollbarGutter scrollbarWidth shapeImageThreshold shapeMargin shapeOutside
|
|
58
|
+
shapeRendering stopColor stopOpacity stroke strokeDasharray strokeDashoffset strokeLinecap
|
|
59
|
+
strokeLinejoin strokeMiterlimit strokeOpacity strokeWidth tabSize tableLayout textAlign textAlignLast
|
|
60
|
+
textAnchor textAutospace textBox textBoxEdge textBoxTrim textCombineUpright textDecoration
|
|
61
|
+
textDecorationColor textDecorationLine textDecorationSkipInk textDecorationStyle
|
|
62
|
+
textDecorationThickness textEmphasis textEmphasisColor textEmphasisPosition textEmphasisStyle
|
|
63
|
+
textIndent textJustify textOrientation textOverflow textRendering textShadow textTransform
|
|
64
|
+
textUnderlineOffset textUnderlinePosition textWrap textWrapMode textWrapStyle timelineScope top
|
|
65
|
+
touchAction transform transformBox transformOrigin transformStyle transition transitionBehavior
|
|
66
|
+
transitionDelay transitionDuration transitionProperty transitionTimingFunction translate unicodeBidi
|
|
67
|
+
userSelect vectorEffect verticalAlign viewTimeline viewTimelineAxis viewTimelineInset viewTimelineName
|
|
68
|
+
viewTransitionClass viewTransitionName visibility webkitAlignContent webkitAlignItems webkitAlignSelf
|
|
69
|
+
webkitAnimation webkitAnimationDelay webkitAnimationDirection webkitAnimationDuration
|
|
70
|
+
webkitAnimationFillMode webkitAnimationIterationCount webkitAnimationName webkitAnimationPlayState
|
|
71
|
+
webkitAnimationTimingFunction webkitAppearance webkitBackfaceVisibility webkitBackgroundClip
|
|
72
|
+
webkitBackgroundOrigin webkitBackgroundSize webkitBorderBottomLeftRadius
|
|
73
|
+
webkitBorderBottomRightRadius webkitBorderRadius webkitBorderTopLeftRadius
|
|
74
|
+
webkitBorderTopRightRadius webkitBoxAlign webkitBoxFlex webkitBoxOrdinalGroup webkitBoxOrient
|
|
75
|
+
webkitBoxPack webkitBoxShadow webkitBoxSizing webkitFilter webkitFlex webkitFlexBasis
|
|
76
|
+
webkitFlexDirection webkitFlexFlow webkitFlexGrow webkitFlexShrink webkitFlexWrap
|
|
77
|
+
webkitJustifyContent webkitLineClamp webkitMask webkitMaskBoxImage webkitMaskBoxImageOutset
|
|
78
|
+
webkitMaskBoxImageRepeat webkitMaskBoxImageSlice webkitMaskBoxImageSource webkitMaskBoxImageWidth
|
|
79
|
+
webkitMaskClip webkitMaskComposite webkitMaskImage webkitMaskOrigin webkitMaskPosition webkitMaskRepeat
|
|
80
|
+
webkitMaskSize webkitOrder webkitPerspective webkitPerspectiveOrigin webkitTextFillColor
|
|
81
|
+
webkitTextSizeAdjust webkitTextStroke webkitTextStrokeColor webkitTextStrokeWidth webkitTransform
|
|
82
|
+
webkitTransformOrigin webkitTransformStyle webkitTransition webkitTransitionDelay
|
|
83
|
+
webkitTransitionDuration webkitTransitionProperty webkitTransitionTimingFunction webkitUserSelect
|
|
84
|
+
whiteSpace whiteSpaceCollapse widows width willChange wordBreak wordSpacing wordWrap writingMode x y
|
|
85
|
+
zIndex zoom
|
|
86
|
+
`;
|
|
87
|
+
/** CSSStyleDeclaration properties supported by typed Foldkit style objects.
|
|
88
|
+
*
|
|
89
|
+
* @internal
|
|
90
|
+
*/
|
|
91
|
+
export const CSS_STYLE_PROPERTIES = new Set(CSS_STYLE_PROPERTY_SOURCE.trim().split(/\s+/));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/customElement/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/customElement/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,MAAM,EAAgB,MAAM,QAAQ,CAAA;AAEzD,OAAO,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAO3E;gFACgF;AAChF,KAAK,aAAa,CAAC,CAAC,SAAS,MAAM,IAAI,CAAC,SAAS,GAAG,MAAM,IAAI,IAAI,MAAM,IAAI,EAAE,GAC1E,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,IAAI,CAAC,EAAE,GAC3C,UAAU,CAAC,CAAC,CAAC,CAAA;AAEjB,KAAK,eAAe,CAAC,OAAO,EAAE,SAAS,IAAI,CACzC,KAAK,EAAE,SAAS,KACb,SAAS,CAAC,OAAO,CAAC,CAAA;AAEvB,KAAK,YAAY,CAAC,OAAO,EAAE,UAAU,IAAI,CACvC,SAAS,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,KACvC,SAAS,CAAC,OAAO,CAAC,CAAA;AAEvB,gBAAgB;AAChB,KAAK,iBAAiB,CACpB,OAAO,EACP,UAAU,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,IAC3C;IACF,QAAQ,EAAE,CAAC,IAAI,MAAM,UAAU,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,eAAe,CACzE,OAAO,EACP,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAClC;CACF,CAAA;AAED,gBAAgB;AAChB,KAAK,cAAc,CAAC,OAAO,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI;IACxE,QAAQ,EAAE,CAAC,IAAI,MAAM,MAAM,IAAI,KAAK,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,GAAG,YAAY,CAC5E,OAAO,EACP,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAC9B;CACF,CAAA;AAED;;+EAE+E;AAC/E,MAAM,MAAM,cAAc,CACxB,OAAO,EACP,UAAU,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,EAC7C,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,IACvC,CAAC,CACH,UAAU,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,EAC9C,QAAQ,CAAC,EAAE,aAAa,CAAC,KAAK,CAAC,KAC5B,IAAI,CAAC,GACR,iBAAiB,CAAC,OAAO,EAAE,UAAU,CAAC,GACtC,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;AAEjC,wDAAwD;AACxD,MAAM,WAAW,mBAAmB,CAClC,GAAG,SAAS,MAAM,EAClB,UAAU,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,EAC7C,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC;IAEzC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAA;IACjB,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAA;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AAED;;;;;wEAKwE;AACxE,MAAM,WAAW,iBAAiB,CAChC,GAAG,SAAS,MAAM,EAClB,UAAU,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,EAC7C,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC;IAEzC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAA;IACjB,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAA;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,WAAW,EAAE,CAAC,OAAO,EAC5B,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,KACpB,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,CAAA;CACjD;AAED;;wEAEwE;AACxE,MAAM,MAAM,OAAO,CAAC,IAAI,EAAE,OAAO,IAC/B,IAAI,SAAS,iBAAiB,CAAC,MAAM,EAAE,MAAM,UAAU,EAAE,MAAM,MAAM,CAAC,GAClE,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,GAC3C,KAAK,CAAA;AAEX;oDACoD;AACpD,eAAO,MAAM,aAAa,GAAI,OAAO,MAAM,KAAG,MACgC,CAAA;AA4C9E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,eAAO,MAAM,MAAM,GACjB,GAAG,SAAS,MAAM,EAClB,UAAU,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,EAC7C,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,EAEzC,QAAQ,mBAAmB,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,CAAC,KACnD,iBAAiB,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,CA+D3C,CAAA"}
|
|
@@ -4,6 +4,23 @@ import { OnCustomEvent, Prop, customElement as customElementVNode, } from '../ht
|
|
|
4
4
|
* the same `On*` factory this module generates. */
|
|
5
5
|
export const kebabToPascal = (input) => pipe(input, String.split('-'), Array.map(String.capitalize), Array.join(''));
|
|
6
6
|
const IDENTIFIER_PATTERN = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
7
|
+
// A conservative subset of the custom-element name grammar: lowercase start,
|
|
8
|
+
// then only characters that cannot carry markup. The hyphen requirement is
|
|
9
|
+
// checked separately so its message stays specific.
|
|
10
|
+
const CUSTOM_ELEMENT_NAME_PATTERN = /^[a-z][a-z0-9._-]*$/;
|
|
11
|
+
// Hyphenated names the custom-element spec reserves for SVG and MathML, which
|
|
12
|
+
// `customElements.define` rejects with a SyntaxError. They pass the character
|
|
13
|
+
// grammar, so they are excluded by name.
|
|
14
|
+
const RESERVED_CUSTOM_ELEMENT_NAMES = new Set([
|
|
15
|
+
'annotation-xml',
|
|
16
|
+
'color-profile',
|
|
17
|
+
'font-face',
|
|
18
|
+
'font-face-src',
|
|
19
|
+
'font-face-uri',
|
|
20
|
+
'font-face-format',
|
|
21
|
+
'font-face-name',
|
|
22
|
+
'missing-glyph',
|
|
23
|
+
]);
|
|
7
24
|
const isValidPropertyName = (name) => IDENTIFIER_PATTERN.test(name);
|
|
8
25
|
const isValidEventName = (name) => {
|
|
9
26
|
if (String.isEmpty(name)) {
|
|
@@ -95,6 +112,12 @@ const validateNames = (input) => {
|
|
|
95
112
|
if (!input.tag.includes('-')) {
|
|
96
113
|
throw new Error(`${context}: tag '${input.tag}' is not a valid custom element name. Autonomous custom elements must contain at least one hyphen (e.g. 'fk-emoji-rating').`);
|
|
97
114
|
}
|
|
115
|
+
if (!CUSTOM_ELEMENT_NAME_PATTERN.test(input.tag)) {
|
|
116
|
+
throw new Error(`${context}: tag '${input.tag}' is not a valid custom element name. Names must be lowercase, start with a letter, and use only letters, numbers, hyphens, dots, and underscores.`);
|
|
117
|
+
}
|
|
118
|
+
if (RESERVED_CUSTOM_ELEMENT_NAMES.has(input.tag)) {
|
|
119
|
+
throw new Error(`${context}: tag '${input.tag}' is a reserved custom element name that the browser rejects.`);
|
|
120
|
+
}
|
|
98
121
|
for (const propertyName of input.propertyNames) {
|
|
99
122
|
if (!isValidPropertyName(propertyName)) {
|
|
100
123
|
throw new Error(`${context}: property name '${propertyName}' is not a valid JS identifier.`);
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/** DOM properties whose attribute is present or absent rather than valued.
|
|
2
|
+
*
|
|
3
|
+
* @internal */
|
|
4
|
+
export declare const BOOLEAN_PROPERTIES: ReadonlySet<string>;
|
|
5
|
+
/** DOM properties whose name differs from the attribute they reflect.
|
|
6
|
+
*
|
|
7
|
+
* @internal */
|
|
8
|
+
export declare const RENAMED_PROPERTY_ATTRIBUTES: Readonly<Record<string, string>>;
|
|
9
|
+
/** DOM properties whose value is written as the same-named attribute verbatim.
|
|
10
|
+
*
|
|
11
|
+
* @internal */
|
|
12
|
+
export declare const PASSTHROUGH_PROPERTIES: ReadonlySet<string>;
|
|
13
|
+
/** The property names that are universal HTML global attributes.
|
|
14
|
+
*
|
|
15
|
+
* @internal */
|
|
16
|
+
export declare const GLOBAL_ATTRIBUTE_PROPERTIES: ReadonlySet<string>;
|
|
17
|
+
/** @internal */
|
|
18
|
+
export declare const FOREIGN_REPRESENTABLE_PROPERTIES: ReadonlySet<string>;
|
|
19
|
+
/** The HTML attribute a typed builder's DOM property reflects, or `undefined`
|
|
20
|
+
* when the property is not one the tables above describe.
|
|
21
|
+
*
|
|
22
|
+
* @internal */
|
|
23
|
+
export declare const reflectedAttributeName: (propertyName: string) => string | undefined;
|
|
24
|
+
/** @internal */
|
|
25
|
+
export declare const toHtmlAttributeName: (name: string) => string;
|
|
26
|
+
export declare const HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
|
|
27
|
+
export declare const SVG_NAMESPACE = "http://www.w3.org/2000/svg";
|
|
28
|
+
export declare const MATHML_NAMESPACE = "http://www.w3.org/1998/Math/MathML";
|
|
29
|
+
/** The attribute name produced by parsing HTML source in the given namespace.
|
|
30
|
+
*
|
|
31
|
+
* @internal
|
|
32
|
+
*/
|
|
33
|
+
export declare const parsedAttributeName: (namespace: string | undefined | null, name: string) => string;
|
|
34
|
+
/** Whether assigning a typed property can be represented by parsed HTML for
|
|
35
|
+
* the target element.
|
|
36
|
+
*
|
|
37
|
+
* @internal
|
|
38
|
+
*/
|
|
39
|
+
export declare const isHtmlPropertyRepresentable: (tagName: string, propertyName: string) => boolean;
|
|
40
|
+
/** The attribute spelling produced by assigning a typed property on a fresh
|
|
41
|
+
* element.
|
|
42
|
+
*
|
|
43
|
+
* @internal
|
|
44
|
+
*/
|
|
45
|
+
export declare const serializedHtmlPropertyValue: (tagName: string, propertyName: string, value: unknown) => string;
|
|
46
|
+
/** Refuses style entries whose property assignment and serialized declaration
|
|
47
|
+
* can describe different CSS.
|
|
48
|
+
*
|
|
49
|
+
* @internal
|
|
50
|
+
*/
|
|
51
|
+
export declare const assertStyleIsRepresentable: (style: Readonly<Record<string, unknown>>) => void;
|
|
52
|
+
/** The CSS declaration name corresponding to a CSSStyleDeclaration property.
|
|
53
|
+
*
|
|
54
|
+
* @internal
|
|
55
|
+
*/
|
|
56
|
+
export declare const serializedStylePropertyName: (name: string) => string;
|
|
57
|
+
/** A style object keyed by the declaration names shared by CSSOM and HTML.
|
|
58
|
+
*
|
|
59
|
+
* @internal
|
|
60
|
+
*/
|
|
61
|
+
export declare const normalizedStyleProperties: (style: Readonly<Record<string, unknown>>) => Record<string, string>;
|
|
62
|
+
/** Inline style source whose parsed declarations match fresh CSSOM property
|
|
63
|
+
* assignment, excluding Snabbdom lifecycle controls.
|
|
64
|
+
*
|
|
65
|
+
* @internal
|
|
66
|
+
*/
|
|
67
|
+
export declare const serializedStyleAttribute: (style: Readonly<Record<string, unknown>>) => string | undefined;
|
|
68
|
+
/** The value of an HTML attribute written under any ASCII casing, or
|
|
69
|
+
* `undefined` when no spelling of it is present.
|
|
70
|
+
*
|
|
71
|
+
* @internal */
|
|
72
|
+
export declare const htmlAttributeValue: (attributes: Readonly<Record<string, unknown>> | undefined, name: string) => unknown;
|
|
73
|
+
//# sourceMappingURL=domReflection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domReflection.d.ts","sourceRoot":"","sources":["../src/domReflection.ts"],"names":[],"mappings":"AAaA;;eAEe;AACf,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,MAAM,CAoBjD,CAAA;AAEF;;eAEe;AACf,eAAO,MAAM,2BAA2B,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAiBxE,CAAA;AAED;;eAEe;AACf,eAAO,MAAM,sBAAsB,EAAE,WAAW,CAAC,MAAM,CAqCrD,CAAA;AAEF;;eAEe;AACf,eAAO,MAAM,2BAA2B,EAAE,WAAW,CAAC,MAAM,CAU1D,CAAA;AAaF,gBAAgB;AAChB,eAAO,MAAM,gCAAgC,EAAE,WAAW,CAAC,MAAM,CAI/D,CAAA;AAEF;;;eAGe;AACf,eAAO,MAAM,sBAAsB,GACjC,cAAc,MAAM,KACnB,MAAM,GAAG,SAaX,CAAA;AAUD,gBAAgB;AAChB,eAAO,MAAM,mBAAmB,GAAI,MAAM,MAAM,KAAG,MACQ,CAAA;AA+D3D,eAAO,MAAM,cAAc,iCAAiC,CAAA;AAC5D,eAAO,MAAM,aAAa,+BAA+B,CAAA;AACzD,eAAO,MAAM,gBAAgB,uCAAuC,CAAA;AAEpE;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAC9B,WAAW,MAAM,GAAG,SAAS,GAAG,IAAI,EACpC,MAAM,MAAM,KACX,MASF,CAAA;AA8HD;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,GACtC,SAAS,MAAM,EACf,cAAc,MAAM,KACnB,OAG2E,CAAA;AAU9E;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,GACtC,SAAS,MAAM,EACf,cAAc,MAAM,EACpB,OAAO,OAAO,KACb,MAYF,CAAA;AAgFD;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,GACrC,OAAO,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,KACvC,IA+DF,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,2BAA2B,GAAI,MAAM,MAAM,KAAG,MAE1D,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,yBAAyB,GACpC,OAAO,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,KACvC,MAAM,CAAC,MAAM,EAAE,MAAM,CAQvB,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,GACnC,OAAO,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,KACvC,MAAM,GAAG,SAQX,CAAA;AAED;;;eAGe;AACf,eAAO,MAAM,kBAAkB,GAC7B,YAAY,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,EACzD,MAAM,MAAM,KACX,OAWF,CAAA"}
|