@mantou/gem 1.7.12 → 2.0.0-alpha.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/LICENSE +21 -0
- package/README.md +1 -1
- package/dist/gem.es.js +2010 -1765
- package/dist/gem.umd.js +52 -53
- package/elements/base/dialog.d.ts +0 -11
- package/elements/base/dialog.d.ts.map +1 -1
- package/elements/base/dialog.js +93 -66
- package/elements/base/dialog.js.map +1 -1
- package/elements/base/gesture.d.ts +1 -2
- package/elements/base/gesture.d.ts.map +1 -1
- package/elements/base/gesture.js +157 -96
- package/elements/base/gesture.js.map +1 -1
- package/elements/base/link.d.ts +5 -5
- package/elements/base/link.d.ts.map +1 -1
- package/elements/base/link.js +249 -145
- package/elements/base/link.js.map +1 -1
- package/elements/base/modal-factory.d.ts +145 -139
- package/elements/base/modal-factory.d.ts.map +1 -1
- package/elements/base/modal-factory.js +84 -25
- package/elements/base/modal-factory.js.map +1 -1
- package/elements/base/reflect.d.ts +0 -1
- package/elements/base/reflect.d.ts.map +1 -1
- package/elements/base/reflect.js +83 -38
- package/elements/base/reflect.js.map +1 -1
- package/elements/base/route.d.ts +12 -24
- package/elements/base/route.d.ts.map +1 -1
- package/elements/base/route.js +263 -164
- package/elements/base/route.js.map +1 -1
- package/elements/base/title.d.ts +3 -11
- package/elements/base/title.d.ts.map +1 -1
- package/elements/base/title.js +110 -59
- package/elements/base/title.js.map +1 -1
- package/elements/base/unsafe.d.ts +0 -1
- package/elements/base/unsafe.d.ts.map +1 -1
- package/elements/base/unsafe.js +82 -33
- package/elements/base/unsafe.js.map +1 -1
- package/elements/base/use.d.ts.map +1 -1
- package/elements/base/use.js +95 -47
- package/elements/base/use.js.map +1 -1
- package/helper/i18n.d.ts +4 -9
- package/helper/i18n.d.ts.map +1 -1
- package/helper/i18n.js +69 -65
- package/helper/i18n.js.map +1 -1
- package/helper/logger.js +10 -9
- package/helper/logger.js.map +1 -1
- package/helper/react-shim.d.ts +15 -0
- package/helper/react-shim.d.ts.map +1 -0
- package/helper/react-shim.js +56 -0
- package/helper/react-shim.js.map +1 -0
- package/helper/react-utils.d.ts +15 -0
- package/helper/react-utils.d.ts.map +1 -0
- package/helper/react-utils.js +50 -0
- package/helper/react-utils.js.map +1 -0
- package/helper/request.d.ts +4 -4
- package/helper/request.d.ts.map +1 -1
- package/helper/request.js +1 -1
- package/helper/request.js.map +1 -1
- package/helper/ssr-shim.d.ts.map +1 -1
- package/helper/ssr-shim.js +8 -1
- package/helper/ssr-shim.js.map +1 -1
- package/helper/theme.d.ts +14 -21
- package/helper/theme.d.ts.map +1 -1
- package/helper/theme.js +55 -38
- package/helper/theme.js.map +1 -1
- package/index.d.ts +4 -3
- package/index.d.ts.map +1 -1
- package/index.js +5 -3
- package/index.js.map +1 -1
- package/lib/decorators.d.ts +74 -42
- package/lib/decorators.d.ts.map +1 -1
- package/lib/decorators.js +324 -84
- package/lib/decorators.js.map +1 -1
- package/lib/directives.d.ts +4 -0
- package/lib/directives.d.ts.map +1 -0
- package/lib/directives.js +5 -0
- package/lib/directives.js.map +1 -0
- package/lib/element.d.ts +112 -110
- package/lib/element.d.ts.map +1 -1
- package/lib/element.js +431 -468
- package/lib/element.js.map +1 -1
- package/lib/history.d.ts +4 -0
- package/lib/history.d.ts.map +1 -1
- package/lib/history.js +12 -13
- package/lib/history.js.map +1 -1
- package/lib/store.d.ts +1 -1
- package/lib/store.d.ts.map +1 -1
- package/lib/store.js +4 -5
- package/lib/store.js.map +1 -1
- package/lib/utils.d.ts +3 -43
- package/lib/utils.d.ts.map +1 -1
- package/lib/utils.js +61 -235
- package/lib/utils.js.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.d.ts.map +1 -1
- package/lib/version.js +2 -1
- package/lib/version.js.map +1 -1
- package/package.json +12 -11
- package/src/dist.ts +3 -2
- package/src/elements/base/dialog.ts +10 -20
- package/src/elements/base/gesture.ts +16 -14
- package/src/elements/base/link.ts +65 -44
- package/src/elements/base/modal-factory.ts +14 -14
- package/src/elements/base/reflect.ts +24 -32
- package/src/elements/base/route.ts +55 -68
- package/src/elements/base/title.ts +25 -42
- package/src/elements/base/unsafe.ts +12 -21
- package/src/elements/base/use.ts +17 -13
- package/src/helper/i18n.ts +20 -14
- package/src/helper/react-utils.ts +66 -0
- package/src/helper/ssr-shim.ts +8 -1
- package/src/helper/theme.ts +72 -45
- package/src/index.ts +6 -4
- package/src/lib/decorators.ts +394 -93
- package/src/lib/directives.ts +6 -0
- package/src/lib/element.ts +473 -500
- package/src/lib/history.ts +4 -3
- package/src/lib/store.ts +2 -1
- package/src/lib/utils.ts +12 -191
- package/src/lib/version.ts +2 -1
- package/src/test/elements/link.test.ts +1 -1
- package/src/test/elements/title.test.ts +1 -0
- package/src/test/gem-element/advance.test.ts +72 -49
- package/src/test/gem-element/basic.test.ts +37 -50
- package/src/test/gem-element/decorators.test.ts +22 -21
- package/src/test/gem-element/multi.test.ts +5 -5
- package/src/test/utils.test.ts +15 -45
|
@@ -1,36 +1,27 @@
|
|
|
1
1
|
import { GemElement } from '../../lib/element';
|
|
2
|
-
import { attribute } from '../../lib/decorators';
|
|
2
|
+
import { attribute, shadow } from '../../lib/decorators';
|
|
3
|
+
import { raw } from '../../lib/utils';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* @customElement gem-unsafe
|
|
6
7
|
* @attr content
|
|
7
8
|
* @attr contentcss
|
|
8
9
|
*/
|
|
10
|
+
@shadow()
|
|
9
11
|
export class GemUnsafeElement extends GemElement {
|
|
10
12
|
@attribute content: string;
|
|
11
13
|
@attribute contentcss: string;
|
|
12
14
|
|
|
13
|
-
constructor() {
|
|
14
|
-
super();
|
|
15
|
-
this.effect(
|
|
16
|
-
() => {
|
|
17
|
-
if (this.shadowRoot) {
|
|
18
|
-
this.shadowRoot.innerHTML = `
|
|
19
|
-
<style>
|
|
20
|
-
:host(:where(:not([hidden]))) {
|
|
21
|
-
display: contents;
|
|
22
|
-
}
|
|
23
|
-
${this.contentcss}
|
|
24
|
-
</style>
|
|
25
|
-
${this.content}
|
|
26
|
-
`;
|
|
27
|
-
}
|
|
28
|
-
},
|
|
29
|
-
() => [this.content, this.contentcss],
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
15
|
render() {
|
|
16
|
+
this.shadowRoot!.innerHTML = raw`
|
|
17
|
+
<style>
|
|
18
|
+
:host(:where(:not([hidden]))) {
|
|
19
|
+
display: contents;
|
|
20
|
+
}
|
|
21
|
+
${this.contentcss}
|
|
22
|
+
</style>
|
|
23
|
+
${this.content}
|
|
24
|
+
`;
|
|
34
25
|
return undefined;
|
|
35
26
|
}
|
|
36
27
|
}
|
package/src/elements/base/use.ts
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
|
-
import { GemElement, html } from '../../lib/element';
|
|
2
|
-
import { attribute, property, state } from '../../lib/decorators';
|
|
1
|
+
import { createCSSSheet, GemElement, html } from '../../lib/element';
|
|
2
|
+
import { adoptedStyle, attribute, property, shadow, state } from '../../lib/decorators';
|
|
3
|
+
import { css } from '../../lib/utils';
|
|
4
|
+
|
|
5
|
+
const styles = createCSSSheet(css`
|
|
6
|
+
:host(:where(:not([hidden]))) {
|
|
7
|
+
position: relative;
|
|
8
|
+
display: inline-flex;
|
|
9
|
+
align-items: center;
|
|
10
|
+
}
|
|
11
|
+
svg {
|
|
12
|
+
width: 100%;
|
|
13
|
+
height: 100%;
|
|
14
|
+
}
|
|
15
|
+
`);
|
|
3
16
|
|
|
4
17
|
const eleCache = new Map<string, HTMLTemplateElement>();
|
|
5
18
|
/**
|
|
@@ -11,6 +24,8 @@ const eleCache = new Map<string, HTMLTemplateElement>();
|
|
|
11
24
|
* @customElement gem-use
|
|
12
25
|
* @attr selector
|
|
13
26
|
*/
|
|
27
|
+
@shadow()
|
|
28
|
+
@adoptedStyle(styles)
|
|
14
29
|
export class GemUseElement extends GemElement {
|
|
15
30
|
@attribute selector: string; // CSS 选择器
|
|
16
31
|
@property root?: HTMLElement | Document | ShadowRoot;
|
|
@@ -37,17 +52,6 @@ export class GemUseElement extends GemElement {
|
|
|
37
52
|
|
|
38
53
|
render() {
|
|
39
54
|
return html`
|
|
40
|
-
<style>
|
|
41
|
-
:host(:where(:not([hidden]))) {
|
|
42
|
-
position: relative;
|
|
43
|
-
display: inline-flex;
|
|
44
|
-
align-items: center;
|
|
45
|
-
}
|
|
46
|
-
svg {
|
|
47
|
-
width: 100%;
|
|
48
|
-
height: 100%;
|
|
49
|
-
}
|
|
50
|
-
</style>
|
|
51
55
|
${this.#getContent()}
|
|
52
56
|
<slot></slot>
|
|
53
57
|
`;
|
package/src/helper/i18n.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import type { UpdateHistoryParams } from '../lib/history';
|
|
2
|
+
import type { TemplateResult } from '../lib/element';
|
|
3
|
+
import { html, UpdateToken } from '../lib/element';
|
|
3
4
|
import { GemError } from '../lib/utils';
|
|
4
5
|
import type { RouteTrigger } from '../elements/base/route';
|
|
5
6
|
|
|
@@ -72,10 +73,8 @@ export class I18n<T = Record<string, Msg>> implements RouteTrigger {
|
|
|
72
73
|
urlParamsName?: string;
|
|
73
74
|
onChange?: (currentLanguage: string) => void;
|
|
74
75
|
|
|
75
|
-
store: Store<any>;
|
|
76
|
-
|
|
77
76
|
// 兼容 `<gem-route>`
|
|
78
|
-
replace = ({ path }:
|
|
77
|
+
replace = ({ path }: UpdateHistoryParams) => this.setLanguage(path!);
|
|
79
78
|
getParams = () => ({ path: this.currentLanguage });
|
|
80
79
|
|
|
81
80
|
get #cacheCurrentKey() {
|
|
@@ -119,7 +118,6 @@ export class I18n<T = Record<string, Msg>> implements RouteTrigger {
|
|
|
119
118
|
throw new GemError('i18n: fallbackLanguage invalid');
|
|
120
119
|
}
|
|
121
120
|
|
|
122
|
-
this.store = createStore(this as any);
|
|
123
121
|
Object.assign<I18n<T>, I18nOptions<T>>(this as I18n<T>, options);
|
|
124
122
|
|
|
125
123
|
let currentLanguage = this.#urlParamsLang || this.currentLanguage || this.#cacheLang;
|
|
@@ -144,8 +142,8 @@ export class I18n<T = Record<string, Msg>> implements RouteTrigger {
|
|
|
144
142
|
}
|
|
145
143
|
|
|
146
144
|
get(s: keyof T): string;
|
|
147
|
-
get(s: keyof T, ...rest: (((
|
|
148
|
-
get(s: keyof T, ...rest: (((
|
|
145
|
+
get(s: keyof T, ...rest: (((str: string) => TemplateResult) | string)[]): TemplateResult;
|
|
146
|
+
get(s: keyof T, ...rest: (((str: string) => TemplateResult) | string)[]) {
|
|
149
147
|
const currentLanguagePack = this.resources[this.currentLanguage] as any;
|
|
150
148
|
const fallbackLanguagePack = this.resources[this.fallbackLanguage] as any;
|
|
151
149
|
const msg = currentLanguagePack[s] || fallbackLanguagePack[s];
|
|
@@ -181,7 +179,7 @@ export class I18n<T = Record<string, Msg>> implements RouteTrigger {
|
|
|
181
179
|
const localPackString = localStorage.getItem(localKey);
|
|
182
180
|
|
|
183
181
|
const fetchPack = async () => {
|
|
184
|
-
const
|
|
182
|
+
const pkg = await (await fetch(data)).json();
|
|
185
183
|
if (this.cache) {
|
|
186
184
|
// 移除之前的版本缓存
|
|
187
185
|
for (let i = 0; i < localStorage.length; i++) {
|
|
@@ -190,9 +188,9 @@ export class I18n<T = Record<string, Msg>> implements RouteTrigger {
|
|
|
190
188
|
localStorage.removeItem(key);
|
|
191
189
|
}
|
|
192
190
|
}
|
|
193
|
-
localStorage.setItem(localKey, JSON.stringify(
|
|
191
|
+
localStorage.setItem(localKey, JSON.stringify(pkg));
|
|
194
192
|
}
|
|
195
|
-
return
|
|
193
|
+
return pkg;
|
|
196
194
|
};
|
|
197
195
|
|
|
198
196
|
if (localPackString) {
|
|
@@ -208,7 +206,17 @@ export class I18n<T = Record<string, Msg>> implements RouteTrigger {
|
|
|
208
206
|
pack = data;
|
|
209
207
|
}
|
|
210
208
|
this.resources[lang] = pack;
|
|
211
|
-
|
|
209
|
+
|
|
210
|
+
// update all element
|
|
211
|
+
const temp: Element[] = [document.documentElement];
|
|
212
|
+
while (!!temp.length) {
|
|
213
|
+
const element = temp.pop()!;
|
|
214
|
+
(element as any)[UpdateToken]?.();
|
|
215
|
+
if (element.shadowRoot?.firstElementChild) temp.push(element.shadowRoot.firstElementChild);
|
|
216
|
+
if (element.firstElementChild) temp.push(element.firstElementChild);
|
|
217
|
+
if (element.nextElementSibling) temp.push(element.nextElementSibling);
|
|
218
|
+
}
|
|
219
|
+
|
|
212
220
|
if (lang !== this.currentLanguage) {
|
|
213
221
|
this.#lang = lang;
|
|
214
222
|
}
|
|
@@ -251,8 +259,6 @@ export class I18n<T = Record<string, Msg>> implements RouteTrigger {
|
|
|
251
259
|
}
|
|
252
260
|
|
|
253
261
|
/**
|
|
254
|
-
* prepare: @connectStore(i18n.store)
|
|
255
|
-
*
|
|
256
262
|
* @example
|
|
257
263
|
*
|
|
258
264
|
* html`
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
2
|
+
// @ts-ignore
|
|
3
|
+
// eslint-disable-next-line import/no-unresolved, import/no-extraneous-dependencies
|
|
4
|
+
import type { ReactNode } from 'react';
|
|
5
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
6
|
+
// @ts-ignore
|
|
7
|
+
// eslint-disable-next-line import/no-unresolved, import/no-extraneous-dependencies
|
|
8
|
+
import { useEffect, useRef, useState } from 'react';
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
10
|
+
// @ts-ignore
|
|
11
|
+
// eslint-disable-next-line import/no-unresolved, import/no-extraneous-dependencies
|
|
12
|
+
import type { Root } from 'react-dom/client';
|
|
13
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
14
|
+
// @ts-ignore
|
|
15
|
+
// eslint-disable-next-line import/no-unresolved, import/no-extraneous-dependencies
|
|
16
|
+
import { createRoot } from 'react-dom/client';
|
|
17
|
+
|
|
18
|
+
import type { Store } from '../lib/store';
|
|
19
|
+
import { connect } from '../lib/store';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* `<gem-route>.routes.getContent`
|
|
23
|
+
*/
|
|
24
|
+
export function renderReactNode(ele: any, node: ReactNode) {
|
|
25
|
+
ele.react?.unmount();
|
|
26
|
+
ele.react = createRoot(ele);
|
|
27
|
+
// async
|
|
28
|
+
ele.react.render(node);
|
|
29
|
+
|
|
30
|
+
const routeEle = ele instanceof HTMLElement ? ele : ele.host;
|
|
31
|
+
if (!routeEle.reactCallback) {
|
|
32
|
+
routeEle.effect(
|
|
33
|
+
() => () => ele.react.unmount(),
|
|
34
|
+
() => [],
|
|
35
|
+
);
|
|
36
|
+
routeEle.reactCallback = true;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Same as `@connectStore`
|
|
42
|
+
*/
|
|
43
|
+
export function connectStore<T extends object>(store: Store<T>) {
|
|
44
|
+
const [_, update] = useState({});
|
|
45
|
+
useEffect(() => connect(store, () => update({})), []);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Warning: https://github.com/facebook/react/issues/25675
|
|
50
|
+
*/
|
|
51
|
+
export function useReactNode(node: ReactNode) {
|
|
52
|
+
const ref = useRef<{ root: Root; container: HTMLElement }>();
|
|
53
|
+
// Warning: Attempted to synchronously unmount a root while React was already rendering. React cannot finish unmounting the root until the current render has completed, which may lead to a race condition.
|
|
54
|
+
useEffect(() => () => ref.current?.root.unmount(), []);
|
|
55
|
+
if (ref.current) {
|
|
56
|
+
ref.current.root.render(node);
|
|
57
|
+
return ref.current.container;
|
|
58
|
+
}
|
|
59
|
+
const container = document.createElement('div');
|
|
60
|
+
container.style.display = 'contents';
|
|
61
|
+
const root = createRoot(container);
|
|
62
|
+
ref.current = { root, container };
|
|
63
|
+
// Warning: Render methods should be a pure function of props and state; triggering nested component updates from render is not allowed. If necessary, trigger nested updates in componentDidUpdate.
|
|
64
|
+
root.render(node);
|
|
65
|
+
return container;
|
|
66
|
+
}
|
package/src/helper/ssr-shim.ts
CHANGED
|
@@ -26,7 +26,6 @@ if (typeof window === 'undefined') {
|
|
|
26
26
|
globalThis.document = any;
|
|
27
27
|
globalThis.addEventListener = any;
|
|
28
28
|
globalThis.history = any;
|
|
29
|
-
globalThis.navigator = any;
|
|
30
29
|
globalThis.customElements = any;
|
|
31
30
|
|
|
32
31
|
// duoyun-ui
|
|
@@ -34,6 +33,14 @@ if (typeof window === 'undefined') {
|
|
|
34
33
|
globalThis.Document = any;
|
|
35
34
|
globalThis.Element = any;
|
|
36
35
|
globalThis.MutationObserver = any;
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
// gem dist i18n
|
|
39
|
+
// https://nodejs.org/api/globals.html#navigator_1
|
|
40
|
+
globalThis.navigator = any;
|
|
41
|
+
} catch {
|
|
42
|
+
//
|
|
43
|
+
}
|
|
37
44
|
}
|
|
38
45
|
|
|
39
46
|
export {};
|
package/src/helper/theme.ts
CHANGED
|
@@ -1,71 +1,98 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { Store } from '../lib/store';
|
|
2
|
+
import { connect, useStore } from '../lib/store';
|
|
2
3
|
import { camelToKebabCase, randomStr } from '../lib/utils';
|
|
4
|
+
import type { GemElement } from '../lib/element';
|
|
5
|
+
import { SheetToken, createCSSSheet } from '../lib/element';
|
|
3
6
|
|
|
4
|
-
type
|
|
5
|
-
[
|
|
7
|
+
export type Theme<T> = ReturnType<typeof createCSSSheet> & {
|
|
8
|
+
[K in keyof T as K extends `${string}Color`
|
|
9
|
+
? `${string & K}${'' | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900}`
|
|
10
|
+
: K]: T[K];
|
|
6
11
|
};
|
|
7
12
|
|
|
8
13
|
const themeStoreMap = new WeakMap();
|
|
14
|
+
const themePropsMap = new WeakMap();
|
|
9
15
|
|
|
10
16
|
/**获取主题原始值 */
|
|
11
|
-
export function getThemeStore<T>(theme:
|
|
17
|
+
export function getThemeStore<T>(theme: Theme<T>) {
|
|
12
18
|
return themeStoreMap.get(theme) as Store<T>;
|
|
13
19
|
}
|
|
14
20
|
|
|
15
|
-
const themePropsMap = new WeakMap();
|
|
16
|
-
|
|
17
21
|
/**获取 css 变量名 */
|
|
18
|
-
export function getThemeProps<T>(theme:
|
|
19
|
-
return themePropsMap.get(theme) as
|
|
22
|
+
export function getThemeProps<T>(theme: Theme<T>) {
|
|
23
|
+
return themePropsMap.get(theme) as Theme<T>;
|
|
20
24
|
}
|
|
21
25
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* 创建主题,插入 `document.head`
|
|
26
|
-
* https://github.com/mantou132/gem/issues/33
|
|
27
|
-
*
|
|
28
|
-
* @example
|
|
29
|
-
* createTheme({
|
|
30
|
-
* primaryColor: '#eee',
|
|
31
|
-
* });
|
|
32
|
-
*/
|
|
33
|
-
export function createTheme<T extends Record<string, unknown>>(themeObj: T) {
|
|
26
|
+
function useThemeFromProps<T extends Record<string, unknown>>(themeObj: T, props: Record<string, string> = {}) {
|
|
34
27
|
const salt = randomStr();
|
|
35
|
-
const
|
|
36
|
-
const store =
|
|
37
|
-
const theme:
|
|
38
|
-
|
|
28
|
+
const styleSheet = createCSSSheet({})[SheetToken];
|
|
29
|
+
const [store, updateStore] = useStore<T>(themeObj);
|
|
30
|
+
const theme: any = new Proxy(
|
|
31
|
+
{ [SheetToken]: styleSheet },
|
|
32
|
+
{
|
|
33
|
+
get(target: any, key: string) {
|
|
34
|
+
if (!target[key]) {
|
|
35
|
+
const [_, origin, weight] = key.match(/^(\w*Color)(\d+)$/) || [];
|
|
36
|
+
if (origin) target[key] = `oklch(from ${target[origin]} calc(l - ${(Number(weight) - 400) / 1000}) c h)`;
|
|
37
|
+
}
|
|
38
|
+
return target[key];
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
);
|
|
39
42
|
themePropsMap.set(theme, props);
|
|
40
43
|
themeStoreMap.set(theme, store);
|
|
41
|
-
|
|
44
|
+
|
|
45
|
+
const updateContent = () => {
|
|
46
|
+
let rules = '';
|
|
42
47
|
Object.keys(store).forEach((key) => {
|
|
43
|
-
if (props[key])
|
|
44
|
-
|
|
45
|
-
|
|
48
|
+
if (!props[key]) {
|
|
49
|
+
props[key] = `--${camelToKebabCase(key)}-${salt}`;
|
|
50
|
+
theme[key] = `var(${props[key]})`;
|
|
51
|
+
}
|
|
52
|
+
rules += `${props[key]}:${store[key]};`;
|
|
46
53
|
});
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
return theme as SomeType<T>;
|
|
54
|
+
styleSheet.setContent(`:scope,:host{${rules}}`);
|
|
55
|
+
};
|
|
56
|
+
updateContent();
|
|
57
|
+
connect(store, () => {
|
|
58
|
+
updateContent();
|
|
59
|
+
styleSheet.updateStyle();
|
|
60
|
+
});
|
|
61
|
+
return [theme as Theme<T>, updateStore] as const;
|
|
56
62
|
}
|
|
57
63
|
|
|
58
64
|
/**
|
|
59
|
-
*
|
|
60
|
-
* @param theme 主题
|
|
61
|
-
* @param newThemeObj 新主题
|
|
65
|
+
* 用于 `@adoptedStyle(theme)`,类似 `createCSSSheet`
|
|
62
66
|
*/
|
|
63
|
-
export function
|
|
64
|
-
|
|
65
|
-
setThemeFnMap.get(theme)();
|
|
67
|
+
export function useScopedTheme<T extends Record<string, unknown>>(themeObj: T) {
|
|
68
|
+
return useThemeFromProps(themeObj);
|
|
66
69
|
}
|
|
67
70
|
|
|
71
|
+
/**全局主题 */
|
|
68
72
|
export function useTheme<T extends Record<string, unknown>>(themeObj: T) {
|
|
69
|
-
const
|
|
70
|
-
|
|
73
|
+
const result = useScopedTheme(themeObj);
|
|
74
|
+
document.adoptedStyleSheets.push(result[0][SheetToken].getStyle());
|
|
75
|
+
return result;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**用来覆盖全局主题 */
|
|
79
|
+
export function useOverrideTheme<T extends Record<string, unknown>>(theme: Theme<T>, themeObj: Partial<T>) {
|
|
80
|
+
return useThemeFromProps(themeObj, getThemeProps(theme));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function useDecoratorTheme<T extends Record<string, unknown>>(themeObj: T) {
|
|
84
|
+
const [themeAsKeys] = useThemeFromProps(themeObj);
|
|
85
|
+
const props = getThemeProps(themeAsKeys);
|
|
86
|
+
const updateDecorator =
|
|
87
|
+
<E extends GemElement, V extends () => T, K = any[] | undefined>(
|
|
88
|
+
getDep?: K extends readonly any[] ? (instance: E) => K : undefined,
|
|
89
|
+
) =>
|
|
90
|
+
(_: any, { addInitializer, access }: ClassFieldDecoratorContext<E, V> | ClassMethodDecoratorContext<E, V>) => {
|
|
91
|
+
addInitializer(function (this: E) {
|
|
92
|
+
const [theme, update] = useThemeFromProps({ ...themeObj }, props);
|
|
93
|
+
this.internals.sheets.push(theme[SheetToken].getStyle(this));
|
|
94
|
+
this.memo(() => update(access.get(this).apply(this)), getDep && (() => getDep(this) as any));
|
|
95
|
+
});
|
|
96
|
+
};
|
|
97
|
+
return [themeAsKeys, updateDecorator] as const;
|
|
71
98
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
export * from './lib/store';
|
|
2
|
-
export * from './lib/history';
|
|
3
|
-
export * from './lib/element';
|
|
4
1
|
export * from './lib/decorators';
|
|
2
|
+
export * from './lib/element';
|
|
3
|
+
export * from './lib/store';
|
|
5
4
|
export * from './lib/utils';
|
|
6
|
-
|
|
7
5
|
export * from './lib/version';
|
|
6
|
+
|
|
7
|
+
// 使用路径时可选模块
|
|
8
|
+
export * from './lib/history';
|
|
9
|
+
export * from './lib/directives';
|