Skip to content

Commit

Permalink
[gem] change decorators
Browse files Browse the repository at this point in the history
移除 @Style #183
添加 @willMount @mounted @render 装饰器 #159
内部元素生命周期使用装饰器
添加 createState #179
  • Loading branch information
mantou132 committed Aug 5, 2024
1 parent c2dd559 commit 3de906a
Show file tree
Hide file tree
Showing 27 changed files with 309 additions and 282 deletions.
10 changes: 3 additions & 7 deletions packages/duoyun-ui/src/patterns/nav.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { history } from '@mantou/gem/lib/history';
import { createCSSSheet, GemElement, TemplateResult, html, render } from '@mantou/gem/lib/element';
import { createCSSSheet, GemElement, TemplateResult, html } from '@mantou/gem/lib/element';
import { adoptedStyle, attribute, connectStore, customElement, property, state } from '@mantou/gem/lib/decorators';
import { addListener, classMap, css } from '@mantou/gem/lib/utils';
import { mediaQuery } from '@mantou/gem/helper/mediaquery';
Expand Down Expand Up @@ -193,7 +193,7 @@ export class DyPatNavElement extends GemElement<State> {
@attribute name: string;
@property links?: Links;
@property logo?: string | Element | DocumentFragment;
@property renderSlot?: (ele: Element) => TemplateResult | undefined;
@property navSlot?: TemplateResult;

@state switching: boolean;

Expand Down Expand Up @@ -225,8 +225,6 @@ export class DyPatNavElement extends GemElement<State> {
drawerOpen: false,
};

#navSlot = document.createElement('div');

#onMobileItemClick = (evt: MouseEvent) => {
(evt.currentTarget as HTMLLIElement).classList.toggle('open-dropdown');
};
Expand All @@ -249,8 +247,6 @@ export class DyPatNavElement extends GemElement<State> {
};

render = () => {
render(this.renderSlot ? this.renderSlot(this.#navSlot) : html``, this.#navSlot);

return html`
<dy-use
class="menu"
Expand Down Expand Up @@ -309,7 +305,7 @@ export class DyPatNavElement extends GemElement<State> {
<div style="flex-grow: 1" @click=${() => this.setState({ drawerOpen: false })}></div>
</nav>
${this.#navSlot}
${this.navSlot}
`;
};
}
15 changes: 11 additions & 4 deletions packages/gem-analyzer/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ interface ConstructorParam {
}

export interface ElementDetail {
shadow: boolean;
name: string;
constructorName: string;
constructorExtendsName: string;
Expand All @@ -66,6 +67,7 @@ export interface ElementDetail {
cssStates: string[];
}

const shadowDecoratorName = ['shadow'];
const elementDecoratorName = ['customElement'];
const attrDecoratorName = ['attribute', 'boolattribute', 'numattribute'];
const propDecoratorName = ['property'];
Expand All @@ -80,6 +82,7 @@ const lifecyclePopsOrMethods = ['state', 'willMount', 'render', 'mounted', 'shou
export const parseElement = (declaration: ClassDeclaration) => {
const detail: ElementDetail = {
name: '',
shadow: false,
constructorName: '',
constructorExtendsName: '',
constructorParams: [],
Expand Down Expand Up @@ -240,9 +243,12 @@ export const parseElement = (declaration: ClassDeclaration) => {
export const getElements = (file: SourceFile) => {
const result: ElementDetail[] = [];
for (const declaration of file.getClasses()) {
const elementDeclaration = declaration
.getDecorators()
.find((decorator) => elementDecoratorName.includes(decorator.getName()));
// need support other decorators?
const elementDecorators = declaration.getDecorators();
const elementDeclaration = elementDecorators.find((decorator) =>
elementDecoratorName.includes(decorator.getName()),
);
const shadowDeclaration = elementDecorators.find((decorator) => shadowDecoratorName.includes(decorator.getName()));
const elementTag =
elementDeclaration
?.getCallExpression()!
Expand All @@ -256,9 +262,10 @@ export const getElements = (file: SourceFile) => {
.find((e) => e.getTagName() === 'customElement')
?.getCommentText();
if (elementTag) {
const detail = {
const detail: ElementDetail = {
...parseElement(declaration),
name: elementTag,
shadow: !!shadowDeclaration,
};
if (!detail.constructorName.startsWith('_')) {
result.push(detail);
Expand Down
2 changes: 0 additions & 2 deletions packages/gem-book/src/element/elements/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,7 @@ const style = createCSSSheet(css`
border-radius: ${theme.smallRound};
}
gem-book-pre {
z-index: 2;
margin: 2rem 0px;
border-radius: ${theme.normalRound};
}
iframe {
width: 100%;
Expand Down
6 changes: 1 addition & 5 deletions packages/gem-book/src/element/elements/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { BookConfig } from '../../common/config';
import { debounce } from '../../common/utils';
import { icons } from '../elements/icons';
import { getRanges, getParts, joinPath, getURL, escapeHTML, capitalize } from '../lib/utils';
import { linkStyle, parseMarkdown, tableStyle, unsafeRenderHTML } from '../lib/renderer';
import { parseMarkdown, unsafeRenderHTML } from '../lib/renderer';
import { originDocLang, selfI18n } from '../helper/i18n';

/**
Expand Down Expand Up @@ -56,10 +56,6 @@ export class GemBookPluginElement<T = any> extends GemElement<T> {
parseMarkdown,
unsafeRenderHTML,
};
static shaderStyles = {
tableStyle,
linkStyle,
};

static caches = new Map<typeof GemBookPluginElement, Map<string, any>>();
static theme = theme;
Expand Down
2 changes: 2 additions & 0 deletions packages/gem-book/src/element/elements/pre.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,8 @@ const styles = createCSSSheet(css`
display: block;
font-family: ${theme.codeFont};
background: rgb(from ${theme.textColor} r g b / 0.05);
border-radius: ${theme.normalRound};
overflow: hidden;
}
.filename {
font-size: 0.75em;
Expand Down
2 changes: 1 addition & 1 deletion packages/gem-book/src/element/helper/default-theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export const defaultTheme = {
sidebarWidthSmall: '270px',

sidebarWidth: '304px',
maxMainWidth: '48rem',
maxMainWidth: '52rem',
headerHeight: '56px',
normalRound: '0.5rem',
smallRound: '0.25rem',
Expand Down
10 changes: 7 additions & 3 deletions packages/gem-book/src/plugins/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@ const gemAnalyzer = 'https://esm.sh/gem-analyzer';
type State = { elements?: ElementDetail[]; exports?: ExportDetail[]; error?: any };

customElements.whenDefined('gem-book').then(({ GemBookPluginElement }: typeof GemBookElement) => {
const { Gem, theme, Utils, shaderStyles } = GemBookPluginElement;
const { html, customElement, attribute, numattribute, createCSSSheet, css, adoptedStyle } = Gem;
const { Gem, theme, Utils } = GemBookPluginElement;
const { html, customElement, attribute, numattribute, createCSSSheet, css, adoptedStyle, BoundaryCSSState } = Gem;

const styles = createCSSSheet(css`
${shaderStyles.tableStyle}
table {
tr td:first-of-type {
white-space: nowrap;
Expand Down Expand Up @@ -40,6 +39,7 @@ customElements.whenDefined('gem-book').then(({ GemBookPluginElement }: typeof Ge
constructor() {
super();
this.cacheState(() => [this.name, this.src]);
this.internals.states.delete(BoundaryCSSState);
}

state: State = {};
Expand Down Expand Up @@ -81,6 +81,7 @@ customElements.whenDefined('gem-book').then(({ GemBookPluginElement }: typeof Ge

#renderElement = (detail: ElementDetail) => {
const {
shadow,
name: eleName,
description: eleDescription = '',
constructorName,
Expand All @@ -99,6 +100,9 @@ customElements.whenDefined('gem-book').then(({ GemBookPluginElement }: typeof Ge

text += eleDescription + '\n\n';
if (constructorExtendsName) {
if (shadow) {
text += `Shadow DOM; `;
}
text += `Extends ${this.#renderCode(constructorExtendsName)}\n\n`;
}

Expand Down
4 changes: 2 additions & 2 deletions packages/gem-book/src/plugins/include.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@ type State = {

customElements.whenDefined('gem-book').then(({ GemBookPluginElement }: typeof GemBookElement) => {
const { Gem, theme, Utils } = GemBookPluginElement;
const { attribute, customElement, html, style } = Gem;
const { attribute, customElement, html, BoundaryCSSState } = Gem;

@customElement('gbp-include')
@style({ scoped: false })
class _GbpIncludeElement extends GemBookPluginElement<State> {
@attribute src: string;
@attribute range: string;

constructor() {
super();
this.cacheState(() => [this.src, this.range]);
this.internals.states.delete(BoundaryCSSState);
}

state: State = {
Expand Down
1 change: 0 additions & 1 deletion packages/gem-book/src/plugins/raw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ customElements.whenDefined('gem-book').then(({ GemBookPluginElement }: typeof Ge
}
gem-book-pre {
margin: 2rem 0px;
border-radius: ${theme.normalRound};
animation: display 0.3s cubic-bezier(0.4, 0, 0.2, 1) forwards;
}
@keyframes display {
Expand Down
8 changes: 6 additions & 2 deletions packages/gem-book/src/plugins/trans-status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,17 @@ const locales: Record<string, Record<Status, string>> = {

customElements.whenDefined('gem-book').then(({ GemBookPluginElement }: typeof GemBookElement) => {
const { Gem, Utils, selfI18n } = GemBookPluginElement;
const { html, customElement, attribute, style } = Gem;
const { html, customElement, attribute, BoundaryCSSState } = Gem;

@customElement('gbp-trans-status')
@style({ scoped: false })
class _GbpTransStatusElement extends GemBookPluginElement {
@attribute status: Status;

constructor() {
super();
this.internals.states.delete(BoundaryCSSState);
}

get #status() {
return this.status || 'none';
}
Expand Down
17 changes: 12 additions & 5 deletions packages/gem-devtools/src/modules/panel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,18 @@ export class Panel extends GemElement {
<devtools-section name="Observed Properties" .items=${panelStore.observedProperties}></devtools-section>
<devtools-section name="Observed Stores" .items=${panelStore.observedStores}></devtools-section>
<devtools-section name="Adopted Styles" .items=${panelStore.adoptedStyles}></devtools-section>
<devtools-section
name="State"
.path=${panelStore.state.length ? ['state'] : undefined}
.items=${panelStore.state}
></devtools-section>
${panelStore.state.length
? html`<devtools-section name="State" .path=${['state']} .items=${panelStore.state}></devtools-section>`
: ''}
${panelStore.stateList.map(
(state, index) => html`
<devtools-section
name=${`State #${index}`}
.path=${['internals', 'stateList', `${index}`]}
.items=${state}
></devtools-section>
`,
)}
<devtools-section name="Emitters" .items=${panelStore.emitters}></devtools-section>
<devtools-section name="Slots" tip=${TIP} .items=${panelStore.slots}></devtools-section>
<devtools-section name="CSS States" tip=${TIP} .items=${panelStore.cssStates}></devtools-section>
Expand Down
13 changes: 13 additions & 0 deletions packages/gem-devtools/src/scripts/get-gem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,12 +226,25 @@ export const getSelectedGem = function (data: PanelStore): PanelStore | string {
type: 'boolean',
});
});
$0.internals?.stateList?.forEach((state: any) => {
data.stateList.push(
Object.keys(state).map((k) => {
const value = state[k];
return {
name: k,
value: objectToString(value),
type: typeof value,
};
}),
);
});
memberSet.forEach((key) => {
memberSet.delete(key);
// GemElement 不允许覆盖内置生命周期,所以不考虑
if (elementMethod.has(key)) return;
if (key === 'state') {
$0.state &&
$0.setState &&
Object.keys($0.state).forEach((k) => {
const value = $0.state[k];
data.state.push({
Expand Down
3 changes: 2 additions & 1 deletion packages/gem-devtools/src/scripts/preload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ export function preload() {
return c.reduce((pp, cc) => pp || (cc === '' ? p : p[cc]), undefined);
} else {
const value = p[c];
return typeof value === 'function' && c !== 'constructor' ? value.bind(p) : value;
// 支持 state 函数
return value instanceof Function && c !== 'constructor' ? value.bind(p) : value;
}
}
}, $0);
Expand Down
1 change: 1 addition & 0 deletions packages/gem-devtools/src/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export class PanelStore {
observedStores = new Array<Item>();
adoptedStyles = new Array<Item>();
state = new Array<Item>();
stateList = new Array<Item[]>();
emitters = new Array<Item>();
slots = new Array<Item>();
cssStates = new Array<Item>();
Expand Down
1 change: 1 addition & 0 deletions packages/gem-devtools/src/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ changePanelStore({
lifecycleMethod: [{ name: 'render', value: 'function ()', type: 'function' }],
method: [{ name: 'click', value: 'function ()', type: 'function' }],
state: [{ name: 'loaded', value: true, type: 'boolean' }],
stateList: [[{ name: 'opened', value: true, type: 'boolean' }]],
properties: [
{ name: 'mute', value: 'true', type: 'boolean' },
{ name: 'data', value: 'null', type: 'object' },
Expand Down
12 changes: 2 additions & 10 deletions packages/gem-examples/src/hash/index.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,16 @@
import { GemElement, render, html, customElement, shadow } from '@mantou/gem';
import { GemElement, render, html, customElement, shadow, addListener } from '@mantou/gem';
import '@mantou/gem/elements/link';

import '../elements/layout';

@customElement('app-article')
@shadow()
class _Article extends GemElement {
constructor() {
super();
window.addEventListener('hashchange', this.checkHash);
}

mounted = () => {
// 在当前页面刷新浏览器会保留滚动位置
// 开新窗口测试带 hash 链接
this.checkHash();
};

unmounted = () => {
window.removeEventListener('hashchange', this.checkHash);
return addListener(window, 'hashchange', this.checkHash);
};

checkHash = () => {
Expand Down
13 changes: 4 additions & 9 deletions packages/gem/src/elements/base/dialog.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { GemElement } from '../../lib/element';
import { attribute, state, connectStore, aria } from '../../lib/decorators';
import { attribute, state, connectStore, aria, mounted } from '../../lib/decorators';
import { history } from '../../lib/history';

const final = Symbol();
Expand All @@ -22,14 +22,6 @@ export abstract class GemDialogBaseElement extends GemElement {
#parentElement: Node | null;
#inertStore: HTMLElement[] = [];

constructor() {
super();
this.effect(
() => (this.inert = true),
() => [],
);
}

/**
* 进入关闭状态
*/
Expand Down Expand Up @@ -60,6 +52,9 @@ export abstract class GemDialogBaseElement extends GemElement {
this.opened = true;
};

@mounted()
#init = () => (this.inert = true);

/**@final */
open = () => {
if (this.opened) return;
Expand Down
Loading

0 comments on commit 3de906a

Please sign in to comment.