amateras 0.10.1 → 0.10.2

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.
Files changed (174) hide show
  1. package/README.md +29 -25
  2. package/build/core.js +1 -0
  3. package/build/css.js +1 -0
  4. package/build/for.js +1 -0
  5. package/build/i18n.js +1 -0
  6. package/build/idb.js +1 -0
  7. package/build/if.js +1 -0
  8. package/build/import-map.js +1 -0
  9. package/build/markdown.js +1 -0
  10. package/build/match.js +1 -0
  11. package/build/meta.js +1 -0
  12. package/build/prefetch.js +1 -0
  13. package/build/router.js +1 -0
  14. package/build/signal.js +1 -0
  15. package/build/ui.js +1 -0
  16. package/build/widget.js +1 -0
  17. package/package.json +7 -5
  18. package/packages/core/package.json +19 -0
  19. package/packages/core/src/env.browser.ts +21 -0
  20. package/packages/core/src/env.node.ts +21 -0
  21. package/packages/core/src/global.ts +5 -0
  22. package/packages/core/src/index.ts +184 -0
  23. package/packages/core/src/lib/hmr.ts +145 -0
  24. package/packages/core/src/lib/symbols.ts +2 -0
  25. package/packages/core/src/structure/ElementProto.ts +95 -0
  26. package/packages/core/src/structure/GlobalState.ts +9 -0
  27. package/packages/core/src/structure/NodeProto.ts +18 -0
  28. package/packages/core/src/structure/Proto.ts +90 -0
  29. package/packages/core/src/structure/ProxyProto.ts +20 -0
  30. package/packages/core/src/structure/TextProto.ts +22 -0
  31. package/packages/core/src/structure/WidgetEvent.ts +17 -0
  32. package/packages/css/README.md +128 -0
  33. package/packages/css/package.json +15 -0
  34. package/packages/css/src/ext/colors/amber.ts +25 -0
  35. package/packages/css/src/ext/colors/blackwhite.ts +13 -0
  36. package/packages/css/src/ext/colors/blue.ts +25 -0
  37. package/packages/css/src/ext/colors/cyan.ts +25 -0
  38. package/packages/css/src/ext/colors/emerald.ts +25 -0
  39. package/packages/css/src/ext/colors/fuchsia.ts +25 -0
  40. package/packages/css/src/ext/colors/gray.ts +25 -0
  41. package/packages/css/src/ext/colors/green.ts +25 -0
  42. package/packages/css/src/ext/colors/indigo.ts +25 -0
  43. package/packages/css/src/ext/colors/lime.ts +25 -0
  44. package/packages/css/src/ext/colors/neutral.ts +25 -0
  45. package/packages/css/src/ext/colors/orange.ts +25 -0
  46. package/packages/css/src/ext/colors/pink.ts +25 -0
  47. package/packages/css/src/ext/colors/purple.ts +25 -0
  48. package/packages/css/src/ext/colors/red.ts +25 -0
  49. package/packages/css/src/ext/colors/rose.ts +25 -0
  50. package/packages/css/src/ext/colors/sky.ts +25 -0
  51. package/packages/css/src/ext/colors/slate.ts +25 -0
  52. package/packages/css/src/ext/colors/stone.ts +25 -0
  53. package/packages/css/src/ext/colors/teal.ts +25 -0
  54. package/packages/css/src/ext/colors/violet.ts +25 -0
  55. package/packages/css/src/ext/colors/yellow.ts +25 -0
  56. package/packages/css/src/ext/colors/zinc.ts +25 -0
  57. package/packages/css/src/ext/colors.ts +23 -0
  58. package/packages/css/src/ext/keyframes.ts +37 -0
  59. package/packages/css/src/ext/property.ts +68 -0
  60. package/packages/css/src/ext/variable.ts +51 -0
  61. package/packages/css/src/index.ts +103 -0
  62. package/packages/css/src/lib/cache.ts +27 -0
  63. package/packages/css/src/lib/colorAssign.ts +6 -0
  64. package/packages/css/src/lib/createRule.ts +31 -0
  65. package/packages/css/src/lib/utils.ts +1 -0
  66. package/packages/css/src/structure/$CSS.ts +4 -0
  67. package/packages/css/src/structure/$CSSKeyframes.ts +13 -0
  68. package/packages/css/src/structure/$CSSProperty.ts +21 -0
  69. package/packages/css/src/structure/$CSSRule.ts +39 -0
  70. package/packages/css/src/structure/$CSSVariable.ts +34 -0
  71. package/packages/css/src/types.ts +300 -0
  72. package/packages/for/package.json +15 -0
  73. package/packages/for/src/global.ts +7 -0
  74. package/packages/for/src/index.ts +15 -0
  75. package/packages/for/src/structure/For.ts +74 -0
  76. package/packages/hmr/package.json +13 -0
  77. package/packages/hmr/src/index.ts +27 -0
  78. package/packages/i18n/README.md +73 -0
  79. package/packages/i18n/package.json +15 -0
  80. package/packages/i18n/src/index.ts +78 -0
  81. package/packages/i18n/src/structure/I18n.ts +51 -0
  82. package/packages/i18n/src/structure/I18nDictionary.ts +31 -0
  83. package/packages/i18n/src/structure/I18nTranslation.ts +51 -0
  84. package/packages/i18n/src/types.ts +77 -0
  85. package/packages/idb/README.md +127 -0
  86. package/packages/idb/package.json +16 -0
  87. package/packages/idb/src/core.ts +6 -0
  88. package/packages/idb/src/index.ts +17 -0
  89. package/packages/idb/src/lib/$IDBRequest.ts +8 -0
  90. package/packages/idb/src/structure/$IDB.ts +63 -0
  91. package/packages/idb/src/structure/$IDBCursor.ts +34 -0
  92. package/packages/idb/src/structure/$IDBIndex.ts +48 -0
  93. package/packages/idb/src/structure/$IDBStore.ts +103 -0
  94. package/packages/idb/src/structure/$IDBStoreBase.ts +30 -0
  95. package/packages/idb/src/structure/$IDBTransaction.ts +38 -0
  96. package/packages/idb/src/structure/builder/$IDBBuilder.ts +229 -0
  97. package/packages/idb/src/structure/builder/$IDBStoreBuilder.ts +100 -0
  98. package/packages/if/package.json +15 -0
  99. package/packages/if/src/global.ts +15 -0
  100. package/packages/if/src/index.ts +51 -0
  101. package/packages/if/src/structure/Condition.ts +44 -0
  102. package/packages/if/src/structure/ConditionStatement.ts +25 -0
  103. package/packages/if/src/structure/Else.ts +6 -0
  104. package/packages/if/src/structure/ElseIf.ts +6 -0
  105. package/packages/if/src/structure/If.ts +6 -0
  106. package/packages/markdown/README.md +53 -0
  107. package/packages/markdown/package.json +15 -0
  108. package/packages/markdown/src/index.ts +3 -0
  109. package/packages/markdown/src/lib/type.ts +26 -0
  110. package/packages/markdown/src/lib/util.ts +21 -0
  111. package/packages/markdown/src/structure/Markdown.ts +57 -0
  112. package/packages/markdown/src/structure/MarkdownLexer.ts +111 -0
  113. package/packages/markdown/src/structure/MarkdownParser.ts +34 -0
  114. package/packages/markdown/src/syntax/alert.ts +46 -0
  115. package/packages/markdown/src/syntax/blockquote.ts +35 -0
  116. package/packages/markdown/src/syntax/bold.ts +11 -0
  117. package/packages/markdown/src/syntax/code.ts +11 -0
  118. package/packages/markdown/src/syntax/codeblock.ts +44 -0
  119. package/packages/markdown/src/syntax/heading.ts +14 -0
  120. package/packages/markdown/src/syntax/horizontalRule.ts +11 -0
  121. package/packages/markdown/src/syntax/image.ts +23 -0
  122. package/packages/markdown/src/syntax/italic.ts +11 -0
  123. package/packages/markdown/src/syntax/link.ts +46 -0
  124. package/packages/markdown/src/syntax/list.ts +121 -0
  125. package/packages/markdown/src/syntax/table.ts +67 -0
  126. package/packages/markdown/src/syntax/text.ts +19 -0
  127. package/packages/match/package.json +15 -0
  128. package/packages/match/src/global.ts +14 -0
  129. package/packages/match/src/index.ts +33 -0
  130. package/packages/match/src/structure/Case.ts +15 -0
  131. package/packages/match/src/structure/Default.ts +12 -0
  132. package/packages/match/src/structure/Match.ts +78 -0
  133. package/packages/meta/package.json +14 -0
  134. package/packages/meta/src/index.ts +36 -0
  135. package/packages/meta/src/lib/resolveMeta.ts +27 -0
  136. package/packages/meta/src/types.ts +36 -0
  137. package/packages/prefetch/package.json +14 -0
  138. package/packages/prefetch/src/index.ts +70 -0
  139. package/packages/router/README.md +18 -0
  140. package/packages/router/package.json +16 -0
  141. package/packages/router/src/global.ts +22 -0
  142. package/packages/router/src/index.ts +106 -0
  143. package/packages/router/src/structure/Link.ts +17 -0
  144. package/packages/router/src/structure/NavLink.ts +19 -0
  145. package/packages/router/src/structure/Page.ts +30 -0
  146. package/packages/router/src/structure/Route.ts +123 -0
  147. package/packages/router/src/structure/RouteGroup.ts +24 -0
  148. package/packages/router/src/structure/RouteNode.ts +54 -0
  149. package/packages/router/src/structure/RouteSlot.ts +34 -0
  150. package/packages/router/src/structure/Router.ts +192 -0
  151. package/packages/router/src/structure/RouterConstructor.ts +18 -0
  152. package/packages/router/src/types.ts +41 -0
  153. package/packages/signal/README.md +93 -0
  154. package/packages/signal/package.json +15 -0
  155. package/packages/signal/src/index.ts +97 -0
  156. package/packages/signal/src/lib/track.ts +18 -0
  157. package/packages/signal/src/structure/Signal.ts +59 -0
  158. package/packages/ui/package.json +14 -0
  159. package/packages/ui/src/index.ts +4 -0
  160. package/packages/ui/src/lib/slideshowAnimations.ts +39 -0
  161. package/packages/ui/src/structure/Radio.ts +77 -0
  162. package/packages/ui/src/structure/Slide.ts +11 -0
  163. package/packages/ui/src/structure/Slideshow.ts +99 -0
  164. package/packages/utils/package.json +18 -0
  165. package/packages/utils/src/global.ts +39 -0
  166. package/packages/utils/src/index.bun.ts +3 -0
  167. package/packages/utils/src/index.ts +2 -0
  168. package/packages/utils/src/lib/debugger.ts +14 -0
  169. package/packages/utils/src/lib/utils.ts +119 -0
  170. package/packages/utils/src/structure/UID.ts +18 -0
  171. package/packages/widget/README.md +29 -0
  172. package/packages/widget/package.json +14 -0
  173. package/packages/widget/src/index.ts +82 -0
  174. 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,2 @@
1
+ export const symbol_ProtoType = Symbol('ProtoType');
2
+ export const symbol_Statement = Symbol('Statement');
@@ -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,9 @@
1
+ import { forEach } from "@amateras/utils";
2
+
3
+ export class GlobalState {
4
+ static disposers = new Set<(global: GlobalState) => void>()
5
+
6
+ dispose() {
7
+ forEach(GlobalState.disposers, disposer => disposer(this))
8
+ }
9
+ }
@@ -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
+ }