amateras 0.2.0 → 0.4.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 +25 -7
- package/ext/css/README.md +19 -0
- package/ext/css/src/index.ts +395 -322
- package/ext/css/src/lib/colorAssign.ts +6 -0
- package/ext/css/src/lib/colors/amber.ts +25 -0
- package/ext/css/src/lib/colors/blackwhite.ts +13 -0
- package/ext/css/src/lib/colors/blue.ts +25 -0
- package/ext/css/src/lib/colors/cyan.ts +25 -0
- package/ext/css/src/lib/colors/emerald.ts +25 -0
- package/ext/css/src/lib/colors/fuchsia.ts +25 -0
- package/ext/css/src/lib/colors/gray.ts +25 -0
- package/ext/css/src/lib/colors/green.ts +25 -0
- package/ext/css/src/lib/colors/indigo.ts +25 -0
- package/ext/css/src/lib/colors/lime.ts +25 -0
- package/ext/css/src/lib/colors/neutral.ts +25 -0
- package/ext/css/src/lib/colors/orange.ts +25 -0
- package/ext/css/src/lib/colors/pink.ts +25 -0
- package/ext/css/src/lib/colors/purple.ts +25 -0
- package/ext/css/src/lib/colors/red.ts +25 -0
- package/ext/css/src/lib/colors/rose.ts +25 -0
- package/ext/css/src/lib/colors/sky.ts +25 -0
- package/ext/css/src/lib/colors/slate.ts +25 -0
- package/ext/css/src/lib/colors/stone.ts +25 -0
- package/ext/css/src/lib/colors/teal.ts +25 -0
- package/ext/css/src/lib/colors/violet.ts +25 -0
- package/ext/css/src/lib/colors/yellow.ts +25 -0
- package/ext/css/src/lib/colors/zinc.ts +25 -0
- package/ext/css/src/lib/colors.ts +23 -0
- package/ext/css/src/structure/$CSSContainerRule.ts +13 -0
- package/ext/css/src/structure/$CSSKeyframesRule.ts +1 -5
- package/ext/css/src/structure/$CSSMediaRule.ts +3 -23
- package/ext/css/src/structure/$CSSRule.ts +6 -18
- package/ext/css/src/structure/$CSSStyleRule.ts +5 -14
- package/ext/css/src/structure/$CSSVariable.ts +3 -3
- package/ext/html/html.ts +1 -13
- package/ext/html/node/$Anchor.ts +31 -1
- package/ext/html/node/$Image.ts +54 -1
- package/ext/html/node/$Input.ts +154 -1
- package/ext/html/node/$OptGroup.ts +8 -1
- package/ext/html/node/$Option.ts +25 -1
- package/ext/html/node/$Select.ts +61 -1
- package/ext/i18n/README.md +53 -0
- package/ext/i18n/package.json +10 -0
- package/ext/i18n/src/index.ts +54 -0
- package/ext/i18n/src/node/I18nText.ts +35 -0
- package/ext/i18n/src/structure/I18n.ts +40 -0
- package/ext/i18n/src/structure/I18nDictionary.ts +31 -0
- package/ext/markdown/index.ts +123 -0
- package/ext/router/index.ts +13 -4
- package/ext/router/node/Page.ts +1 -0
- package/ext/router/node/Route.ts +4 -3
- package/ext/router/node/Router.ts +62 -17
- package/ext/router/node/RouterAnchor.ts +1 -1
- package/ext/ssr/index.ts +7 -5
- package/ext/ui/lib/VirtualScroll.ts +24 -0
- package/ext/ui/node/Accordian.ts +97 -0
- package/ext/ui/node/Tabs.ts +114 -0
- package/ext/ui/node/Toast.ts +16 -0
- package/ext/ui/node/Waterfall.ts +73 -0
- package/ext/ui/package.json +11 -0
- package/package.json +6 -7
- package/src/core.ts +36 -19
- package/src/global.ts +4 -0
- package/src/lib/assign.ts +12 -12
- package/src/lib/assignHelper.ts +2 -2
- package/src/lib/chain.ts +3 -0
- package/src/lib/debounce.ts +7 -0
- package/src/lib/env.ts +2 -0
- package/src/lib/native.ts +22 -24
- package/src/lib/randomId.ts +1 -1
- package/src/lib/sleep.ts +1 -1
- package/src/node/$Element.ts +301 -35
- package/src/node/$HTMLElement.ts +94 -1
- package/src/node/$Node.ts +148 -54
- package/src/node/$Virtual.ts +58 -0
- package/src/{node/node.ts → node.ts} +2 -4
- package/src/structure/Signal.ts +3 -3
- package/ext/css/src/structure/$CSSKeyframeRule.ts +0 -14
package/src/node/$Node.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _document } from "#lib/env";
|
|
2
|
+
import { _Array_from, _instanceof, _JSON_stringify, forEach, isFunction, isNull, isObject, isUndefined } from "#lib/native";
|
|
2
3
|
import { Signal } from "#structure/Signal";
|
|
3
4
|
|
|
4
5
|
export class $Node {
|
|
@@ -10,74 +11,100 @@ export class $Node {
|
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
content(children: $NodeContentResolver<this>) {
|
|
13
|
-
|
|
14
|
+
if (isUndefined(children)) return this;
|
|
15
|
+
forEach(_Array_from(this.childNodes), node => node.remove());
|
|
14
16
|
return this.insert(children);
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
insert(resolver: $NodeContentResolver<this>, position = -1) {
|
|
18
|
-
// insert node helper function for depend position
|
|
19
|
-
const appendChild = (children: OrArray<$Node | undefined | null>) => {
|
|
20
|
-
// get child node at position
|
|
21
|
-
const positionChild = _Array_from(this.node.childNodes).filter(node => node.nodeType !== node.TEXT_NODE).at(position);
|
|
22
|
-
$.orArrayResolver(children).forEach(child => {
|
|
23
|
-
if (!child) return;
|
|
24
|
-
if (_instanceof(child, Array)) this.insert(child);
|
|
25
|
-
else if (!positionChild) this.node.appendChild(child.node);
|
|
26
|
-
else this.insertBefore(child.node, position < 0 ? positionChild.nextSibling : positionChild);
|
|
27
|
-
})
|
|
28
|
-
}
|
|
29
20
|
// process nodes
|
|
30
|
-
|
|
21
|
+
forEach($.toArray(resolver), resolve_child => forEach($Node.process(this, resolve_child), $node => $Node.append(this, $node, position)));
|
|
31
22
|
return this;
|
|
32
23
|
}
|
|
33
24
|
|
|
34
|
-
await<T>(promise:
|
|
35
|
-
return promise.then(result => callback(this, result)), this;
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
remove() {
|
|
39
|
-
return this.node.remove(), this
|
|
25
|
+
await<T>(promise: OrPromise<T>, callback: ($node: this, result: T) => void): this {
|
|
26
|
+
if (_instanceof(promise, Promise)) return promise.then(result => callback(this, result)), this;
|
|
27
|
+
else return callback(this, promise), this;
|
|
40
28
|
}
|
|
41
29
|
|
|
42
30
|
replace($node: $NodeContentResolver<$Node>) {
|
|
43
|
-
if (!$node) return this
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
parentNode?.$.insert($node, index)
|
|
31
|
+
if (!$node) return this;
|
|
32
|
+
this.replaceWith(
|
|
33
|
+
...$.toArray($Node.process(this, $node)).filter($node => $node).map($node => $node?.node) as Node[]
|
|
34
|
+
)
|
|
48
35
|
return this;
|
|
49
36
|
}
|
|
50
37
|
|
|
38
|
+
inDOM() {
|
|
39
|
+
return _document.contains(this.node);
|
|
40
|
+
}
|
|
41
|
+
|
|
51
42
|
toString() {
|
|
52
|
-
return this.
|
|
43
|
+
return this.textContent();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
mounted($parent: $Node) {
|
|
47
|
+
return this;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
use<F extends ($ele: this, ...args: any) => void>(callback: F, ...args: F extends ($ele: this, ...args: infer P) => void ? P : never) {
|
|
51
|
+
callback(this, ...args);
|
|
52
|
+
return this;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
is<T extends (abstract new (...args: any[]) => $Node)>(instance: T): InstanceType<T> | null {
|
|
56
|
+
return _instanceof(this, instance) ? this : null;
|
|
53
57
|
}
|
|
54
|
-
}
|
|
55
58
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
59
|
+
static process<T extends $Node>($node: T, content: $NodeContentResolver<any>): Array<$Node | undefined | null> {
|
|
60
|
+
if (isUndefined(content) || isNull(content) || _instanceof(content, $Node)) return [content];
|
|
61
|
+
// is Promise
|
|
62
|
+
if (_instanceof(content, Promise)) return [$('async').await(content, ($async, $child) => $async.replace($child as any))];
|
|
63
|
+
// is SignalFunction or ContentHandler
|
|
64
|
+
if (isFunction(content)) {
|
|
65
|
+
const signal = (content as any).signal;
|
|
66
|
+
if (_instanceof(signal, Signal)) {
|
|
67
|
+
const resolver = (content as $.SignalFunction<any>)();
|
|
68
|
+
if (_instanceof(resolver, $Node)) {
|
|
69
|
+
// handler signal $Node result
|
|
70
|
+
let node = resolver;
|
|
71
|
+
const set = (value: any) => {
|
|
72
|
+
node.replace(value);
|
|
73
|
+
node = value;
|
|
74
|
+
}
|
|
75
|
+
signal.subscribe(set);
|
|
76
|
+
return [resolver];
|
|
77
|
+
} else {
|
|
78
|
+
// handler signal other type result
|
|
79
|
+
const $text = _document ? new $Text() : $('signal').attr({ type: typeof signal.value() });
|
|
80
|
+
const set = (value: any) => $text.textContent(isObject(value) ? _JSON_stringify(value) : value);
|
|
81
|
+
if (_instanceof($text, $Text)) $text.signals.add(signal);
|
|
82
|
+
signal.subscribe(set);
|
|
83
|
+
set(resolver);
|
|
84
|
+
return [$text];
|
|
85
|
+
}
|
|
86
|
+
} else {
|
|
87
|
+
const _content = content($node) as $NodeContentResolver<$Node>;
|
|
88
|
+
if (_instanceof(_content, Promise)) return this.process($node, _content as any);
|
|
89
|
+
else return $.toArray(_content).map(content => this.process($node, content)).flat();
|
|
90
|
+
}
|
|
77
91
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
92
|
+
// is nested array
|
|
93
|
+
if (_instanceof(content, Array)) return content.map(c => this.process($node, c)).flat();
|
|
94
|
+
// is string | number | boolean
|
|
95
|
+
return [new $Text(`${content}`)];
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** */
|
|
99
|
+
static append($node: $Node, child: $Node | undefined | null, position: number) {
|
|
100
|
+
// insert each child, child may be an array
|
|
101
|
+
if (!child) return;
|
|
102
|
+
// get child node at position
|
|
103
|
+
let positionChild = _Array_from($node.childNodes).at(position);
|
|
104
|
+
if (!positionChild) $node.appendChild(child.node);
|
|
105
|
+
else $node.insertBefore(child.node, position < 0 ? positionChild.nextSibling : positionChild);
|
|
106
|
+
child.mounted($node);
|
|
107
|
+
}
|
|
81
108
|
}
|
|
82
109
|
|
|
83
110
|
export class $Text extends $Node {
|
|
@@ -89,14 +116,81 @@ export class $Text extends $Node {
|
|
|
89
116
|
|
|
90
117
|
export type $NodeContentHandler<T extends $Node> = ($node: T) => OrPromise<$NodeContentResolver<T>>;
|
|
91
118
|
export type $NodeContentTypes = $Node | string | number | boolean | $.SignalFunction<any> | null | undefined;
|
|
92
|
-
export type $NodeContentResolver<T extends $Node> =
|
|
119
|
+
export type $NodeContentResolver<T extends $Node> = OrPromise<$NodeContentTypes | $NodeContentHandler<T> | $NodeContentResolver<T>[]>;
|
|
93
120
|
|
|
94
121
|
export interface $Node {
|
|
95
|
-
|
|
122
|
+
/** {@link Node.baseURI} */
|
|
123
|
+
readonly baseURI: string;
|
|
124
|
+
/** {@link Node.childNodes} */
|
|
96
125
|
readonly childNodes: NodeListOf<ChildNode>;
|
|
126
|
+
/** {@link Node.firstChild} */
|
|
127
|
+
readonly firstChild: ChildNode | null;
|
|
128
|
+
/** {@link Node.isConnected} */
|
|
129
|
+
readonly isConnected: boolean;
|
|
130
|
+
/** {@link Node.lastChild} */
|
|
131
|
+
readonly lastChild: ChildNode | null;
|
|
132
|
+
/** {@link Node.nextSibling} */
|
|
133
|
+
readonly nextSibling: ChildNode | null;
|
|
134
|
+
/** {@link Node.nodeName} */
|
|
135
|
+
readonly nodeName: string;
|
|
136
|
+
/** {@link Node.nodeType} */
|
|
137
|
+
readonly nodeType: number;
|
|
138
|
+
/** {@link Node.ownerDocument} */
|
|
139
|
+
readonly ownerDocument: Document | null;
|
|
140
|
+
/** {@link Node.parentElement} */
|
|
141
|
+
readonly parentElement?: HTMLElement | null;
|
|
142
|
+
/** {@link Node.parentNode} */
|
|
143
|
+
readonly parentNode?: ParentNode | null;
|
|
144
|
+
/** {@link Node.previousSibling} */
|
|
145
|
+
readonly previousSibling?: ChildNode | null;
|
|
146
|
+
|
|
147
|
+
/** {@link Node.appendChild} */
|
|
97
148
|
appendChild<T extends Node>(node: T): T;
|
|
149
|
+
/** {@link Node.cloneNode} */
|
|
150
|
+
cloneNode(subtree?: boolean): Node;
|
|
151
|
+
/** {@link Node.compareDocumentPosition} */
|
|
152
|
+
compareDocumentPosition(other: Node): number;
|
|
153
|
+
/** {@link Node.getRootNode} */
|
|
154
|
+
getRootNode(options?: GetRootNodeOptions): Node;
|
|
155
|
+
/** {@link Node.hasChildNodes} */
|
|
156
|
+
hasChildNodes(): boolean;
|
|
157
|
+
/** {@link Node.insertBefore} */
|
|
98
158
|
insertBefore<T extends Node>(node: T, child: Node | null): T;
|
|
159
|
+
/** {@link Node.isDefaultNamespace} */
|
|
160
|
+
isDefaultNamespace(namespace: string | null): boolean;
|
|
161
|
+
/** {@link Node.isEqualNode} */
|
|
162
|
+
isEqualNode(otherNode: Node | null): boolean;
|
|
163
|
+
/** {@link Node.isSameNode} */
|
|
164
|
+
isSameNode(otherNode: Node | null): boolean;
|
|
165
|
+
/** {@link Node.lookupNamespaceURI} */
|
|
166
|
+
lookupNamespaceURI(prefix: string | null): string | null;
|
|
167
|
+
/** {@link Node.lookupPrefix} */
|
|
168
|
+
lookupPrefix(namespace: string | null): string | null;
|
|
169
|
+
/** {@link Node.normalize} */
|
|
170
|
+
normalize(): this;
|
|
171
|
+
/** {@link Node.removeChild} */
|
|
172
|
+
removeChild<T extends Node>(child: T): T;
|
|
173
|
+
/** {@link Node.replaceChild} */
|
|
174
|
+
replaceChild<T extends Node>(node: Node, child: T): T;
|
|
175
|
+
/** {@link Node.replaceChild} */
|
|
176
|
+
after(...nodes: (Node | string)[]): this;
|
|
177
|
+
/** {@link Node.replaceChild} */
|
|
178
|
+
before(...nodes: (Node | string)[]): this;
|
|
179
|
+
/** {@link Node.replaceChild} */
|
|
180
|
+
remove(): this;
|
|
181
|
+
/** {@link Node.replaceChild} */
|
|
182
|
+
replaceWith(...nodes: (Node | string)[]): this;
|
|
183
|
+
/** {@link EventTarget.addEventListener} */
|
|
184
|
+
addEventListener(type: string, callback: EventListenerOrEventListenerObject | null, options?: AddEventListenerOptions | boolean): void;
|
|
185
|
+
/** {@link EventTarget.removeEventListener} */
|
|
186
|
+
removeEventListener(type: string, callback: EventListenerOrEventListenerObject | null, options?: EventListenerOptions | boolean): void;
|
|
187
|
+
/** {@link EventTarget.dispatchEvent} */
|
|
188
|
+
dispatchEvent(event: Event): boolean;
|
|
99
189
|
|
|
100
|
-
|
|
190
|
+
/** {@link Node.nodeValue} */
|
|
191
|
+
nodeValue(nodeValue: $Parameter<string | null>): this;
|
|
192
|
+
nodeValue(): string | null;
|
|
193
|
+
/** {@link Node.textContent} */
|
|
194
|
+
textContent(textContent: $Parameter<string | null>): this;
|
|
101
195
|
textContent(): string | null;
|
|
102
196
|
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { forEach, _Array_from, isUndefined, _instanceof } from "#lib/native";
|
|
2
|
+
import { $HTMLElement } from "#node/$HTMLElement";
|
|
3
|
+
import { $Node, type $NodeContentResolver } from "#node/$Node";
|
|
4
|
+
|
|
5
|
+
export class $Virtual<Ele extends HTMLElement = HTMLElement, EvMap = HTMLElementEventMap> extends $HTMLElement<Ele, EvMap> {
|
|
6
|
+
nodes = new Set<$Node>;
|
|
7
|
+
hiddenNodes = new Set<$Node>;
|
|
8
|
+
constructor(resolver: string | Ele) {
|
|
9
|
+
super(resolver);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
content(children: $NodeContentResolver<this>) {
|
|
13
|
+
this.nodes.clear();
|
|
14
|
+
forEach(_Array_from(this.childNodes), node => node.remove());
|
|
15
|
+
return this.insert(children);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
insert(resolver: $NodeContentResolver<this>, position = -1) {
|
|
19
|
+
// process nodes
|
|
20
|
+
forEach($.toArray(resolver), resolve_child => {
|
|
21
|
+
forEach($Node.process(this, resolve_child), $node => $Virtual.append(this, $node, position))
|
|
22
|
+
});
|
|
23
|
+
this.render();
|
|
24
|
+
return this;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
hide($node?: $Node | null) {
|
|
28
|
+
if (!$node || !this.nodes.has($node)) return this;
|
|
29
|
+
this.hiddenNodes.add($node);
|
|
30
|
+
return this;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
show($node?: $Node | null) {
|
|
34
|
+
if (!$node) return this;
|
|
35
|
+
this.hiddenNodes.delete($node);
|
|
36
|
+
return this;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
render() {
|
|
40
|
+
// remove hidden node
|
|
41
|
+
forEach(_Array_from(this.childNodes), node => this.hiddenNodes.has($(node)) && node.remove());
|
|
42
|
+
// add visible node with position
|
|
43
|
+
forEach(_Array_from(this.nodes), ($node, i) => {
|
|
44
|
+
if (this.hiddenNodes.has($node)) return;
|
|
45
|
+
if (_Array_from(this.childNodes).at(i) !== $node.node) $Node.append(this, $node, i);
|
|
46
|
+
})
|
|
47
|
+
return this;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
static append($node: $Virtual, child: $Node | undefined | null, position: number) {
|
|
51
|
+
if (!child) return;
|
|
52
|
+
const childList = _Array_from($node.nodes);
|
|
53
|
+
let $positionChild = childList.at(position);
|
|
54
|
+
if (!$positionChild) childList.push(child);
|
|
55
|
+
else childList.splice(position >= 0 ? position : childList.length + 1 + position, 0, child);
|
|
56
|
+
$node.nodes = new Set(childList);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { $HTMLElement } from '#node/$HTMLElement';
|
|
2
2
|
import { assignHelper } from '#lib/assignHelper';
|
|
3
3
|
import { $Element } from '#node/$Element';
|
|
4
|
-
import { $Node, $Text } from '
|
|
5
|
-
|
|
6
|
-
export * from './$Element';
|
|
7
|
-
export * from './$Node';
|
|
4
|
+
import { $Node, $Text } from '#node/$Node';
|
|
8
5
|
|
|
6
|
+
assignHelper(EventTarget, $Node);
|
|
9
7
|
assignHelper(Node, $Node);
|
|
10
8
|
assignHelper(Text, $Text);
|
|
11
9
|
assignHelper(Element, $Element);
|
package/src/structure/Signal.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _instanceof, isUndefined } from "#lib/native";
|
|
1
|
+
import { _instanceof, forEach, isUndefined } from "#lib/native";
|
|
2
2
|
|
|
3
3
|
export class Signal<T> {
|
|
4
4
|
#value: T;
|
|
@@ -13,7 +13,7 @@ export class Signal<T> {
|
|
|
13
13
|
value(callback: (oldValue: T) => T): this;
|
|
14
14
|
value(resolver?: T | ((oldValue: T) => T)) {
|
|
15
15
|
if (!arguments.length) {
|
|
16
|
-
Signal.listeners
|
|
16
|
+
forEach(Signal.listeners, fn => fn(this));
|
|
17
17
|
return this.#value;
|
|
18
18
|
}
|
|
19
19
|
if (_instanceof(resolver, Function)) this.value(resolver(this.#value));
|
|
@@ -25,7 +25,7 @@ export class Signal<T> {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
emit() {
|
|
28
|
-
this.subscribers
|
|
28
|
+
forEach(this.subscribers, subs => subs(this.#value))
|
|
29
29
|
return this;
|
|
30
30
|
}
|
|
31
31
|
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { $CSSStyleRule } from "#structure/$CSSStyleRule";
|
|
2
|
-
import { _Array_from } from "../../../../src/lib/native";
|
|
3
|
-
|
|
4
|
-
export class $CSSKeyframeRule extends $CSSStyleRule {
|
|
5
|
-
keyframe: string
|
|
6
|
-
constructor(keyframe: string) {
|
|
7
|
-
super();
|
|
8
|
-
this.keyframe = keyframe;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
get css(): string {
|
|
12
|
-
return `${this.keyframe} { ${_Array_from(this.declarations).map(([_, dec]) => `${dec}`).join(' ')} }`
|
|
13
|
-
}
|
|
14
|
-
}
|