diff --git a/packages/duoyun-ui/src/elements/action-text.ts b/packages/duoyun-ui/src/elements/action-text.ts index 172e9af7..89fa94b3 100644 --- a/packages/duoyun-ui/src/elements/action-text.ts +++ b/packages/duoyun-ui/src/elements/action-text.ts @@ -1,6 +1,7 @@ import { GemElement, html, createCSSSheet } from '@mantou/gem/lib/element'; import { adoptedStyle, customElement, attribute, state, slot, aria, shadow, mounted } from '@mantou/gem/lib/decorators'; import { addListener, css } from '@mantou/gem/lib/utils'; +import { useDecoratorTheme } from '@mantou/gem/helper/theme'; import { theme, getSemanticColor } from '../lib/theme'; import { commonHandle } from '../lib/hotkeys'; @@ -8,17 +9,19 @@ import { focusStyle } from '../lib/styles'; import './tooltip'; +const [elementTheme, updateTheme] = useDecoratorTheme({ color: '', activeColor: '' }); + const style = createCSSSheet(css` :host { overflow: hidden; text-overflow: ellipsis; cursor: default; line-height: 1.5; - color: var(--color, inherit); + color: ${elementTheme.color}; border-radius: ${theme.normalRound}; } :host(:where(:hover, :state(active))) { - color: var(--color, ${theme.primaryColor}); + color: ${elementTheme.activeColor}; text-decoration: underline; } :host(:where(:lang(zh), :lang(ja), :lang(kr))) { @@ -46,13 +49,14 @@ export class DuoyunActionTextElement extends GemElement { @mounted() #init = () => addListener(this, 'keydown', commonHandle); + @updateTheme() + #theme = () => { + const color = getSemanticColor(this.color) || this.color; + return { color: color || 'inherit', activeColor: color || theme.primaryColor }; + }; + render = () => { return html` - diff --git a/packages/duoyun-ui/src/elements/alert.ts b/packages/duoyun-ui/src/elements/alert.ts index 91fb3a6f..a4b04b93 100644 --- a/packages/duoyun-ui/src/elements/alert.ts +++ b/packages/duoyun-ui/src/elements/alert.ts @@ -2,6 +2,7 @@ import { adoptedStyle, customElement, attribute, property, slot, aria, shadow } from '@mantou/gem/lib/decorators'; import { GemElement, html, createCSSSheet } from '@mantou/gem/lib/element'; import { css } from '@mantou/gem/lib/utils'; +import { useDecoratorTheme } from '@mantou/gem/helper/theme'; import { theme, getSemanticColor } from '../lib/theme'; import { icons } from '../lib/icons'; @@ -9,13 +10,15 @@ import { icons } from '../lib/icons'; import './use'; import './action-text'; +const [elementTheme, updateTheme] = useDecoratorTheme({ color: '' }); + const style = createCSSSheet(css` :host(:where(:not([hidden]))) { display: flex; flex-direction: column; padding: 1.2em 1.5em; gap: 0.8em; - border: 2px solid var(--color); + border: 2px solid ${elementTheme.color}; border-radius: ${theme.normalRound}; } .header { @@ -35,7 +38,7 @@ const style = createCSSSheet(css` } .icon { width: 1.5em; - color: var(--color); + color: ${elementTheme.color}; } .footer { text-align: right; @@ -72,18 +75,12 @@ export class DuoyunAlertElement extends GemElement { } } - get #color() { - return getSemanticColor(this.status) || theme.neutralColor; - } + @updateTheme() + #theme = () => ({ color: getSemanticColor(this.status) || theme.neutralColor }); render = () => { const icon = this.#icon; return html` -
${this.header}
${icon ? html`` : ''} diff --git a/packages/duoyun-ui/src/elements/area-chart.ts b/packages/duoyun-ui/src/elements/area-chart.ts index 57f1bd42..213fcb1c 100644 --- a/packages/duoyun-ui/src/elements/area-chart.ts +++ b/packages/duoyun-ui/src/elements/area-chart.ts @@ -1,6 +1,7 @@ -import { createState, html, svg } from '@mantou/gem/lib/element'; -import { customElement, emitter, Emitter, memo, mounted, property } from '@mantou/gem/lib/decorators'; -import { addListener, classMap } from '@mantou/gem/lib/utils'; +import { createCSSSheet, createState, html, svg } from '@mantou/gem/lib/element'; +import { adoptedStyle, customElement, emitter, Emitter, memo, mounted, property } from '@mantou/gem/lib/decorators'; +import { addListener, classMap, css } from '@mantou/gem/lib/utils'; +import { useDecoratorTheme } from '@mantou/gem/helper/theme'; import { isNotNullish } from '../lib/types'; import { theme } from '../lib/theme'; @@ -35,10 +36,65 @@ export function defaultSymbolRender({ point, color, isHover, chart }: SymbolRend `; } +const [elementTheme, updateTheme] = useDecoratorTheme({ + lineStrokeWidth: 0, + areaHighlightOpacity: 0, + areaPointer: '', + areaOpacity: 0, + zoomLeft: '', + zoomRight: '', + symbolStrokeWidth: 0, +}); + +const style = createCSSSheet(css` + .hit-line { + pointer-events: stroke; + } + .hit-line:hover + .line { + stroke-width: ${elementTheme.lineStrokeWidth}; + } + .hit-line:hover + .line + .area { + opacity: ${elementTheme.areaHighlightOpacity}; + } + .hit-line + .line, + .hover-line, + .disabled { + pointer-events: none; + } + .area { + pointer-events: ${elementTheme.areaPointer}; + } + .area:hover { + filter: brightness(1.1); + } + .line.disabled { + stroke: ${theme.disabledColor}; + opacity: 0.3; + } + .area { + opacity: ${elementTheme.areaOpacity}; + } + .area.disabled { + fill: ${theme.disabledColor}; + opacity: 0.1; + } + .symbol { + pointer-events: none; + fill: ${theme.backgroundColor}; + stroke-width: ${elementTheme.symbolStrokeWidth}; + } + dy-chart-zoom { + width: calc(100% - ${elementTheme.zoomLeft} - ${elementTheme.zoomRight}); + margin-inline-start: ${elementTheme.zoomLeft}; + align-self: flex-start; + } +`); + /** * @customElement dy-area-chart */ @customElement('dy-area-chart') +@adoptedStyle(style) export class DuoyunAreaChartElement extends DuoyunChartBaseElement { @property fill = true; @property stroke = true; @@ -299,56 +355,23 @@ export class DuoyunAreaChartElement extends DuoyunChartBaseElement { return () => ChartTooltip.close(); }; + @updateTheme() + #theme = () => ({ + lineStrokeWidth: this.getSVGPixel(2), + symbolStrokeWidth: this.getSVGPixel(1), + areaHighlightOpacity: this.#gradient ? 0.4 : 0.2, + areaOpacity: this.stack ? 1 : this.#gradient ? 0.3 : 0.15, + areaPointer: this.stack ? 'all' : 'none', + zoomLeft: `${-this.viewBox[0] * this.getStageScale()}px`, + zoomRight: `${(this.viewBox[2] + this.viewBox[0] - this.stageWidth) * this.getStageScale()}px`, + }); + render = () => { if (this.loading) return this.renderLoading(); if (this.noData) return this.renderNotData(); if (!this.contentRect.width || !this.#sequences?.length) return html``; - const areaOpacity = this.stack ? 1 : this.#gradient ? 0.3 : 0.15; - const areaHighlightOpacity = this.#gradient ? 0.4 : 0.2; return html` - ${svg` addListener(this, 'click', this.#onClick); + @updateTheme() + #theme = () => { + if (this.disabled) return { bg: theme.disabledColor, color: theme.backgroundColor }; + switch (this.color) { + case 'normal': + return { bg: theme.primaryColor, color: theme.backgroundColor }; + case 'danger': + return { bg: theme.negativeColor, color: theme.backgroundColor }; + case 'cancel': + return { bg: theme.hoverBackgroundColor, color: theme.textColor }; + default: + return { bg: getSemanticColor(this.color) || this.color || theme.primaryColor, color: theme.backgroundColor }; + } + }; + render = () => { return html` -
${this.icon ? html`` : ''} @@ -220,16 +225,6 @@ export class DuoyunButtonElement extends GemElement {
${this.dropdown ? html` - [i.#state.currentIndex]) - #updateImg = () => (_: number[], oldDeps?: number[]) => { + #updateImg = (_: number[], oldDeps?: number[]) => { if (oldDeps) { this.#prevImg = this.#items?.[oldDeps[0]]?.img; this.#isFirstRender = false; @@ -250,15 +254,13 @@ export class DuoyunCarouselElement extends GemElement { @effect((i) => [i.#state.currentIndex]) #emitterEvent = () => this.change(this.#state.currentIndex); + @updateTheme() + #theme = () => ({ bgImg: this.#prevImg ? `url(${this.#prevImg})` : 'none' }); + render = () => { const { currentIndex } = this.#state; return html` -