@mantou/gem 1.6.8 → 1.6.12

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 (108) hide show
  1. package/dist/gem.es.js +3266 -0
  2. package/dist/gem.umd.js +229 -0
  3. package/elements/{dialog-base.d.ts → base/dialog.d.ts} +3 -3
  4. package/elements/base/dialog.d.ts.map +1 -0
  5. package/elements/{dialog-base.js → base/dialog.js} +24 -24
  6. package/elements/base/dialog.js.map +1 -0
  7. package/elements/base/gesture.d.ts +66 -0
  8. package/elements/base/gesture.d.ts.map +1 -0
  9. package/elements/base/gesture.js +214 -0
  10. package/elements/base/gesture.js.map +1 -0
  11. package/elements/base/link.d.ts +44 -0
  12. package/elements/base/link.d.ts.map +1 -0
  13. package/elements/base/link.js +206 -0
  14. package/elements/base/link.js.map +1 -0
  15. package/elements/{modal-base.d.ts → base/modal-factory.d.ts} +17 -8
  16. package/elements/base/modal-factory.d.ts.map +1 -0
  17. package/elements/{modal-base.js → base/modal-factory.js} +4 -4
  18. package/elements/base/modal-factory.js.map +1 -0
  19. package/elements/base/reflect.d.ts +6 -0
  20. package/elements/base/reflect.d.ts.map +1 -0
  21. package/elements/base/reflect.js +34 -0
  22. package/elements/base/reflect.js.map +1 -0
  23. package/elements/base/route.d.ts +78 -0
  24. package/elements/base/route.d.ts.map +1 -0
  25. package/elements/base/route.js +220 -0
  26. package/elements/base/route.js.map +1 -0
  27. package/elements/base/title.d.ts +30 -0
  28. package/elements/base/title.d.ts.map +1 -0
  29. package/elements/base/title.js +74 -0
  30. package/elements/base/title.js.map +1 -0
  31. package/elements/base/unsafe.d.ts +14 -0
  32. package/elements/base/unsafe.d.ts.map +1 -0
  33. package/elements/base/unsafe.js +42 -0
  34. package/elements/base/unsafe.js.map +1 -0
  35. package/elements/base/use.d.ts +19 -0
  36. package/elements/base/use.d.ts.map +1 -0
  37. package/elements/base/use.js +70 -0
  38. package/elements/base/use.js.map +1 -0
  39. package/elements/gesture.d.ts +1 -67
  40. package/elements/gesture.d.ts.map +1 -1
  41. package/elements/gesture.js +3 -219
  42. package/elements/gesture.js.map +1 -1
  43. package/elements/link.d.ts +1 -45
  44. package/elements/link.d.ts.map +1 -1
  45. package/elements/link.js +4 -208
  46. package/elements/link.js.map +1 -1
  47. package/elements/reflect.d.ts +1 -8
  48. package/elements/reflect.d.ts.map +1 -1
  49. package/elements/reflect.js +3 -39
  50. package/elements/reflect.js.map +1 -1
  51. package/elements/route.d.ts +1 -81
  52. package/elements/route.d.ts.map +1 -1
  53. package/elements/route.js +4 -228
  54. package/elements/route.js.map +1 -1
  55. package/elements/title.d.ts +1 -30
  56. package/elements/title.d.ts.map +1 -1
  57. package/elements/title.js +3 -75
  58. package/elements/title.js.map +1 -1
  59. package/elements/unsafe.d.ts +1 -14
  60. package/elements/unsafe.d.ts.map +1 -1
  61. package/elements/unsafe.js +3 -46
  62. package/elements/unsafe.js.map +1 -1
  63. package/elements/use.d.ts +1 -19
  64. package/elements/use.d.ts.map +1 -1
  65. package/elements/use.js +3 -74
  66. package/elements/use.js.map +1 -1
  67. package/lib/element.d.ts.map +1 -1
  68. package/lib/element.js +1 -1
  69. package/lib/element.js.map +1 -1
  70. package/lib/history.d.ts +28 -16
  71. package/lib/history.d.ts.map +1 -1
  72. package/lib/history.js +166 -168
  73. package/lib/history.js.map +1 -1
  74. package/lib/utils.d.ts +3 -1
  75. package/lib/utils.d.ts.map +1 -1
  76. package/lib/utils.js +16 -16
  77. package/lib/utils.js.map +1 -1
  78. package/package.json +9 -6
  79. package/src/{all.ts → dist.ts} +6 -3
  80. package/src/elements/{dialog-base.ts → base/dialog.ts} +4 -4
  81. package/src/elements/base/gesture.ts +256 -0
  82. package/src/elements/base/link.ts +178 -0
  83. package/src/elements/{modal-base.ts → base/modal-factory.ts} +3 -3
  84. package/src/elements/base/reflect.ts +30 -0
  85. package/src/elements/base/route.ts +244 -0
  86. package/src/elements/base/title.ts +68 -0
  87. package/src/elements/base/unsafe.ts +37 -0
  88. package/src/elements/base/use.ts +57 -0
  89. package/src/elements/gesture.ts +3 -257
  90. package/src/elements/link.ts +4 -179
  91. package/src/elements/reflect.ts +3 -31
  92. package/src/elements/route.ts +4 -248
  93. package/src/elements/title.ts +3 -68
  94. package/src/elements/unsafe.ts +3 -37
  95. package/src/elements/use.ts +3 -57
  96. package/src/lib/element.ts +3 -1
  97. package/src/lib/history.ts +182 -194
  98. package/src/lib/utils.ts +24 -16
  99. package/src/test/history.test.ts +15 -10
  100. package/src/test/utils.test.ts +6 -2
  101. package/all.d.ts +0 -14
  102. package/all.d.ts.map +0 -1
  103. package/all.js +0 -14
  104. package/all.js.map +0 -1
  105. package/elements/dialog-base.d.ts.map +0 -1
  106. package/elements/dialog-base.js.map +0 -1
  107. package/elements/modal-base.d.ts.map +0 -1
  108. package/elements/modal-base.js.map +0 -1
@@ -1,181 +1,6 @@
1
- import { GemElement, html, ifDefined } from '../lib/element';
2
- import { attribute, property, customElement, state, part, connectStore } from '../lib/decorators';
3
- import { history, basePathStore } from '../lib/history';
4
- import { absoluteLocation } from '../lib/utils';
1
+ import { GemLinkElement, GemActiveLinkElement } from './base/link';
5
2
 
6
- import { matchPath, RouteItem, RouteOptions, createHistoryParams, createPath } from './route';
3
+ export * from './base/link';
7
4
 
8
- /**
9
- * @customElement gem-link
10
- * @attr href
11
- * @attr target
12
- * @attr doc-title
13
- * @attr path
14
- * @attr query
15
- * @attr hash
16
- * @attr pattern
17
- * @attr hint
18
- * @part link
19
- *
20
- * print bug: https://github.com/mantou132/gem/issues/36
21
- */
22
- @customElement('gem-link')
23
- @connectStore(basePathStore)
24
- export class GemLinkElement extends GemElement {
25
- @attribute href: string;
26
- @attribute target: string;
27
- @attribute path: string;
28
- @attribute query: string;
29
- @attribute hash: string;
30
- @attribute docTitle: string;
31
- @attribute hint: 'on' | 'off';
32
-
33
- // 动态路由,根据 route.pattern 和 options.params 计算出 path
34
- @property route: RouteItem | undefined;
35
- @property options: RouteOptions | undefined;
36
- @property prepare: (() => void | Promise<void>) | undefined;
37
-
38
- @part link: string;
39
-
40
- constructor() {
41
- super();
42
- this.addEventListener('click', this.clickHandle);
43
- }
44
-
45
- // 不包含 basePath
46
- getPathInfo() {
47
- if (this.route) {
48
- const queryProp = this.options?.query || '';
49
- const hashProp = this.options?.hash || '';
50
- return createPath(this.route, this.options) + queryProp + hashProp;
51
- } else {
52
- const url = this.href || this.path + this.query + this.hash;
53
- const { path, query } = history.getParams();
54
- if (url.startsWith('#')) {
55
- return `${path}${query}${url}`;
56
- } else if (url.startsWith('?')) {
57
- return `${path}${url}`;
58
- } else if (url.startsWith('.')) {
59
- return absoluteLocation(path, url);
60
- } else {
61
- return url;
62
- }
63
- }
64
- }
65
-
66
- isExternal(pathInfo: string) {
67
- return !pathInfo.startsWith('/');
68
- }
69
-
70
- clickHandle = async (e: MouseEvent) => {
71
- const pathInfo = this.getPathInfo();
72
-
73
- if (!pathInfo) return;
74
-
75
- // 外部链接使用 `window.open`
76
- if (this.isExternal(pathInfo)) {
77
- switch (this.target) {
78
- case '_self':
79
- window.location.href = pathInfo;
80
- return;
81
- case '_parent':
82
- window.parent.location.href = pathInfo;
83
- return;
84
- case '_top':
85
- window.top!.location.href = pathInfo;
86
- return;
87
- default:
88
- window.open(pathInfo);
89
- return;
90
- }
91
- }
92
-
93
- const { path, query, hash } = history.getParams();
94
- if (path + query + hash === pathInfo) {
95
- // 点击当前路由链接时,什么也没做
96
- return;
97
- }
98
-
99
- e.stopPropagation();
100
-
101
- await this.prepare?.();
102
-
103
- if (this.route) {
104
- history.pushIgnoreCloseHandle({
105
- ...createHistoryParams(this.route, this.options),
106
- title: this.route.title || this.docTitle,
107
- });
108
- } else if (this.href) {
109
- const { pathname, search, hash } = new URL(pathInfo, location.origin);
110
- history.pushIgnoreCloseHandle({
111
- path: pathname,
112
- query: search,
113
- hash: hash,
114
- title: this.docTitle,
115
- });
116
- } else {
117
- history.pushIgnoreCloseHandle({ path: this.path, query: this.query, hash: this.hash, title: this.docTitle });
118
- }
119
- };
120
-
121
- preventDefault = (e: MouseEvent) => {
122
- e.preventDefault();
123
- };
124
-
125
- render(pathInfo = this.getPathInfo()) {
126
- return html`
127
- <style>
128
- :host {
129
- /* link default style */
130
- cursor: pointer;
131
- color: blue;
132
- text-decoration: underline;
133
- }
134
- a {
135
- all: unset;
136
- display: contents;
137
- }
138
- a:visited {
139
- color: unset;
140
- }
141
- </style>
142
- <a
143
- part=${this.link}
144
- @click=${this.preventDefault}
145
- href=${ifDefined(
146
- this.hint === 'off'
147
- ? undefined
148
- : this.isExternal(pathInfo)
149
- ? pathInfo
150
- : new URL(history.basePath + pathInfo, location.origin).toString(),
151
- )}
152
- >
153
- <slot></slot>
154
- </a>
155
- `;
156
- }
157
- }
158
-
159
- /**
160
- * @customElement gem-active-link
161
- * @attr pattern
162
- * @state active
163
- */
164
- @customElement('gem-active-link')
165
- @connectStore(history.store)
166
- export class GemActiveLinkElement extends GemLinkElement {
167
- @attribute pattern: string; // 使用匹配模式设定 active
168
- @state active: boolean;
169
-
170
- render() {
171
- const { path, query, hash } = history.getParams();
172
- const isMatchPattern = this.pattern && matchPath(this.pattern, path);
173
- const pathInfo = this.getPathInfo();
174
- if (isMatchPattern || path + query + hash === pathInfo) {
175
- this.active = true;
176
- } else {
177
- this.active = false;
178
- }
179
- return super.render(pathInfo);
180
- }
181
- }
5
+ customElements.define('gem-link', GemLinkElement);
6
+ customElements.define('gem-active-link', GemActiveLinkElement);
@@ -1,33 +1,5 @@
1
- import { GemElement } from '../lib/element';
2
- import { property, customElement } from '../lib/decorators';
1
+ import { GemReflectElement } from './base/reflect';
3
2
 
4
- // support prerender
5
- document.querySelectorAll('[data-reflect]').forEach((e) => e.remove());
3
+ export * from './base/reflect';
6
4
 
7
- /**
8
- * @customElement gem-reflect
9
- */
10
- @customElement('gem-reflect')
11
- export class GemReflectElement extends GemElement {
12
- @property target: HTMLElement = document.head;
13
-
14
- constructor() {
15
- super({ isLight: true });
16
- this.hidden = true;
17
- this.effect(
18
- () => {
19
- const childNodes = [...this.childNodes];
20
- childNodes.forEach((node) => {
21
- if (node instanceof HTMLElement) {
22
- node.dataset.reflect = '';
23
- }
24
- this.target.append(node);
25
- });
26
- return () => {
27
- childNodes.forEach((node) => node.remove());
28
- };
29
- },
30
- () => [this.target],
31
- );
32
- }
33
- }
5
+ customElements.define('gem-reflect', GemReflectElement);
@@ -1,250 +1,6 @@
1
- import { GemElement, html, TemplateResult } from '../lib/element';
2
- import { property, customElement, connectStore, emitter, Emitter } from '../lib/decorators';
3
- import { createStore, updateStore, Store } from '../lib/store';
4
- import { titleStore, history, UpdateHistoryParams } from '../lib/history';
5
- import { QueryString } from '../lib/utils';
1
+ import { GemRouteElement, GemLightRouteElement } from './base/route';
6
2
 
7
- interface NamePostition {
8
- [index: string]: number;
9
- }
3
+ export * from './base/route';
10
4
 
11
- // TODO: use `URLPattern`
12
- class ParamsRegExp extends RegExp {
13
- namePosition: NamePostition;
14
- constructor(pattern: string) {
15
- const namePosition: NamePostition = {};
16
- let i = 0;
17
- super(
18
- `^${pattern
19
- .replace(/:([^/$]+)/g, (_m, name: string) => {
20
- namePosition[name] = i++;
21
- return `([^/]+)`;
22
- })
23
- .replace('*', '.*')}$`,
24
- 'i',
25
- );
26
- this.namePosition = namePosition;
27
- }
28
- }
29
-
30
- type Params = Record<string, string>;
31
-
32
- // `/a/b/:c/:d` `/a/b/1/2`
33
- // 匹配成功时返回 params
34
- export function matchPath(pattern: string, path: string) {
35
- const reg = new ParamsRegExp(pattern);
36
- const matchResult = path.match(reg) || `${path}/`.match(reg);
37
- if (!matchResult) return null;
38
- const params: Params = {};
39
- if (matchResult) {
40
- Object.keys(reg.namePosition).forEach((name) => {
41
- params[name] = matchResult[reg.namePosition[name] + 1];
42
- });
43
- }
44
- return params;
45
- }
46
-
47
- export interface RouteItem<T = unknown> {
48
- // 支持 *
49
- // 支持 /a/*
50
- // 不支持相对路径
51
- // 不能匹配查询字符串
52
- pattern: string;
53
- redirect?: string;
54
- content?: TemplateResult;
55
- getContent?: (params: Params) => TemplateResult | Promise<TemplateResult>;
56
- title?: string;
57
- // 用来传递数据
58
- data?: T;
59
- }
60
-
61
- type RoutesObject = Record<string, RouteItem>;
62
-
63
- // params 中的成员不会验证
64
- export interface RouteOptions extends Omit<UpdateHistoryParams, 'path'> {
65
- params?: Params;
66
- }
67
-
68
- // 从路由创建路径
69
- // 不包含 basePath
70
- export function createPath(route: RouteItem, options?: RouteOptions) {
71
- let path = route.pattern;
72
- const params = options?.params;
73
- if (params) {
74
- Object.keys(params).forEach((key) => {
75
- path = path.replace(new RegExp(`:${key}`, 'g'), params[key]);
76
- });
77
- }
78
- return path;
79
- }
80
-
81
- export function createHistoryParams(route: RouteItem, options?: RouteOptions): UpdateHistoryParams {
82
- const path = createPath(route, options);
83
- return {
84
- path,
85
- ...options,
86
- };
87
- }
88
-
89
- interface ConstructorOptions {
90
- isLight?: boolean;
91
- routes?: RouteItem[] | RoutesObject;
92
- }
93
-
94
- type State = {
95
- content?: TemplateResult;
96
- };
97
-
98
- /**
99
- * @customElement gem-route
100
- * @attr inert 暂停路由更新
101
- * @fires routechange
102
- * @fires error
103
- * @fires loading
104
- */
105
- @connectStore(history.store)
106
- @customElement('gem-route')
107
- export class GemRouteElement extends GemElement<State> {
108
- @property routes?: RouteItem[] | RoutesObject;
109
- /**
110
- * @example
111
- * const locationStore = GemRouteElement.createLocationStore()
112
- * html`<gem-route .locationStore=${locationStore}>`
113
- */
114
- @property locationStore?: Store<{ path: string; params: Params; query: QueryString; data?: any }>;
115
- @property key: any; // 除了 href 提供另外一种方式来更新,比如语言更新也需要刷新 <gem-route>
116
- @emitter routechange: Emitter<RouteItem | null>; // path 改变或者 key 改变,包含初始渲染
117
- @emitter loading: Emitter<RouteItem>;
118
- @emitter error: Emitter<any>;
119
-
120
- currentRoute: RouteItem | null;
121
- // 当前匹配的路由的 params
122
- currentParams: Params = {};
123
-
124
- #lastLoader?: Promise<TemplateResult>;
125
-
126
- static createLocationStore = () => {
127
- const { path, query, data } = history.getParams();
128
- return createStore({ path, query, data, params: {} as Record<string, string> });
129
- };
130
-
131
- static findRoute = (target: RouteItem[] | RoutesObject = [], path: string) => {
132
- let defaultRoute: RouteItem | null = null;
133
- let routes: RouteItem[];
134
- if (target instanceof Array) {
135
- routes = target;
136
- } else {
137
- routes = Object.values(target);
138
- }
139
- for (const route of routes) {
140
- if ('*' === route.pattern) {
141
- defaultRoute = route;
142
- } else {
143
- const params = matchPath(route.pattern, path);
144
- if (params) {
145
- return { route, params };
146
- }
147
- }
148
- }
149
- return { route: defaultRoute };
150
- };
151
-
152
- constructor({ isLight, routes }: ConstructorOptions = {}) {
153
- super({ isLight });
154
- this.routes = routes;
155
- }
156
-
157
- state: State = {
158
- content: undefined,
159
- };
160
-
161
- #updateLocationStore = () => {
162
- if (this.locationStore) {
163
- const { path, query, data } = history.getParams();
164
- updateStore(this.locationStore, {
165
- path,
166
- params: this.currentParams,
167
- query,
168
- data,
169
- });
170
- }
171
- };
172
-
173
- #setContent = (route: RouteItem | null, params: Params, content?: TemplateResult) => {
174
- this.#lastLoader = undefined;
175
- this.currentRoute = route;
176
- this.currentParams = params;
177
- this.setState({ content });
178
- this.routechange(this.currentRoute);
179
- const title = route?.title;
180
- if (title) updateStore(titleStore, { title });
181
- this.#updateLocationStore();
182
- };
183
-
184
- mounted() {
185
- this.effect(
186
- ([key, path], old) => {
187
- // 只有查询参数改变
188
- if (old && key === old[0] && path === old[1]) {
189
- this.#updateLocationStore();
190
- return;
191
- }
192
- const { route, params = {} } = GemRouteElement.findRoute(this.routes, path);
193
- const { redirect, content, getContent } = route || {};
194
- if (redirect) {
195
- history.replace({ path: redirect });
196
- return;
197
- }
198
- const contentOrLoader = content || getContent?.(params);
199
- if (contentOrLoader instanceof Promise) {
200
- this.loading(route!);
201
- this.#lastLoader = contentOrLoader;
202
- const isSomeLoader = () => this.#lastLoader === contentOrLoader;
203
- contentOrLoader
204
- .then((content) => {
205
- if (isSomeLoader()) this.#setContent(route, params, content);
206
- })
207
- .catch((err) => {
208
- if (isSomeLoader()) this.error(err);
209
- });
210
- return;
211
- }
212
- this.#setContent(route, params, contentOrLoader);
213
- },
214
- () => {
215
- const { path } = history.getParams();
216
- return [this.key, path, location.search];
217
- },
218
- );
219
- }
220
-
221
- shouldUpdate() {
222
- if (this.inert) return false;
223
- return true;
224
- }
225
-
226
- render() {
227
- const { content } = this.state;
228
- if (!this.shadowRoot) return html`${content}`;
229
-
230
- return html`
231
- <style>
232
- :host,
233
- :not(:defined) {
234
- display: contents;
235
- }
236
- </style>
237
- ${content ?? html`<slot></slot>`}
238
- `;
239
- }
240
- }
241
-
242
- /**
243
- * @customElement gem-light-route
244
- */
245
- @customElement('gem-light-route')
246
- export class GemLightRouteElement extends GemRouteElement {
247
- constructor(options: ConstructorOptions = {}) {
248
- super({ ...options, isLight: true });
249
- }
250
- }
5
+ customElements.define('gem-route', GemRouteElement);
6
+ customElements.define('gem-light-route', GemLightRouteElement);
@@ -1,70 +1,5 @@
1
- /**
2
- * 标题显示在:
3
- *
4
- * - 桌面端 Tab 的 title
5
- * - 移动端 Appbar 的 title
6
- *
7
- * 修改标题:
8
- *
9
- * - `<gem-route>` 匹配路由时自动设置 `route.title`
10
- * - `<gem-link>` 的 `doc-title` 属性和 `route.title`
11
- * - 修改路径时,`history` 默认设置 `title` 为空
12
- * - 数据获取后,手动调用 `Title.setTitle`
13
- * - `<gem-title>` 作为默认值设置
14
- */
1
+ import { GemTitleElement } from './base/title';
15
2
 
16
- import { GemElement, html } from '../lib/element';
17
- import { attribute, customElement, connectStore } from '../lib/decorators';
18
- import { updateStore, connect } from '../lib/store';
19
- import { titleStore } from '../lib/history';
3
+ export * from './base/title';
20
4
 
21
- /**
22
- * 允许声明式设置 `document.title`
23
- * @customElement gem-title
24
- * @attr suffix
25
- */
26
- @connectStore(titleStore)
27
- @customElement('gem-title')
28
- export class GemTitleElement extends GemElement {
29
- // 没有后缀的标题
30
- static title = document.title;
31
- static defaultTitle = document.title;
32
- static defaultSuffix = ` - ${document.title}`;
33
-
34
- static setTitle(title: string) {
35
- updateStore(titleStore, { title });
36
- }
37
-
38
- static updateTitle(str = '', suffix = '') {
39
- const { title } = titleStore;
40
- if (title && title !== GemTitleElement.defaultTitle) {
41
- GemTitleElement.title = title;
42
- document.title = GemTitleElement.title + suffix;
43
- } else if (str) {
44
- GemTitleElement.title = str;
45
- document.title = GemTitleElement.title + suffix;
46
- } else {
47
- GemTitleElement.title = GemTitleElement.defaultTitle;
48
- document.title = GemTitleElement.title;
49
- }
50
- }
51
-
52
- @attribute suffix: string;
53
-
54
- constructor() {
55
- super();
56
- new MutationObserver(() => this.update()).observe(this, { childList: true, characterData: true, subtree: true });
57
- }
58
-
59
- render() {
60
- // 多个 <gem-title> 时,最终 document.title 按执行顺序决定
61
- GemTitleElement.updateTitle(this.textContent || '', this.suffix);
62
-
63
- if (this.hidden) {
64
- return html``;
65
- }
66
- return html`${GemTitleElement.title}`;
67
- }
68
- }
69
-
70
- connect(titleStore, GemTitleElement.updateTitle);
5
+ customElements.define('gem-title', GemTitleElement);
@@ -1,39 +1,5 @@
1
- import { GemElement } from '../lib/element';
2
- import { attribute, customElement } from '../lib/decorators';
1
+ import { GemUnsafeElement } from './base/unsafe';
3
2
 
4
- /**
5
- * 直接写会被解释成固定属性,需要使用变量赋值
6
- *
7
- * @customElement gem-unsafe
8
- * @attr content
9
- * @attr contentcss
10
- */
11
- @customElement('gem-unsafe')
12
- export class GemUnsafeElement extends GemElement {
13
- @attribute content: string;
14
- @attribute contentcss: string;
3
+ export * from './base/unsafe';
15
4
 
16
- constructor() {
17
- super();
18
- this.effect(
19
- () => {
20
- if (this.shadowRoot) {
21
- this.shadowRoot.innerHTML = `
22
- <style>
23
- :host {
24
- display: contents;
25
- }
26
- ${this.contentcss}
27
- </style>
28
- ${this.content}
29
- `;
30
- }
31
- },
32
- () => [this.content, this.contentcss],
33
- );
34
- }
35
-
36
- render() {
37
- return undefined;
38
- }
39
- }
5
+ customElements.define('gem-unsafe', GemUnsafeElement);
@@ -1,59 +1,5 @@
1
- import { GemElement, html } from '../lib/element';
2
- import { attribute, property, customElement, state } from '../lib/decorators';
1
+ import { GemUseElement } from './base/use';
3
2
 
4
- const eleCache = new Map<string, HTMLTemplateElement>();
5
- /**
6
- * svg 中的 `<use>` 不能穿透 ShadowDOM,
7
- * 此元素用来模拟 `<use>`,
8
- * 由于是复制元素,所以不能像 `<use>` 一样自动更新
9
- *
10
- * slot 支持为 icon 添加效果,如涟漪,徽章
11
- *
12
- * @customElement gem-use
13
- * @attr selector
14
- */
15
- @customElement('gem-use')
16
- export class GemUseElement extends GemElement {
17
- @attribute selector: string; // CSS 选择器
18
- @property root?: HTMLElement | Document | ShadowRoot;
19
- @property element?: string | DocumentFragment | Element;
3
+ export * from './base/use';
20
4
 
21
- @state active: boolean;
22
-
23
- private getContent() {
24
- const ele = this.element || (this.selector ? (this.root || document).querySelector(this.selector) : null);
25
- if (typeof ele === 'string') {
26
- let temp = eleCache.get(ele);
27
- if (!temp) {
28
- temp = document.createElement('template');
29
- temp.innerHTML = ele;
30
- eleCache.set(ele, temp);
31
- }
32
- return temp.content.cloneNode(true);
33
- } else if (ele instanceof HTMLTemplateElement) {
34
- return ele.content.cloneNode(true);
35
- } else {
36
- return ele?.cloneNode(true);
37
- }
38
- }
39
-
40
- render() {
41
- return html`
42
- <style>
43
- :host {
44
- position: relative;
45
- }
46
- :host(:not([hidden])) {
47
- display: inline-flex;
48
- align-items: center;
49
- }
50
- svg {
51
- width: 100%;
52
- height: 100%;
53
- }
54
- </style>
55
- ${this.getContent()}
56
- <slot></slot>
57
- `;
58
- }
59
- }
5
+ customElements.define('gem-use', GemUseElement);
@@ -574,7 +574,9 @@ export function defineRef(target: GemElement, prop: string, ref: string) {
574
574
  return ref;
575
575
  },
576
576
  get element() {
577
- const gemReflects = ([...ele.querySelectorAll('gem-reflect')] as GemReflectElement[]).map((e) => e.target);
577
+ const gemReflects = ([...ele.querySelectorAll('[data-gemreflect]')] as GemReflectElement[]).map(
578
+ (e) => e.target,
579
+ );
578
580
  for (const e of [ele, ...gemReflects]) {
579
581
  const result = e.querySelector(`[ref=${ref}]`);
580
582
  if (result) return result;