From e8d87f765eb2de0fb3b52322c5c637ad45c6c5f7 Mon Sep 17 00:00:00 2001
From: mantou132 <709922234@qq.com>
Date: Sun, 1 Sep 2024 14:35:01 +0800
Subject: [PATCH] [duoyun-ui] Closed #191
---
.../duoyun-ui/docs/en/02-elements/empty.md | 1 +
.../duoyun-ui/docs/zh/02-elements/empty.md | 1 +
packages/duoyun-ui/src/elements/card.ts | 18 +++--
packages/duoyun-ui/src/elements/collapse.ts | 6 +-
.../duoyun-ui/src/elements/compartment.ts | 2 +-
packages/duoyun-ui/src/elements/empty.ts | 28 ++++++--
packages/duoyun-ui/src/elements/meter.ts | 14 ++--
packages/duoyun-ui/src/elements/modal.ts | 70 +++++++++++--------
packages/duoyun-ui/src/elements/popover.ts | 1 +
packages/duoyun-ui/src/elements/result.ts | 25 +++++--
packages/duoyun-ui/src/elements/statistic.ts | 19 ++++-
packages/duoyun-ui/src/elements/table.ts | 11 ++-
packages/duoyun-ui/src/lib/styles.ts | 1 +
packages/duoyun-ui/src/patterns/nav.ts | 4 +-
.../004-blog/001-create-standard-element.md | 19 ++++-
.../004-blog/001-create-standard-element.md | 20 +++++-
16 files changed, 170 insertions(+), 70 deletions(-)
diff --git a/packages/duoyun-ui/docs/en/02-elements/empty.md b/packages/duoyun-ui/docs/en/02-elements/empty.md
index f0c48839..f4bc0931 100644
--- a/packages/duoyun-ui/docs/en/02-elements/empty.md
+++ b/packages/duoyun-ui/docs/en/02-elements/empty.md
@@ -4,6 +4,7 @@
## API
diff --git a/packages/duoyun-ui/docs/zh/02-elements/empty.md b/packages/duoyun-ui/docs/zh/02-elements/empty.md
index f0c48839..f4bc0931 100644
--- a/packages/duoyun-ui/docs/zh/02-elements/empty.md
+++ b/packages/duoyun-ui/docs/zh/02-elements/empty.md
@@ -4,6 +4,7 @@
## API
diff --git a/packages/duoyun-ui/src/elements/card.ts b/packages/duoyun-ui/src/elements/card.ts
index 9d188c81..01e8ccfa 100644
--- a/packages/duoyun-ui/src/elements/card.ts
+++ b/packages/duoyun-ui/src/elements/card.ts
@@ -1,12 +1,13 @@
// https://spectrum.adobe.com/page/cards/
import { adoptedStyle, customElement, attribute, property, part, slot, shadow, aria } from '@mantou/gem/lib/decorators';
-import { createCSSSheet, html, TemplateResult } from '@mantou/gem/lib/element';
+import { createCSSSheet, html } from '@mantou/gem/lib/element';
import { css } from '@mantou/gem/lib/utils';
import { theme } from '../lib/theme';
import { icons } from '../lib/icons';
import { commonHandle } from '../lib/hotkeys';
import { focusStyle } from '../lib/styles';
+import { StringList } from '../lib/types';
import { DuoyunLoadableBaseElement } from './base/loadable';
import { ContextMenuItem, ContextMenu } from './contextmenu';
@@ -105,6 +106,9 @@ export class DuoyunCardElement extends DuoyunLoadableBaseElement {
@part static preview: string;
@part static avatar: string;
+ @slot static header: string;
+ @slot static detail: string;
+ @slot static detailRight: string;
@slot static body: string;
@slot static unnamed: string;
@slot static footer: string;
@@ -112,9 +116,9 @@ export class DuoyunCardElement extends DuoyunLoadableBaseElement {
@attribute avatar: string;
@attribute preview: string;
- @property header?: string | TemplateResult;
- @property detail?: string | TemplateResult;
- @property detailRight?: string | TemplateResult;
+ @attribute header: StringList<'slot'>;
+ @attribute detail: string;
+ @attribute detailRight: string;
@property actions?: ActionItem[];
@attribute crossorigin: 'anonymous' | 'use-credentials';
@@ -149,9 +153,9 @@ export class DuoyunCardElement extends DuoyunLoadableBaseElement {
${this.header
? html`
${expand || this.searchable
? html`
diff --git a/packages/duoyun-ui/src/elements/compartment.ts b/packages/duoyun-ui/src/elements/compartment.ts
index 36cf7f0b..33a148da 100644
--- a/packages/duoyun-ui/src/elements/compartment.ts
+++ b/packages/duoyun-ui/src/elements/compartment.ts
@@ -10,7 +10,7 @@ import { contentsContainer } from '../lib/styles';
@adoptedStyle(contentsContainer)
@shadow()
export class DuoyunCompartmentElement extends GemElement {
- @property content?: string | number | TemplateResult;
+ @property content?: string | number | TemplateResult | Element | Element[];
render = () => {
return html`${this.content}`;
diff --git a/packages/duoyun-ui/src/elements/empty.ts b/packages/duoyun-ui/src/elements/empty.ts
index 06f2038c..22342142 100644
--- a/packages/duoyun-ui/src/elements/empty.ts
+++ b/packages/duoyun-ui/src/elements/empty.ts
@@ -1,8 +1,17 @@
-import { connectStore, adoptedStyle, customElement, property, shadow } from '@mantou/gem/lib/decorators';
-import { GemElement, html, TemplateResult, createCSSSheet } from '@mantou/gem/lib/element';
+import {
+ connectStore,
+ adoptedStyle,
+ customElement,
+ property,
+ shadow,
+ attribute,
+ slot,
+} from '@mantou/gem/lib/decorators';
+import { GemElement, html, createCSSSheet, render } from '@mantou/gem/lib/element';
import { css } from '@mantou/gem/lib/utils';
import { locale } from '../lib/locale';
+import { theme } from '../lib/theme';
import './use';
@@ -13,9 +22,10 @@ const style = createCSSSheet(css`
align-items: center;
justify-content: center;
gap: 1em;
+ color: ${theme.describeColor};
}
.icon {
- width: 3em;
+ width: 5em;
}
`);
@@ -27,13 +37,21 @@ const style = createCSSSheet(css`
@connectStore(locale)
@shadow()
export class DuoyunEmptyElement extends GemElement {
+ @slot static unnamed: string;
+
@property icon?: string | Element | DocumentFragment;
- @property description?: string | TemplateResult;
+ @attribute text: string;
+ @attribute slotName: string;
render = () => {
+ if (this.slotName && !this.text) {
+ render(html``, this);
+ } else {
+ this.innerHTML = '';
+ }
return html`
${this.icon ? html`` : ''}
- ${this.description || locale.noData}
+ ${this.text || locale.noData}
`;
};
}
diff --git a/packages/duoyun-ui/src/elements/meter.ts b/packages/duoyun-ui/src/elements/meter.ts
index 83e7332a..767b6cb0 100644
--- a/packages/duoyun-ui/src/elements/meter.ts
+++ b/packages/duoyun-ui/src/elements/meter.ts
@@ -8,8 +8,9 @@ import {
aria,
shadow,
effect,
+ slot,
} from '@mantou/gem/lib/decorators';
-import { createCSSSheet, GemElement, html, TemplateResult } from '@mantou/gem/lib/element';
+import { createCSSSheet, GemElement, html } from '@mantou/gem/lib/element';
import { css, styleMap } from '@mantou/gem/lib/utils';
import { theme, getSemanticColor } from '../lib/theme';
@@ -60,15 +61,18 @@ const style = createCSSSheet(css`
@aria({ role: 'meter' })
@shadow()
export class DuoyunMeterElement extends GemElement {
+ @slot static label: string;
+ @slot static valueLabel: string;
+
/**range: 0-100 */
@numattribute value: number;
@numattribute max: number;
@numattribute min: number;
@attribute color: StringList<'positive' | 'informative' | 'negative' | 'notice'>;
@attribute layout: 'stack' | 'flat';
+ @attribute label: string;
+ @attribute valueLabel: StringList<'percentage'>;
- @property label?: string | TemplateResult;
- @property valueLabel?: 'percentage' | TemplateResult;
@property calculateColor = () => {
const progress = this.#progress;
if (progress > 0.9) return theme.negativeColor;
@@ -110,8 +114,8 @@ export class DuoyunMeterElement extends GemElement {
render = () => {
return html`
- ${this.label}
- ${this.#valueLabel}
+ ${this.label}
+ ${this.valueLabel}
diff --git a/packages/duoyun-ui/src/elements/modal.ts b/packages/duoyun-ui/src/elements/modal.ts
index c0909145..940a06fd 100644
--- a/packages/duoyun-ui/src/elements/modal.ts
+++ b/packages/duoyun-ui/src/elements/modal.ts
@@ -125,6 +125,7 @@ const style2 = createCSSSheet({
export interface ModalOptions {
header?: string | TemplateResult;
body?: string | TemplateResult;
+ footer?: string | TemplateResult;
/**render body only */
customize?: boolean;
maskClosable?: boolean;
@@ -154,12 +155,11 @@ export interface ModalOpenOptions
{
@shadow({ delegatesFocus: true })
export class DuoyunModalElement extends GemElement {
@part static dialog: string;
- @part static heading: string;
@part static divider: string;
+ @part @slot static header: string;
@part static body: string;
- @part @slot static footer: string;
- // break change: body -> unnamed
@slot static unnamed: string;
+ @part @slot static footer: string;
@boolattribute open: boolean;
@boolattribute customize: boolean;
@@ -169,18 +169,22 @@ export class DuoyunModalElement extends GemElement {
@boolattribute disableDefaultCancelBtn: boolean;
@boolattribute disableDefaultOKBtn: boolean;
@boolattribute dangerDefaultOkBtn: boolean;
+ @attribute header: string;
+ @attribute body: string;
@emitter close: Emitter;
@emitter ok: Emitter;
@emitter maskclick: Emitter;
- @property header?: string | TemplateResult;
- @property body?: string | TemplateResult;
@property openAnimation: PropertyIndexedKeyframes | Keyframe[] = slideInUp;
@property closeAnimation: PropertyIndexedKeyframes | Keyframe[] = fadeOut;
@state closing: boolean;
+ headerSlot?: string | TemplateResult;
+ bodySlot?: string | TemplateResult;
+ footerSlot?: string | TemplateResult;
+
// Cannot be used for dynamic forms
static open(options: ModalOptions & ModalOpenOptions) {
const modal = new this({ ...options, open: true });
@@ -230,23 +234,25 @@ export class DuoyunModalElement extends GemElement {
open,
customize,
maskClosable,
- cancelText,
- okText,
+ cancelText = '',
+ okText = '',
body,
+ footer,
disableDefaultCancelBtn,
disableDefaultOKBtn,
dangerDefaultOkBtn,
} = options;
- if (header) this.header = header;
- if (customize) this.customize = customize;
- if (maskClosable) this.maskClosable = maskClosable;
- if (open) this.open = open;
- if (cancelText) this.cancelText = cancelText;
- if (okText) this.okText = okText;
- if (disableDefaultCancelBtn) this.disableDefaultCancelBtn = disableDefaultCancelBtn;
- if (disableDefaultOKBtn) this.disableDefaultOKBtn = disableDefaultOKBtn;
- if (dangerDefaultOkBtn) this.dangerDefaultOkBtn = dangerDefaultOkBtn;
- if (body) this.body = body;
+ this.headerSlot = header;
+ this.bodySlot = body;
+ this.footerSlot = footer;
+ this.customize = !!customize;
+ this.maskClosable = !!maskClosable;
+ this.open = !!open;
+ this.cancelText = cancelText;
+ this.okText = okText;
+ this.disableDefaultCancelBtn = !!disableDefaultCancelBtn;
+ this.disableDefaultOKBtn = !!disableDefaultOKBtn;
+ this.dangerDefaultOkBtn = !!dangerDefaultOkBtn;
}
#maskRef = createRef();
@@ -316,7 +322,7 @@ export class DuoyunModalElement extends GemElement {
aria-modal="true"
class="dialog absolute"
>
- ${this.body || html``}
+ ${this.body || this.bodySlot || html``}
`
: html`
@@ -330,26 +336,30 @@ export class DuoyunModalElement extends GemElement {
>
${this.header
? html`
-
diff --git a/packages/duoyun-ui/src/elements/popover.ts b/packages/duoyun-ui/src/elements/popover.ts
index bf2de3b1..b9c0001b 100644
--- a/packages/duoyun-ui/src/elements/popover.ts
+++ b/packages/duoyun-ui/src/elements/popover.ts
@@ -67,6 +67,7 @@ export class DuoyunPopoverElement extends GemElement {
@attribute trigger: 'click' | 'hover';
@attribute position: Position | 'auto';
+ // 不能通过 slot 元素支持
@property content?: string | TemplateResult;
@emitter open: Emitter;
diff --git a/packages/duoyun-ui/src/elements/result.ts b/packages/duoyun-ui/src/elements/result.ts
index 683f25ab..8490ee31 100644
--- a/packages/duoyun-ui/src/elements/result.ts
+++ b/packages/duoyun-ui/src/elements/result.ts
@@ -1,8 +1,9 @@
-import { GemElement, html, TemplateResult, createCSSSheet } from '@mantou/gem/lib/element';
+import { GemElement, html, createCSSSheet } from '@mantou/gem/lib/element';
import { adoptedStyle, customElement, property, attribute, slot, shadow } from '@mantou/gem/lib/decorators';
import { css } from '@mantou/gem/lib/utils';
import { theme } from '../lib/theme';
+import { StringList } from '../lib/types';
import { Status, getStatusColor } from './status-light';
@@ -45,14 +46,16 @@ const style = createCSSSheet(css`
@adoptedStyle(style)
@shadow()
export class DuoyunResultElement extends GemElement {
+ @slot static header: string;
+ @slot static description: string;
@slot static unnamed: string;
@attribute status: Status;
+ @attribute header: StringList<'slot'>;
+ @attribute description: StringList<'slot'>;
@property icon?: string | Element | DocumentFragment;
@property illustrator?: string | Element | DocumentFragment;
- @property header?: string | TemplateResult;
- @property description?: string | TemplateResult;
get #status() {
return this.status || 'default';
@@ -66,8 +69,20 @@ export class DuoyunResultElement extends GemElement {
return html`
${this.icon ? html`` : ''}
${this.illustrator ? html`` : ''}
- ${this.header ? html`` : ''}
- ${this.description ? html`${this.description}` : ''}
+ ${this.header
+ ? html`
+
+ `
+ : ''}
+ ${this.description
+ ? html`
+
+ ${this.description}
+
+ `
+ : ''}
`;
};
diff --git a/packages/duoyun-ui/src/elements/statistic.ts b/packages/duoyun-ui/src/elements/statistic.ts
index 33f4d1ce..99cc002d 100644
--- a/packages/duoyun-ui/src/elements/statistic.ts
+++ b/packages/duoyun-ui/src/elements/statistic.ts
@@ -7,8 +7,9 @@ import {
property,
aria,
shadow,
+ slot,
} from '@mantou/gem/lib/decorators';
-import { GemElement, html, TemplateResult, createCSSSheet } from '@mantou/gem/lib/element';
+import { GemElement, html, createCSSSheet } from '@mantou/gem/lib/element';
import { css, classMap } from '@mantou/gem/lib/utils';
import { parseDuration } from '../lib/time';
@@ -82,9 +83,13 @@ export const formatFnMap: Record { number: string;
@aria({ role: 'group' })
@shadow()
export class DuoyunStatisticElement extends GemElement {
+ @slot static header: string;
+
@attribute neutral: StatisticNeutral;
@attribute type: StatisticType;
- @property text: string | TemplateResult;
+ /**@deprecated */
+ @attribute text: string;
+ @attribute header: string;
@property icon: string | Element | DocumentFragment;
@boolattribute loading: boolean;
@numattribute value: number;
@@ -98,6 +103,10 @@ export class DuoyunStatisticElement extends GemElement {
return this.type || 'decimal';
}
+ get #header() {
+ return this.header || this.text;
+ }
+
render = () => {
const { number, unit } = formatFnMap[this.#type](this.value);
@@ -110,7 +119,11 @@ export class DuoyunStatisticElement extends GemElement {
return html`
diff --git a/packages/duoyun-ui/src/elements/table.ts b/packages/duoyun-ui/src/elements/table.ts
index 9c6d857a..c13dfd8d 100644
--- a/packages/duoyun-ui/src/elements/table.ts
+++ b/packages/duoyun-ui/src/elements/table.ts
@@ -11,6 +11,7 @@ import {
part,
shadow,
memo,
+ slot,
} from '@mantou/gem/lib/decorators';
import { createCSSSheet, html, TemplateResult } from '@mantou/gem/lib/element';
import { css, styleMap, classMap, StyleObject, isArrayChange } from '@mantou/gem/lib/utils';
@@ -164,9 +165,11 @@ export class DuoyunTableElement
extends DuoyunScrollBoxElement
@part static td: string;
@part static tr: string;
@part static side: string;
+ @slot static noData: string;
@attribute caption: string;
@boolattribute headless: boolean;
+ @attribute noData: string;
@boolattribute selectable: boolean;
@property selection?: K[];
@@ -180,8 +183,6 @@ export class DuoyunTableElement extends DuoyunScrollBoxElement
@property data?: T[] | (T | undefined)[];
@property getRowStyle?: (record: T) => StyleObject;
- @property noData?: string | TemplateResult;
-
@property rowKey?: string | string[];
@property getKey?: (record: T) => K;
@property expandedRowRender?: (record: T) => undefined | string | TemplateResult;
@@ -476,7 +477,11 @@ export class DuoyunTableElement extends DuoyunScrollBoxElement
${!this.data
? html`
`
: this.data.length === 0
- ? html`${this.noData || html``}
`
+ ? html`
+
+
+
+ `
: ''}
`;
};
diff --git a/packages/duoyun-ui/src/lib/styles.ts b/packages/duoyun-ui/src/lib/styles.ts
index 78a3cd99..6637318c 100644
--- a/packages/duoyun-ui/src/lib/styles.ts
+++ b/packages/duoyun-ui/src/lib/styles.ts
@@ -38,6 +38,7 @@ export const contentsContainer = createCSSSheet(css`
}
`);
+/** render empty content */
export const noneTemplate = html`