amateras 0.10.1 → 0.11.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 +30 -25
- package/build/core.js +1 -0
- package/build/css.js +1 -0
- package/build/for.js +1 -0
- package/build/i18n.js +1 -0
- package/build/idb.js +1 -0
- package/build/if.js +1 -0
- package/build/import-map.js +1 -0
- package/build/markdown.js +1 -0
- package/build/match.js +1 -0
- package/build/meta.js +1 -0
- package/build/prefetch.js +1 -0
- package/build/router.js +1 -0
- package/build/signal.js +1 -0
- package/build/ui.js +1 -0
- package/build/utils.js +1 -0
- package/build/widget.js +1 -0
- package/package.json +9 -7
- package/packages/core/package.json +19 -0
- package/packages/core/src/env.browser.ts +21 -0
- package/packages/core/src/env.node.ts +21 -0
- package/packages/core/src/global.ts +5 -0
- package/packages/core/src/index.ts +184 -0
- package/packages/core/src/lib/hmr.ts +145 -0
- package/packages/core/src/lib/symbols.ts +2 -0
- package/packages/core/src/structure/ElementProto.ts +95 -0
- package/packages/core/src/structure/GlobalState.ts +9 -0
- package/packages/core/src/structure/NodeProto.ts +18 -0
- package/packages/core/src/structure/Proto.ts +90 -0
- package/packages/core/src/structure/ProxyProto.ts +20 -0
- package/packages/core/src/structure/TextProto.ts +22 -0
- package/packages/core/src/structure/WidgetEvent.ts +17 -0
- package/packages/css/README.md +128 -0
- package/packages/css/package.json +15 -0
- package/packages/css/src/ext/colors/amber.ts +25 -0
- package/packages/css/src/ext/colors/blackwhite.ts +13 -0
- package/packages/css/src/ext/colors/blue.ts +25 -0
- package/packages/css/src/ext/colors/cyan.ts +25 -0
- package/packages/css/src/ext/colors/emerald.ts +25 -0
- package/packages/css/src/ext/colors/fuchsia.ts +25 -0
- package/packages/css/src/ext/colors/gray.ts +25 -0
- package/packages/css/src/ext/colors/green.ts +25 -0
- package/packages/css/src/ext/colors/indigo.ts +25 -0
- package/packages/css/src/ext/colors/lime.ts +25 -0
- package/packages/css/src/ext/colors/neutral.ts +25 -0
- package/packages/css/src/ext/colors/orange.ts +25 -0
- package/packages/css/src/ext/colors/pink.ts +25 -0
- package/packages/css/src/ext/colors/purple.ts +25 -0
- package/packages/css/src/ext/colors/red.ts +25 -0
- package/packages/css/src/ext/colors/rose.ts +25 -0
- package/packages/css/src/ext/colors/sky.ts +25 -0
- package/packages/css/src/ext/colors/slate.ts +25 -0
- package/packages/css/src/ext/colors/stone.ts +25 -0
- package/packages/css/src/ext/colors/teal.ts +25 -0
- package/packages/css/src/ext/colors/violet.ts +25 -0
- package/packages/css/src/ext/colors/yellow.ts +25 -0
- package/packages/css/src/ext/colors/zinc.ts +25 -0
- package/packages/css/src/ext/colors.ts +23 -0
- package/packages/css/src/ext/keyframes.ts +37 -0
- package/packages/css/src/ext/property.ts +68 -0
- package/packages/css/src/ext/variable.ts +51 -0
- package/packages/css/src/index.ts +103 -0
- package/packages/css/src/lib/cache.ts +27 -0
- package/packages/css/src/lib/colorAssign.ts +6 -0
- package/packages/css/src/lib/createRule.ts +31 -0
- package/packages/css/src/lib/utils.ts +1 -0
- package/packages/css/src/structure/$CSS.ts +4 -0
- package/packages/css/src/structure/$CSSKeyframes.ts +13 -0
- package/packages/css/src/structure/$CSSProperty.ts +21 -0
- package/packages/css/src/structure/$CSSRule.ts +39 -0
- package/packages/css/src/structure/$CSSVariable.ts +34 -0
- package/packages/css/src/types.ts +300 -0
- package/packages/for/package.json +15 -0
- package/packages/for/src/global.ts +7 -0
- package/packages/for/src/index.ts +15 -0
- package/packages/for/src/structure/For.ts +74 -0
- package/packages/hmr/package.json +13 -0
- package/packages/hmr/src/index.ts +27 -0
- package/packages/i18n/README.md +73 -0
- package/packages/i18n/package.json +15 -0
- package/packages/i18n/src/index.ts +78 -0
- package/packages/i18n/src/structure/I18n.ts +51 -0
- package/packages/i18n/src/structure/I18nDictionary.ts +31 -0
- package/packages/i18n/src/structure/I18nTranslation.ts +51 -0
- package/packages/i18n/src/types.ts +77 -0
- package/packages/idb/README.md +127 -0
- package/packages/idb/package.json +16 -0
- package/packages/idb/src/core.ts +6 -0
- package/packages/idb/src/index.ts +17 -0
- package/packages/idb/src/lib/$IDBRequest.ts +8 -0
- package/packages/idb/src/structure/$IDB.ts +63 -0
- package/packages/idb/src/structure/$IDBCursor.ts +34 -0
- package/packages/idb/src/structure/$IDBIndex.ts +48 -0
- package/packages/idb/src/structure/$IDBStore.ts +103 -0
- package/packages/idb/src/structure/$IDBStoreBase.ts +30 -0
- package/packages/idb/src/structure/$IDBTransaction.ts +38 -0
- package/packages/idb/src/structure/builder/$IDBBuilder.ts +229 -0
- package/packages/idb/src/structure/builder/$IDBStoreBuilder.ts +100 -0
- package/packages/if/package.json +15 -0
- package/packages/if/src/global.ts +15 -0
- package/packages/if/src/index.ts +51 -0
- package/packages/if/src/structure/Condition.ts +44 -0
- package/packages/if/src/structure/ConditionStatement.ts +25 -0
- package/packages/if/src/structure/Else.ts +6 -0
- package/packages/if/src/structure/ElseIf.ts +6 -0
- package/packages/if/src/structure/If.ts +6 -0
- package/packages/markdown/README.md +53 -0
- package/packages/markdown/package.json +15 -0
- package/packages/markdown/src/index.ts +3 -0
- package/packages/markdown/src/lib/type.ts +26 -0
- package/packages/markdown/src/lib/util.ts +21 -0
- package/packages/markdown/src/structure/Markdown.ts +57 -0
- package/packages/markdown/src/structure/MarkdownLexer.ts +111 -0
- package/packages/markdown/src/structure/MarkdownParser.ts +34 -0
- package/packages/markdown/src/syntax/alert.ts +46 -0
- package/packages/markdown/src/syntax/blockquote.ts +35 -0
- package/packages/markdown/src/syntax/bold.ts +11 -0
- package/packages/markdown/src/syntax/code.ts +11 -0
- package/packages/markdown/src/syntax/codeblock.ts +44 -0
- package/packages/markdown/src/syntax/heading.ts +14 -0
- package/packages/markdown/src/syntax/horizontalRule.ts +11 -0
- package/packages/markdown/src/syntax/image.ts +23 -0
- package/packages/markdown/src/syntax/italic.ts +11 -0
- package/packages/markdown/src/syntax/link.ts +46 -0
- package/packages/markdown/src/syntax/list.ts +121 -0
- package/packages/markdown/src/syntax/table.ts +67 -0
- package/packages/markdown/src/syntax/text.ts +19 -0
- package/packages/match/package.json +15 -0
- package/packages/match/src/global.ts +14 -0
- package/packages/match/src/index.ts +33 -0
- package/packages/match/src/structure/Case.ts +15 -0
- package/packages/match/src/structure/Default.ts +12 -0
- package/packages/match/src/structure/Match.ts +78 -0
- package/packages/meta/package.json +14 -0
- package/packages/meta/src/index.ts +36 -0
- package/packages/meta/src/lib/resolveMeta.ts +27 -0
- package/packages/meta/src/types.ts +36 -0
- package/packages/prefetch/package.json +14 -0
- package/packages/prefetch/src/index.ts +70 -0
- package/packages/router/README.md +18 -0
- package/packages/router/package.json +16 -0
- package/packages/router/src/global.ts +22 -0
- package/packages/router/src/index.ts +106 -0
- package/packages/router/src/structure/Link.ts +17 -0
- package/packages/router/src/structure/NavLink.ts +19 -0
- package/packages/router/src/structure/Page.ts +30 -0
- package/packages/router/src/structure/Route.ts +123 -0
- package/packages/router/src/structure/RouteGroup.ts +24 -0
- package/packages/router/src/structure/RouteNode.ts +54 -0
- package/packages/router/src/structure/RouteSlot.ts +34 -0
- package/packages/router/src/structure/Router.ts +192 -0
- package/packages/router/src/structure/RouterConstructor.ts +18 -0
- package/packages/router/src/types.ts +41 -0
- package/packages/signal/README.md +93 -0
- package/packages/signal/package.json +15 -0
- package/packages/signal/src/index.ts +97 -0
- package/packages/signal/src/lib/track.ts +18 -0
- package/packages/signal/src/structure/Signal.ts +59 -0
- package/packages/ui/package.json +14 -0
- package/packages/ui/src/index.ts +4 -0
- package/packages/ui/src/lib/slideshowAnimations.ts +39 -0
- package/packages/ui/src/structure/Radio.ts +77 -0
- package/packages/ui/src/structure/Slide.ts +11 -0
- package/packages/ui/src/structure/Slideshow.ts +99 -0
- package/packages/utils/package.json +18 -0
- package/packages/utils/src/global.ts +39 -0
- package/packages/utils/src/index.bun.ts +3 -0
- package/packages/utils/src/index.ts +2 -0
- package/packages/utils/src/lib/debugger.ts +14 -0
- package/packages/utils/src/lib/utils.ts +119 -0
- package/packages/utils/src/structure/UID.ts +18 -0
- package/packages/widget/README.md +29 -0
- package/packages/widget/package.json +14 -0
- package/packages/widget/src/index.ts +82 -0
- package/packages/widget/src/structure/Widget.ts +42 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { ElementProto } from "#structure/ElementProto";
|
|
2
|
+
import { NodeProto } from "#structure/NodeProto";
|
|
3
|
+
import { Proto } from "#structure/Proto";
|
|
4
|
+
import { ProxyProto } from "#structure/ProxyProto";
|
|
5
|
+
import { TextProto } from "#structure/TextProto";
|
|
6
|
+
import { _Array_from, _instanceof, _undefined, forEach, is } from "@amateras/utils";
|
|
7
|
+
import { symbol_ProtoType } from "./symbols";
|
|
8
|
+
|
|
9
|
+
const elementProtoMap = import.meta.hot?.data.protoMap ?? new Map<HTMLElement, Proto>()
|
|
10
|
+
// save data before HMR
|
|
11
|
+
if (import.meta.hot) import.meta.hot.dispose(data => {
|
|
12
|
+
data.protoMap = elementProtoMap;
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
export const hmr = (element: HTMLElement, proto: Proto): boolean => {
|
|
16
|
+
if (!import.meta.hot) return false;
|
|
17
|
+
|
|
18
|
+
function replace() {
|
|
19
|
+
let nodes = proto.build().toDOM();
|
|
20
|
+
element.replaceChildren(...nodes);
|
|
21
|
+
elementProtoMap.set(element, proto);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// get proto from data;
|
|
25
|
+
const oldProto = elementProtoMap.get(element);
|
|
26
|
+
if (!oldProto) return replace(), true;
|
|
27
|
+
|
|
28
|
+
diff(element, proto.build(), oldProto)
|
|
29
|
+
elementProtoMap.set(element, proto);
|
|
30
|
+
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
function diff(parentElement: HTMLElement, newProto: Proto, oldProto?: Proto, prevSibling?: Node): void {
|
|
36
|
+
// console.table({
|
|
37
|
+
// parent: [parentElement],
|
|
38
|
+
// new: [newProto, newProto.toString()],
|
|
39
|
+
// old: [oldProto, oldProto?.toString()],
|
|
40
|
+
// prev: [prevSibling]
|
|
41
|
+
// })
|
|
42
|
+
function processNoneNodeProto() {
|
|
43
|
+
// None node Proto type
|
|
44
|
+
if (prevSibling) {
|
|
45
|
+
if (prevSibling.nextSibling)
|
|
46
|
+
forEach(newProto.toDOM(), newNode => parentElement.insertBefore(newNode,prevSibling.nextSibling))
|
|
47
|
+
else parentElement.append(...newProto.toDOM())
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
parentElement.replaceChildren(...newProto.toDOM())
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function transferNode() {
|
|
55
|
+
if (!_instanceof(oldProto, NodeProto) || !_instanceof(newProto, NodeProto)) return;
|
|
56
|
+
newProto.node = oldProto.node;
|
|
57
|
+
oldProto.dispose();
|
|
58
|
+
forEach(newProto.modifiers, mod => {
|
|
59
|
+
if (!newProto.node) throw 'diff:transferNode:newProto.node==null'
|
|
60
|
+
mod(newProto.node)
|
|
61
|
+
})
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (!oldProto) {
|
|
65
|
+
processNoneNodeProto();
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
//@ts-ignore
|
|
69
|
+
if (oldProto.constructor[symbol_ProtoType] !== 'Widget' || newProto.constructor[symbol_ProtoType] !== 'Widget')
|
|
70
|
+
if (oldProto.constructor !== newProto.constructor) {
|
|
71
|
+
if (_instanceof(oldProto, NodeProto)) {
|
|
72
|
+
forEach(newProto.toDOM(), newNode => oldProto.node?.parentNode?.insertBefore(newNode, oldProto.node));
|
|
73
|
+
oldProto.removeNode();
|
|
74
|
+
oldProto.dispose();
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
processNoneNodeProto();
|
|
78
|
+
oldProto.dispose();
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (_instanceof(oldProto, ProxyProto)) {
|
|
83
|
+
oldProto.node?.replaceWith(...newProto.toDOM());
|
|
84
|
+
oldProto.removeNode();
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (_instanceof(oldProto, TextProto) && _instanceof(newProto, TextProto)) {
|
|
88
|
+
if (oldProto.content !== newProto.content) {
|
|
89
|
+
oldProto.node!.textContent = newProto.content;
|
|
90
|
+
}
|
|
91
|
+
transferNode();
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (_instanceof(oldProto, ElementProto) && _instanceof(newProto, ElementProto)) {
|
|
95
|
+
if (!oldProto.node) return processNoneNodeProto();
|
|
96
|
+
if (oldProto.tagname !== newProto.tagname) {
|
|
97
|
+
oldProto.node?.replaceWith(...newProto.toDOM());
|
|
98
|
+
return;
|
|
99
|
+
};
|
|
100
|
+
let newAttrList = _Array_from(newProto.attr())
|
|
101
|
+
let nodeAttrList = _Array_from(oldProto.node.attributes);
|
|
102
|
+
let length = Math.max(newAttrList.length, nodeAttrList.length);
|
|
103
|
+
for (let i = 0; i < length; i++) {
|
|
104
|
+
let newAttr = newAttrList[i];
|
|
105
|
+
let nodeAttr = nodeAttrList[i];
|
|
106
|
+
if (!nodeAttr && newAttr) {
|
|
107
|
+
oldProto.node.setAttribute(newAttr[0], newAttr[1])
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
if (nodeAttr) {
|
|
111
|
+
if (!newAttr) {
|
|
112
|
+
oldProto.node.removeAttributeNode(nodeAttr);
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
if (nodeAttr.value !== newAttr[1]) nodeAttr.value = newAttr[1];
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
throw 'diff:newAttr==nodeAttr==undefined';
|
|
121
|
+
}
|
|
122
|
+
transferNode();
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const oldProtoList = _Array_from(oldProto.protos);
|
|
126
|
+
const newProtoList = _Array_from(newProto.protos);
|
|
127
|
+
let length = Math.max(oldProto.protos.size, newProto.protos.size);
|
|
128
|
+
let prevNode: Node | undefined = is(oldProto, ProxyProto)?.node ?? _undefined;
|
|
129
|
+
for (let i = 0; i < length; i++) {
|
|
130
|
+
const oldChildProto = oldProtoList[i];
|
|
131
|
+
const newChildProto = newProtoList[i];
|
|
132
|
+
if (!newChildProto) {
|
|
133
|
+
if (oldChildProto) oldChildProto.removeNode();
|
|
134
|
+
continue;
|
|
135
|
+
};
|
|
136
|
+
const parent = is(oldProto, ElementProto)?.node ?? parentElement;
|
|
137
|
+
diff(parent, newChildProto, oldChildProto, prevNode);
|
|
138
|
+
// set current child proto to be prev proto;
|
|
139
|
+
if (_instanceof(newChildProto, NodeProto)) {
|
|
140
|
+
// current proto node should not be undefined
|
|
141
|
+
if (!newChildProto.node) throw 'diff:newChildProto.node==undefined';
|
|
142
|
+
prevNode = newChildProto.node;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { _Array_from, _Object_entries, forEach, isNull, isUndefined, map } from "@amateras/utils";
|
|
2
|
+
import { NodeProto } from "./NodeProto";
|
|
3
|
+
|
|
4
|
+
const SELF_CLOSING_TAGNAMES = ['img', 'hr', 'br', 'input', 'link', 'meta'];
|
|
5
|
+
|
|
6
|
+
export class ElementProto<H extends HTMLElement = HTMLElement> extends NodeProto<H> {
|
|
7
|
+
tagname: string;
|
|
8
|
+
#attr = new Map<string, string>();
|
|
9
|
+
declare layout: $.Layout | null;
|
|
10
|
+
#innerHTML = '';
|
|
11
|
+
constructor(tagname: string, props: $.Props | null, layout?: $.Layout | null) {
|
|
12
|
+
super(() => layout?.(this));
|
|
13
|
+
this.tagname = tagname;
|
|
14
|
+
if (props) this.attrProcess(props);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
on<K extends keyof HTMLElementEventMap>(type: K, listener: (event: HTMLElementEventMap[K] & { currentTarget: H }) => void) {
|
|
18
|
+
this.ondom(node => {
|
|
19
|
+
node.addEventListener(type, listener as any)
|
|
20
|
+
this.disposers.add(() => node.removeEventListener(type, listener as any))
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
override toString(): string {
|
|
25
|
+
return this.parseHTML()
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
parseHTML(options?: { children?: string, attr?: string }) {
|
|
29
|
+
let tagname = this.tagname;
|
|
30
|
+
let childrenHTML = options?.children ?? (this.#innerHTML || map(this.protos, proto => `${proto}`).join(''));
|
|
31
|
+
let attr = options?.attr ?? map(this.#attr, ([key, value]) => value.length ? `${key}="${value}"` : key).join(' ');
|
|
32
|
+
let attrText = attr.length ? ' ' + attr : '';
|
|
33
|
+
if (SELF_CLOSING_TAGNAMES.includes(tagname)) return `<${tagname}${attrText} />`;
|
|
34
|
+
return `<${tagname}${attrText}>${childrenHTML}</${tagname}>`;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
override toDOM(children = true): H[] {
|
|
38
|
+
if (this.node) return [this.node];
|
|
39
|
+
let element = document.createElement(this.tagname) as H;
|
|
40
|
+
this.node = element;
|
|
41
|
+
if (this.#innerHTML) this.node.innerHTML = this.#innerHTML;
|
|
42
|
+
else if (children) element.append(...map(this.protos, proto => proto.toDOM(children)).flat());
|
|
43
|
+
forEach(this.#attr, ([key, value]) => element.setAttribute(key, value));
|
|
44
|
+
forEach(this.modifiers, process => process(element));
|
|
45
|
+
return [element];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
private attrProcess(attrObj: $.Props) {
|
|
49
|
+
forEach(_Object_entries(attrObj), ([key, value]) => {
|
|
50
|
+
for (let process of $.process.attr) {
|
|
51
|
+
let result = process(key, value, this as any);
|
|
52
|
+
if (!isUndefined(result)) return;
|
|
53
|
+
}
|
|
54
|
+
this.attr(key, value);
|
|
55
|
+
})
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
innerHTML(html: string) {
|
|
59
|
+
this.#innerHTML = html;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
attr(): Map<string, string>;
|
|
63
|
+
attr(attrName: string): string | undefined;
|
|
64
|
+
attr(attrName: string, attrValue: string | null): this;
|
|
65
|
+
attr(attrName?: string, attrValue?: string | null) {
|
|
66
|
+
if (!arguments.length) return this.#attr;
|
|
67
|
+
if (isUndefined(attrValue)) return this.#attr.get(attrName!);
|
|
68
|
+
if (isNull(attrValue)) {
|
|
69
|
+
this.#attr.delete(attrName!);
|
|
70
|
+
this.node?.removeAttribute(attrName!);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
this.#attr.set(attrName!, attrValue);
|
|
74
|
+
this.node?.setAttribute(attrName!, attrValue);
|
|
75
|
+
}
|
|
76
|
+
return this;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
addClass(...tokens: string[]) {
|
|
80
|
+
this.token('add', 'class', ...tokens)
|
|
81
|
+
this.node?.classList.add(...tokens);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
removeClass(...tokens: string[]) {
|
|
85
|
+
this.token('delete', 'class', ...tokens)
|
|
86
|
+
this.node?.classList.remove(...tokens);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
private token(method: 'add' | 'delete', name: string, ...tokens: string[]) {
|
|
90
|
+
let value = this.#attr.get(name);
|
|
91
|
+
let tokenArr = new Set(value?.split(' ') ?? []);
|
|
92
|
+
forEach(tokens, t => tokenArr[method](t));
|
|
93
|
+
this.#attr.set(name, _Array_from(tokenArr).join(' '));
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { _null } from "@amateras/utils";
|
|
2
|
+
import { Proto } from "./Proto";
|
|
3
|
+
|
|
4
|
+
export class NodeProto<N extends Node & ChildNode = Node & ChildNode> extends Proto {
|
|
5
|
+
node: null | N = _null;
|
|
6
|
+
modifiers = new Set<(node: N) => void>();
|
|
7
|
+
constructor(layout?: $.Layout) {
|
|
8
|
+
super(layout);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
ondom(callback: (node: N) => void) {
|
|
12
|
+
this.modifiers.add(callback);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
override removeNode(): void {
|
|
16
|
+
this.node?.remove();
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { symbol_ProtoType, symbol_Statement } from "#lib/symbols";
|
|
2
|
+
import { _null, forEach, map } from "@amateras/utils";
|
|
3
|
+
import { GlobalState } from "./GlobalState";
|
|
4
|
+
|
|
5
|
+
export type ProtoLayout = (...args: any[]) => void;
|
|
6
|
+
|
|
7
|
+
export abstract class Proto {
|
|
8
|
+
static proto: Proto | null = _null;
|
|
9
|
+
static [symbol_ProtoType] = 'Proto';
|
|
10
|
+
static [symbol_Statement] = false;
|
|
11
|
+
protos = new Set<Proto>();
|
|
12
|
+
disposers = new Set<() => void>();
|
|
13
|
+
layout: $.Layout | null;
|
|
14
|
+
#parent: Proto | null = _null;
|
|
15
|
+
global: GlobalState = Proto.proto?.global ?? new GlobalState();
|
|
16
|
+
/**
|
|
17
|
+
* @virtual This property is phantom types, declare the return type of {@link Proto.children}
|
|
18
|
+
* @deprecated
|
|
19
|
+
*/
|
|
20
|
+
declare __child__: Proto;
|
|
21
|
+
constructor(layout?: $.Layout) {
|
|
22
|
+
this.layout = layout ?? _null;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
set parent(proto: Proto | null) {
|
|
26
|
+
this.#parent?.protos.delete(this);
|
|
27
|
+
this.#parent = proto;
|
|
28
|
+
if (proto) this.global = proto.global;
|
|
29
|
+
proto?.protos.add(this);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
get parent() {
|
|
33
|
+
return this.#parent;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
get children(): this['__child__'][] {
|
|
37
|
+
return map(this.protos, proto => {
|
|
38
|
+
//@ts-ignore
|
|
39
|
+
if (proto.constructor[symbol_Statement])
|
|
40
|
+
return proto.children
|
|
41
|
+
else return proto
|
|
42
|
+
}).flat()
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
build(children = true): this {
|
|
46
|
+
this.clear(true);
|
|
47
|
+
$.context(Proto, this, () => this.layout?.(this));
|
|
48
|
+
if (children) forEach(this.protos, proto => {
|
|
49
|
+
proto.build()
|
|
50
|
+
});
|
|
51
|
+
return this
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
toString(): string {
|
|
55
|
+
return map(this.protos, proto => `${proto}`).join('')
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
toDOM(children = true): Node[] {
|
|
59
|
+
return children ? map(this.protos, proto => proto.toDOM(children)).flat() : [];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
dispose() {
|
|
63
|
+
forEach(this.disposers, disposer => disposer());
|
|
64
|
+
forEach(this.protos, proto => proto.dispose());
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
removeNode() {
|
|
68
|
+
forEach(this.protos, proto => proto.removeNode());
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
clear(dispose = false) {
|
|
72
|
+
this.protos.clear();
|
|
73
|
+
if (dispose) forEach(this.protos, proto => proto.dispose())
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
findAbove<T>(filter: (proto: Proto) => boolean | T | void | null): T | null {
|
|
77
|
+
let parent = this.parent;
|
|
78
|
+
if (parent) return filter(parent) ? parent as T : parent.findAbove(filter);
|
|
79
|
+
return _null;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
findBelow(filter: (proto: Proto) => boolean | void): Proto | null {
|
|
83
|
+
for (let proto of this.protos) {
|
|
84
|
+
if (filter(proto)) return proto;
|
|
85
|
+
let nested = proto.findBelow(filter);
|
|
86
|
+
if (nested) return nested;
|
|
87
|
+
}
|
|
88
|
+
return _null;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { onclient } from "#env";
|
|
2
|
+
import { forEach } from "@amateras/utils";
|
|
3
|
+
import { NodeProto } from "./NodeProto";
|
|
4
|
+
|
|
5
|
+
export class ProxyProto extends NodeProto<Text> {
|
|
6
|
+
declare node: Text | null
|
|
7
|
+
constructor(layout?: $.Layout) {
|
|
8
|
+
super(layout);
|
|
9
|
+
if (onclient()) this.node = new Text();
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
override toDOM(): Node[] {
|
|
13
|
+
return [this.node!, ...super.toDOM()]
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
override removeNode(): void {
|
|
17
|
+
super.removeNode();
|
|
18
|
+
forEach(this.protos, proto => proto.removeNode())
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { forEach } from "@amateras/utils";
|
|
2
|
+
import { NodeProto } from "./NodeProto";
|
|
3
|
+
|
|
4
|
+
export class TextProto extends NodeProto<Text> {
|
|
5
|
+
content: string;
|
|
6
|
+
constructor(content: string) {
|
|
7
|
+
super();
|
|
8
|
+
this.content = content;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
override toString(): string {
|
|
12
|
+
return this.content;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
override toDOM(): Text[] {
|
|
16
|
+
if (this.node) return [this.node];
|
|
17
|
+
let node = new Text(this.content);
|
|
18
|
+
this.node = node;
|
|
19
|
+
forEach(this.modifiers, mod => mod(node));
|
|
20
|
+
return [node];
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { forEach } from "@amateras/utils";
|
|
2
|
+
|
|
3
|
+
export class WidgetEvent {
|
|
4
|
+
name: string;
|
|
5
|
+
subs = new Set<() => void>();
|
|
6
|
+
constructor(name: string) {
|
|
7
|
+
this.name = name;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
emit() {
|
|
11
|
+
forEach(this.subs, sub => sub())
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
listen(sub: () => void) {
|
|
15
|
+
this.subs.add(sub);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# amateras/css
|
|
2
|
+
|
|
3
|
+
## Usage
|
|
4
|
+
```ts
|
|
5
|
+
import 'amateras';
|
|
6
|
+
import 'amateras/css';
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Define Style
|
|
10
|
+
```ts
|
|
11
|
+
const style = $.css({
|
|
12
|
+
backgroundColor: 'black',
|
|
13
|
+
margin: 0,
|
|
14
|
+
|
|
15
|
+
'p': {
|
|
16
|
+
color: 'blue'
|
|
17
|
+
|
|
18
|
+
'@media (max-width: 800px)': {
|
|
19
|
+
color: 'red'
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
$(document.body).css(style).content([
|
|
25
|
+
$('p').content('Text with blue color.')
|
|
26
|
+
]);
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Define Style in Method Chain
|
|
30
|
+
```ts
|
|
31
|
+
$(document.body).content([
|
|
32
|
+
$('h1').css({ color: 'red' }).content('This is a title with red color!')
|
|
33
|
+
])
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Define Variables
|
|
37
|
+
|
|
38
|
+
### Single Variable
|
|
39
|
+
```ts
|
|
40
|
+
const largeText = $.css.variables('1.2rem');
|
|
41
|
+
|
|
42
|
+
$.css({
|
|
43
|
+
fontSize: largeText
|
|
44
|
+
})
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Variable Group
|
|
48
|
+
```ts
|
|
49
|
+
const text = $.css.variables({
|
|
50
|
+
small: '0.8rem',
|
|
51
|
+
medium: '1rem',
|
|
52
|
+
large: '1.2rem'
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
$.css({
|
|
56
|
+
fontSize: text.large
|
|
57
|
+
})
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Define Keyframes
|
|
61
|
+
```ts
|
|
62
|
+
const keyframes = $.css.keyframes({
|
|
63
|
+
fadeIn: {
|
|
64
|
+
'0%': { opacity: 0 },
|
|
65
|
+
'100%': { opacity: 1 }
|
|
66
|
+
},
|
|
67
|
+
fadeOut: {
|
|
68
|
+
from: { opacity: 1 },
|
|
69
|
+
to: { opacity: 0 }
|
|
70
|
+
}
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
$.css({
|
|
74
|
+
animation: keyframes.fadeIn
|
|
75
|
+
})
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Define CSS Rules with Selectors
|
|
79
|
+
```ts
|
|
80
|
+
$.CSS({
|
|
81
|
+
'html': {
|
|
82
|
+
fontSize: '18px',
|
|
83
|
+
fontFamily: 'Noto Sans',
|
|
84
|
+
|
|
85
|
+
'body': {
|
|
86
|
+
margin: 0,
|
|
87
|
+
|
|
88
|
+
'.title': {
|
|
89
|
+
color: 'red'
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
'@media (max-width: 800px)': {
|
|
95
|
+
'html': {
|
|
96
|
+
fontSize: '1rem',
|
|
97
|
+
|
|
98
|
+
'@media (orientation: landscape)': {
|
|
99
|
+
fontSize: '1.2rem'
|
|
100
|
+
},
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
$(document.body).content([
|
|
106
|
+
$('h1').class('title').content('A red color title.')
|
|
107
|
+
])
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### CSS Colors Preset
|
|
112
|
+
You can import colors preset from `amateras/color/COLOR_NAME` or `amateras/colors` path. These colors are reference from Tailwind colors, read the [documentation](https://tailwindcss.com/docs/colors) to know about the concepts.
|
|
113
|
+
```ts
|
|
114
|
+
// import black and white color preset
|
|
115
|
+
import 'amateras/color/blackwhite';
|
|
116
|
+
$.color.black; // '#000000'
|
|
117
|
+
$.color.white; // '#ffffff'
|
|
118
|
+
|
|
119
|
+
// import slate colors preset
|
|
120
|
+
import 'amateras/color/slate';
|
|
121
|
+
$.color.slate[100]; // '#f1f5f9'
|
|
122
|
+
$.color.slate[200]; // '#e2e8f0'
|
|
123
|
+
|
|
124
|
+
// import all colors preset
|
|
125
|
+
import 'amateras/colors';
|
|
126
|
+
$.color.red[600]; // '#dc2626'
|
|
127
|
+
$.color.zinc[500]; // '#71717a'
|
|
128
|
+
```
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@amateras/css",
|
|
3
|
+
"peerDependencies": {
|
|
4
|
+
"@amateras/core": "workspace:*",
|
|
5
|
+
"@amateras/utils": "workspace:*"
|
|
6
|
+
},
|
|
7
|
+
"imports": {
|
|
8
|
+
"#structure/*": "./src/structure/*.ts",
|
|
9
|
+
"#lib/*": "./src/lib/*.ts",
|
|
10
|
+
"#node/*": "./src/node/*.ts"
|
|
11
|
+
},
|
|
12
|
+
"exports": {
|
|
13
|
+
".": "./src/index.ts"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { colorAssign } from "../../lib/colorAssign";
|
|
2
|
+
|
|
3
|
+
const _amber = {
|
|
4
|
+
50: '#fffbeb',
|
|
5
|
+
100: '#fef3c7',
|
|
6
|
+
200: '#fde68a',
|
|
7
|
+
300: '#fcd34d',
|
|
8
|
+
400: '#fbbf24',
|
|
9
|
+
500: '#f59e0b',
|
|
10
|
+
600: '#d97706',
|
|
11
|
+
700: '#b45309',
|
|
12
|
+
800: '#92400e',
|
|
13
|
+
900: '#78350f',
|
|
14
|
+
950: '#451a03',
|
|
15
|
+
} as const;
|
|
16
|
+
|
|
17
|
+
colorAssign('amber', _amber);
|
|
18
|
+
|
|
19
|
+
declare global {
|
|
20
|
+
export namespace $ {
|
|
21
|
+
export namespace color {
|
|
22
|
+
export const amber: typeof _amber;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { colorAssign } from "../../lib/colorAssign";
|
|
2
|
+
|
|
3
|
+
colorAssign('black', '#000000');
|
|
4
|
+
colorAssign('white', '#ffffff');
|
|
5
|
+
|
|
6
|
+
declare global {
|
|
7
|
+
export namespace $ {
|
|
8
|
+
export namespace color {
|
|
9
|
+
export const black: '#000000';
|
|
10
|
+
export const white: '#ffffff';
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { colorAssign } from "../../lib/colorAssign";
|
|
2
|
+
|
|
3
|
+
const _blue = {
|
|
4
|
+
50: '#eff6ff',
|
|
5
|
+
100: '#dbeafe',
|
|
6
|
+
200: '#bfdbfe',
|
|
7
|
+
300: '#93c5fd',
|
|
8
|
+
400: '#60a5fa',
|
|
9
|
+
500: '#3b82f6',
|
|
10
|
+
600: '#2563eb',
|
|
11
|
+
700: '#1d4ed8',
|
|
12
|
+
800: '#1e40af',
|
|
13
|
+
900: '#1e3a8a',
|
|
14
|
+
950: '#172554',
|
|
15
|
+
} as const;
|
|
16
|
+
|
|
17
|
+
colorAssign('blue', _blue);
|
|
18
|
+
|
|
19
|
+
declare global {
|
|
20
|
+
export namespace $ {
|
|
21
|
+
export namespace color {
|
|
22
|
+
export const blue: typeof _blue;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { colorAssign } from "../../lib/colorAssign";
|
|
2
|
+
|
|
3
|
+
const _cyan = {
|
|
4
|
+
50: '#ecfeff',
|
|
5
|
+
100: '#cffafe',
|
|
6
|
+
200: '#a5f3fc',
|
|
7
|
+
300: '#67e8f9',
|
|
8
|
+
400: '#22d3ee',
|
|
9
|
+
500: '#06b6d4',
|
|
10
|
+
600: '#0891b2',
|
|
11
|
+
700: '#0e7490',
|
|
12
|
+
800: '#155e75',
|
|
13
|
+
900: '#164e63',
|
|
14
|
+
950: '#083344',
|
|
15
|
+
} as const;
|
|
16
|
+
|
|
17
|
+
colorAssign('cyan', _cyan);
|
|
18
|
+
|
|
19
|
+
declare global {
|
|
20
|
+
export namespace $ {
|
|
21
|
+
export namespace color {
|
|
22
|
+
export const cyan: typeof _cyan;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { colorAssign } from "../../lib/colorAssign";
|
|
2
|
+
|
|
3
|
+
const _emerald = {
|
|
4
|
+
50: '#ecfdf5',
|
|
5
|
+
100: '#d1fae5',
|
|
6
|
+
200: '#a7f3d0',
|
|
7
|
+
300: '#6ee7b7',
|
|
8
|
+
400: '#34d399',
|
|
9
|
+
500: '#10b981',
|
|
10
|
+
600: '#059669',
|
|
11
|
+
700: '#047857',
|
|
12
|
+
800: '#065f46',
|
|
13
|
+
900: '#064e3b',
|
|
14
|
+
950: '#022c22',
|
|
15
|
+
} as const;
|
|
16
|
+
|
|
17
|
+
colorAssign('emerald', _emerald);
|
|
18
|
+
|
|
19
|
+
declare global {
|
|
20
|
+
export namespace $ {
|
|
21
|
+
export namespace color {
|
|
22
|
+
export const emerald: typeof _emerald;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|