/** * components/kf-empty.js —— 空态 / 错误态 / 加载骨架。 * 空态 = 图标 + 一句主文案(≤15 字)+ 一个按钮;不放复合解释。 * * 属性:title / hint / action-label(有值时渲染按钮,点击派发 empty-action) * kind: empty | error | loading */ import { LitElement, html, css } from 'lit'; import { useTokens, define } from './base.js'; import { icon } from './icons.js'; export class KfEmpty extends LitElement { static properties = { title: { type: String }, hint: { type: String }, actionLabel: { type: String, attribute: 'action-label' }, kind: { type: String, reflect: true }, }; constructor() { super(); this.title = '这里将来会出现内容'; this.hint = ''; this.actionLabel = ''; this.kind = 'empty'; } connectedCallback() { super.connectedCallback(); useTokens(this); } static styles = css` :host { display: block; min-width: 0; } /* 空态(v10 任务书 2.9):图标 24px opacity .6 + 一句 13px 说明 + 次级按钮; 最小高度 = 正常内容高度(168px),切换筛选时页面不跳。 */ .e { min-height: 168px; box-sizing: border-box; display: grid; justify-items: center; align-content: center; justify-content: center; gap: 8px; padding: 32px 16px; text-align: center; } .ico { display: grid; place-items: center; width: 24px; height: 24px; opacity: 0.6; } .ico svg { width: 24px; height: 24px; stroke: var(--kf-ink-3); } :host([kind="error"]) .ico svg { stroke: var(--kf-danger); } .t { color: var(--kf-ink); font-weight: 500; font-size: 14px; line-height: 1.4; letter-spacing: 0; overflow-wrap: anywhere; } .h { color: var(--kf-ink-3); font-size: 14px; max-width: 46ch; min-width: 0; line-height: 1.6; overflow-wrap: anywhere; } .e .kf-btn { margin-top: 8px; height: 28px; font-size: 14px; } /* 加载骨架:与空态同高,数据回来不跳 */ .e.load { justify-items: stretch; justify-content: stretch; gap: 12px; padding: 24px; } .bar { width: 100%; height: 12px; } `; render() { if (this.kind === 'loading') { return html`
`; } const ico = this.kind === 'error' ? icon('alert', 24) : icon('inbox', 24); return html`
${this.title}
${this.hint ? html`
${this.hint}
` : ''} ${this.actionLabel ? html`` : ''}
`; } } define('kf-empty', KfEmpty);