Skip to content

Commit

Permalink
[gem] Fixed #202, #203
Browse files Browse the repository at this point in the history
  • Loading branch information
mantou132 committed Oct 1, 2024
1 parent 6bf42f0 commit cd0e9a4
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 37 deletions.
2 changes: 1 addition & 1 deletion packages/duoyun-ui/src/elements/page-loadbar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ export class DuoyunPageLoadbarElement extends GemElement {
clearInterval(Loadbar.timer);
Loadbar.timer = window.setTimeout(() => {
const instance = Loadbar.instance || new Loadbar();
if (!instance.isConnected) document.body.append(instance);
instance.#state({ progress: 0 });
if (!instance.isConnected) document.body.append(instance);
Loadbar.timer = window.setInterval(() => {
instance.#state({ progress: instance.#state.progress + (95 - instance.#state.progress) * 0.1 });
}, 100);
Expand Down
45 changes: 22 additions & 23 deletions packages/duoyun-ui/src/elements/popover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ export class DuoyunPopoverElement extends GemElement {
toggleActiveState(element, true);
const popover = new DuoyunPopoverElement(options);
const restoreInert = options.trigger === 'click' ? setBodyInert(popover) : undefined;
document.body.append(popover);
popover.#open({ left, right, top, bottom });
document.body.append(popover);
// handle mask click
popover.addEventListener('close', () => {
restoreInert?.();
Expand Down Expand Up @@ -275,30 +275,29 @@ export class DuoyunPopoverElement extends GemElement {

@effect((i) => [i.#state.open])
#updateState = () => {
if (this.#state.open && this.#position === 'auto') {
const { top, left, right, bottom, height } = this.popoverElement!.getBoundingClientRect();
let position: Position = 'top';
if (right > innerWidth) {
if (top < 0) {
position = 'bottomRight';
} else if (innerHeight - bottom < height / 2) {
position = 'topRight';
} else {
position = 'left';
}
} else if (left < 0) {
if (top < 0) {
position = 'bottomLeft';
} else if (innerHeight - bottom < height / 2) {
position = 'topLeft';
} else {
position = 'right';
}
} else if (top < 0) {
position = 'bottom';
if (!this.#state.open || this.#position !== 'auto') return;
const { top, left, right, bottom, height } = this.popoverElement!.getBoundingClientRect();
let position: Position = 'top';
if (right > innerWidth) {
if (top < 0) {
position = 'bottomRight';
} else if (innerHeight - bottom < height / 2) {
position = 'topRight';
} else {
position = 'left';
}
} else if (left < 0) {
if (top < 0) {
position = 'bottomLeft';
} else if (innerHeight - bottom < height / 2) {
position = 'topLeft';
} else {
position = 'right';
}
this.#state({ style: this.#genStyle(position), position });
} else if (top < 0) {
position = 'bottom';
}
this.#state({ style: this.#genStyle(position), position });
};

render = () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/gem-book/src/element/elements/loadbar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ export class GemBookLoadbarElement extends GemElement {
clearInterval(Loadbar.timer);
Loadbar.timer = window.setTimeout(() => {
const instance = Loadbar.instance || new Loadbar();
if (!instance.isConnected) document.body.append(instance);
instance.#state({ progress: 0 });
if (!instance.isConnected) document.body.append(instance);
Loadbar.timer = window.setInterval(() => {
instance.#state({ progress: instance.#state.progress + (95 - instance.#state.progress) * 0.1 });
}, 100);
Expand Down
31 changes: 19 additions & 12 deletions packages/gem/src/lib/element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import type { GemReflectElement } from '../elements/reflect';

import type { Store } from './store';
import { connect } from './store';
import { LinkedList, addMicrotask, isArrayChange, addListener, randomStr, createUpdater } from './utils';
import { LinkedList, addMicrotask, isArrayChange, addListener, randomStr, createUpdater, GemError } from './utils';

export { html, svg, render, directive, TemplateResult, SVGTemplateResult } from 'lit-html';

Expand Down Expand Up @@ -232,7 +232,7 @@ type EffectItem<T> = {
fixed?: boolean; // 不需要清理,只会添加一次
values?: T;
getDep?: GetDepFun<T>;
preCallback?: () => void;
preCallback?: any;
};

function execEffectList(list?: EffectItem<any>[]) {
Expand Down Expand Up @@ -318,24 +318,28 @@ export abstract class GemElement extends HTMLElement {
#isAppendReason?: boolean;
#isMounted?: boolean;
// not in constructor 的近似值
#isConnected?: boolean;
#notInCons?: boolean;
#rendering?: boolean;
#clearStyle?: any;
#clearStyle?: (() => void) | undefined;

[updateTokenAlias]() {
// 避免 `connectedCallback` 中的 property 赋值造成多余更新
if (this.#isMounted) {
addMicrotask(this.#update);
}
if (this.#isMounted) addMicrotask(this.#update);
}

static {
createState = <T>(initState: T) => {
const ele = currentConstructGemElement;
const state = createUpdater(initState, (payload) => {
const effect = ele.#effectList.at(0);
// https://github.com/mantou132/gem/issues/203
if (ele.#isMounted && effect && !effect.initialized) {
throw new GemError(`Do't set state sync before insert the DOM`);
}
assign(state, payload);
// 避免无限刷新
if (!ele.#rendering) addMicrotask(ele.#update);
// 挂载前 set state 不应该触发更新
if (!ele.#rendering && ele.#isMounted) addMicrotask(ele.#update);
});
ele.#internals.stateList.push(state);
return state;
Expand Down Expand Up @@ -494,8 +498,12 @@ export abstract class GemElement extends HTMLElement {
#connectedCallback = async () => {
if (this.#isAppendReason) {
this.#isAppendReason = false;
// https://github.com/mantou132/gem/issues/202
this.#clearStyle?.();
this.#clearStyle = this.#prepareStyle();
return;
}
this.#notInCons = true;
this.#compat();

const { observedStores, mode, penetrable } = this.#metadata;
Expand All @@ -504,7 +512,6 @@ export abstract class GemElement extends HTMLElement {
// 如果渲染内容需要应用外部样式,需要手动 `delete` 边界
if (!mode && this.#renderList.length && !penetrable) this.#internals.states.add(BoundaryCSSState);

this.#isConnected = true;
this.#disconnectStore = observedStores?.map((store) => connect(store, this.#update));
this.#render(this.#renderItem);
this.#isMounted = true;
Expand Down Expand Up @@ -554,7 +561,7 @@ export abstract class GemElement extends HTMLElement {
// 是否要异步执行回调?
this.#effectList = clearEffect(this.#effectList);
this.#memoList = clearEffect(this.#memoList);
execCallback(this.#clearStyle);
this.#clearStyle?.();
return GemElement.#final;
}

Expand All @@ -577,7 +584,7 @@ export abstract class GemElement extends HTMLElement {
callback,
getDep,
initialized: this.#isMounted,
fixed: !this.#isConnected,
fixed: !this.#notInCons,
};
// 已挂载时立即执行副作用,未挂载时等挂载后执行
if (this.#isMounted) {
Expand Down Expand Up @@ -608,7 +615,7 @@ export abstract class GemElement extends HTMLElement {
this.#memoList.push({
callback,
getDep,
fixed: !this.#isConnected,
fixed: !this.#notInCons,
});
};

Expand Down

0 comments on commit cd0e9a4

Please sign in to comment.