From ad97b51e0d104441d62522bb241749e9ff7ad4b2 Mon Sep 17 00:00:00 2001 From: mantou132 <709922234@qq.com> Date: Sat, 20 Jul 2024 01:58:34 +0800 Subject: [PATCH] [gem] Closed #158, #180 --- packages/gem-devtools/src/scripts/get-gem.ts | 4 ++-- packages/gem-examples/src/scope/index.ts | 20 ++++++++++++++++---- packages/gem-examples/src/styled/index.ts | 4 +++- packages/gem/src/helper/theme.ts | 19 +++++++++++++++++-- packages/gem/src/lib/element.ts | 4 ++-- packages/gem/src/lib/utils.ts | 3 ++- 6 files changed, 42 insertions(+), 12 deletions(-) diff --git a/packages/gem-devtools/src/scripts/get-gem.ts b/packages/gem-devtools/src/scripts/get-gem.ts index dac20997..20fb3711 100644 --- a/packages/gem-devtools/src/scripts/get-gem.ts +++ b/packages/gem-devtools/src/scripts/get-gem.ts @@ -114,7 +114,7 @@ export const getSelectedGem = function (data: PanelStore): PanelStore | string { const lifecycleMethod = new Set(['willMount', 'render', 'mounted', 'shouldUpdate', 'updated', 'unmounted']); const buildInMethod = new Set(['update', 'setState', 'effect', 'memo']); const buildInProperty = new Set(['internals']); - const buildInAttribute = new Set(['ref']); + const buildInAttribute = new Set(['ref', 'data-style-scope']); const memberSet = getProps($0); metadata.observedAttributes?.forEach((attr) => { const prop = kebabToCamelCase(attr); @@ -266,7 +266,7 @@ export const getSelectedGem = function (data: PanelStore): PanelStore | string { value: objectToString($0[key]), type: typeof $0[key], path: [key], - buildIn: buildInProperty.has(key) ? 2 : 0, + buildIn: buildInProperty.has(key) ? 1 : 0, }); }); diff --git a/packages/gem-examples/src/scope/index.ts b/packages/gem-examples/src/scope/index.ts index 5b84217f..dca8783e 100644 --- a/packages/gem-examples/src/scope/index.ts +++ b/packages/gem-examples/src/scope/index.ts @@ -1,10 +1,21 @@ -/** - * TODO: auto add `@scope` to light dom custom element - */ -import { GemElement, adoptedStyle, createCSSSheet, css, customElement, html, render } from '@mantou/gem'; +import { GemElement, adoptedStyle, createCSSSheet, css, customElement, html, render, shadow } from '@mantou/gem'; import '../elements/layout'; +const closedStyles = createCSSSheet(css` + div { + color: red; + } +`); +@shadow({ mode: 'closed' }) +@adoptedStyle(closedStyles) +@customElement('app-closed') +class _Closed extends GemElement { + render() { + return html`
Closed shadow
`; + } +} + @customElement('other-element') class _OtherElement extends GemElement {} @@ -31,6 +42,7 @@ export class App extends GemElement {

Content

+ `; } } diff --git a/packages/gem-examples/src/styled/index.ts b/packages/gem-examples/src/styled/index.ts index d3643ec0..4eb9f2cd 100644 --- a/packages/gem-examples/src/styled/index.ts +++ b/packages/gem-examples/src/styled/index.ts @@ -28,7 +28,9 @@ export class App extends GemElement { render() { return html`
Header 1
- ${[styles, styles2].map((styles) => html`
${styles[SheetToken].getStyle(this).cssRules[0].cssText}
`)} + ${[styles, styles2].map( + (gemStyles) => html`
${gemStyles[SheetToken].getStyle(this).cssRules[0].cssText}
`, + )} `; } } diff --git a/packages/gem/src/helper/theme.ts b/packages/gem/src/helper/theme.ts index ff76a406..74530b1c 100644 --- a/packages/gem/src/helper/theme.ts +++ b/packages/gem/src/helper/theme.ts @@ -1,7 +1,11 @@ import { connect, Store, useStore } from '../lib/store'; import { camelToKebabCase, randomStr, Sheet, SheetToken, GemCSSSheet } from '../lib/utils'; -export type Theme = Sheet; +export type Theme = Sheet & { + [K in keyof T as K extends `${string}Color` + ? `${string & K}${'' | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900}` + : K]: T[K]; +}; const themeStoreMap = new WeakMap(); const themePropsMap = new WeakMap(); @@ -20,7 +24,18 @@ function useThemeFromProps>(themeObj: T, props const salt = randomStr(); const styleSheet = new GemCSSSheet(); const [store, updateStore] = useStore(themeObj); - const theme: any = { [SheetToken]: styleSheet }; + const theme: any = new Proxy( + { [SheetToken]: styleSheet }, + { + get(target: any, key: string) { + if (!target[key]) { + const [_, origin, weight] = key.match(/^(\w*Color)(\d+)$/) || []; + if (origin) target[key] = `oklch(from ${target[origin]} calc(l - ${(Number(weight) - 400) / 1000}) c h)`; + } + return target[key]; + }, + }, + ); themePropsMap.set(theme, props); themeStoreMap.set(theme, store); diff --git a/packages/gem/src/lib/element.ts b/packages/gem/src/lib/element.ts index 2b18cd4d..22277a15 100644 --- a/packages/gem/src/lib/element.ts +++ b/packages/gem/src/lib/element.ts @@ -168,8 +168,8 @@ export abstract class GemElement> extends HTMLEl Object.assign(this.internals, aria); const sheets = adoptedStyleSheets?.map((item) => item[SheetToken].getStyle(this)) || []; - if (this.shadowRoot) { - this.shadowRoot.adoptedStyleSheets = sheets; + if (this.#renderRoot instanceof ShadowRoot) { + this.#renderRoot.adoptedStyleSheets = sheets; } else { this.effect( () => { diff --git a/packages/gem/src/lib/utils.ts b/packages/gem/src/lib/utils.ts index c91cca9f..0a649f98 100644 --- a/packages/gem/src/lib/utils.ts +++ b/packages/gem/src/lib/utils.ts @@ -254,7 +254,8 @@ export class GemCSSSheet { #record = new Map(); #applyd = new Map(); getStyle(host?: HTMLElement) { - const isLight = host && !host.shadowRoot; + // GemElement.internals + const isLight = host && !(host as any).internals?.shadowRoot; // 对同一类 dom 只使用同一个样式表 const key = isLight ? host.constructor : this;