yandel 1.1.2 → 1.2.1
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 +8 -7
- package/dist/index.d.ts +2 -1
- package/dist/index.js +9 -1
- package/dist/node.d.ts +6 -59
- package/dist/node.js +181 -101
- package/dist/tags.d.ts +1 -1
- package/dist/tags.js +1 -1
- package/package.json +3 -2
- package/types/index.d.ts +225 -0
package/README.md
CHANGED
|
@@ -199,10 +199,10 @@ function AppNotifications() {
|
|
|
199
199
|
|
|
200
200
|
#### Future node
|
|
201
201
|
|
|
202
|
-
Future nodes are `templates` (functions) and will be created at render time (as `components` and `text`). This applies for all type of functions that return a `ValidTemplateReturn`; also the generic tags like `div`, `span`, etc. are allowed
|
|
202
|
+
Future nodes are `templates` (functions) used as a child and will be created at render time (as `components` and `text`). This applies for all type of functions that return a `ValidTemplateReturn`; also the generic tags like `div`, `span`, etc. are allowed
|
|
203
203
|
|
|
204
204
|
```ts
|
|
205
|
-
import { div, main, nav } from "yandel"
|
|
205
|
+
import { div, main, nav } from "yandel";
|
|
206
206
|
|
|
207
207
|
function MyGridOfPhotos () {
|
|
208
208
|
return div(...);
|
|
@@ -566,7 +566,7 @@ function UserConsumerWithError() {
|
|
|
566
566
|
|
|
567
567
|
#### Future nodes
|
|
568
568
|
|
|
569
|
-
As explained in the section of [future nodes](#future-node), `components`, `text` and `future nodes` are created at render time
|
|
569
|
+
As explained in the section of [future nodes](#future-node), `components`, `text` and `future nodes` are created at render time. You have to understand how they are being created:
|
|
570
570
|
|
|
571
571
|
```ts
|
|
572
572
|
function UserConsumer() {
|
|
@@ -580,7 +580,8 @@ class App extends Component {
|
|
|
580
580
|
}
|
|
581
581
|
```
|
|
582
582
|
|
|
583
|
-
`
|
|
583
|
+
When a component is created, its `render` method will be called at render time. In this example, `UserConsumer` will be called before the `UserProvider` `render`
|
|
584
|
+
method at render time, so the context will be undefined.
|
|
584
585
|
|
|
585
586
|
```ts
|
|
586
587
|
public render(): ValidTemplateReturn {
|
|
@@ -591,11 +592,11 @@ public render(): ValidTemplateReturn {
|
|
|
591
592
|
}
|
|
592
593
|
```
|
|
593
594
|
|
|
594
|
-
Now, `UserConsumer` will be able to consume
|
|
595
|
+
Now, `UserConsumer` will be able to consume, because It will be created at render time right after the `UserProvider` `render` method, so it will be accesible.
|
|
595
596
|
|
|
596
597
|
### Ref
|
|
597
598
|
|
|
598
|
-
The `ref` prop allows you to have access to the
|
|
599
|
+
The `ref` prop allows you to have access to the tag's reference:
|
|
599
600
|
|
|
600
601
|
```ts
|
|
601
602
|
import { Component, ElementRef, Stores, input } from "yandel";
|
|
@@ -635,7 +636,7 @@ class WithKey extends Component {
|
|
|
635
636
|
|
|
636
637
|
## Usage
|
|
637
638
|
|
|
638
|
-
Define your
|
|
639
|
+
Define your UI: components, templates, nodes... then, use `createRoot.render` to start rendering and done!
|
|
639
640
|
|
|
640
641
|
```ts
|
|
641
642
|
import {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
|
|
1
|
+
/// <reference path="../types/index.d.ts" preserve="true" />
|
|
2
|
+
export { Component, createContext, createRoot, EffectHandler, Portal, Stores, ValidNode, ValidNodeChild, ValidTemplateReturn, FutureNode, } from "./node";
|
|
2
3
|
export * from "./tags";
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
/// <reference path="../types/index.d.ts" preserve="true"/>
|
|
2
|
+
export { Component, createContext, createRoot,
|
|
3
|
+
// Element,
|
|
4
|
+
// ElementRef,
|
|
5
|
+
// HTMLProps,
|
|
6
|
+
// HTMLTags,
|
|
7
|
+
Portal,
|
|
8
|
+
// StateHandler,
|
|
9
|
+
Stores, } from "./node";
|
|
2
10
|
export * from "./tags";
|
package/dist/node.d.ts
CHANGED
|
@@ -1,62 +1,12 @@
|
|
|
1
|
-
type HTMLExcludedProperties = `aria${string}` | "tagName" | "shadowRoot" | "slot" | "classList" | "style" | "attributes" | "attributeStyleMap" | "ATTRIBUTE_NODE" | "CDATA_SECTION_NODE" | "COMMENT_NODE" | "childElementCount" | "childNodes" | "children" | "isConnected" | "ownerDocument" | "lastChild" | "lastElement" | "nextElementSibling" | "nextSibling" | "previousElementSibling" | "previousSibling" | "parentElement" | "parent" | "outerContent" | "firstChild" | "firstElementChild" | "lastChild" | "lastElementChild" | "innerHTML" | "outerHTML" | "innerContent" | "textContent" | `DOCUMENT_${string}` | "NOTATION_NODE" | "PROCESSING_INSTRUCTION_NODE" | "CONTENT_NODE" | "ELEMENT_NODE" | "TEXT_NODE" | `ENTITY_${string}`;
|
|
2
|
-
type AriaWidgetProperties = "aria-autocomplete" | "aria-checked" | "aria-disabled" | "aria-errormessage" | "aria-expanded" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-label" | "aria-level" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-placeholder" | "aria-pressed" | "aria-readonly" | "aria-required" | "aria-selected" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext";
|
|
3
|
-
type AriaLiveRegionProperties = "aria-busy" | "aria-live" | "aria-relevant" | "aria-atomic";
|
|
4
|
-
type AriaDragAndDropProperties = "aria-dropeffect" | "aria-grabbed";
|
|
5
|
-
type AriaRelatonshipProperties = "aria-activedescendant" | "aria-colcount" | "aria-colindex" | "aria-colspan" | "aria-controls" | "aria-describedby" | "aria-description" | "aria-details" | "aria-errormessage" | "aria-flowto" | "aria-labelledby" | "aria-owns" | "aria-posinset" | "aria-rowcount" | "aria-rowindex" | "aria-rowspan" | "aria-setsize";
|
|
6
|
-
type AriaGlobalProperties = "aria-atomic" | "aria-busy" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-description" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-live" | "aria-owns" | "aria-relevant" | "aria-roledescription";
|
|
7
|
-
type AriaProps = AriaWidgetProperties | AriaDragAndDropProperties | AriaLiveRegionProperties | AriaRelatonshipProperties | AriaGlobalProperties;
|
|
8
|
-
type AriaBoolean = "true" | "false";
|
|
9
|
-
type AriaValue = Exclude<string, AriaBoolean>;
|
|
10
|
-
type AriaValueMap = Partial<Record<AriaProps, AriaBoolean | AriaValue>>;
|
|
11
|
-
type KeyedObject = Record<string | symbol | number, any>;
|
|
12
|
-
type HTMLTags = keyof HTMLElementTagNameMap;
|
|
13
|
-
type HTMLSVGTags = keyof SVGElementTagNameMap;
|
|
14
|
-
type Element<K extends HTMLTags = HTMLTags> = HTMLElementTagNameMap[K];
|
|
15
|
-
type SVGElement<K extends HTMLSVGTags = HTMLSVGTags> = SVGElementTagNameMap[K];
|
|
16
|
-
interface SwitchableNode<T extends Node> {
|
|
17
|
-
switch(t: T): boolean;
|
|
18
|
-
}
|
|
19
|
-
type FutureNode = () => ValidNodeChild;
|
|
20
1
|
type ValidNode = Node | Component | Component<KeyedObject> | FutureNode;
|
|
21
2
|
type ValidNodeChild = ValidNode | null | string;
|
|
22
3
|
type ValidTemplateReturn = ValidNodeChild | ValidNodeChild[];
|
|
4
|
+
type FutureNode = () => ValidNodeChild;
|
|
23
5
|
type EffectHandler = (() => void) | (() => () => void);
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
};
|
|
27
|
-
type Styles = Partial<CSSStyleDeclaration>;
|
|
28
|
-
interface ElementOverridedProperties extends AriaValueMap {
|
|
29
|
-
style?: Styles;
|
|
30
|
-
}
|
|
31
|
-
type AnyElement<T extends HTMLTags | HTMLSVGTags = HTMLTags> = T extends HTMLTags ? Element<T> : T extends HTMLSVGTags ? SVGElement<T> : never;
|
|
32
|
-
type AnyProps<T extends HTMLTags | HTMLSVGTags = HTMLTags> = T extends HTMLTags ? HTMLProps<T> : T extends HTMLSVGTags ? SVGProps<T> : never;
|
|
33
|
-
type ElementRef<T extends HTMLTags | HTMLSVGTags = HTMLTags> = Stores<(T extends HTMLTags ? HTMLElementTagNameMap[T] : T extends HTMLSVGTags ? SVGElementTagNameMap[T] : never) | undefined>;
|
|
34
|
-
interface ElementProps<T extends HTMLTags | HTMLSVGTags = HTMLTags> {
|
|
35
|
-
ref?: ElementRef<T>;
|
|
36
|
-
key?: string | number | symbol;
|
|
37
|
-
}
|
|
38
|
-
type ExcludeProperties<T> = {
|
|
39
|
-
[K in keyof T as K extends HTMLExcludedProperties ? never : K]: T[K];
|
|
40
|
-
};
|
|
41
|
-
type HTMLProps<T extends HTMLTags> = Partial<ExcludeProperties<ExcludeFunctions<Element<T>>>> & ElementProps<T> & ElementOverridedProperties;
|
|
42
|
-
type SVGAttributeValue = string | number;
|
|
43
|
-
type NormalizeSVGProp<T> = T extends SVGAnimatedLength ? SVGAttributeValue : T extends SVGAnimatedAngle ? SVGAttributeValue : T extends SVGAnimatedBoolean ? SVGAttributeValue : T extends SVGAnimatedEnumeration ? SVGAttributeValue : T extends SVGAnimatedInteger ? SVGAttributeValue : T extends SVGAnimatedNumber ? SVGAttributeValue : T extends SVGAnimatedPreserveAspectRatio ? SVGAttributeValue : T extends SVGAnimatedRect ? SVGAttributeValue : T extends SVGAnimatedString ? SVGAttributeValue : T extends SVGAnimatedTransformList ? SVGAttributeValue : T extends SVGPointList ? SVGAttributeValue : T;
|
|
44
|
-
type SVGRawProps<T extends HTMLSVGTags> = ExcludeProperties<ExcludeFunctions<SVGElementTagNameMap[T]>>;
|
|
45
|
-
interface SVGOverridedProperties {
|
|
46
|
-
fill?: string;
|
|
47
|
-
"fill-opacity"?: string;
|
|
48
|
-
stroke?: string;
|
|
49
|
-
"stroke-width"?: SVGAttributeValue;
|
|
50
|
-
"stroke-linecap"?: "butt" | "round" | "square";
|
|
51
|
-
"stroke-linejoin"?: "miter" | "round" | "bevel";
|
|
52
|
-
d?: string;
|
|
53
|
-
"stroke-dasharray"?: SVGAttributeValue;
|
|
6
|
+
interface SwitchableNode<T extends Node> {
|
|
7
|
+
switch(t: T): boolean;
|
|
54
8
|
}
|
|
55
|
-
|
|
56
|
-
[K in keyof SVGRawProps<T>]: NormalizeSVGProp<SVGRawProps<T>[K]>;
|
|
57
|
-
}> & ElementProps<T> & ElementOverridedProperties & SVGOverridedProperties;
|
|
58
|
-
type StateHandler<S extends KeyedObject | undefined = undefined> = S | ((l: S) => S);
|
|
59
|
-
declare const enum NodeType {
|
|
9
|
+
declare enum NodeType {
|
|
60
10
|
Tag = 0,
|
|
61
11
|
Content = 1,
|
|
62
12
|
Parent = 2,
|
|
@@ -93,10 +43,7 @@ declare class TagNode<T extends HTMLTags | HTMLSVGTags = HTMLTags> extends Node
|
|
|
93
43
|
key: symbol | string | number | undefined;
|
|
94
44
|
index_length: number;
|
|
95
45
|
constructor(tag: T, props?: AnyProps<T>, children?: ValidNodeChild[]);
|
|
96
|
-
private _apply_dom_props;
|
|
97
46
|
private _diff_dom_props;
|
|
98
|
-
private _clear_dom_props;
|
|
99
|
-
private _clear_dom_events;
|
|
100
47
|
get dom(): AnyElement<T> | undefined;
|
|
101
48
|
get props(): AnyProps<T> | undefined;
|
|
102
49
|
get children(): ValidNodeChild[] | undefined;
|
|
@@ -105,7 +52,7 @@ declare class TagNode<T extends HTMLTags | HTMLSVGTags = HTMLTags> extends Node
|
|
|
105
52
|
clearChildren(): void;
|
|
106
53
|
clearDom(): void;
|
|
107
54
|
delete(): void;
|
|
108
|
-
switch(t: TagNode
|
|
55
|
+
switch(t: TagNode): boolean;
|
|
109
56
|
}
|
|
110
57
|
declare class ParentNode<T extends HTMLElement = HTMLElement> extends Node implements SwitchableNode<ParentNode> {
|
|
111
58
|
static is(t: any): t is ParentNode;
|
|
@@ -141,4 +88,4 @@ declare function createRoot<T extends HTMLElement>(root: T): {
|
|
|
141
88
|
render: (...children: ValidNodeChild[]) => void;
|
|
142
89
|
};
|
|
143
90
|
declare function createContext<T extends KeyedObject>(): Context<T>;
|
|
144
|
-
export { Component, createContext, createRoot, EffectHandler,
|
|
91
|
+
export { Component, createContext, createRoot, EffectHandler, Node, Portal, Stores, TagNode, ValidNode, ValidNodeChild, ValidTemplateReturn, FutureNode, };
|
package/dist/node.js
CHANGED
|
@@ -64,6 +64,13 @@ const SVG_TAGS = new Set([
|
|
|
64
64
|
"use",
|
|
65
65
|
"view",
|
|
66
66
|
]);
|
|
67
|
+
var NodeType;
|
|
68
|
+
(function (NodeType) {
|
|
69
|
+
NodeType[NodeType["Tag"] = 0] = "Tag";
|
|
70
|
+
NodeType[NodeType["Content"] = 1] = "Content";
|
|
71
|
+
NodeType[NodeType["Parent"] = 2] = "Parent";
|
|
72
|
+
NodeType[NodeType["Component"] = 3] = "Component";
|
|
73
|
+
})(NodeType || (NodeType = {}));
|
|
67
74
|
class Stores {
|
|
68
75
|
#_stores;
|
|
69
76
|
constructor(s) {
|
|
@@ -76,7 +83,7 @@ class Stores {
|
|
|
76
83
|
this.#_stores = s;
|
|
77
84
|
}
|
|
78
85
|
}
|
|
79
|
-
class
|
|
86
|
+
class UpdateQueue {
|
|
80
87
|
static _update_scheduled = false;
|
|
81
88
|
static _queue = new Set();
|
|
82
89
|
static processNodeQueue() {
|
|
@@ -118,16 +125,14 @@ class ComponentUpdateQueue {
|
|
|
118
125
|
if (!this._update_scheduled)
|
|
119
126
|
this.notifyQueue();
|
|
120
127
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
}
|
|
130
|
-
});
|
|
128
|
+
static queueNodesDeletion(ns) {
|
|
129
|
+
queueMicrotask(() => {
|
|
130
|
+
for (const c of ns) {
|
|
131
|
+
if (c && c instanceof Node)
|
|
132
|
+
c.delete();
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
}
|
|
131
136
|
}
|
|
132
137
|
const ComponentInternalKey = Symbol("_$ci$_");
|
|
133
138
|
function _c_el(t) {
|
|
@@ -149,16 +154,16 @@ class Node {
|
|
|
149
154
|
this.$typeof = t;
|
|
150
155
|
}
|
|
151
156
|
get isTag() {
|
|
152
|
-
return this.$typeof ===
|
|
157
|
+
return this.$typeof === NodeType.Tag;
|
|
153
158
|
}
|
|
154
159
|
get isContent() {
|
|
155
|
-
return this.$typeof ===
|
|
160
|
+
return this.$typeof === NodeType.Content;
|
|
156
161
|
}
|
|
157
162
|
get isParent() {
|
|
158
|
-
return this.$typeof ===
|
|
163
|
+
return this.$typeof === NodeType.Parent;
|
|
159
164
|
}
|
|
160
165
|
get isComponent() {
|
|
161
|
-
return this.$typeof ===
|
|
166
|
+
return this.$typeof === NodeType.Component;
|
|
162
167
|
}
|
|
163
168
|
get deleted() {
|
|
164
169
|
return this._deleted;
|
|
@@ -183,7 +188,7 @@ class ContentNode extends Node {
|
|
|
183
188
|
_content;
|
|
184
189
|
_dom = undefined;
|
|
185
190
|
constructor(content) {
|
|
186
|
-
super(
|
|
191
|
+
super(NodeType.Content);
|
|
187
192
|
this._content = content;
|
|
188
193
|
this.needs_update = true;
|
|
189
194
|
}
|
|
@@ -225,21 +230,10 @@ class ContentNode extends Node {
|
|
|
225
230
|
super.delete();
|
|
226
231
|
}
|
|
227
232
|
}
|
|
228
|
-
function
|
|
229
|
-
|
|
230
|
-
return t();
|
|
231
|
-
}
|
|
232
|
-
catch (error) {
|
|
233
|
-
throw new Error(`Template create error: ${error}`);
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
function _get_node_from_future(t) {
|
|
237
|
-
const n = create_template(t);
|
|
238
|
-
if (_is_fn(n))
|
|
239
|
-
return _get_node_from_future(n);
|
|
240
|
-
return n;
|
|
233
|
+
function _create_html_tag(tag) {
|
|
234
|
+
return SVG_TAGS.has(tag) ? _c_s(tag) : _c_el(tag);
|
|
241
235
|
}
|
|
242
|
-
function
|
|
236
|
+
function _apply_html_prop(dom, props, prop) {
|
|
243
237
|
const v = props[prop];
|
|
244
238
|
if (v == null)
|
|
245
239
|
return;
|
|
@@ -287,7 +281,7 @@ function _apply_dom_prop(dom, props, prop) {
|
|
|
287
281
|
else
|
|
288
282
|
dom.setAttribute(prop, v);
|
|
289
283
|
}
|
|
290
|
-
function
|
|
284
|
+
function _remove_html_prop(dom, props, prop) {
|
|
291
285
|
if (/^on[a-z]/.test(prop)) {
|
|
292
286
|
const ev_name = prop.slice(2);
|
|
293
287
|
dom.removeEventListener(ev_name, props[prop]);
|
|
@@ -295,11 +289,21 @@ function _remove_dom_prop(dom, props, prop) {
|
|
|
295
289
|
}
|
|
296
290
|
if (prop === "ref" && props.ref instanceof Stores) {
|
|
297
291
|
props.ref.stores = undefined;
|
|
298
|
-
return;
|
|
299
292
|
}
|
|
300
293
|
const v = props[prop];
|
|
301
|
-
if (v == null)
|
|
294
|
+
if (v == null) {
|
|
295
|
+
if (prop === "style")
|
|
296
|
+
return;
|
|
297
|
+
if (prop in dom) {
|
|
298
|
+
try {
|
|
299
|
+
dom[prop] = undefined;
|
|
300
|
+
}
|
|
301
|
+
catch (error) {
|
|
302
|
+
console.error("Remove prop error:", error);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
302
305
|
return;
|
|
306
|
+
}
|
|
303
307
|
if (prop === "style" && typeof v === "object") {
|
|
304
308
|
try {
|
|
305
309
|
Object.entries(v).forEach(([cssProp]) => {
|
|
@@ -323,15 +327,15 @@ function _remove_dom_prop(dom, props, prop) {
|
|
|
323
327
|
switch (t) {
|
|
324
328
|
case "boolean": {
|
|
325
329
|
dom[prop] = false;
|
|
326
|
-
|
|
330
|
+
break;
|
|
327
331
|
}
|
|
328
332
|
case "string": {
|
|
329
333
|
dom[prop] = "";
|
|
330
|
-
|
|
334
|
+
break;
|
|
331
335
|
}
|
|
332
336
|
case "object": {
|
|
333
|
-
dom[prop] =
|
|
334
|
-
|
|
337
|
+
dom[prop] = undefined;
|
|
338
|
+
break;
|
|
335
339
|
}
|
|
336
340
|
}
|
|
337
341
|
}
|
|
@@ -339,6 +343,69 @@ function _remove_dom_prop(dom, props, prop) {
|
|
|
339
343
|
}
|
|
340
344
|
dom.removeAttribute(prop);
|
|
341
345
|
}
|
|
346
|
+
function _get_props_diff(a, b) {
|
|
347
|
+
const _to_remove = {};
|
|
348
|
+
const _to_apply = {};
|
|
349
|
+
for (const key in a) {
|
|
350
|
+
if (!b.hasOwnProperty(key)) {
|
|
351
|
+
_to_remove[key] = a[key];
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
for (const key in b) {
|
|
355
|
+
if (b[key] == null) {
|
|
356
|
+
_to_remove[key] = b[key];
|
|
357
|
+
}
|
|
358
|
+
else {
|
|
359
|
+
if (b[key] === a[key])
|
|
360
|
+
continue;
|
|
361
|
+
_to_apply[key] = b[key];
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
return {
|
|
365
|
+
apply: _to_apply,
|
|
366
|
+
remove: _to_remove,
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
// function _diff_html_props<T extends HTMLTags | HTMLSVGTags>(
|
|
370
|
+
// dom: AnyElement<T>,
|
|
371
|
+
// a: AnyProps<T>,
|
|
372
|
+
// b: AnyProps<T>
|
|
373
|
+
// ) {
|
|
374
|
+
// for (const prop of Object.keys(a)) {
|
|
375
|
+
// if (prop.startsWith("on")) {
|
|
376
|
+
// _remove_html_prop(dom, a, prop);
|
|
377
|
+
// if (prop in b) _apply_html_prop(dom, b, prop);
|
|
378
|
+
// } else if (!(prop in b)) {
|
|
379
|
+
// _remove_html_prop(dom, a, prop);
|
|
380
|
+
// } else _apply_html_prop(dom, b, prop);
|
|
381
|
+
// }
|
|
382
|
+
// }
|
|
383
|
+
function _clear_events(dom, props) {
|
|
384
|
+
for (const prop of Object.keys(props)) {
|
|
385
|
+
if (prop.startsWith("on")) {
|
|
386
|
+
if (typeof props[prop] !== "function")
|
|
387
|
+
continue;
|
|
388
|
+
const ev_name = prop.slice(2);
|
|
389
|
+
dom.removeEventListener(ev_name, props[prop]);
|
|
390
|
+
delete props[prop];
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
function _apply_props(dom, props) {
|
|
395
|
+
for (const prop of Object.keys(props)) {
|
|
396
|
+
_apply_html_prop(dom, props, prop);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
function _clear_props(dom, props) {
|
|
400
|
+
for (const prop of Object.keys(props)) {
|
|
401
|
+
_remove_html_prop(dom, props, prop);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
function _remove_style(dom, styles) {
|
|
405
|
+
for (const style of Object.keys(styles)) {
|
|
406
|
+
dom.style[style] = "";
|
|
407
|
+
}
|
|
408
|
+
}
|
|
342
409
|
class TagNode extends Node {
|
|
343
410
|
static is(t) {
|
|
344
411
|
return t instanceof TagNode;
|
|
@@ -350,7 +417,7 @@ class TagNode extends Node {
|
|
|
350
417
|
key = undefined;
|
|
351
418
|
index_length = 0;
|
|
352
419
|
constructor(tag, props, children) {
|
|
353
|
-
super(
|
|
420
|
+
super(NodeType.Tag);
|
|
354
421
|
this.tag = tag;
|
|
355
422
|
this._props = props;
|
|
356
423
|
if (this._props && "key" in this._props) {
|
|
@@ -359,51 +426,26 @@ class TagNode extends Node {
|
|
|
359
426
|
this._children = children;
|
|
360
427
|
this.needs_update = true;
|
|
361
428
|
}
|
|
362
|
-
_apply_dom_props() {
|
|
363
|
-
if (!this._props || !this._dom)
|
|
364
|
-
return;
|
|
365
|
-
for (const prop in this._props) {
|
|
366
|
-
_apply_dom_prop(this._dom, this._props, prop);
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
429
|
_diff_dom_props(nprops) {
|
|
370
|
-
if (
|
|
371
|
-
this._props
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
if (this._dom)
|
|
376
|
-
for (const prop in this._props) {
|
|
377
|
-
if (prop.startsWith("on")) {
|
|
378
|
-
_remove_dom_prop(this._dom, this._props, prop);
|
|
379
|
-
if (prop in nprops)
|
|
380
|
-
_apply_dom_prop(this._dom, nprops, prop);
|
|
381
|
-
}
|
|
382
|
-
else if (!(prop in nprops)) {
|
|
383
|
-
_remove_dom_prop(this._dom, this._props, prop);
|
|
430
|
+
if (this._dom) {
|
|
431
|
+
if (this._props) {
|
|
432
|
+
if (this._props.style) {
|
|
433
|
+
_remove_style(this._dom, this._props.style);
|
|
434
|
+
delete this._props.style;
|
|
384
435
|
}
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
_clear_dom_props() {
|
|
391
|
-
if (this._props && this._dom)
|
|
392
|
-
for (const prop in this._props) {
|
|
393
|
-
_remove_dom_prop(this._dom, this._props, prop);
|
|
436
|
+
_clear_events(this._dom, this._props);
|
|
437
|
+
const diff = _get_props_diff(this._props, nprops);
|
|
438
|
+
_clear_props(this._dom, diff.remove);
|
|
439
|
+
_apply_props(this._dom, diff.apply);
|
|
440
|
+
this._props = nprops;
|
|
394
441
|
}
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
const v = Reflect.get(this._props, prop);
|
|
400
|
-
if (!v)
|
|
401
|
-
continue;
|
|
402
|
-
if (prop.startsWith("on") && typeof v === "function") {
|
|
403
|
-
const ev_name = prop.slice(2);
|
|
404
|
-
this._dom.removeEventListener(ev_name, Reflect.get(this._props, prop));
|
|
405
|
-
}
|
|
442
|
+
else {
|
|
443
|
+
this._props = nprops;
|
|
444
|
+
_apply_props(this._dom, this._props);
|
|
445
|
+
return;
|
|
406
446
|
}
|
|
447
|
+
}
|
|
448
|
+
this._props = nprops;
|
|
407
449
|
}
|
|
408
450
|
get dom() {
|
|
409
451
|
return this._dom;
|
|
@@ -423,12 +465,16 @@ class TagNode extends Node {
|
|
|
423
465
|
if (this._deleted)
|
|
424
466
|
throw new Error("Attempt to create a deleted node");
|
|
425
467
|
if (this._dom) {
|
|
426
|
-
this.
|
|
427
|
-
|
|
428
|
-
|
|
468
|
+
if (this._props) {
|
|
469
|
+
_apply_props(this._dom, this._props);
|
|
470
|
+
this.needs_update = true;
|
|
471
|
+
return true;
|
|
472
|
+
}
|
|
473
|
+
return false;
|
|
429
474
|
}
|
|
430
|
-
this._dom = (
|
|
431
|
-
this.
|
|
475
|
+
this._dom = _create_html_tag(this.tag);
|
|
476
|
+
if (this._props)
|
|
477
|
+
_apply_props(this._dom, this._props);
|
|
432
478
|
this.needs_update = false;
|
|
433
479
|
return true;
|
|
434
480
|
}
|
|
@@ -436,7 +482,7 @@ class TagNode extends Node {
|
|
|
436
482
|
if (this._deleted)
|
|
437
483
|
return;
|
|
438
484
|
if (this._children?.length) {
|
|
439
|
-
queueNodesDeletion(this._children);
|
|
485
|
+
UpdateQueue.queueNodesDeletion(this._children);
|
|
440
486
|
delete this._children;
|
|
441
487
|
}
|
|
442
488
|
}
|
|
@@ -446,7 +492,8 @@ class TagNode extends Node {
|
|
|
446
492
|
return;
|
|
447
493
|
}
|
|
448
494
|
this.needs_update = true;
|
|
449
|
-
this.
|
|
495
|
+
if (this._props)
|
|
496
|
+
_clear_events(this._dom, this._props);
|
|
450
497
|
this._dom.remove();
|
|
451
498
|
delete this._dom;
|
|
452
499
|
}
|
|
@@ -464,10 +511,20 @@ class TagNode extends Node {
|
|
|
464
511
|
this.key = t.props?.key ?? t.key;
|
|
465
512
|
if (this.tag === t.tag) {
|
|
466
513
|
// Tag is the same
|
|
467
|
-
if (
|
|
468
|
-
this.
|
|
469
|
-
|
|
470
|
-
|
|
514
|
+
if (this._dom) {
|
|
515
|
+
if (this._props) {
|
|
516
|
+
if (t.props)
|
|
517
|
+
this._diff_dom_props(t.props);
|
|
518
|
+
else
|
|
519
|
+
_clear_props(this._dom, this._props);
|
|
520
|
+
}
|
|
521
|
+
else if (t.props) {
|
|
522
|
+
this._props = t.props;
|
|
523
|
+
_apply_props(this._dom, this._props);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
else if (t.props)
|
|
527
|
+
this._props = t.props;
|
|
471
528
|
}
|
|
472
529
|
else {
|
|
473
530
|
// Tag has changed
|
|
@@ -500,7 +557,7 @@ class ParentNode extends Node {
|
|
|
500
557
|
_children = undefined;
|
|
501
558
|
child_length = 0;
|
|
502
559
|
constructor(root, children) {
|
|
503
|
-
super(
|
|
560
|
+
super(NodeType.Parent);
|
|
504
561
|
this.dom = root;
|
|
505
562
|
this._children = children;
|
|
506
563
|
}
|
|
@@ -515,7 +572,7 @@ class ParentNode extends Node {
|
|
|
515
572
|
clearChildren() {
|
|
516
573
|
this.child_length = 0;
|
|
517
574
|
if (this._children?.length) {
|
|
518
|
-
queueNodesDeletion(this._children);
|
|
575
|
+
UpdateQueue.queueNodesDeletion(this._children);
|
|
519
576
|
delete this._children;
|
|
520
577
|
}
|
|
521
578
|
}
|
|
@@ -542,6 +599,20 @@ class ParentNode extends Node {
|
|
|
542
599
|
return this.needs_update;
|
|
543
600
|
}
|
|
544
601
|
}
|
|
602
|
+
function _create_template(t) {
|
|
603
|
+
try {
|
|
604
|
+
return t();
|
|
605
|
+
}
|
|
606
|
+
catch (error) {
|
|
607
|
+
throw new Error(`Template create error: ${error}`);
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
function _get_node_from_future(t) {
|
|
611
|
+
const n = _create_template(t);
|
|
612
|
+
if (_is_fn(n))
|
|
613
|
+
return _get_node_from_future(n);
|
|
614
|
+
return n;
|
|
615
|
+
}
|
|
545
616
|
class ComponentNode extends Node {
|
|
546
617
|
static is(t) {
|
|
547
618
|
return t instanceof ComponentNode;
|
|
@@ -551,7 +622,7 @@ class ComponentNode extends Node {
|
|
|
551
622
|
_children = undefined;
|
|
552
623
|
child_length = 0;
|
|
553
624
|
constructor(template) {
|
|
554
|
-
super(
|
|
625
|
+
super(NodeType.Component);
|
|
555
626
|
this._template = template;
|
|
556
627
|
getInternals(this._template).switch(this);
|
|
557
628
|
this.needs_update = true;
|
|
@@ -563,7 +634,7 @@ class ComponentNode extends Node {
|
|
|
563
634
|
throw new Error("Template has been deleted");
|
|
564
635
|
nextInternalTick(this._template);
|
|
565
636
|
try {
|
|
566
|
-
const child =
|
|
637
|
+
const child = _create_template(this._template.render.bind(this._template));
|
|
567
638
|
if (child == null) {
|
|
568
639
|
if (this.hasChildren) {
|
|
569
640
|
this.clearChildren();
|
|
@@ -603,7 +674,7 @@ class ComponentNode extends Node {
|
|
|
603
674
|
return;
|
|
604
675
|
this.child_length = 0;
|
|
605
676
|
if (this._children?.length) {
|
|
606
|
-
queueNodesDeletion(this._children);
|
|
677
|
+
UpdateQueue.queueNodesDeletion(this._children);
|
|
607
678
|
delete this._children;
|
|
608
679
|
}
|
|
609
680
|
}
|
|
@@ -619,10 +690,8 @@ class ComponentNode extends Node {
|
|
|
619
690
|
if (t.hasChildren) {
|
|
620
691
|
this.needs_update = diffChildren(this._children, t.children);
|
|
621
692
|
}
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
this.clearChildren();
|
|
625
|
-
}
|
|
693
|
+
this.needs_update = true;
|
|
694
|
+
this.clearChildren();
|
|
626
695
|
}
|
|
627
696
|
else if (t.hasChildren)
|
|
628
697
|
this._children = t.children;
|
|
@@ -686,7 +755,7 @@ class ComponentInternals {
|
|
|
686
755
|
: s;
|
|
687
756
|
Promise.resolve().then(() => {
|
|
688
757
|
if (this.#_n)
|
|
689
|
-
|
|
758
|
+
UpdateQueue.queueNodeUpdate(this.#_n);
|
|
690
759
|
});
|
|
691
760
|
}
|
|
692
761
|
addEffect(e) {
|
|
@@ -1202,4 +1271,15 @@ function createRoot(root) {
|
|
|
1202
1271
|
function createContext() {
|
|
1203
1272
|
return new Context();
|
|
1204
1273
|
}
|
|
1205
|
-
export { Component, createContext, createRoot,
|
|
1274
|
+
export { Component, createContext, createRoot,
|
|
1275
|
+
// Element,
|
|
1276
|
+
// ElementRef,
|
|
1277
|
+
// HTMLProps,
|
|
1278
|
+
// HTMLTags,
|
|
1279
|
+
// HTMLSVGTags,
|
|
1280
|
+
// SVGProps,
|
|
1281
|
+
Node, Portal,
|
|
1282
|
+
// StateHandler,
|
|
1283
|
+
Stores,
|
|
1284
|
+
// Styles,
|
|
1285
|
+
TagNode, };
|
package/dist/tags.d.ts
CHANGED
package/dist/tags.js
CHANGED
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yandel",
|
|
3
3
|
"description": "A reactive lightweight TS frontend framework",
|
|
4
|
-
"version": "1.1
|
|
4
|
+
"version": "1.2.1",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"files": [
|
|
8
|
-
"dist"
|
|
8
|
+
"dist",
|
|
9
|
+
"types"
|
|
9
10
|
],
|
|
10
11
|
"scripts": {
|
|
11
12
|
"build": "tsc",
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
type HTMLExcludedProperties =
|
|
2
|
+
| `aria${string}`
|
|
3
|
+
| "tagName"
|
|
4
|
+
| "shadowRoot"
|
|
5
|
+
| "slot"
|
|
6
|
+
| "classList"
|
|
7
|
+
| "style"
|
|
8
|
+
| "attributes"
|
|
9
|
+
| "attributeStyleMap"
|
|
10
|
+
| "ATTRIBUTE_NODE"
|
|
11
|
+
| "CDATA_SECTION_NODE"
|
|
12
|
+
| "COMMENT_NODE"
|
|
13
|
+
| "childElementCount"
|
|
14
|
+
| "childNodes"
|
|
15
|
+
| "children"
|
|
16
|
+
| "isConnected"
|
|
17
|
+
| "ownerDocument"
|
|
18
|
+
| "lastChild"
|
|
19
|
+
| "lastElement"
|
|
20
|
+
| "nextElementSibling"
|
|
21
|
+
| "nextSibling"
|
|
22
|
+
| "previousElementSibling"
|
|
23
|
+
| "previousSibling"
|
|
24
|
+
| "parentElement"
|
|
25
|
+
| "parent"
|
|
26
|
+
| "outerContent"
|
|
27
|
+
| "firstChild"
|
|
28
|
+
| "firstElementChild"
|
|
29
|
+
| "lastChild"
|
|
30
|
+
| "lastElementChild"
|
|
31
|
+
| "innerHTML"
|
|
32
|
+
| "outerHTML"
|
|
33
|
+
| "innerContent"
|
|
34
|
+
| "textContent"
|
|
35
|
+
| `DOCUMENT_${string}`
|
|
36
|
+
| "NOTATION_NODE"
|
|
37
|
+
| "PROCESSING_INSTRUCTION_NODE"
|
|
38
|
+
| "CONTENT_NODE"
|
|
39
|
+
| "ELEMENT_NODE"
|
|
40
|
+
| "TEXT_NODE"
|
|
41
|
+
| `ENTITY_${string}`;
|
|
42
|
+
type AriaWidgetProperties =
|
|
43
|
+
| "aria-autocomplete"
|
|
44
|
+
| "aria-checked"
|
|
45
|
+
| "aria-disabled"
|
|
46
|
+
| "aria-errormessage"
|
|
47
|
+
| "aria-expanded"
|
|
48
|
+
| "aria-haspopup"
|
|
49
|
+
| "aria-hidden"
|
|
50
|
+
| "aria-invalid"
|
|
51
|
+
| "aria-label"
|
|
52
|
+
| "aria-level"
|
|
53
|
+
| "aria-modal"
|
|
54
|
+
| "aria-multiline"
|
|
55
|
+
| "aria-multiselectable"
|
|
56
|
+
| "aria-orientation"
|
|
57
|
+
| "aria-placeholder"
|
|
58
|
+
| "aria-pressed"
|
|
59
|
+
| "aria-readonly"
|
|
60
|
+
| "aria-required"
|
|
61
|
+
| "aria-selected"
|
|
62
|
+
| "aria-sort"
|
|
63
|
+
| "aria-valuemax"
|
|
64
|
+
| "aria-valuemin"
|
|
65
|
+
| "aria-valuenow"
|
|
66
|
+
| "aria-valuetext";
|
|
67
|
+
type AriaLiveRegionProperties =
|
|
68
|
+
| "aria-busy"
|
|
69
|
+
| "aria-live"
|
|
70
|
+
| "aria-relevant"
|
|
71
|
+
| "aria-atomic";
|
|
72
|
+
type AriaDragAndDropProperties = "aria-dropeffect" | "aria-grabbed";
|
|
73
|
+
type AriaRelatonshipProperties =
|
|
74
|
+
| "aria-activedescendant"
|
|
75
|
+
| "aria-colcount"
|
|
76
|
+
| "aria-colindex"
|
|
77
|
+
| "aria-colspan"
|
|
78
|
+
| "aria-controls"
|
|
79
|
+
| "aria-describedby"
|
|
80
|
+
| "aria-description"
|
|
81
|
+
| "aria-details"
|
|
82
|
+
| "aria-errormessage"
|
|
83
|
+
| "aria-flowto"
|
|
84
|
+
| "aria-labelledby"
|
|
85
|
+
| "aria-owns"
|
|
86
|
+
| "aria-posinset"
|
|
87
|
+
| "aria-rowcount"
|
|
88
|
+
| "aria-rowindex"
|
|
89
|
+
| "aria-rowspan"
|
|
90
|
+
| "aria-setsize";
|
|
91
|
+
type AriaGlobalProperties =
|
|
92
|
+
| "aria-atomic"
|
|
93
|
+
| "aria-busy"
|
|
94
|
+
| "aria-controls"
|
|
95
|
+
| "aria-current"
|
|
96
|
+
| "aria-describedby"
|
|
97
|
+
| "aria-description"
|
|
98
|
+
| "aria-details"
|
|
99
|
+
| "aria-disabled"
|
|
100
|
+
| "aria-dropeffect"
|
|
101
|
+
| "aria-errormessage"
|
|
102
|
+
| "aria-flowto"
|
|
103
|
+
| "aria-grabbed"
|
|
104
|
+
| "aria-haspopup"
|
|
105
|
+
| "aria-hidden"
|
|
106
|
+
| "aria-invalid"
|
|
107
|
+
| "aria-keyshortcuts"
|
|
108
|
+
| "aria-label"
|
|
109
|
+
| "aria-labelledby"
|
|
110
|
+
| "aria-live"
|
|
111
|
+
| "aria-owns"
|
|
112
|
+
| "aria-relevant"
|
|
113
|
+
| "aria-roledescription";
|
|
114
|
+
type AriaProps =
|
|
115
|
+
| AriaWidgetProperties
|
|
116
|
+
| AriaDragAndDropProperties
|
|
117
|
+
| AriaLiveRegionProperties
|
|
118
|
+
| AriaRelatonshipProperties
|
|
119
|
+
| AriaGlobalProperties;
|
|
120
|
+
type AriaBoolean = "true" | "false";
|
|
121
|
+
type AriaValue = Exclude<string, AriaBoolean>;
|
|
122
|
+
type AriaValueMap = Partial<Record<AriaProps, AriaBoolean | AriaValue>>;
|
|
123
|
+
type KeyedObject = Record<string | symbol | number, any>;
|
|
124
|
+
type HTMLTags = keyof HTMLElementTagNameMap;
|
|
125
|
+
type HTMLSVGTags = keyof SVGElementTagNameMap;
|
|
126
|
+
type YElement<K extends HTMLTags = HTMLTags> = HTMLElementTagNameMap[K];
|
|
127
|
+
type YSVGElement<K extends HTMLSVGTags = HTMLSVGTags> = SVGElementTagNameMap[K];
|
|
128
|
+
|
|
129
|
+
type ExcludeFunctions<T> = {
|
|
130
|
+
[K in keyof T as T[K] extends Function ? never : K]: T[K];
|
|
131
|
+
};
|
|
132
|
+
type Styles = Partial<CSSStyleDeclaration>;
|
|
133
|
+
interface ElementOverridedProperties extends AriaValueMap {
|
|
134
|
+
style?: Styles;
|
|
135
|
+
}
|
|
136
|
+
type AnyElement<T extends HTMLTags | HTMLSVGTags = HTMLTags> =
|
|
137
|
+
T extends HTMLTags
|
|
138
|
+
? YElement<T>
|
|
139
|
+
: T extends HTMLSVGTags
|
|
140
|
+
? YSVGElement<T>
|
|
141
|
+
: never;
|
|
142
|
+
type AnyProps<T extends HTMLTags | HTMLSVGTags = HTMLTags> = T extends HTMLTags
|
|
143
|
+
? HTMLProps<T>
|
|
144
|
+
: T extends HTMLSVGTags
|
|
145
|
+
? SVGProps<T>
|
|
146
|
+
: never;
|
|
147
|
+
interface Stores<T> {
|
|
148
|
+
get stores(): T;
|
|
149
|
+
}
|
|
150
|
+
type ElementRef<T extends HTMLTags | HTMLSVGTags = HTMLTags> = Stores<
|
|
151
|
+
| (T extends HTMLTags
|
|
152
|
+
? HTMLElementTagNameMap[T]
|
|
153
|
+
: T extends HTMLSVGTags
|
|
154
|
+
? SVGElementTagNameMap[T]
|
|
155
|
+
: never)
|
|
156
|
+
| undefined
|
|
157
|
+
>;
|
|
158
|
+
interface ElementProps<T extends HTMLTags | HTMLSVGTags = HTMLTags> {
|
|
159
|
+
ref?: ElementRef<T>;
|
|
160
|
+
key?: string | number | symbol;
|
|
161
|
+
}
|
|
162
|
+
type ExcludeProperties<T> = {
|
|
163
|
+
[K in keyof T as K extends HTMLExcludedProperties ? never : K]: T[K];
|
|
164
|
+
};
|
|
165
|
+
type HTMLProps<T extends HTMLTags> = Partial<
|
|
166
|
+
ExcludeProperties<ExcludeFunctions<YElement<T>>>
|
|
167
|
+
> &
|
|
168
|
+
ElementProps<T> &
|
|
169
|
+
ElementOverridedProperties;
|
|
170
|
+
|
|
171
|
+
type SVGAttributeValue = string | number;
|
|
172
|
+
|
|
173
|
+
type NormalizeSVGProp<T> = T extends SVGAnimatedLength
|
|
174
|
+
? SVGAttributeValue
|
|
175
|
+
: T extends SVGAnimatedAngle
|
|
176
|
+
? SVGAttributeValue
|
|
177
|
+
: T extends SVGAnimatedBoolean
|
|
178
|
+
? SVGAttributeValue
|
|
179
|
+
: T extends SVGAnimatedEnumeration
|
|
180
|
+
? SVGAttributeValue
|
|
181
|
+
: T extends SVGAnimatedInteger
|
|
182
|
+
? SVGAttributeValue
|
|
183
|
+
: T extends SVGAnimatedNumber
|
|
184
|
+
? SVGAttributeValue
|
|
185
|
+
: T extends SVGAnimatedPreserveAspectRatio
|
|
186
|
+
? SVGAttributeValue
|
|
187
|
+
: T extends SVGAnimatedRect
|
|
188
|
+
? SVGAttributeValue
|
|
189
|
+
: T extends SVGAnimatedString
|
|
190
|
+
? SVGAttributeValue
|
|
191
|
+
: T extends SVGAnimatedTransformList
|
|
192
|
+
? SVGAttributeValue
|
|
193
|
+
: T extends SVGPointList
|
|
194
|
+
? SVGAttributeValue
|
|
195
|
+
: T;
|
|
196
|
+
|
|
197
|
+
type SVGRawProps<T extends HTMLSVGTags> = ExcludeProperties<
|
|
198
|
+
ExcludeFunctions<SVGElementTagNameMap[T]>
|
|
199
|
+
>;
|
|
200
|
+
interface SVGOverridedProperties {
|
|
201
|
+
fill?: string;
|
|
202
|
+
"fill-opacity"?: string;
|
|
203
|
+
stroke?: string;
|
|
204
|
+
"stroke-width"?: SVGAttributeValue;
|
|
205
|
+
"stroke-linecap"?: "butt" | "round" | "square";
|
|
206
|
+
"stroke-linejoin"?: "miter" | "round" | "bevel";
|
|
207
|
+
d?: string;
|
|
208
|
+
"stroke-dasharray"?: SVGAttributeValue;
|
|
209
|
+
}
|
|
210
|
+
type SVGProps<T extends HTMLSVGTags> = Partial<{
|
|
211
|
+
[K in keyof SVGRawProps<T>]: NormalizeSVGProp<SVGRawProps<T>[K]>;
|
|
212
|
+
}> &
|
|
213
|
+
ElementProps<T> &
|
|
214
|
+
ElementOverridedProperties &
|
|
215
|
+
SVGOverridedProperties;
|
|
216
|
+
type StateHandler<S extends KeyedObject | undefined = undefined> =
|
|
217
|
+
| S
|
|
218
|
+
| ((l: S) => S);
|
|
219
|
+
|
|
220
|
+
// declare abstract class Component<S extends KeyedObject | void = void> {
|
|
221
|
+
// protected get state(): S;
|
|
222
|
+
// protected setState(h: StateHandler<S extends void ? undefined : S>): void;
|
|
223
|
+
// public render(): ValidTemplateReturn;
|
|
224
|
+
// public delete(): void;
|
|
225
|
+
// }
|