diff --git a/packages/duoyun-ui/docs/en/02-elements/carousel.md b/packages/duoyun-ui/docs/en/02-elements/carousel.md index 2ab946b1..70d705a2 100644 --- a/packages/duoyun-ui/docs/en/02-elements/carousel.md +++ b/packages/duoyun-ui/docs/en/02-elements/carousel.md @@ -9,14 +9,22 @@ "style": "width: 100%; color: white;", "items": [ { - "img": "https://picsum.photos/800/600?grayscale", + "img": "https://picsum.photos/id/23/800/600?grayscale", "title": "Title 1", + "background": "gray", "description": "This is description section 1" }, { - "img": "https://picsum.photos/800/601?grayscale", + "img": "https://picsum.photos/id/43/800/600?grayscale", "title": "Title 2", + "background": "#dfdfdf", "description": "This is description section 2" + }, + { + "img": "https://picsum.photos/id/63/800/600?grayscale", + "title": "Title 3", + "background": "#dfdfdf", + "description": "This is description section 3" } ] } diff --git a/packages/duoyun-ui/docs/zh/02-elements/carousel.md b/packages/duoyun-ui/docs/zh/02-elements/carousel.md index 2ab946b1..70d705a2 100644 --- a/packages/duoyun-ui/docs/zh/02-elements/carousel.md +++ b/packages/duoyun-ui/docs/zh/02-elements/carousel.md @@ -9,14 +9,22 @@ "style": "width: 100%; color: white;", "items": [ { - "img": "https://picsum.photos/800/600?grayscale", + "img": "https://picsum.photos/id/23/800/600?grayscale", "title": "Title 1", + "background": "gray", "description": "This is description section 1" }, { - "img": "https://picsum.photos/800/601?grayscale", + "img": "https://picsum.photos/id/43/800/600?grayscale", "title": "Title 2", + "background": "#dfdfdf", "description": "This is description section 2" + }, + { + "img": "https://picsum.photos/id/63/800/600?grayscale", + "title": "Title 3", + "background": "#dfdfdf", + "description": "This is description section 3" } ] } diff --git a/packages/duoyun-ui/src/elements/carousel.ts b/packages/duoyun-ui/src/elements/carousel.ts index 370b2ecc..09b4353a 100644 --- a/packages/duoyun-ui/src/elements/carousel.ts +++ b/packages/duoyun-ui/src/elements/carousel.ts @@ -29,6 +29,9 @@ const style = createCSSSheet(css` aspect-ratio: 20 / 7; position: relative; color: ${theme.highlightColor}; + /** use prevImg */ + background-size: cover; + background-position: center; } .list, .item, @@ -49,10 +52,6 @@ const style = createCSSSheet(css` .img { position: absolute; object-fit: cover; - --mask-range: 35%; - --m: linear-gradient(to right top, transparent, black var(--mask-range)); - -webkit-mask-image: var(--m); - mask-image: var(--m); } .content { position: absolute; @@ -63,7 +62,6 @@ const style = createCSSSheet(css` inset: 0; padding-inline: 4em; max-width: 35%; - opacity: 0; animation-duration: 1.3s; } .img, @@ -75,13 +73,10 @@ const style = createCSSSheet(css` animation-direction: reverse; } @keyframes fadeIn { - 0% { + from { + opacity: 0; transform: translateX(calc(var(--direction) * 3em)); } - 100% { - transform: translateX(0); - opacity: 1; - } } .tag { font-style: italic; @@ -206,7 +201,6 @@ export class DuoyunCarouselElement extends GemElement { this.#clearTimer(); this.#timer = window.setTimeout(async () => { await this.#waitLeave; - this.#isFirstRender = false; this.#add(1); }, this.#interval); }; @@ -230,6 +224,19 @@ export class DuoyunCarouselElement extends GemElement { } }; + #prevImg?: string; + willMount() { + this.memo( + (_, oldDeps) => { + if (oldDeps) { + this.#prevImg = this.#items?.[oldDeps[0]]?.img; + this.#isFirstRender = false; + } + }, + () => [this.state.currentIndex], + ); + } + mounted = () => { this.#reset(); this.effect( @@ -245,19 +252,16 @@ export class DuoyunCarouselElement extends GemElement { render = () => { const { currentIndex, direction } = this.state; + return html` +
    ${this.#items?.map( - ({ img, background = 'none', title, description, action, tag, onClick }, index) => html` - ${currentIndex === index - ? html` - - ` - : ''} + ({ img, title, background, description, action, tag, onClick }, index) => html`
  • { ${title { }; jump = (index: number) => { - this.setState({ currentIndex: index, direction: 1 }); + this.setState({ currentIndex: index, direction: index > this.state.currentIndex ? 1 : -1 }); this.#reset(); }; } diff --git a/packages/duoyun-ui/src/elements/modal.ts b/packages/duoyun-ui/src/elements/modal.ts index 4f332ee6..e736efb5 100644 --- a/packages/duoyun-ui/src/elements/modal.ts +++ b/packages/duoyun-ui/src/elements/modal.ts @@ -27,7 +27,9 @@ import './button'; import './divider'; const style = createCSSSheet(css` + /* modal 可能会在刷新前后保持打开 */ :host { + view-transition-name: dy-modal; position: fixed; z-index: ${theme.popupZIndex}; top: env(titlebar-area-height, var(--titlebar-area-height, 0px)); @@ -259,7 +261,7 @@ export class DuoyunModalElement extends GemElement { willMount = () => { this.memo( - () => (this.closing = !this.open), + (_, oldDeps) => oldDeps && (this.closing = !this.open), () => [this.open], ); }; @@ -268,11 +270,13 @@ export class DuoyunModalElement extends GemElement { mounted = () => { this.effect( - () => { + async () => { if (this.open) { !this.shadowRoot?.activeElement && this.focus(); - } else { - this.#closeAnimate().finished.then(() => (this.closing = false)); + } else if (this.closing) { + await this.#closeAnimate().finished; + this.closing = false; + this.update(); } }, () => [this.open], diff --git a/packages/gem/src/lib/element.ts b/packages/gem/src/lib/element.ts index c9bd9612..d7417787 100644 --- a/packages/gem/src/lib/element.ts +++ b/packages/gem/src/lib/element.ts @@ -220,6 +220,7 @@ export abstract class GemElement> extends HTMLElemen * @helper * 记录副作用回调和值,在 `constructor`/`mounted` 中使用 * 回调到返回值如果是函数将再卸载时执行 + * 第一次执行时 `oldDeps` 为空 * * ```js * class App extends GemElement { @@ -234,7 +235,6 @@ export abstract class GemElement> extends HTMLElemen const effectItem: EffectItem = { callback, getDep, - values: undefined, initialized: this.#isMounted, inConstructor: (this as any)[constructorSymbol], }; @@ -248,7 +248,8 @@ export abstract class GemElement> extends HTMLElemen /** * @helper - * 在 `render` 前执行回调,和 `effect` 一样接受依赖数组参数,在 `constructor`/`willMount` 中使用 + * 在 `render` 前执行回调,和 `effect` 一样接受依赖数组参数,在 `constructor`/`willMount` 中使用; + * 第一次执行时 `oldDeps` 为空 * * ```js * class App extends GemElement { @@ -265,8 +266,6 @@ export abstract class GemElement> extends HTMLElemen this.#memoList.push({ callback, getDep, - // 这里为什么跟 effect 不同??? - values: [Symbol()], inConstructor: (this as any)[constructorSymbol], }); };