@greypan/web-ui 11.1.0 → 11.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.CN.md CHANGED
@@ -369,44 +369,44 @@ dropdown、tooltip)不需要它。
369
369
 
370
370
  每个组件都有自己的文档页,API 参考、行为说明和可交互示例都在 [`docs/`](./docs/) 下。下面的表只是索引。
371
371
 
372
- | 分类 | 组件 |
373
- | --------------------- | ----------------------------------------------------------- |
374
- | **表单控件** | [`<web-ui-input>`](./docs/input.md) |
375
- | | [`<web-ui-textarea>`](./docs/textarea.md) |
376
- | | [`<web-ui-editable-text>`](./docs/editable-text.md) |
377
- | | [`<web-ui-input-number>`](./docs/input-number.md) |
378
- | | [`<web-ui-select>`](./docs/select.md) |
379
- | | [`<web-ui-autocomplete>`](./docs/autocomplete.md) |
380
- | | [`<web-ui-slider>`](./docs/slider.md) |
381
- | | [`<web-ui-checkbox>`](./docs/checkbox.md) |
382
- | | [`<web-ui-radio>`](./docs/radio.md) |
383
- | | [`<web-ui-switch>`](./docs/switch.md) |
384
- | | [`<web-ui-segmented>`](./docs/segmented.md) |
385
- | | [`<web-ui-checkbox-group>`](./docs/checkbox-group.md) |
386
- | | [`<web-ui-radio-group>`](./docs/radio-group.md) |
387
- | **button** | [`<web-ui-button>`](./docs/button.md) |
388
- | | [`<web-ui-button-group>`](./docs/button-group.md) |
389
- | **overlay / 模态** | [`<web-ui-dialog>`](./docs/dialog.md) |
390
- | | [`<web-ui-drawer>`](./docs/drawer.md) |
391
- | | [`imagePreview()`](./docs/image-preview.md) |
392
- | **文档流 Disclosure** | [`<web-ui-collapse>`](./docs/collapse.md) |
393
- | **浮动** | [`<web-ui-popover>`](./docs/popover.md) |
394
- | | [`<web-ui-tooltip>`](./docs/tooltip.md) |
395
- | | [`<web-ui-context-menu>`](./docs/context-menu.md) |
396
- | **menu** | [`<web-ui-dropdown>`](./docs/dropdown.md) |
397
- | | [`<web-ui-dropdown-item>`](./docs/dropdown-item.md) |
398
- | | [`<web-ui-dropdown-divider>`](./docs/dropdown-divider.md) |
399
- | | [`<web-ui-dropdown-header>`](./docs/dropdown-header.md) |
400
- | **数据展示** | [`<web-ui-avatar>`](./docs/avatar.md) |
401
- | | [`<web-ui-badge>`](./docs/badge.md) |
402
- | | [`<web-ui-empty>`](./docs/empty.md) |
403
- | | [`<web-ui-middle-ellipsis>`](./docs/middle-ellipsis.md) |
404
- | | [`<web-ui-icon>`](./docs/icon.md) |
405
- | | [`<web-ui-spinner>`](./docs/spinner.md) |
406
- | **布局与工具** | [`<web-ui-layout>`](./docs/layout.md) |
407
- | | [`<web-ui-back-top>`](./docs/back-top.md) |
408
- | | [`<web-ui-svg-draw-lines>`](./docs/svg-draw-lines.md) |
409
- | | [`<web-ui-theme>`](./docs/theme.md) |
410
- | **通知** | [`<web-ui-toast>`](./docs/toast.md) |
411
- | **子项** | [`<web-ui-option>`](./docs/option.md) |
412
- | | [`<web-ui-segmented-trigger>`](./docs/segmented-trigger.md) |
372
+ | 分类 | 组件 |
373
+ | --------------------- | -------------------------------------------------------------- |
374
+ | **表单控件** | [`<web-ui-input>`](./docs/input.CN.md) |
375
+ | | [`<web-ui-textarea>`](./docs/textarea.CN.md) |
376
+ | | [`<web-ui-editable-text>`](./docs/editable-text.CN.md) |
377
+ | | [`<web-ui-input-number>`](./docs/input-number.CN.md) |
378
+ | | [`<web-ui-select>`](./docs/select.CN.md) |
379
+ | | [`<web-ui-autocomplete>`](./docs/autocomplete.CN.md) |
380
+ | | [`<web-ui-slider>`](./docs/slider.CN.md) |
381
+ | | [`<web-ui-checkbox>`](./docs/checkbox.CN.md) |
382
+ | | [`<web-ui-radio>`](./docs/radio.CN.md) |
383
+ | | [`<web-ui-switch>`](./docs/switch.CN.md) |
384
+ | | [`<web-ui-segmented>`](./docs/segmented.CN.md) |
385
+ | | [`<web-ui-checkbox-group>`](./docs/checkbox-group.CN.md) |
386
+ | | [`<web-ui-radio-group>`](./docs/radio-group.CN.md) |
387
+ | **button** | [`<web-ui-button>`](./docs/button.CN.md) |
388
+ | | [`<web-ui-button-group>`](./docs/button-group.CN.md) |
389
+ | **overlay / 模态** | [`<web-ui-dialog>`](./docs/dialog.CN.md) |
390
+ | | [`<web-ui-drawer>`](./docs/drawer.CN.md) |
391
+ | | [`imagePreview()`](./docs/image-preview.CN.md) |
392
+ | **文档流 Disclosure** | [`<web-ui-collapse>`](./docs/collapse.CN.md) |
393
+ | **浮动** | [`<web-ui-popover>`](./docs/popover.CN.md) |
394
+ | | [`<web-ui-tooltip>`](./docs/tooltip.CN.md) |
395
+ | | [`<web-ui-context-menu>`](./docs/context-menu.CN.md) |
396
+ | **menu** | [`<web-ui-dropdown>`](./docs/dropdown.CN.md) |
397
+ | | [`<web-ui-dropdown-item>`](./docs/dropdown-item.CN.md) |
398
+ | | [`<web-ui-dropdown-divider>`](./docs/dropdown-divider.CN.md) |
399
+ | | [`<web-ui-dropdown-header>`](./docs/dropdown-header.CN.md) |
400
+ | **数据展示** | [`<web-ui-avatar>`](./docs/avatar.CN.md) |
401
+ | | [`<web-ui-badge>`](./docs/badge.CN.md) |
402
+ | | [`<web-ui-empty>`](./docs/empty.CN.md) |
403
+ | | [`<web-ui-middle-ellipsis>`](./docs/middle-ellipsis.CN.md) |
404
+ | | [`<web-ui-icon>`](./docs/icon.CN.md) |
405
+ | | [`<web-ui-spinner>`](./docs/spinner.CN.md) |
406
+ | **布局与工具** | [`<web-ui-layout>`](./docs/layout.CN.md) |
407
+ | | [`<web-ui-back-top>`](./docs/back-top.CN.md) |
408
+ | | [`<web-ui-svg-draw-lines>`](./docs/svg-draw-lines.CN.md) |
409
+ | | [`<web-ui-theme>`](./docs/theme.CN.md) |
410
+ | **通知** | [`<web-ui-toast>`](./docs/toast.CN.md) |
411
+ | **子项** | [`<web-ui-option>`](./docs/option.CN.md) |
412
+ | | [`<web-ui-segmented-trigger>`](./docs/segmented-trigger.CN.md) |
@@ -378,7 +378,6 @@ export declare class WebUiButton extends WebUiButton_base {
378
378
  set type(value: unknown);
379
379
  private _type;
380
380
  ariaLabel: string | null;
381
- ariaDisabled: string | null;
382
381
  ariaExpanded: string | null;
383
382
  private readonly _groupManagement;
384
383
  private get _groupContext();
@@ -50,7 +50,7 @@ var S = class extends i(d) {
50
50
  return this.disabled || this.loading || this._formAssociation.isFormDisabled();
51
51
  }
52
52
  constructor() {
53
- super(), this._variant = "glass", this.disabled = !1, this.loading = !1, this.full = !1, this.icon = !1, this.size = "", this._type = "button", this.ariaLabel = null, this.ariaDisabled = null, this.ariaExpanded = null, this._groupManagement = c(this, {
53
+ super(), this._variant = "glass", this.disabled = !1, this.loading = !1, this.full = !1, this.icon = !1, this.size = "", this._type = "button", this.ariaLabel = null, this.ariaExpanded = null, this._groupManagement = c(this, {
54
54
  context: s,
55
55
  requestUpdate: () => this.requestUpdate(),
56
56
  equals: (e, t) => e?.direction === t?.direction && e?.isLast === t?.isLast
@@ -62,7 +62,7 @@ var S = class extends i(d) {
62
62
  getFormState: () => null,
63
63
  restoreState: () => {}
64
64
  }).make(), this._formAssociationController = new a(this, this._formAssociation), this._handleHostClick = (e) => {
65
- e.composedPath()[0] !== this || !this._isDisabled && this.ariaDisabled !== "true" || (e.preventDefault(), e.stopPropagation());
65
+ e.composedPath()[0] === this && this._isDisabled && (e.preventDefault(), e.stopPropagation());
66
66
  }, this.addEventListener("click", this._handleHostClick);
67
67
  }
68
68
  get _sizeStyle() {
@@ -73,7 +73,7 @@ var S = class extends i(d) {
73
73
  return t ? { "--wui-control-size": /^[+-]?(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?$/i.test(t) ? `${Number(t)}px` : t } : {};
74
74
  }
75
75
  handleClick(e) {
76
- if (this._isDisabled || this.ariaDisabled === "true") {
76
+ if (this._isDisabled) {
77
77
  e.preventDefault(), e.stopPropagation();
78
78
  return;
79
79
  }
@@ -96,7 +96,6 @@ var S = class extends i(d) {
96
96
  <button
97
97
  type=${this.type}
98
98
  aria-label=${v(this.ariaLabel)}
99
- aria-disabled=${v(this.ariaDisabled)}
100
99
  aria-expanded=${v(this.ariaExpanded)}
101
100
  class=${_(t)}
102
101
  part="button"
@@ -140,9 +139,6 @@ e([g({
140
139
  type: String,
141
140
  attribute: "aria-label"
142
141
  })], S.prototype, "ariaLabel", void 0), e([g({
143
- type: String,
144
- attribute: "aria-disabled"
145
- })], S.prototype, "ariaDisabled", void 0), e([g({
146
142
  type: String,
147
143
  attribute: "aria-expanded"
148
144
  })], S.prototype, "ariaExpanded", void 0), S = e([h("web-ui-button")], S);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/button/index.ts"],"sourcesContent":["import '@/components/icon'\n\nimport { html, LitElement, nothing, unsafeCSS } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { ifDefined } from 'lit/directives/if-defined.js'\nimport { styleMap } from 'lit/directives/style-map.js'\n\nimport glass from '@/classes/glass.css?inline'\nimport { lucideLoaderCircle } from '@/icons'\nimport { installPointerFocusSuppression } from '@/shared/focus/pointer-focus'\nimport { FormAssociated, defineFormAssociation, FormAssociationController } from '@/shared/form-association'\nimport { buttonGroupContextKey, defineGroupManaged, type ButtonGroupContext } from '@/shared/group-management'\nimport { normalizeLiteral } from '@/shared/normalize'\n\nimport style from './style.css?inline'\n\nconst ALLOWED_VARIANTS = ['primary', 'secondary', 'ghost', 'danger', 'glass'] as const\nconst ALLOWED_TYPES = ['button', 'submit', 'reset'] as const\n\ninstallPointerFocusSuppression()\n\n@customElement('web-ui-button')\nexport class WebUiButton extends FormAssociated(LitElement) {\n static override styles = [unsafeCSS(glass), unsafeCSS(style)]\n\n @property({ type: String, reflect: true })\n get variant(): 'primary' | 'secondary' | 'ghost' | 'danger' | 'glass' {\n return this._variant\n }\n set variant(v: string) {\n const old = this._variant\n this._variant = normalizeLiteral(v, ALLOWED_VARIANTS, 'glass')\n this.requestUpdate('variant', old)\n }\n private _variant: 'primary' | 'secondary' | 'ghost' | 'danger' | 'glass' = 'glass'\n\n @property({ type: Boolean, reflect: true }) disabled = false\n @property({ type: Boolean, reflect: true }) loading = false\n @property({ type: Boolean, reflect: true }) full = false\n @property({ type: Boolean, reflect: true }) icon = false\n @property({ type: String, reflect: true }) size = ''\n\n @property({ type: String, reflect: true })\n get type(): (typeof ALLOWED_TYPES)[number] {\n return this._type\n }\n set type(value: unknown) {\n const old = this._type\n this._type = normalizeLiteral(value, ALLOWED_TYPES, 'button')\n this.requestUpdate('type', old)\n }\n private _type: (typeof ALLOWED_TYPES)[number] = 'button'\n\n // Explicitly delegated ARIA attributes.\n @property({ type: String, attribute: 'aria-label' }) override ariaLabel: string | null = null\n @property({ type: String, attribute: 'aria-disabled' }) override ariaDisabled: string | null = null\n @property({ type: String, attribute: 'aria-expanded' }) override ariaExpanded: string | null = null\n\n private readonly _groupManagement = defineGroupManaged<ButtonGroupContext>(this, {\n context: buttonGroupContextKey,\n requestUpdate: () => this.requestUpdate(),\n equals: (a, b) => a?.direction === b?.direction && a?.isLast === b?.isLast\n }).make()\n\n private get _groupContext(): ButtonGroupContext | undefined {\n return this._groupManagement.getContext()\n }\n\n /*\n * button 不贡献表单值,接 shared form-association 只为拿 ElementInternals 与原生禁用回调:\n * 禁用态由浏览器在宿主 disabled 反射时同步回报,自己镜像一份会漏掉更新时机。\n */\n private readonly _formAssociation = defineFormAssociation<null>({\n host: this,\n getState: () => null,\n setState: () => {},\n getFormValue: () => null,\n getFormState: () => null,\n restoreState: () => {}\n }).make()\n\n private readonly _formAssociationController = new FormAssociationController(this, this._formAssociation)\n\n private get _isDisabled(): boolean {\n return this.disabled || this.loading || this._formAssociation.isFormDisabled()\n }\n\n constructor() {\n super()\n this.addEventListener('click', this._handleHostClick)\n }\n\n private get _sizeStyle(): Record<string, string> {\n // size 仅控制 button 高度;icon 模式下 min-width 同步为相同值,天然保持正方形。\n if (this._groupContext) {\n return { '--wui-control-size': 'var(--wui-internal-button-group-button-size, 30px)' }\n }\n\n const sizeValue: unknown = this.size\n if (typeof sizeValue !== 'string' && typeof sizeValue !== 'number') return {}\n\n const size = `${sizeValue}`.trim()\n if (!size) return {}\n\n // 裸数字按 px 解释;带单位的 CSS 长度原样使用。\n const isBareNumber = /^[+-]?(?:\\d+\\.?\\d*|\\.\\d+)(?:e[+-]?\\d+)?$/i.test(size)\n const cssSize = isBareNumber ? `${Number(size)}px` : size\n return { '--wui-control-size': cssSize }\n }\n\n private handleClick(e: Event) {\n if (this._isDisabled || this.ariaDisabled === 'true') {\n e.preventDefault()\n e.stopPropagation()\n return\n }\n\n const action = this.type\n if (action === 'button') return\n\n /*\n * Shadow 内 button 没有 form owner;等 composed click 的同步监听器全部完成后,\n * 再读取宿主的 live form owner 并转发,调用方仍可用 preventDefault 取消这次原生 activation。\n */\n setTimeout(() => {\n if (e.defaultPrevented) return\n const form = this._formAssociation.getInternals()?.form\n if (!form) return\n if (action === 'submit') form.requestSubmit()\n else form.reset()\n })\n }\n\n private readonly _handleHostClick = (event: Event) => {\n if (event.composedPath()[0] !== this || (!this._isDisabled && this.ariaDisabled !== 'true')) return\n event.preventDefault()\n event.stopPropagation()\n }\n\n override render() {\n const groupContext = this._groupContext\n const btnClass = {\n 'wui-glass': this.variant === 'glass' && !groupContext,\n 'is-grouped': Boolean(groupContext)\n }\n const dividerClass = {\n 'group-divider': true,\n vertical: groupContext?.direction === 'vertical'\n }\n\n return html`\n <button\n type=${this.type}\n aria-label=${ifDefined(this.ariaLabel)}\n aria-disabled=${ifDefined(this.ariaDisabled)}\n aria-expanded=${ifDefined(this.ariaExpanded)}\n class=${classMap(btnClass)}\n part=\"button\"\n style=${Object.keys(this._sizeStyle).length > 0 ? styleMap(this._sizeStyle) : nothing}\n ?disabled=${this._isDisabled}\n @click=${this.handleClick}\n >\n ${\n this.icon\n ? // loading 优先于 icon 内容:icon 模式下只展示 spinner,不投影默认 slot,避免双 icon 叠加\n this.loading\n ? html`<web-ui-icon .icon=${lucideLoaderCircle} spin></web-ui-icon>`\n : html`<slot></slot>`\n : html`\n ${this.loading ? html`<web-ui-icon .icon=${lucideLoaderCircle} spin></web-ui-icon>` : ''}\n <slot name=\"prefix\"></slot>\n <span class=\"label\"><slot></slot></span>\n <slot name=\"suffix\"></slot>\n `\n }\n </button>\n ${\n groupContext && !groupContext.isLast\n ? html`<span class=${classMap(dividerClass)} aria-hidden=\"true\"></span>`\n : ''\n }\n `\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-button': WebUiButton\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/button/index.ts"],"sourcesContent":["import '@/components/icon'\n\nimport { html, LitElement, nothing, unsafeCSS } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { ifDefined } from 'lit/directives/if-defined.js'\nimport { styleMap } from 'lit/directives/style-map.js'\n\nimport glass from '@/classes/glass.css?inline'\nimport { lucideLoaderCircle } from '@/icons'\nimport { installPointerFocusSuppression } from '@/shared/focus/pointer-focus'\nimport { FormAssociated, defineFormAssociation, FormAssociationController } from '@/shared/form-association'\nimport { buttonGroupContextKey, defineGroupManaged, type ButtonGroupContext } from '@/shared/group-management'\nimport { normalizeLiteral } from '@/shared/normalize'\n\nimport style from './style.css?inline'\n\nconst ALLOWED_VARIANTS = ['primary', 'secondary', 'ghost', 'danger', 'glass'] as const\nconst ALLOWED_TYPES = ['button', 'submit', 'reset'] as const\n\ninstallPointerFocusSuppression()\n\n@customElement('web-ui-button')\nexport class WebUiButton extends FormAssociated(LitElement) {\n static override styles = [unsafeCSS(glass), unsafeCSS(style)]\n\n @property({ type: String, reflect: true })\n get variant(): 'primary' | 'secondary' | 'ghost' | 'danger' | 'glass' {\n return this._variant\n }\n set variant(v: string) {\n const old = this._variant\n this._variant = normalizeLiteral(v, ALLOWED_VARIANTS, 'glass')\n this.requestUpdate('variant', old)\n }\n private _variant: 'primary' | 'secondary' | 'ghost' | 'danger' | 'glass' = 'glass'\n\n @property({ type: Boolean, reflect: true }) disabled = false\n @property({ type: Boolean, reflect: true }) loading = false\n @property({ type: Boolean, reflect: true }) full = false\n @property({ type: Boolean, reflect: true }) icon = false\n @property({ type: String, reflect: true }) size = ''\n\n @property({ type: String, reflect: true })\n get type(): (typeof ALLOWED_TYPES)[number] {\n return this._type\n }\n set type(value: unknown) {\n const old = this._type\n this._type = normalizeLiteral(value, ALLOWED_TYPES, 'button')\n this.requestUpdate('type', old)\n }\n private _type: (typeof ALLOWED_TYPES)[number] = 'button'\n\n /*\n * Explicitly delegated ARIA attributes.\n *\n * `aria-disabled` 不在其中:禁用只有 `disabled` 一条路径,它把内部原生 button 真的置为\n * disabled(不可点、不进 tab 序列)。`aria-disabled` 那套「看起来禁用但仍可聚焦」的\n * 语义不提供,因此既不读取也不转发——写上去只留在宿主,对行为零影响。\n */\n @property({ type: String, attribute: 'aria-label' }) override ariaLabel: string | null = null\n @property({ type: String, attribute: 'aria-expanded' }) override ariaExpanded: string | null = null\n\n private readonly _groupManagement = defineGroupManaged<ButtonGroupContext>(this, {\n context: buttonGroupContextKey,\n requestUpdate: () => this.requestUpdate(),\n equals: (a, b) => a?.direction === b?.direction && a?.isLast === b?.isLast\n }).make()\n\n private get _groupContext(): ButtonGroupContext | undefined {\n return this._groupManagement.getContext()\n }\n\n /*\n * button 不贡献表单值,接 shared form-association 只为拿 ElementInternals 与原生禁用回调:\n * 禁用态由浏览器在宿主 disabled 反射时同步回报,自己镜像一份会漏掉更新时机。\n */\n private readonly _formAssociation = defineFormAssociation<null>({\n host: this,\n getState: () => null,\n setState: () => {},\n getFormValue: () => null,\n getFormState: () => null,\n restoreState: () => {}\n }).make()\n\n private readonly _formAssociationController = new FormAssociationController(this, this._formAssociation)\n\n private get _isDisabled(): boolean {\n return this.disabled || this.loading || this._formAssociation.isFormDisabled()\n }\n\n constructor() {\n super()\n this.addEventListener('click', this._handleHostClick)\n }\n\n private get _sizeStyle(): Record<string, string> {\n // size 仅控制 button 高度;icon 模式下 min-width 同步为相同值,天然保持正方形。\n if (this._groupContext) {\n return { '--wui-control-size': 'var(--wui-internal-button-group-button-size, 30px)' }\n }\n\n const sizeValue: unknown = this.size\n if (typeof sizeValue !== 'string' && typeof sizeValue !== 'number') return {}\n\n const size = `${sizeValue}`.trim()\n if (!size) return {}\n\n // 裸数字按 px 解释;带单位的 CSS 长度原样使用。\n const isBareNumber = /^[+-]?(?:\\d+\\.?\\d*|\\.\\d+)(?:e[+-]?\\d+)?$/i.test(size)\n const cssSize = isBareNumber ? `${Number(size)}px` : size\n return { '--wui-control-size': cssSize }\n }\n\n private handleClick(e: Event) {\n if (this._isDisabled) {\n e.preventDefault()\n e.stopPropagation()\n return\n }\n\n const action = this.type\n if (action === 'button') return\n\n /*\n * Shadow 内 button 没有 form owner;等 composed click 的同步监听器全部完成后,\n * 再读取宿主的 live form owner 并转发,调用方仍可用 preventDefault 取消这次原生 activation。\n */\n setTimeout(() => {\n if (e.defaultPrevented) return\n const form = this._formAssociation.getInternals()?.form\n if (!form) return\n if (action === 'submit') form.requestSubmit()\n else form.reset()\n })\n }\n\n private readonly _handleHostClick = (event: Event) => {\n if (event.composedPath()[0] !== this || !this._isDisabled) return\n event.preventDefault()\n event.stopPropagation()\n }\n\n override render() {\n const groupContext = this._groupContext\n const btnClass = {\n 'wui-glass': this.variant === 'glass' && !groupContext,\n 'is-grouped': Boolean(groupContext)\n }\n const dividerClass = {\n 'group-divider': true,\n vertical: groupContext?.direction === 'vertical'\n }\n\n return html`\n <button\n type=${this.type}\n aria-label=${ifDefined(this.ariaLabel)}\n aria-expanded=${ifDefined(this.ariaExpanded)}\n class=${classMap(btnClass)}\n part=\"button\"\n style=${Object.keys(this._sizeStyle).length > 0 ? styleMap(this._sizeStyle) : nothing}\n ?disabled=${this._isDisabled}\n @click=${this.handleClick}\n >\n ${\n this.icon\n ? // loading 优先于 icon 内容:icon 模式下只展示 spinner,不投影默认 slot,避免双 icon 叠加\n this.loading\n ? html`<web-ui-icon .icon=${lucideLoaderCircle} spin></web-ui-icon>`\n : html`<slot></slot>`\n : html`\n ${this.loading ? html`<web-ui-icon .icon=${lucideLoaderCircle} spin></web-ui-icon>` : ''}\n <slot name=\"prefix\"></slot>\n <span class=\"label\"><slot></slot></span>\n <slot name=\"suffix\"></slot>\n `\n }\n </button>\n ${\n groupContext && !groupContext.isLast\n ? html`<span class=${classMap(dividerClass)} aria-hidden=\"true\"></span>`\n : ''\n }\n `\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-button': WebUiButton\n }\n}\n"],"mappings":"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"}
@@ -4,9 +4,16 @@ import { LitElement } from 'lit';
4
4
  *
5
5
  * trigger 语义完全来自 slot 进来的交互元素(原生 button / web-ui-button 等):
6
6
  * Enter/Space 激活走该元素的原生 click,不做 role="button" 补齐;组件把
7
- * `aria-expanded` / `aria-controls` / `aria-disabled` 回写到首个 assigned
8
- * element(与 popover trigger 的既定回写模式一致)。wrapper 仅负责点击代理,
9
- * 不可聚焦,不承载 ARIA。
7
+ * `aria-expanded` 回写到首个 assigned element,并在 `disabled` 时把该元素置为
8
+ * `disabled`。wrapper 仅负责点击代理,不可聚焦,不承载 ARIA。
9
+ *
10
+ * 不回写 `aria-controls`:目标 track 在组件 shadow root 内,IDREF 不能跨 shadow
11
+ * root 解析(Chrome 的 AX 树里该属性会被当作悬空引用丢弃),写出去只是死属性。
12
+ * 展开关系由 `aria-expanded` 表达,这也是 AT 实际依赖的那一条。
13
+ *
14
+ * 禁用也走 `disabled` 而不是 `aria-disabled`:后者在 `<web-ui-button>` 上只会落在
15
+ * 宿主(属性不跨 shadow 转发),AT 读不到;`disabled` 是真禁用,原生 button 与
16
+ * web-ui-button 都能生效。
10
17
  *
11
18
  * 内容区在 shadow 内以 grid `0fr ↔ 1fr` track 过渡驱动高度/宽度动画(ADR-0030
12
19
  * 选型保留)。关闭稳态三态(消费者 light DOM 永不移动,hidden 全部命令式管理,
@@ -23,7 +30,7 @@ export declare class WebUiCollapse extends LitElement {
23
30
  static styles: import('lit').CSSResult[];
24
31
  /** 展开状态;严格受控,唯一状态源。 */
25
32
  open: boolean;
26
- /** 禁用触发:点击忽略、aria-disabled 写入 trigger 元素;已展开内容保持现状。 */
33
+ /** 禁用触发:点击忽略、`disabled` 写入 trigger 元素;已展开内容保持现状。 */
27
34
  disabled: boolean;
28
35
  /** 水平方向:true 时沿宽度展开,默认沿高度。 */
29
36
  horizontal: boolean;
@@ -45,12 +52,11 @@ export declare class WebUiCollapse extends LitElement {
45
52
  */
46
53
  peek: string | null;
47
54
  private _triggerWrapper;
48
- private _contentId;
49
55
  private readonly _userOpenChange;
50
56
  private _exitTimer?;
51
57
  private _generation;
52
58
  private _lastOpen?;
53
- private _triggerAriaSnapshot?;
59
+ private _triggerSnapshot?;
54
60
  connectedCallback(): void;
55
61
  disconnectedCallback(): void;
56
62
  protected updated(changed: Map<string, unknown>): void;
@@ -61,8 +67,8 @@ export declare class WebUiCollapse extends LitElement {
61
67
  private _onTriggerClick;
62
68
  private _queryTrigger;
63
69
  private readonly _onTriggerSlotChange;
64
- private _restoreTriggerAriaSnapshot;
65
- private _syncTriggerAria;
70
+ private _restoreTriggerSnapshot;
71
+ private _syncTriggerState;
66
72
  /** 关闭稳态是否露出部分内容;空值与非空判断避免 `peek=""` 被当作有效长度。 */
67
73
  private get _peeks();
68
74
  private _applyOpenSteadyState;
@@ -20,9 +20,9 @@ function h() {
20
20
  } catch {}
21
21
  }
22
22
  h();
23
- var g = 0, _ = class extends o {
23
+ var g = class extends o {
24
24
  constructor(...e) {
25
- super(...e), this.open = !1, this.disabled = !1, this.horizontal = !1, this.keepMounted = !1, this.peek = null, this._contentId = `wui-collapse-content-${++g}`, this._userOpenChange = new i(), this._generation = 0, this._onTriggerClick = (e) => {
25
+ super(...e), this.open = !1, this.disabled = !1, this.horizontal = !1, this.keepMounted = !1, this.peek = null, this._userOpenChange = new i(), this._generation = 0, this._onTriggerClick = (e) => {
26
26
  this.disabled || e.composedPath().includes(this._triggerWrapper) && (this._userOpenChange.mark(), this.toggle());
27
27
  }, this._onTriggerSlotChange = () => {
28
28
  this.requestUpdate();
@@ -35,10 +35,10 @@ var g = 0, _ = class extends o {
35
35
  super.connectedCallback(), this.addEventListener("click", this._onTriggerClick), this.hasUpdated && (this._generation++, this._clearExitTimer(), this._lastOpen = void 0, this.requestUpdate());
36
36
  }
37
37
  disconnectedCallback() {
38
- super.disconnectedCallback(), this._clearExitTimer(), this._restoreTriggerAriaSnapshot();
38
+ super.disconnectedCallback(), this._clearExitTimer(), this._restoreTriggerSnapshot();
39
39
  }
40
40
  updated(e) {
41
- if (this._syncTriggerAria(), this._syncPeek(), this._lastOpen === void 0) {
41
+ if (this._syncTriggerState(), this._syncPeek(), this._lastOpen === void 0) {
42
42
  this._lastOpen = this.open, this.open ? this._applyOpenSteadyState() : this._applyClosedSteadyState();
43
43
  return;
44
44
  }
@@ -60,25 +60,23 @@ var g = 0, _ = class extends o {
60
60
  let e = (this.shadowRoot?.querySelector(".wui-collapse-trigger-wrapper slot"))?.assignedElements()[0];
61
61
  return e instanceof HTMLElement ? e : null;
62
62
  }
63
- _restoreTriggerAriaSnapshot() {
64
- let e = this._triggerAriaSnapshot;
63
+ _restoreTriggerSnapshot() {
64
+ let e = this._triggerSnapshot;
65
65
  if (e) {
66
66
  for (let [t, n] of Object.entries({
67
67
  "aria-expanded": e.expanded,
68
- "aria-controls": e.controls,
69
- "aria-disabled": e.disabled
68
+ disabled: e.disabled
70
69
  })) n === null ? e.trigger.removeAttribute(t) : e.trigger.setAttribute(t, n);
71
- this._triggerAriaSnapshot = void 0;
70
+ this._triggerSnapshot = void 0;
72
71
  }
73
72
  }
74
- _syncTriggerAria() {
73
+ _syncTriggerState() {
75
74
  let e = this._queryTrigger();
76
- this._triggerAriaSnapshot?.trigger !== e && (this._restoreTriggerAriaSnapshot(), e && (this._triggerAriaSnapshot = {
75
+ this._triggerSnapshot?.trigger !== e && (this._restoreTriggerSnapshot(), e && (this._triggerSnapshot = {
77
76
  trigger: e,
78
77
  expanded: e.getAttribute("aria-expanded"),
79
- controls: e.getAttribute("aria-controls"),
80
- disabled: e.getAttribute("aria-disabled")
81
- })), e && (e.setAttribute("aria-expanded", String(this.open)), e.setAttribute("aria-controls", this._contentId), this.disabled ? e.setAttribute("aria-disabled", "true") : e.removeAttribute("aria-disabled"));
78
+ disabled: e.getAttribute("disabled")
79
+ })), e && (e.setAttribute("aria-expanded", String(this.open)), e.toggleAttribute("disabled", this.disabled));
82
80
  }
83
81
  get _peeks() {
84
82
  return typeof this.peek == "string" && this.peek.trim() !== "";
@@ -203,7 +201,7 @@ var g = 0, _ = class extends o {
203
201
  return s`
204
202
  <div class="wui-collapse-trigger-wrapper" @slotchange=${this._onTriggerSlotChange}><slot></slot></div>
205
203
  <div class="wui-collapse-content">
206
- <div class=${f(e)} id=${this._contentId}>
204
+ <div class=${f(e)}>
207
205
  <div class=${f({
208
206
  "wui-collapse-inner": !0,
209
207
  "wui-glow": this._peeks
@@ -218,21 +216,21 @@ var g = 0, _ = class extends o {
218
216
  e([u({
219
217
  type: Boolean,
220
218
  reflect: !0
221
- })], _.prototype, "open", void 0), e([u({
219
+ })], g.prototype, "open", void 0), e([u({
222
220
  type: Boolean,
223
221
  reflect: !0
224
- })], _.prototype, "disabled", void 0), e([u({
222
+ })], g.prototype, "disabled", void 0), e([u({
225
223
  type: Boolean,
226
224
  reflect: !0
227
- })], _.prototype, "horizontal", void 0), e([u({
225
+ })], g.prototype, "horizontal", void 0), e([u({
228
226
  type: Boolean,
229
227
  reflect: !0,
230
228
  attribute: "keep-mounted"
231
- })], _.prototype, "keepMounted", void 0), e([u({
229
+ })], g.prototype, "keepMounted", void 0), e([u({
232
230
  type: String,
233
231
  reflect: !0
234
- })], _.prototype, "peek", void 0), e([d(".wui-collapse-trigger-wrapper")], _.prototype, "_triggerWrapper", void 0), _ = e([l("web-ui-collapse")], _);
232
+ })], g.prototype, "peek", void 0), e([d(".wui-collapse-trigger-wrapper")], g.prototype, "_triggerWrapper", void 0), g = e([l("web-ui-collapse")], g);
235
233
  //#endregion
236
- export { _ as WebUiCollapse };
234
+ export { g as WebUiCollapse };
237
235
 
238
236
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/collapse/index.ts"],"sourcesContent":["import { html, LitElement, unsafeCSS } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\n\nimport glow from '@/classes/glow.css?inline'\nimport { UserChangeController } from '@/shared/events/user-change'\nimport { dispatchOpenChangeEvent } from '@/shared/open-state'\nimport { getTransitionDuration } from '@/shared/overlay/presence'\n\nimport style from './style.css?inline'\n\nconst EXIT_FALLBACK_BUFFER = 80\n\n/** peek 边缘渐隐的活动长度:关闭/收起态取由 peek 推导的长度,展开态归 0。 */\nconst PEEK_EDGE_ACTIVE = '--wui-collapse-peek-edge-active'\n\n/*\n * 注册成 `<length>` 才能被 transition 插值(未注册的自定义属性是离散值,只能瞬变)。\n *\n * 必须用 JS 的 `CSS.registerProperty` 而不是 CSS 里的 `@property`:实测后者写在\n * shadow root 的样式表里不产生注册(getComputedStyle 读打开态得到空串而非\n * initial-value),而自定义属性的注册本质上是 document 级的。\n * 注册失败(jsdom、旧浏览器、重复注册)时降级为离散过渡——渐变带长度瞬变,\n * 但位置百分比仍跟随裁剪边缘,行为依旧正确。\n *\n * `inherits` 必须是 true:晕染伪元素(style.css 的 ::after)读同一个值来调制模糊,\n * 继承为 false 时伪元素读到的是 initialValue 0px——mask 的各色标随之塌缩到 100%,\n * 模糊层静默消失且其余渲染一切照旧,只少一层效果。\n */\nfunction registerPeekEdgeActive() {\n // jsdom 与不支持的环境直接跳过;样式里的 var() fallback 保证声明仍然有效。\n if (typeof CSS === 'undefined' || typeof CSS.registerProperty !== 'function') return\n try {\n CSS.registerProperty({\n name: PEEK_EDGE_ACTIVE,\n syntax: '<length>',\n inherits: true,\n initialValue: '0px'\n })\n } catch {\n // 已注册过(HMR、多份副本)或定义冲突:保持现有注册即可。\n }\n}\n\nregisterPeekEdgeActive()\n\nlet collapseIdCounter = 0\n\n/**\n * 文档流内 collapse panel:trigger 经默认 slot 提供,内容经 `slot=\"content\"` 提供。\n *\n * trigger 语义完全来自 slot 进来的交互元素(原生 button / web-ui-button 等):\n * Enter/Space 激活走该元素的原生 click,不做 role=\"button\" 补齐;组件把\n * `aria-expanded` / `aria-controls` / `aria-disabled` 回写到首个 assigned\n * element(与 popover trigger 的既定回写模式一致)。wrapper 仅负责点击代理,\n * 不可聚焦,不承载 ARIA。\n *\n * 内容区在 shadow 内以 grid `0fr ↔ 1fr` track 过渡驱动高度/宽度动画(ADR-0030\n * 选型保留)。关闭稳态三态(消费者 light DOM 永不移动,hidden 全部命令式管理,\n * 避免渲染绑定在关闭动画起点抢先 display:none):\n * - 默认:content 容器 `hidden`(display:none,脱离渲染与可访问性树);\n * - `keep-mounted`:inner `inert`(保留在 0fr track 内,滚动位置与布局可测量);\n * - `peek`:inner `inert`,track 停在固定长度的裁剪窗口,只露出内容头部;\n * - 动画进行中:inner `inert` + track pointer-events 禁用,结束后进入对应稳态。\n *\n * `peek` 与展开态之间是固定长度与内容自适应高度的过渡,CSS 无法插值;这两个\n * 方向的动画改为读出像素后以显式长度写入 track,落稳态时清除内联值交回 CSS 规则。\n */\n@customElement('web-ui-collapse')\nexport class WebUiCollapse extends LitElement {\n static override styles = [unsafeCSS(glow), unsafeCSS(style)]\n\n /** 展开状态;严格受控,唯一状态源。 */\n @property({ type: Boolean, reflect: true }) open = false\n\n /** 禁用触发:点击忽略、aria-disabled 写入 trigger 元素;已展开内容保持现状。 */\n @property({ type: Boolean, reflect: true }) disabled = false\n\n /** 水平方向:true 时沿宽度展开,默认沿高度。 */\n @property({ type: Boolean, reflect: true }) horizontal = false\n\n /** 关闭稳态保持内容 `inert` 而非 `hidden`(保留滚动位置,可测量)。 */\n @property({ type: Boolean, reflect: true, attribute: 'keep-mounted' }) keepMounted = false\n\n /**\n * 关闭稳态露出的尺寸(CSS 长度,如 `120px`、`6rem`),沿动画轴生效:默认是高度,\n * `horizontal` 时为宽度;未设置时保持完全收起。\n *\n * 设置后关闭稳态语义等同 `keep-mounted`(内容留在 track 内、`inert` 阻断交互),\n * 只露出 `peek` 范围内的部分;内容本身不足 `peek` 时按内容实际尺寸收起。\n * 注意 `peek` 是固定长度与内容自适应高度之间的过渡:CSS 无法在两者之间插值,\n * 因此这两个方向的动画由本组件读出内容尺寸后以显式长度驱动(其余路径仍是\n * 零测量的 grid fr 过渡)。\n *\n * 露出区域末端自带一段边缘渐隐(提示下方还有内容),长度由 `peek` 按比例推导,\n * 无需也不接受调用方单独指定——见 style.css 中 `--wui-collapse-peek-edge-*`\n * 系列变量(比例、上限、末端颜色可用 CSS 覆盖,属于主题级调优而非组件 API)。\n */\n @property({ type: String, reflect: true }) peek: string | null = null\n\n @query('.wui-collapse-trigger-wrapper') private _triggerWrapper!: HTMLElement\n\n private _contentId = `wui-collapse-content-${++collapseIdCounter}`\n\n private readonly _userOpenChange = new UserChangeController()\n\n private _exitTimer?: ReturnType<typeof setTimeout>\n // 动画代际:每次管线启动自增,旧管线的 transitionend/兜底定时器/rAF 全部失效。\n private _generation = 0\n private _lastOpen?: boolean\n private _triggerAriaSnapshot?: {\n trigger: HTMLElement\n expanded: string | null\n controls: string | null\n disabled: string | null\n }\n\n override connectedCallback() {\n super.connectedCallback()\n // 点击监听与生命周期同寿(宿主移除即整体销毁),无需 disconnected 清理。\n this.addEventListener('click', this._onTriggerClick)\n // 断连可能打断动画管线(瞬态残留:presence='closing'、容器未 hidden)。\n // 首次连接不必处理(初始 render 走 _lastOpen===undefined 落稳态,请求多余\n // 渲染会触发「scheduled an update after update completed」告警);重连时\n // 重置同步状态并强制一轮 update,由首次同步分支重新落稳态、丢弃在途管线。\n if (this.hasUpdated) {\n this._generation++\n this._clearExitTimer()\n this._lastOpen = undefined\n this.requestUpdate()\n }\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback()\n this._clearExitTimer()\n this._restoreTriggerAriaSnapshot()\n }\n\n protected override updated(changed: Map<string, unknown>) {\n // ARIA 回写不依赖 open 分支,任何渲染后都保持与宿主状态同步。\n this._syncTriggerAria()\n // peek 的稳态长度与动画写入共用 track 内联样式,先同步再落稳态,避免被稳态清除。\n this._syncPeek()\n\n // 首次同步(含 open 为默认值的场景,changed map 不含默认值属性):\n // 直接落到正确稳态,不播动画(popover 初始 open 同款)。\n if (this._lastOpen === undefined) {\n this._lastOpen = this.open\n if (this.open) this._applyOpenSteadyState()\n else this._applyClosedSteadyState()\n return\n }\n\n if ((changed.has('keepMounted') || changed.has('peek')) && !this.open) {\n // 运行态切换 keep-mounted / peek:关闭稳态需在 hidden / inert / 裁剪长度间重新落地。\n this._applyClosedSteadyState()\n }\n if (!changed.has('open') || this.open === this._lastOpen) return\n\n this._lastOpen = this.open\n if (this._userOpenChange.consume()) this._dispatchChange(this.open)\n if (this.open) this._beginExpand()\n else this._beginCollapse()\n }\n\n show() {\n if (this.open) return\n this.open = true\n }\n\n close() {\n if (!this.open) return\n this.open = false\n }\n\n toggle() {\n if (this.open) this.close()\n else this.show()\n }\n\n private _dispatchChange(open: boolean) {\n dispatchOpenChangeEvent(this, open)\n }\n\n /*\n * 点击代理:冒泡路径穿过 trigger wrapper 的 click 一律切换。语义由 slot 内\n * 的交互元素(原生 button / web-ui-button)提供;slot 放纯文本时无激活语义\n * (README 约定)。内容区与嵌套内层 collapse 的 click 不经过本 wrapper,天然隔离。\n */\n private _onTriggerClick = (event: MouseEvent) => {\n if (this.disabled) return\n if (!event.composedPath().includes(this._triggerWrapper)) return\n this._userOpenChange.mark()\n this.toggle()\n }\n\n /*\n * Trigger 元素取首个 assigned element(与 popover `_queryTrigger` 同款惰性查询,\n * 不依赖 slotchange——jsdom 不派发该事件,无法用状态缓存)。slot 为空时无回写目标。\n */\n private _queryTrigger(): HTMLElement | null {\n const slot = this.shadowRoot?.querySelector<HTMLSlotElement>('.wui-collapse-trigger-wrapper slot')\n const el = slot?.assignedElements()[0]\n return el instanceof HTMLElement ? el : null\n }\n\n /*\n * slot 内容增删不触发宿主响应式更新:显式请求一轮渲染,由 updated() 的\n * ARIA 回写覆盖晚到的 trigger 元素(slotchange 在 jsdom 不派发,无法监听)。\n */\n private readonly _onTriggerSlotChange = () => {\n this.requestUpdate()\n }\n\n private _restoreTriggerAriaSnapshot() {\n const snapshot = this._triggerAriaSnapshot\n if (!snapshot) return\n\n for (const [attribute, value] of Object.entries({\n 'aria-expanded': snapshot.expanded,\n 'aria-controls': snapshot.controls,\n 'aria-disabled': snapshot.disabled\n })) {\n if (value === null) snapshot.trigger.removeAttribute(attribute)\n else snapshot.trigger.setAttribute(attribute, value)\n }\n this._triggerAriaSnapshot = undefined\n }\n\n // ARIA 状态回写到 trigger 元素本身(wrapper 不可聚焦,AT 读不到)。\n private _syncTriggerAria() {\n const trigger = this._queryTrigger()\n if (this._triggerAriaSnapshot?.trigger !== trigger) {\n this._restoreTriggerAriaSnapshot()\n if (trigger) {\n this._triggerAriaSnapshot = {\n trigger,\n expanded: trigger.getAttribute('aria-expanded'),\n controls: trigger.getAttribute('aria-controls'),\n disabled: trigger.getAttribute('aria-disabled')\n }\n }\n }\n if (!trigger) return\n trigger.setAttribute('aria-expanded', String(this.open))\n trigger.setAttribute('aria-controls', this._contentId)\n if (this.disabled) trigger.setAttribute('aria-disabled', 'true')\n else trigger.removeAttribute('aria-disabled')\n }\n\n // ===== 内容区动画管线(三态语义自 ADR-0030 迁移) =====\n\n /** 关闭稳态是否露出部分内容;空值与非空判断避免 `peek=\"\"` 被当作有效长度。 */\n private get _peeks(): boolean {\n return typeof this.peek === 'string' && this.peek.trim() !== ''\n }\n\n private _applyOpenSteadyState() {\n this._generation++\n this._clearExitTimer()\n const container = this._contentContainer()\n const track = this._contentTrack()\n if (container) container.hidden = false\n if (track) track.dataset.wuiPresence = 'open'\n this._clearInnerClamp()\n this._setInnerInert(false)\n }\n\n private _applyClosedSteadyState() {\n this._generation++\n this._clearExitTimer()\n const container = this._contentContainer()\n const track = this._contentTrack()\n if (track) delete track.dataset.wuiPresence\n this._clearInnerClamp()\n if (this.keepMounted || this._peeks) {\n if (container) container.hidden = false\n this._setInnerInert(true)\n return\n }\n this._setInnerInert(false)\n if (container) container.hidden = true\n }\n\n private _beginExpand() {\n this._generation++\n this._clearExitTimer()\n const container = this._contentContainer()\n const track = this._contentTrack()\n if (!container || !track) return\n\n const generation = this._generation\n // 中断关闭动画时 inner 已 inert:先恢复可交互,内容随展开重新可见。\n this._setInnerInert(false)\n // 从 display:none 进入时无先前计算样式可过渡:提交 0fr 起点后再翻转。\n container.hidden = false\n\n if (this._peeks) {\n const inner = this._contentInner()\n // 无过渡时长(reduced motion、jsdom)或无 inner 时不做测量,直接落展开稳态。\n if (!inner || getTransitionDuration(inner, 0) === 0) {\n this._applyOpenSteadyState()\n return\n }\n /*\n * peek 的裁剪长度是固定值,展开目标是内容自适应高度,两者无法由 CSS 插值,\n * 动画必须由两个显式长度驱动:起点是当前露出的长度,目标是内容完整尺寸。\n * 起点要在同任务内先写入并提交回流,否则过渡会退化成跳变(实测分帧写入\n * 反而完全不参与插值判定);目标读 inner 的 scroll 尺寸,不写探针样式。\n */\n const from = this._measureInnerSize(inner)\n const to = this._measureContentSize(inner)\n this._setInnerClamp(inner, `${from}px`)\n void this._measureInnerSize(inner)\n track.dataset.wuiPresence = 'open'\n this._setInnerClamp(inner, `${to}px`)\n this._awaitTransition(inner, generation, () => this._settle(true), [this._clampProperty()])\n return\n }\n\n void track.offsetWidth\n\n requestAnimationFrame(() => {\n if (generation !== this._generation || !this.open) return\n track.dataset.wuiPresence = 'open'\n this._awaitTransition(track, generation, () => this._settle(true))\n })\n }\n\n private _beginCollapse() {\n this._generation++\n this._clearExitTimer()\n const track = this._contentTrack()\n if (!track) return\n\n // 收起期间立即阻断交互,防止焦点落入正在消失的区域。\n this._setInnerInert(true)\n const generation = this._generation\n\n if (this._peeks) {\n const inner = this._contentInner()\n // 无过渡时长(reduced motion、jsdom)或无 inner 时不做测量,直接落裁剪稳态。\n if (!inner || getTransitionDuration(inner, 0) === 0) {\n this._applyClosedSteadyState()\n return\n }\n /*\n * 收起目标是 `peek` 长度本身:与内容尺寸的较小值由 CSS 稳态规则解析,\n * 动画只需把当前展开长度过渡到这个长度。起点同样要先写入并提交回流,\n * 顺序与 _beginExpand 一致。\n */\n const from = this._measureInnerSize(inner)\n this._setInnerClamp(inner, `${from}px`)\n void this._measureInnerSize(inner)\n track.dataset.wuiPresence = 'closing'\n this._setInnerClamp(inner, `${this.peek}`)\n this._awaitTransition(inner, generation, () => this._settle(false), [this._clampProperty()])\n return\n }\n\n track.dataset.wuiPresence = 'closing'\n this._awaitTransition(track, generation, () => this._settle(false))\n }\n\n // 关闭稳态:keep-mounted → 内容保留在 0fr track 内并 inert;peek → 保留在裁剪\n // 窗口内并 inert;默认 → 容器 hidden。\n private _settle(open: boolean) {\n this._clearExitTimer()\n const track = this._contentTrack()\n // peek 过渡以显式长度写入 inner:落稳态一律清除,交回 CSS 稳态规则(长度声明)。\n this._clearInnerClamp()\n if (open) {\n this._setInnerInert(false)\n return\n }\n // 落稳态必须清除 closing 瞬态标记:否则 track 永久保留 pointer-events:none\n // 与 exit 过渡配置(keep-mounted 分支同样清除,避免残留)。\n if (track) delete track.dataset.wuiPresence\n if (this.keepMounted || this._peeks) return\n const container = this._contentContainer()\n this._setInnerInert(false)\n if (container) container.hidden = true\n }\n\n // 等待动画属性过渡结束;时长为 0(reduced motion、jsdom)直接稳态,\n // transitionend 不触发时按时长 + 缓冲兜底。默认等待 grid track 过渡;peek 的\n // 过渡落在 inner 的裁剪长度上,由调用方传入对应属性。\n private _awaitTransition(\n animated: HTMLElement,\n generation: number,\n onDone: () => void,\n properties: readonly string[] = ['grid-template-rows', 'grid-template-columns']\n ) {\n const duration = getTransitionDuration(animated, 0)\n if (duration === 0) {\n if (generation === this._generation) onDone()\n return\n }\n\n let settled = false\n const finish = () => {\n animated.removeEventListener('transitionend', onTransitionEnd)\n if (this._exitTimer === timer) this._exitTimer = undefined\n clearTimeout(timer)\n // 过渡可能被属性匹配的后续动画触发(如中断重开):代际不符时静默退场。\n if (settled || generation !== this._generation) return\n settled = true\n onDone()\n }\n const timer = setTimeout(finish, duration + EXIT_FALLBACK_BUFFER)\n this._exitTimer = timer\n\n const onTransitionEnd = (event: TransitionEvent) => {\n if (event.target === animated && properties.includes(event.propertyName)) finish()\n }\n animated.addEventListener('transitionend', onTransitionEnd)\n }\n\n private _clearExitTimer() {\n if (this._exitTimer !== undefined) {\n clearTimeout(this._exitTimer)\n this._exitTimer = undefined\n }\n }\n\n // ===== peek 尺寸读写(裁剪长度落在 inner 上,track 只负责 1fr 与裁剪窗口) =====\n\n /*\n * peek 长度经自定义属性下发给 shadow 样式规则,而不是直接写 inner 的裁剪长度:\n * 关闭稳态由 CSS 声明(长度与内容尺寸的较小值由 CSS 原生解析),动画写入的内联\n * 长度在其上覆盖,落稳态时清除即可回到声明值。\n */\n private _syncPeek() {\n const track = this._contentTrack()\n if (!track) return\n track.toggleAttribute('data-wui-peek', this._peeks)\n if (this._peeks) {\n track.style.setProperty('--wui-collapse-peek', this.peek ?? '')\n } else {\n track.style.removeProperty('--wui-collapse-peek')\n }\n }\n\n private _clampProperty(): 'max-height' | 'max-width' {\n return this.horizontal ? 'max-width' : 'max-height'\n }\n\n private _measureInnerSize(inner: HTMLElement): number {\n return this.horizontal ? inner.offsetWidth : inner.offsetHeight\n }\n\n /*\n * 内容在动画轴上的完整尺寸(px):裁剪只作用在 inner 的 max-height/max-width 上,\n * 被测内容的布局盒子仍是完整尺寸,故读 scroll 尺寸即可,不写任何样式——写样式\n * 会被 grid 过渡机制当作过渡起点读取,必须避开。\n */\n private _measureContentSize(inner: HTMLElement): number {\n return this.horizontal ? inner.scrollWidth : inner.scrollHeight\n }\n\n private _setInnerClamp(inner: HTMLElement, size: string) {\n inner.style.setProperty(this._clampProperty(), size)\n }\n\n private _clearInnerClamp() {\n const inner = this._contentInner()\n if (!inner) return\n inner.style.removeProperty('max-height')\n inner.style.removeProperty('max-width')\n }\n\n private _setInnerInert(inert: boolean) {\n this._contentInner()?.toggleAttribute('inert', inert)\n }\n\n private _contentInner(): HTMLElement | null {\n return this.shadowRoot?.querySelector<HTMLElement>('.wui-collapse-inner') ?? null\n }\n\n private _contentContainer(): HTMLElement | null {\n return this.shadowRoot?.querySelector<HTMLElement>('.wui-collapse-content') ?? null\n }\n\n private _contentTrack(): HTMLElement | null {\n return this.shadowRoot?.querySelector<HTMLElement>('.wui-collapse-track') ?? null\n }\n\n override render() {\n // 三态由 data-wui-presence 驱动(open/closing),缺省即关闭稳态。\n const trackClass = {\n 'wui-collapse-track': true,\n 'is-horizontal': this.horizontal\n }\n\n return html`\n <div class=\"wui-collapse-trigger-wrapper\" @slotchange=${this._onTriggerSlotChange}><slot></slot></div>\n <div class=\"wui-collapse-content\">\n <div class=${classMap(trackClass)} id=${this._contentId}>\n <div class=${classMap({ 'wui-collapse-inner': true, 'wui-glow': this._peeks })}>\n <slot name=\"content\"></slot>\n </div>\n </div>\n </div>\n `\n }\n\n declare readonly $events: {\n 'open-change': CustomEvent<{ open: boolean }>\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-collapse': WebUiCollapse\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/collapse/index.ts"],"sourcesContent":["import { html, LitElement, unsafeCSS } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\n\nimport glow from '@/classes/glow.css?inline'\nimport { UserChangeController } from '@/shared/events/user-change'\nimport { dispatchOpenChangeEvent } from '@/shared/open-state'\nimport { getTransitionDuration } from '@/shared/overlay/presence'\n\nimport style from './style.css?inline'\n\nconst EXIT_FALLBACK_BUFFER = 80\n\n/** peek 边缘渐隐的活动长度:关闭/收起态取由 peek 推导的长度,展开态归 0。 */\nconst PEEK_EDGE_ACTIVE = '--wui-collapse-peek-edge-active'\n\n/*\n * 注册成 `<length>` 才能被 transition 插值(未注册的自定义属性是离散值,只能瞬变)。\n *\n * 必须用 JS 的 `CSS.registerProperty` 而不是 CSS 里的 `@property`:实测后者写在\n * shadow root 的样式表里不产生注册(getComputedStyle 读打开态得到空串而非\n * initial-value),而自定义属性的注册本质上是 document 级的。\n * 注册失败(jsdom、旧浏览器、重复注册)时降级为离散过渡——渐变带长度瞬变,\n * 但位置百分比仍跟随裁剪边缘,行为依旧正确。\n *\n * `inherits` 必须是 true:晕染伪元素(style.css 的 ::after)读同一个值来调制模糊,\n * 继承为 false 时伪元素读到的是 initialValue 0px——mask 的各色标随之塌缩到 100%,\n * 模糊层静默消失且其余渲染一切照旧,只少一层效果。\n */\nfunction registerPeekEdgeActive() {\n // jsdom 与不支持的环境直接跳过;样式里的 var() fallback 保证声明仍然有效。\n if (typeof CSS === 'undefined' || typeof CSS.registerProperty !== 'function') return\n try {\n CSS.registerProperty({\n name: PEEK_EDGE_ACTIVE,\n syntax: '<length>',\n inherits: true,\n initialValue: '0px'\n })\n } catch {\n // 已注册过(HMR、多份副本)或定义冲突:保持现有注册即可。\n }\n}\n\nregisterPeekEdgeActive()\n\n/**\n * 文档流内 collapse panel:trigger 经默认 slot 提供,内容经 `slot=\"content\"` 提供。\n *\n * trigger 语义完全来自 slot 进来的交互元素(原生 button / web-ui-button 等):\n * Enter/Space 激活走该元素的原生 click,不做 role=\"button\" 补齐;组件把\n * `aria-expanded` 回写到首个 assigned element,并在 `disabled` 时把该元素置为\n * `disabled`。wrapper 仅负责点击代理,不可聚焦,不承载 ARIA。\n *\n * 不回写 `aria-controls`:目标 track 在组件 shadow root 内,IDREF 不能跨 shadow\n * root 解析(Chrome 的 AX 树里该属性会被当作悬空引用丢弃),写出去只是死属性。\n * 展开关系由 `aria-expanded` 表达,这也是 AT 实际依赖的那一条。\n *\n * 禁用也走 `disabled` 而不是 `aria-disabled`:后者在 `<web-ui-button>` 上只会落在\n * 宿主(属性不跨 shadow 转发),AT 读不到;`disabled` 是真禁用,原生 button 与\n * web-ui-button 都能生效。\n *\n * 内容区在 shadow 内以 grid `0fr ↔ 1fr` track 过渡驱动高度/宽度动画(ADR-0030\n * 选型保留)。关闭稳态三态(消费者 light DOM 永不移动,hidden 全部命令式管理,\n * 避免渲染绑定在关闭动画起点抢先 display:none):\n * - 默认:content 容器 `hidden`(display:none,脱离渲染与可访问性树);\n * - `keep-mounted`:inner `inert`(保留在 0fr track 内,滚动位置与布局可测量);\n * - `peek`:inner `inert`,track 停在固定长度的裁剪窗口,只露出内容头部;\n * - 动画进行中:inner `inert` + track pointer-events 禁用,结束后进入对应稳态。\n *\n * `peek` 与展开态之间是固定长度与内容自适应高度的过渡,CSS 无法插值;这两个\n * 方向的动画改为读出像素后以显式长度写入 track,落稳态时清除内联值交回 CSS 规则。\n */\n@customElement('web-ui-collapse')\nexport class WebUiCollapse extends LitElement {\n static override styles = [unsafeCSS(glow), unsafeCSS(style)]\n\n /** 展开状态;严格受控,唯一状态源。 */\n @property({ type: Boolean, reflect: true }) open = false\n\n /** 禁用触发:点击忽略、`disabled` 写入 trigger 元素;已展开内容保持现状。 */\n @property({ type: Boolean, reflect: true }) disabled = false\n\n /** 水平方向:true 时沿宽度展开,默认沿高度。 */\n @property({ type: Boolean, reflect: true }) horizontal = false\n\n /** 关闭稳态保持内容 `inert` 而非 `hidden`(保留滚动位置,可测量)。 */\n @property({ type: Boolean, reflect: true, attribute: 'keep-mounted' }) keepMounted = false\n\n /**\n * 关闭稳态露出的尺寸(CSS 长度,如 `120px`、`6rem`),沿动画轴生效:默认是高度,\n * `horizontal` 时为宽度;未设置时保持完全收起。\n *\n * 设置后关闭稳态语义等同 `keep-mounted`(内容留在 track 内、`inert` 阻断交互),\n * 只露出 `peek` 范围内的部分;内容本身不足 `peek` 时按内容实际尺寸收起。\n * 注意 `peek` 是固定长度与内容自适应高度之间的过渡:CSS 无法在两者之间插值,\n * 因此这两个方向的动画由本组件读出内容尺寸后以显式长度驱动(其余路径仍是\n * 零测量的 grid fr 过渡)。\n *\n * 露出区域末端自带一段边缘渐隐(提示下方还有内容),长度由 `peek` 按比例推导,\n * 无需也不接受调用方单独指定——见 style.css 中 `--wui-collapse-peek-edge-*`\n * 系列变量(比例、上限、末端颜色可用 CSS 覆盖,属于主题级调优而非组件 API)。\n */\n @property({ type: String, reflect: true }) peek: string | null = null\n\n @query('.wui-collapse-trigger-wrapper') private _triggerWrapper!: HTMLElement\n\n private readonly _userOpenChange = new UserChangeController()\n\n private _exitTimer?: ReturnType<typeof setTimeout>\n // 动画代际:每次管线启动自增,旧管线的 transitionend/兜底定时器/rAF 全部失效。\n private _generation = 0\n private _lastOpen?: boolean\n private _triggerSnapshot?: {\n trigger: HTMLElement\n expanded: string | null\n disabled: string | null\n }\n\n override connectedCallback() {\n super.connectedCallback()\n // 点击监听与生命周期同寿(宿主移除即整体销毁),无需 disconnected 清理。\n this.addEventListener('click', this._onTriggerClick)\n // 断连可能打断动画管线(瞬态残留:presence='closing'、容器未 hidden)。\n // 首次连接不必处理(初始 render 走 _lastOpen===undefined 落稳态,请求多余\n // 渲染会触发「scheduled an update after update completed」告警);重连时\n // 重置同步状态并强制一轮 update,由首次同步分支重新落稳态、丢弃在途管线。\n if (this.hasUpdated) {\n this._generation++\n this._clearExitTimer()\n this._lastOpen = undefined\n this.requestUpdate()\n }\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback()\n this._clearExitTimer()\n this._restoreTriggerSnapshot()\n }\n\n protected override updated(changed: Map<string, unknown>) {\n // trigger 状态回写不依赖 open 分支,任何渲染后都保持与宿主状态同步。\n this._syncTriggerState()\n // peek 的稳态长度与动画写入共用 track 内联样式,先同步再落稳态,避免被稳态清除。\n this._syncPeek()\n\n // 首次同步(含 open 为默认值的场景,changed map 不含默认值属性):\n // 直接落到正确稳态,不播动画(popover 初始 open 同款)。\n if (this._lastOpen === undefined) {\n this._lastOpen = this.open\n if (this.open) this._applyOpenSteadyState()\n else this._applyClosedSteadyState()\n return\n }\n\n if ((changed.has('keepMounted') || changed.has('peek')) && !this.open) {\n // 运行态切换 keep-mounted / peek:关闭稳态需在 hidden / inert / 裁剪长度间重新落地。\n this._applyClosedSteadyState()\n }\n if (!changed.has('open') || this.open === this._lastOpen) return\n\n this._lastOpen = this.open\n if (this._userOpenChange.consume()) this._dispatchChange(this.open)\n if (this.open) this._beginExpand()\n else this._beginCollapse()\n }\n\n show() {\n if (this.open) return\n this.open = true\n }\n\n close() {\n if (!this.open) return\n this.open = false\n }\n\n toggle() {\n if (this.open) this.close()\n else this.show()\n }\n\n private _dispatchChange(open: boolean) {\n dispatchOpenChangeEvent(this, open)\n }\n\n /*\n * 点击代理:冒泡路径穿过 trigger wrapper 的 click 一律切换。语义由 slot 内\n * 的交互元素(原生 button / web-ui-button)提供;slot 放纯文本时无激活语义\n * (README 约定)。内容区与嵌套内层 collapse 的 click 不经过本 wrapper,天然隔离。\n */\n private _onTriggerClick = (event: MouseEvent) => {\n if (this.disabled) return\n if (!event.composedPath().includes(this._triggerWrapper)) return\n this._userOpenChange.mark()\n this.toggle()\n }\n\n /*\n * Trigger 元素取首个 assigned element(与 popover `_queryTrigger` 同款惰性查询,\n * 不依赖 slotchange——jsdom 不派发该事件,无法用状态缓存)。slot 为空时无回写目标。\n */\n private _queryTrigger(): HTMLElement | null {\n const slot = this.shadowRoot?.querySelector<HTMLSlotElement>('.wui-collapse-trigger-wrapper slot')\n const el = slot?.assignedElements()[0]\n return el instanceof HTMLElement ? el : null\n }\n\n /*\n * slot 内容增删不触发宿主响应式更新:显式请求一轮渲染,由 updated() 的\n * trigger 状态回写覆盖晚到的 trigger 元素(slotchange 在 jsdom 不派发,无法监听)。\n */\n private readonly _onTriggerSlotChange = () => {\n this.requestUpdate()\n }\n\n private _restoreTriggerSnapshot() {\n const snapshot = this._triggerSnapshot\n if (!snapshot) return\n\n for (const [attribute, value] of Object.entries({\n 'aria-expanded': snapshot.expanded,\n disabled: snapshot.disabled\n })) {\n if (value === null) snapshot.trigger.removeAttribute(attribute)\n else snapshot.trigger.setAttribute(attribute, value)\n }\n this._triggerSnapshot = undefined\n }\n\n /*\n * 状态回写到 trigger 元素本身(wrapper 不可聚焦,AT 读不到):展开态用\n * `aria-expanded`,禁用态用 `disabled`——后者是唯一能穿透 `<web-ui-button>`\n * shadow 边界的表达(属性会被内部原生 button 读到),且与「真禁用」语义一致。\n */\n private _syncTriggerState() {\n const trigger = this._queryTrigger()\n if (this._triggerSnapshot?.trigger !== trigger) {\n this._restoreTriggerSnapshot()\n if (trigger) {\n this._triggerSnapshot = {\n trigger,\n expanded: trigger.getAttribute('aria-expanded'),\n disabled: trigger.getAttribute('disabled')\n }\n }\n }\n if (!trigger) return\n trigger.setAttribute('aria-expanded', String(this.open))\n trigger.toggleAttribute('disabled', this.disabled)\n }\n\n // ===== 内容区动画管线(三态语义自 ADR-0030 迁移) =====\n\n /** 关闭稳态是否露出部分内容;空值与非空判断避免 `peek=\"\"` 被当作有效长度。 */\n private get _peeks(): boolean {\n return typeof this.peek === 'string' && this.peek.trim() !== ''\n }\n\n private _applyOpenSteadyState() {\n this._generation++\n this._clearExitTimer()\n const container = this._contentContainer()\n const track = this._contentTrack()\n if (container) container.hidden = false\n if (track) track.dataset.wuiPresence = 'open'\n this._clearInnerClamp()\n this._setInnerInert(false)\n }\n\n private _applyClosedSteadyState() {\n this._generation++\n this._clearExitTimer()\n const container = this._contentContainer()\n const track = this._contentTrack()\n if (track) delete track.dataset.wuiPresence\n this._clearInnerClamp()\n if (this.keepMounted || this._peeks) {\n if (container) container.hidden = false\n this._setInnerInert(true)\n return\n }\n this._setInnerInert(false)\n if (container) container.hidden = true\n }\n\n private _beginExpand() {\n this._generation++\n this._clearExitTimer()\n const container = this._contentContainer()\n const track = this._contentTrack()\n if (!container || !track) return\n\n const generation = this._generation\n // 中断关闭动画时 inner 已 inert:先恢复可交互,内容随展开重新可见。\n this._setInnerInert(false)\n // 从 display:none 进入时无先前计算样式可过渡:提交 0fr 起点后再翻转。\n container.hidden = false\n\n if (this._peeks) {\n const inner = this._contentInner()\n // 无过渡时长(reduced motion、jsdom)或无 inner 时不做测量,直接落展开稳态。\n if (!inner || getTransitionDuration(inner, 0) === 0) {\n this._applyOpenSteadyState()\n return\n }\n /*\n * peek 的裁剪长度是固定值,展开目标是内容自适应高度,两者无法由 CSS 插值,\n * 动画必须由两个显式长度驱动:起点是当前露出的长度,目标是内容完整尺寸。\n * 起点要在同任务内先写入并提交回流,否则过渡会退化成跳变(实测分帧写入\n * 反而完全不参与插值判定);目标读 inner 的 scroll 尺寸,不写探针样式。\n */\n const from = this._measureInnerSize(inner)\n const to = this._measureContentSize(inner)\n this._setInnerClamp(inner, `${from}px`)\n void this._measureInnerSize(inner)\n track.dataset.wuiPresence = 'open'\n this._setInnerClamp(inner, `${to}px`)\n this._awaitTransition(inner, generation, () => this._settle(true), [this._clampProperty()])\n return\n }\n\n void track.offsetWidth\n\n requestAnimationFrame(() => {\n if (generation !== this._generation || !this.open) return\n track.dataset.wuiPresence = 'open'\n this._awaitTransition(track, generation, () => this._settle(true))\n })\n }\n\n private _beginCollapse() {\n this._generation++\n this._clearExitTimer()\n const track = this._contentTrack()\n if (!track) return\n\n // 收起期间立即阻断交互,防止焦点落入正在消失的区域。\n this._setInnerInert(true)\n const generation = this._generation\n\n if (this._peeks) {\n const inner = this._contentInner()\n // 无过渡时长(reduced motion、jsdom)或无 inner 时不做测量,直接落裁剪稳态。\n if (!inner || getTransitionDuration(inner, 0) === 0) {\n this._applyClosedSteadyState()\n return\n }\n /*\n * 收起目标是 `peek` 长度本身:与内容尺寸的较小值由 CSS 稳态规则解析,\n * 动画只需把当前展开长度过渡到这个长度。起点同样要先写入并提交回流,\n * 顺序与 _beginExpand 一致。\n */\n const from = this._measureInnerSize(inner)\n this._setInnerClamp(inner, `${from}px`)\n void this._measureInnerSize(inner)\n track.dataset.wuiPresence = 'closing'\n this._setInnerClamp(inner, `${this.peek}`)\n this._awaitTransition(inner, generation, () => this._settle(false), [this._clampProperty()])\n return\n }\n\n track.dataset.wuiPresence = 'closing'\n this._awaitTransition(track, generation, () => this._settle(false))\n }\n\n // 关闭稳态:keep-mounted → 内容保留在 0fr track 内并 inert;peek → 保留在裁剪\n // 窗口内并 inert;默认 → 容器 hidden。\n private _settle(open: boolean) {\n this._clearExitTimer()\n const track = this._contentTrack()\n // peek 过渡以显式长度写入 inner:落稳态一律清除,交回 CSS 稳态规则(长度声明)。\n this._clearInnerClamp()\n if (open) {\n this._setInnerInert(false)\n return\n }\n // 落稳态必须清除 closing 瞬态标记:否则 track 永久保留 pointer-events:none\n // 与 exit 过渡配置(keep-mounted 分支同样清除,避免残留)。\n if (track) delete track.dataset.wuiPresence\n if (this.keepMounted || this._peeks) return\n const container = this._contentContainer()\n this._setInnerInert(false)\n if (container) container.hidden = true\n }\n\n // 等待动画属性过渡结束;时长为 0(reduced motion、jsdom)直接稳态,\n // transitionend 不触发时按时长 + 缓冲兜底。默认等待 grid track 过渡;peek 的\n // 过渡落在 inner 的裁剪长度上,由调用方传入对应属性。\n private _awaitTransition(\n animated: HTMLElement,\n generation: number,\n onDone: () => void,\n properties: readonly string[] = ['grid-template-rows', 'grid-template-columns']\n ) {\n const duration = getTransitionDuration(animated, 0)\n if (duration === 0) {\n if (generation === this._generation) onDone()\n return\n }\n\n let settled = false\n const finish = () => {\n animated.removeEventListener('transitionend', onTransitionEnd)\n if (this._exitTimer === timer) this._exitTimer = undefined\n clearTimeout(timer)\n // 过渡可能被属性匹配的后续动画触发(如中断重开):代际不符时静默退场。\n if (settled || generation !== this._generation) return\n settled = true\n onDone()\n }\n const timer = setTimeout(finish, duration + EXIT_FALLBACK_BUFFER)\n this._exitTimer = timer\n\n const onTransitionEnd = (event: TransitionEvent) => {\n if (event.target === animated && properties.includes(event.propertyName)) finish()\n }\n animated.addEventListener('transitionend', onTransitionEnd)\n }\n\n private _clearExitTimer() {\n if (this._exitTimer !== undefined) {\n clearTimeout(this._exitTimer)\n this._exitTimer = undefined\n }\n }\n\n // ===== peek 尺寸读写(裁剪长度落在 inner 上,track 只负责 1fr 与裁剪窗口) =====\n\n /*\n * peek 长度经自定义属性下发给 shadow 样式规则,而不是直接写 inner 的裁剪长度:\n * 关闭稳态由 CSS 声明(长度与内容尺寸的较小值由 CSS 原生解析),动画写入的内联\n * 长度在其上覆盖,落稳态时清除即可回到声明值。\n */\n private _syncPeek() {\n const track = this._contentTrack()\n if (!track) return\n track.toggleAttribute('data-wui-peek', this._peeks)\n if (this._peeks) {\n track.style.setProperty('--wui-collapse-peek', this.peek ?? '')\n } else {\n track.style.removeProperty('--wui-collapse-peek')\n }\n }\n\n private _clampProperty(): 'max-height' | 'max-width' {\n return this.horizontal ? 'max-width' : 'max-height'\n }\n\n private _measureInnerSize(inner: HTMLElement): number {\n return this.horizontal ? inner.offsetWidth : inner.offsetHeight\n }\n\n /*\n * 内容在动画轴上的完整尺寸(px):裁剪只作用在 inner 的 max-height/max-width 上,\n * 被测内容的布局盒子仍是完整尺寸,故读 scroll 尺寸即可,不写任何样式——写样式\n * 会被 grid 过渡机制当作过渡起点读取,必须避开。\n */\n private _measureContentSize(inner: HTMLElement): number {\n return this.horizontal ? inner.scrollWidth : inner.scrollHeight\n }\n\n private _setInnerClamp(inner: HTMLElement, size: string) {\n inner.style.setProperty(this._clampProperty(), size)\n }\n\n private _clearInnerClamp() {\n const inner = this._contentInner()\n if (!inner) return\n inner.style.removeProperty('max-height')\n inner.style.removeProperty('max-width')\n }\n\n private _setInnerInert(inert: boolean) {\n this._contentInner()?.toggleAttribute('inert', inert)\n }\n\n private _contentInner(): HTMLElement | null {\n return this.shadowRoot?.querySelector<HTMLElement>('.wui-collapse-inner') ?? null\n }\n\n private _contentContainer(): HTMLElement | null {\n return this.shadowRoot?.querySelector<HTMLElement>('.wui-collapse-content') ?? null\n }\n\n private _contentTrack(): HTMLElement | null {\n return this.shadowRoot?.querySelector<HTMLElement>('.wui-collapse-track') ?? null\n }\n\n override render() {\n // 三态由 data-wui-presence 驱动(open/closing),缺省即关闭稳态。\n const trackClass = {\n 'wui-collapse-track': true,\n 'is-horizontal': this.horizontal\n }\n\n return html`\n <div class=\"wui-collapse-trigger-wrapper\" @slotchange=${this._onTriggerSlotChange}><slot></slot></div>\n <div class=\"wui-collapse-content\">\n <div class=${classMap(trackClass)}>\n <div class=${classMap({ 'wui-collapse-inner': true, 'wui-glow': this._peeks })}>\n <slot name=\"content\"></slot>\n </div>\n </div>\n </div>\n `\n }\n\n declare readonly $events: {\n 'open-change': CustomEvent<{ open: boolean }>\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-collapse': WebUiCollapse\n }\n}\n"],"mappings":"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"}
@@ -1,34 +1,22 @@
1
1
  import { LitElement } from 'lit';
2
+ /**
3
+ * 空态图形区。
4
+ *
5
+ * 默认图形直接渲染成 `svg`,不再包 `web-ui-icon`:`web-ui-icon` 的边长是 JS 属性
6
+ * (`.size`),CSS 变量驱动不了它,而空态的默认图形是固定资产,没有必要为了几个像素
7
+ * 去读 computed style 再回写属性。样式因此全部落在 CSS 上,调用方换尺寸只写变量。
8
+ *
9
+ * 副作用导入 `@/components/icon` 保留:`icon` 插槽的既有写法只 import 图标数据
10
+ * (`@greypan/web-ui/icons`),组件注册由这里提供。
11
+ */
2
12
  export declare class WebUiEmpty extends LitElement {
3
13
  static styles: import('lit').CSSResult[];
4
14
  title: string;
5
15
  description: string;
6
- /**
7
- * 版面缩放基准,单位 px,默认 56。驱动 icon 盒、min-height、padding 与标题/描述字号,
8
- * 使大 icon 不再配 medium 留白。
9
- *
10
- * 派生规则:icon 容器边长即 `size`,默认字形边长 `round(size * 3 / 7)`,min-height
11
- * `round(size * 30 / 7)`,padding 块 `round(size * 4 / 7)`、行 `round(size * 3 / 7)`;
12
- * 字号在 56 处分两档,低于 56 为 14px / 13px,56 及以上为 16px / 14px。段间距与内容宽度
13
- * 不随它变化。
14
- *
15
- * 派生值全部落在 `--wui-internal-empty-*` 上,`--wui-empty-*` 仍压在其上,所以逐项覆盖
16
- * 优先于本属性。非法输入(非有限数、0、负数)回退默认边长 56。
17
- */
18
- get size(): number;
19
- set size(value: number);
20
- private _size;
21
- private get _iconSize();
22
- /**
23
- * `size` 派生的整套度量。CSS 侧按 `var(--wui-empty-*, var(--wui-internal-empty-*, 默认值))`
24
- * 消费,公开 token 因此始终压在派生值之上。
25
- */
26
- private get _sizeStyle();
27
16
  private _hasTitleSlot;
28
17
  private _hasDescriptionSlot;
29
18
  private _hasActionSlot;
30
19
  connectedCallback(): void;
31
- protected updated(): void;
32
20
  private _syncSlotContent;
33
21
  private _hasAssignedContent;
34
22
  render(): import('lit').TemplateResult<1>;
@@ -1,56 +1,43 @@
1
1
  import e from "../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorate.js";
2
2
  import "../icon/index.js";
3
- import t from "../../icons/generated/lucide-inbox.js";
3
+ import t from "../../icons/generated/andrsrxn-inbox.js";
4
4
  import n from "./style.js";
5
5
  import { LitElement as r, html as i, unsafeCSS as a } from "lit";
6
6
  import { customElement as o, property as s, state as c } from "lit/decorators.js";
7
7
  import { classMap as l } from "lit/directives/class-map.js";
8
+ import { unsafeSVG as u } from "lit/directives/unsafe-svg.js";
8
9
  //#region src/components/empty/index.ts
9
- var u = 56, d = 7, f = 3, p = 30, m = 4, h = 3, g = 56, _ = 14, v = 13, y = 16, b = 14, x = (e) => Number.isFinite(e) && e > 0 ? e : u, S = class extends r {
10
+ var d = 16, f = 40, p = class extends r {
10
11
  constructor(...e) {
11
- super(...e), this.title = "", this.description = "", this._size = u, this._hasTitleSlot = !1, this._hasDescriptionSlot = !1, this._hasActionSlot = !1, this._syncSlotContent = () => {
12
+ super(...e), this.title = "", this.description = "", this._hasTitleSlot = !1, this._hasDescriptionSlot = !1, this._hasActionSlot = !1, this._syncSlotContent = () => {
12
13
  this._hasTitleSlot = this._hasAssignedContent(), this._hasDescriptionSlot = this._hasAssignedContent("description"), this._hasActionSlot = this._hasAssignedContent("action");
13
14
  };
14
15
  }
15
16
  static {
16
17
  this.styles = [a(n)];
17
18
  }
18
- get size() {
19
- return this._size;
20
- }
21
- set size(e) {
22
- let t = this._size, n = x(e);
23
- n !== t && (this._size = n, this.requestUpdate("size", t));
24
- }
25
- get _iconSize() {
26
- return Math.round(this.size * f / d);
27
- }
28
- get _sizeStyle() {
29
- let e = this.size, t = e < g, n = (t) => `${Math.round(e * t / d)}px`;
30
- return {
31
- "--wui-internal-empty-size": `${e}px`,
32
- "--wui-internal-empty-min-height": n(p),
33
- "--wui-internal-empty-padding-block": n(m),
34
- "--wui-internal-empty-padding-inline": n(h),
35
- "--wui-internal-empty-title-font-size": `${t ? _ : y}px`,
36
- "--wui-internal-empty-description-font-size": `${t ? v : b}px`
37
- };
38
- }
39
19
  connectedCallback() {
40
20
  super.connectedCallback(), this._syncSlotContent();
41
21
  }
42
- updated() {
43
- for (let [e, t] of Object.entries(this._sizeStyle)) this.style.setProperty(e, t);
44
- }
45
22
  _hasAssignedContent(e) {
46
23
  return [...this.childNodes].some((t) => t instanceof HTMLElement && (t.getAttribute("slot") ?? "") === (e ?? "") || !e && t.nodeType === Node.TEXT_NODE && !!t.textContent?.trim());
47
24
  }
48
25
  render() {
49
- let e = this._hasTitleSlot || !!this.title, n = this._hasDescriptionSlot || !!this.description;
26
+ let e = this._hasTitleSlot || !!this.title, n = this._hasDescriptionSlot || !!this.description, r = t, a = `${r.left ?? 0} ${r.top ?? 0} ${r.width ?? d} ${r.height ?? d}`;
50
27
  return i`
51
28
  <section class="empty">
52
29
  <div class="empty-icon" aria-hidden="true">
53
- <slot name="icon"><web-ui-icon .icon=${t} .size=${this._iconSize}></web-ui-icon></slot>
30
+ <slot name="icon">
31
+ <svg
32
+ class="empty-glyph"
33
+ viewBox="${a}"
34
+ width="${f}"
35
+ height="${f}"
36
+ aria-hidden="true"
37
+ >
38
+ ${u(t.body)}
39
+ </svg>
40
+ </slot>
54
41
  </div>
55
42
  <div class=${l({
56
43
  "empty-title": !0,
@@ -77,14 +64,11 @@ var u = 56, d = 7, f = 3, p = 30, m = 4, h = 3, g = 56, _ = 14, v = 13, y = 16,
77
64
  e([s({
78
65
  type: String,
79
66
  reflect: !0
80
- })], S.prototype, "title", void 0), e([s({
67
+ })], p.prototype, "title", void 0), e([s({
81
68
  type: String,
82
69
  reflect: !0
83
- })], S.prototype, "description", void 0), e([s({
84
- type: Number,
85
- reflect: !0
86
- })], S.prototype, "size", null), e([c()], S.prototype, "_hasTitleSlot", void 0), e([c()], S.prototype, "_hasDescriptionSlot", void 0), e([c()], S.prototype, "_hasActionSlot", void 0), S = e([o("web-ui-empty")], S);
70
+ })], p.prototype, "description", void 0), e([c()], p.prototype, "_hasTitleSlot", void 0), e([c()], p.prototype, "_hasDescriptionSlot", void 0), e([c()], p.prototype, "_hasActionSlot", void 0), p = e([o("web-ui-empty")], p);
87
71
  //#endregion
88
- export { S as WebUiEmpty };
72
+ export { p as WebUiEmpty };
89
73
 
90
74
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/empty/index.ts"],"sourcesContent":["import '@/components/icon'\n\nimport { html, LitElement, unsafeCSS } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\n\nimport { lucideInbox } from '@/icons'\n\nimport style from './style.css?inline'\n\n/**\n * icon 容器边长默认值(px),也是非法输入的回退目标。\n */\nconst DEFAULT_SIZE = 56\n\n/**\n * 派生度量统一除以 7。取 7 是为了让默认档 56 整除出改前 medium 的四个值:字形 3/7 → 24、\n * min-height 30/7 → 240、padding 块 4/7 → 32、padding 行 3/7 → 24。40 与 72 因此落到\n * 171 / 23 / 17 与 309 / 41 / 31,字形 17 与 31。\n */\nconst DERIVED_DENOMINATOR = 7\nconst GLYPH_NUMERATOR = 3\nconst MIN_HEIGHT_NUMERATOR = 30\nconst PADDING_BLOCK_NUMERATOR = 4\nconst PADDING_INLINE_NUMERATOR = 3\n\n/**\n * 字号只有两档,阈值与默认边长同为 56:低于阈值取改前 small 的字号,其余取改前 medium 的\n * 字号。大尺寸靠留白撑开而不是靠字变大,所以 72 与 56 同档。\n */\nconst COMPACT_SIZE_THRESHOLD = 56\nconst COMPACT_TITLE_FONT_SIZE = 14\nconst COMPACT_DESCRIPTION_FONT_SIZE = 13\nconst DEFAULT_TITLE_FONT_SIZE = 16\nconst DEFAULT_DESCRIPTION_FONT_SIZE = 14\n\n/**\n * 只做数值合法性判断,不做枚举映射:有限正数原样采用,其余输入(NaN、±Infinity、0、负数)\n * 回退默认边长。\n *\n * 这一层是必要的:`size` 会同时写进 `--wui-internal-empty-size`,未守卫时\n * `size=\"abc\"` 会产出失效的 `NaNpx`(盒退回 unset 而涨成 300×300),\n * `size=\"\"` 会产出 `0px`(icon 不可见)。回退的是边长本身,整套派生度量因此一起回到默认档\n * 56,而不是按 `NaN` 算出垃圾值。\n */\nconst normalizeSize = (value: number): number => (Number.isFinite(value) && value > 0 ? value : DEFAULT_SIZE)\n\n@customElement('web-ui-empty')\nexport class WebUiEmpty extends LitElement {\n static override styles = [unsafeCSS(style)]\n\n @property({ type: String, reflect: true }) override title = ''\n\n @property({ type: String, reflect: true }) description = ''\n\n /**\n * 版面缩放基准,单位 px,默认 56。驱动 icon 盒、min-height、padding 与标题/描述字号,\n * 使大 icon 不再配 medium 留白。\n *\n * 派生规则:icon 容器边长即 `size`,默认字形边长 `round(size * 3 / 7)`,min-height\n * `round(size * 30 / 7)`,padding 块 `round(size * 4 / 7)`、行 `round(size * 3 / 7)`;\n * 字号在 56 处分两档,低于 56 为 14px / 13px,56 及以上为 16px / 14px。段间距与内容宽度\n * 不随它变化。\n *\n * 派生值全部落在 `--wui-internal-empty-*` 上,`--wui-empty-*` 仍压在其上,所以逐项覆盖\n * 优先于本属性。非法输入(非有限数、0、负数)回退默认边长 56。\n */\n @property({ type: Number, reflect: true })\n get size(): number {\n return this._size\n }\n\n set size(value: number) {\n const old = this._size\n const normalized = normalizeSize(value)\n if (normalized === old) return\n this._size = normalized\n this.requestUpdate('size', old)\n }\n\n private _size = DEFAULT_SIZE\n\n private get _iconSize(): number {\n return Math.round((this.size * GLYPH_NUMERATOR) / DERIVED_DENOMINATOR)\n }\n\n /**\n * `size` 派生的整套度量。CSS 侧按 `var(--wui-empty-*, var(--wui-internal-empty-*, 默认值))`\n * 消费,公开 token 因此始终压在派生值之上。\n */\n private get _sizeStyle(): Record<string, string> {\n const size = this.size\n const compact = size < COMPACT_SIZE_THRESHOLD\n const scaled = (numerator: number) => `${Math.round((size * numerator) / DERIVED_DENOMINATOR)}px`\n return {\n '--wui-internal-empty-size': `${size}px`,\n '--wui-internal-empty-min-height': scaled(MIN_HEIGHT_NUMERATOR),\n '--wui-internal-empty-padding-block': scaled(PADDING_BLOCK_NUMERATOR),\n '--wui-internal-empty-padding-inline': scaled(PADDING_INLINE_NUMERATOR),\n '--wui-internal-empty-title-font-size': `${compact ? COMPACT_TITLE_FONT_SIZE : DEFAULT_TITLE_FONT_SIZE}px`,\n '--wui-internal-empty-description-font-size': `${\n compact ? COMPACT_DESCRIPTION_FONT_SIZE : DEFAULT_DESCRIPTION_FONT_SIZE\n }px`\n }\n }\n\n @state() private _hasTitleSlot = false\n @state() private _hasDescriptionSlot = false\n @state() private _hasActionSlot = false\n\n override connectedCallback() {\n super.connectedCallback()\n this._syncSlotContent()\n }\n\n protected override updated() {\n // 无条件写:条件写同样覆盖得到默认实例(实测首次 changedProperties 里带 size)。\n // 这里换来的不变量是「派生 token 永远与当前 size 一致」——将来新增派生 token 不必\n // 再补一处 changed 判断,而同值 setProperty 不触发样式失效,代价可忽略。\n for (const [token, value] of Object.entries(this._sizeStyle)) {\n this.style.setProperty(token, value)\n }\n }\n\n private _syncSlotContent = () => {\n this._hasTitleSlot = this._hasAssignedContent()\n this._hasDescriptionSlot = this._hasAssignedContent('description')\n this._hasActionSlot = this._hasAssignedContent('action')\n }\n\n private _hasAssignedContent(slotName?: string): boolean {\n return [...this.childNodes].some(node => {\n if (node instanceof HTMLElement && (node.getAttribute('slot') ?? '') === (slotName ?? '')) return true\n return !slotName && node.nodeType === Node.TEXT_NODE && Boolean(node.textContent?.trim())\n })\n }\n\n override render() {\n const showTitle = this._hasTitleSlot || Boolean(this.title)\n const showDescription = this._hasDescriptionSlot || Boolean(this.description)\n\n return html`\n <section class=\"empty\">\n <div class=\"empty-icon\" aria-hidden=\"true\">\n <slot name=\"icon\"><web-ui-icon .icon=${lucideInbox} .size=${this._iconSize}></web-ui-icon></slot>\n </div>\n <div class=${classMap({ 'empty-title': true, 'is-hidden': !showTitle })}>\n <slot @slotchange=${this._syncSlotContent}>${this.title}</slot>\n </div>\n <div class=${classMap({ 'empty-description': true, 'is-hidden': !showDescription })}>\n <slot name=\"description\" @slotchange=${this._syncSlotContent}>${this.description}</slot>\n </div>\n <div class=${classMap({ 'empty-action': true, 'is-hidden': !this._hasActionSlot })}>\n <slot name=\"action\" @slotchange=${this._syncSlotContent}></slot>\n </div>\n </section>\n `\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-empty': WebUiEmpty\n }\n}\n"],"mappings":";;;;;;;;AAaA,IAAM,IAAe,IAOf,IAAsB,GACtB,IAAkB,GAClB,IAAuB,IACvB,IAA0B,GAC1B,IAA2B,GAM3B,IAAyB,IACzB,IAA0B,IAC1B,IAAgC,IAChC,IAA0B,IAC1B,IAAgC,IAWhC,KAAiB,MAA2B,OAAO,SAAS,CAAK,KAAK,IAAQ,IAAI,IAAQ,GAGnF,IAAN,cAAyB,EAAW;;EA4ER,aAzE2B,KAAA,QAAA,IAEH,KAAA,cAAA,IA2BzC,KAAA,QAAA,GA0BiB,KAAA,gBAAA,IACM,KAAA,sBAAA,IACL,KAAA,iBAAA,IAgBD,KAAA,yBAAA;GAG/B,AAFA,KAAK,gBAAgB,KAAK,oBAAoB,GAC9C,KAAK,sBAAsB,KAAK,oBAAoB,aAAa,GACjE,KAAK,iBAAiB,KAAK,oBAAoB,QAAQ;EACzD;;;EA/EyB,KAAA,SAAA,CAAC,EAAU,CAAK,CAAC;;CAkB1C,IACI,OAAe;EACjB,OAAO,KAAK;CACd;CAEA,IAAI,KAAK,GAAe;EACtB,IAAM,IAAM,KAAK,OACX,IAAa,EAAc,CAAK;EAClC,MAAe,MACnB,KAAK,QAAQ,GACb,KAAK,cAAc,QAAQ,CAAG;CAChC;CAIA,IAAY,YAAoB;EAC9B,OAAO,KAAK,MAAO,KAAK,OAAO,IAAmB,CAAmB;CACvE;CAMA,IAAY,aAAqC;EAC/C,IAAM,IAAO,KAAK,MACZ,IAAU,IAAO,GACjB,KAAU,MAAsB,GAAG,KAAK,MAAO,IAAO,IAAa,CAAmB,EAAE;EAC9F,OAAO;GACL,6BAA6B,GAAG,EAAK;GACrC,mCAAmC,EAAO,CAAoB;GAC9D,sCAAsC,EAAO,CAAuB;GACpE,uCAAuC,EAAO,CAAwB;GACtE,wCAAwC,GAAG,IAAU,IAA0B,EAAwB;GACvG,8CAA8C,GAC5C,IAAU,IAAgC,EAC3C;EACH;CACF;CAMA,oBAA6B;EAE3B,AADA,MAAM,kBAAkB,GACxB,KAAK,iBAAiB;CACxB;CAEA,UAA6B;EAI3B,KAAK,IAAM,CAAC,GAAO,MAAU,OAAO,QAAQ,KAAK,UAAU,GACzD,KAAK,MAAM,YAAY,GAAO,CAAK;CAEvC;CAQA,oBAA4B,GAA4B;EACtD,OAAO,CAAC,GAAG,KAAK,UAAU,CAAC,CAAC,MAAK,MAC3B,aAAgB,gBAAgB,EAAK,aAAa,MAAM,KAAK,SAAS,KAAY,OAC/E,CAAC,KAAY,EAAK,aAAa,KAAK,aAAa,EAAQ,EAAK,aAAa,KAAK,CACxF;CACH;CAEA,SAAkB;EAChB,IAAM,IAAY,KAAK,iBAAiB,EAAQ,KAAK,OAC/C,IAAkB,KAAK,uBAAuB,EAAQ,KAAK;EAEjE,OAAO,CAAI;;;iDAGkC,EAAY,SAAS,KAAK,UAAU;;qBAEhE,EAAS;GAAE,eAAe;GAAM,aAAa,CAAC;EAAU,CAAC,EAAE;8BAClD,KAAK,iBAAiB,GAAG,KAAK,MAAM;;qBAE7C,EAAS;GAAE,qBAAqB;GAAM,aAAa,CAAC;EAAgB,CAAC,EAAE;iDAC3C,KAAK,iBAAiB,GAAG,KAAK,YAAY;;qBAEtE,EAAS;GAAE,gBAAgB;GAAM,aAAa,CAAC,KAAK;EAAe,CAAC,EAAE;4CAC/C,KAAK,iBAAiB;;;;CAIhE;AACF;AA3GG,EAAA,CAAA,EAAS;CAAE,MAAM;CAAQ,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,SAAA,KAAA,CAAA,GAExC,EAAA,CAAA,EAAS;CAAE,MAAM;CAAQ,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,eAAA,KAAA,CAAA,GAcxC,EAAA,CAAA,EAAS;CAAE,MAAM;CAAQ,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,QAAA,IAAA,GAuCxC,EAAA,CAAA,EAAM,CAAA,GAAA,EAAA,WAAA,iBAAA,KAAA,CAAA,GACN,EAAA,CAAA,EAAM,CAAA,GAAA,EAAA,WAAA,uBAAA,KAAA,CAAA,GACN,EAAA,CAAA,EAAM,CAAA,GAAA,EAAA,WAAA,kBAAA,KAAA,CAAA,GA7DR,IAAA,EAAA,CAAA,EAAc,cAAc,CAAA,GAAA,CAAA"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/empty/index.ts"],"sourcesContent":["import '@/components/icon'\n\nimport type { IconifyIcon } from '@iconify/types'\nimport { html, LitElement, unsafeCSS } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { unsafeSVG } from 'lit/directives/unsafe-svg.js'\n\nimport { andrsrxnInbox } from '@/icons'\n\nimport style from './style.css?inline'\n\n/**\n * Iconify 规范里画布缺省按 16 计(见 @iconify/types README)。生成资产自带尺寸,\n * 这条兜底服务的是把默认图形换成手写 IconifyIcon 对象的场景。\n */\nconst ICONIFY_DEFAULT_CANVAS = 16\n\n/**\n * SVG 的 width/height 属性值,与 CSS 里 `--wui-empty-icon-size` 的默认值一致。\n * 只负责首帧与 CSS 未生效时的高度,实际边长由 CSS 变量决定。\n */\nconst FALLBACK_ICON_SIZE = 40\n\n/**\n * 空态图形区。\n *\n * 默认图形直接渲染成 `svg`,不再包 `web-ui-icon`:`web-ui-icon` 的边长是 JS 属性\n * (`.size`),CSS 变量驱动不了它,而空态的默认图形是固定资产,没有必要为了几个像素\n * 去读 computed style 再回写属性。样式因此全部落在 CSS 上,调用方换尺寸只写变量。\n *\n * 副作用导入 `@/components/icon` 保留:`icon` 插槽的既有写法只 import 图标数据\n * (`@greypan/web-ui/icons`),组件注册由这里提供。\n */\n@customElement('web-ui-empty')\nexport class WebUiEmpty extends LitElement {\n static override styles = [unsafeCSS(style)]\n\n @property({ type: String, reflect: true }) override title = ''\n\n @property({ type: String, reflect: true }) description = ''\n\n @state() private _hasTitleSlot = false\n @state() private _hasDescriptionSlot = false\n @state() private _hasActionSlot = false\n\n override connectedCallback() {\n super.connectedCallback()\n this._syncSlotContent()\n }\n\n private _syncSlotContent = () => {\n this._hasTitleSlot = this._hasAssignedContent()\n this._hasDescriptionSlot = this._hasAssignedContent('description')\n this._hasActionSlot = this._hasAssignedContent('action')\n }\n\n private _hasAssignedContent(slotName?: string): boolean {\n return [...this.childNodes].some(node => {\n if (node instanceof HTMLElement && (node.getAttribute('slot') ?? '') === (slotName ?? '')) return true\n return !slotName && node.nodeType === Node.TEXT_NODE && Boolean(node.textContent?.trim())\n })\n }\n\n override render() {\n const showTitle = this._hasTitleSlot || Boolean(this.title)\n const showDescription = this._hasDescriptionSlot || Boolean(this.description)\n\n // 生成物只写下有值的字段,`left` / `top` 缺省即 0(Iconify 规范),所以按 IconifyIcon 读。\n const glyph: IconifyIcon = andrsrxnInbox\n const viewBox = `${glyph.left ?? 0} ${glyph.top ?? 0} ${glyph.width ?? ICONIFY_DEFAULT_CANVAS} ${\n glyph.height ?? ICONIFY_DEFAULT_CANVAS\n }`\n\n return html`\n <section class=\"empty\">\n <div class=\"empty-icon\" aria-hidden=\"true\">\n <slot name=\"icon\">\n <svg\n class=\"empty-glyph\"\n viewBox=\"${viewBox}\"\n width=\"${FALLBACK_ICON_SIZE}\"\n height=\"${FALLBACK_ICON_SIZE}\"\n aria-hidden=\"true\"\n >\n ${unsafeSVG(andrsrxnInbox.body)}\n </svg>\n </slot>\n </div>\n <div class=${classMap({ 'empty-title': true, 'is-hidden': !showTitle })}>\n <slot @slotchange=${this._syncSlotContent}>${this.title}</slot>\n </div>\n <div class=${classMap({ 'empty-description': true, 'is-hidden': !showDescription })}>\n <slot name=\"description\" @slotchange=${this._syncSlotContent}>${this.description}</slot>\n </div>\n <div class=${classMap({ 'empty-action': true, 'is-hidden': !this._hasActionSlot })}>\n <slot name=\"action\" @slotchange=${this._syncSlotContent}></slot>\n </div>\n </section>\n `\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-empty': WebUiEmpty\n }\n}\n"],"mappings":";;;;;;;;;AAgBA,IAAM,IAAyB,IAMzB,IAAqB,IAad,IAAN,cAAyB,EAAW;;EAgBR,aAb2B,KAAA,QAAA,IAEH,KAAA,cAAA,IAExB,KAAA,gBAAA,IACM,KAAA,sBAAA,IACL,KAAA,iBAAA,IAOD,KAAA,yBAAA;GAG/B,AAFA,KAAK,gBAAgB,KAAK,oBAAoB,GAC9C,KAAK,sBAAsB,KAAK,oBAAoB,aAAa,GACjE,KAAK,iBAAiB,KAAK,oBAAoB,QAAQ;EACzD;;;EAnByB,KAAA,SAAA,CAAC,EAAU,CAAK,CAAC;;CAU1C,oBAA6B;EAE3B,AADA,MAAM,kBAAkB,GACxB,KAAK,iBAAiB;CACxB;CAQA,oBAA4B,GAA4B;EACtD,OAAO,CAAC,GAAG,KAAK,UAAU,CAAC,CAAC,MAAK,MAC3B,aAAgB,gBAAgB,EAAK,aAAa,MAAM,KAAK,SAAS,KAAY,OAC/E,CAAC,KAAY,EAAK,aAAa,KAAK,aAAa,EAAQ,EAAK,aAAa,KAAK,CACxF;CACH;CAEA,SAAkB;EAChB,IAAM,IAAY,KAAK,iBAAiB,EAAQ,KAAK,OAC/C,IAAkB,KAAK,uBAAuB,EAAQ,KAAK,aAG3D,IAAqB,GACrB,IAAU,GAAG,EAAM,QAAQ,EAAE,GAAG,EAAM,OAAO,EAAE,GAAG,EAAM,SAAS,EAAuB,GAC5F,EAAM,UAAU;EAGlB,OAAO,CAAI;;;;;;yBAMU,EAAQ;uBACV,EAAmB;wBAClB,EAAmB;;;gBAG3B,EAAU,EAAc,IAAI,EAAE;;;;qBAIzB,EAAS;GAAE,eAAe;GAAM,aAAa,CAAC;EAAU,CAAC,EAAE;8BAClD,KAAK,iBAAiB,GAAG,KAAK,MAAM;;qBAE7C,EAAS;GAAE,qBAAqB;GAAM,aAAa,CAAC;EAAgB,CAAC,EAAE;iDAC3C,KAAK,iBAAiB,GAAG,KAAK,YAAY;;qBAEtE,EAAS;GAAE,gBAAgB;GAAM,aAAa,CAAC,KAAK;EAAe,CAAC,EAAE;4CAC/C,KAAK,iBAAiB;;;;CAIhE;AACF;AA/DG,EAAA,CAAA,EAAS;CAAE,MAAM;CAAQ,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,SAAA,KAAA,CAAA,GAExC,EAAA,CAAA,EAAS;CAAE,MAAM;CAAQ,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,eAAA,KAAA,CAAA,GAExC,EAAA,CAAA,EAAM,CAAA,GAAA,EAAA,WAAA,iBAAA,KAAA,CAAA,GACN,EAAA,CAAA,EAAM,CAAA,GAAA,EAAA,WAAA,uBAAA,KAAA,CAAA,GACN,EAAA,CAAA,EAAM,CAAA,GAAA,EAAA,WAAA,kBAAA,KAAA,CAAA,GAVR,IAAA,EAAA,CAAA,EAAc,cAAc,CAAA,GAAA,CAAA"}
@@ -1,5 +1,5 @@
1
1
  //#region src/components/empty/style.css?inline
2
- var e = "*,:before,:after{box-sizing:border-box}:host{display:block}.empty{width:100%;min-block-size:var(--wui-empty-min-height,var(--wui-internal-empty-min-height,240px));padding:var(--wui-empty-padding,var(--wui-internal-empty-padding-block,32px) var(--wui-internal-empty-padding-inline,24px));text-align:center;flex-direction:column;align-items:center;display:flex}.empty-icon{width:var(--wui-empty-icon-size,var(--wui-internal-empty-size,56px));height:var(--wui-empty-icon-size,var(--wui-internal-empty-size,56px));color:var(--wui-color-text-secondary,#6a6a6a);flex:none;justify-content:center;align-items:center;display:flex}.empty-title,.empty-description,.empty-action{max-inline-size:var(--wui-empty-content-width,480px)}.empty-title{margin-top:var(--wui-empty-title-margin-top,var(--wui-space-4,16px));font-size:var(--wui-empty-title-font-size,var(--wui-internal-empty-title-font-size,16px));font-weight:var(--wui-font-weight-semibold,600);line-height:var(--wui-line-height-normal,1.5);color:var(--wui-color-text,#1b1b1b);overflow-wrap:anywhere}.empty-description{font-size:var(--wui-empty-description-font-size,var(--wui-internal-empty-description-font-size,14px));line-height:var(--wui-line-height-relaxed,1.6);color:var(--wui-color-text-secondary,#6a6a6a);overflow-wrap:anywhere;margin-top:6px}.empty-action{margin-top:var(--wui-empty-action-margin-top,var(--wui-space-5,20px))}.is-hidden{display:none}";
2
+ var e = "*,:before,:after{box-sizing:border-box}:host{display:block}.empty{width:100%;min-block-size:var(--wui-empty-min-height,240px);padding:var(--wui-empty-padding,32px 24px);text-align:center;flex-direction:column;align-items:center;display:flex}.empty-icon{inline-size:var(--wui-empty-icon-size,40px);block-size:var(--wui-empty-icon-size,40px);color:var(--wui-empty-icon-color,var(--wui-color-text-secondary,#6a6a6a));flex:none;justify-content:center;align-items:center;display:flex}.empty-glyph{block-size:100%;inline-size:100%;opacity:var(--wui-empty-icon-opacity,.75);display:block}.empty-title,.empty-description,.empty-action{max-inline-size:var(--wui-empty-content-width,480px)}.empty-title{margin-top:var(--wui-empty-title-margin-top,var(--wui-space-3,12px));font-size:var(--wui-empty-title-font-size,16px);font-weight:var(--wui-font-weight-semibold,600);line-height:var(--wui-line-height-normal,1.5);color:var(--wui-empty-title-color,var(--wui-color-text,#1b1b1b));overflow-wrap:anywhere}.empty-description{font-size:var(--wui-empty-description-font-size,14px);line-height:var(--wui-line-height-relaxed,1.6);color:var(--wui-empty-description-color,var(--wui-color-text-secondary,#6a6a6a));overflow-wrap:anywhere;margin-top:6px}.empty-action{margin-top:var(--wui-empty-action-margin-top,var(--wui-space-5,20px))}.is-hidden{display:none}";
3
3
  //#endregion
4
4
  export { e as default };
5
5
 
@@ -1 +1 @@
1
- {"version":3,"file":"style.js","names":[],"sources":["../../../src/components/empty/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n display: block;\n}\n\n.empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n\n width: 100%;\n min-block-size: var(--wui-empty-min-height, var(--wui-internal-empty-min-height, 240px));\n padding: var(\n --wui-empty-padding,\n var(--wui-internal-empty-padding-block, 32px) var(--wui-internal-empty-padding-inline, 24px)\n );\n\n text-align: center;\n}\n\n.empty-icon {\n display: flex;\n flex: none;\n align-items: center;\n justify-content: center;\n\n width: var(--wui-empty-icon-size, var(--wui-internal-empty-size, 56px));\n height: var(--wui-empty-icon-size, var(--wui-internal-empty-size, 56px));\n\n /*\n * 纯图形,不绘制底面:盒只负责占位与居中,图形直接坐在它背后那张表面上,\n * 因此这里既不画背景也不画阴影,圆角随之无对象可作用。\n *\n * 图形色取 secondary 而非 tertiary:无底面时字形就是这一区唯一的图形元素,\n * tertiary 在浅色 page 上对比度不足 3:1。\n */\n color: var(--wui-color-text-secondary, #6a6a6a);\n}\n\n.empty-title,\n.empty-description,\n.empty-action {\n max-inline-size: var(--wui-empty-content-width, 480px);\n}\n\n.empty-title {\n margin-top: var(--wui-empty-title-margin-top, var(--wui-space-4, 16px));\n\n font-size: var(--wui-empty-title-font-size, var(--wui-internal-empty-title-font-size, 16px));\n font-weight: var(--wui-font-weight-semibold, 600);\n line-height: var(--wui-line-height-normal, 1.5);\n color: var(--wui-color-text, #1b1b1b);\n overflow-wrap: anywhere;\n}\n\n.empty-description {\n margin-top: 6px;\n\n font-size: var(--wui-empty-description-font-size, var(--wui-internal-empty-description-font-size, 14px));\n line-height: var(--wui-line-height-relaxed, 1.6);\n color: var(--wui-color-text-secondary, #6a6a6a);\n overflow-wrap: anywhere;\n}\n\n.empty-action {\n margin-top: var(--wui-empty-action-margin-top, var(--wui-space-5, 20px));\n}\n\n.is-hidden {\n display: none;\n}\n"],"mappings":""}
1
+ {"version":3,"file":"style.js","names":[],"sources":["../../../src/components/empty/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n display: block;\n}\n\n.empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n\n width: 100%;\n min-block-size: var(--wui-empty-min-height, 240px);\n padding: var(--wui-empty-padding, 32px 24px);\n\n text-align: center;\n}\n\n.empty-icon {\n display: flex;\n flex: none;\n align-items: center;\n justify-content: center;\n\n /*\n * 盒与图形同尺寸:底色退役后隐形内边距只会把图形推离标题(#440)。盒不比图形大,\n * 图形与标题之间的距离就正好是 .empty-title 的 margin-top。\n */\n inline-size: var(--wui-empty-icon-size, 40px);\n block-size: var(--wui-empty-icon-size, 40px);\n\n /*\n * 纯图形,不绘制底面:盒只负责占位与居中,图形直接坐在它背后那张表面上,\n * 因此这里既不画背景也不画阴影,圆角随之无对象可作用。\n *\n * 取实色 secondary,不掺 alpha:线框图形的笔画在转角与端点处本来就互相重叠\n * (填底压在描边上、横线与外轮廓在两端交汇),带 alpha 的颜色会在这些重叠处\n * 二次合成、局部变深,看起来像\"角上笔画发黑\"。淡一档由 .empty-glyph 的\n * group opacity 负责——那是在整颗图形合成之后一次性施加的,重叠处不起变化。\n */\n color: var(--wui-empty-icon-color, var(--wui-color-text-secondary, #6a6a6a));\n}\n\n/*\n * 默认图形填满盒:`width` / `height` 属性只兜首帧,尺寸的单一来源是 --wui-empty-icon-size。\n * 图形资产用 currentColor 描边与填充,颜色因此跟着 .empty-icon 的 color 走。\n *\n * 0.75 把整颗默认色压到 secondary 与 tertiary 之间(浅色合成 #8f8f8f ≈ 3.22:1,\n * 深色合成 #828282 ≈ 3.98:1,两档都守住非文本图形的 3:1),比整颗 secondary 轻,\n * 又不至于像 tertiary 那样在浅色 page 上只有 2.19:1。\n *\n * 关键在这是 group opacity:整颗 SVG 先按不透明合成成一层,再统一按 0.75 落到背景上。\n * 若改用带 alpha 的颜色,每条绘制指令各自带 0.75,笔画重叠处会叠到 0.94,交角明显发黑。\n * 只作用于默认图形,`icon` 插槽里的内容由调用方自己控制颜色与深浅。\n */\n.empty-glyph {\n display: block;\n inline-size: 100%;\n block-size: 100%;\n opacity: var(--wui-empty-icon-opacity, 0.75);\n}\n\n.empty-title,\n.empty-description,\n.empty-action {\n max-inline-size: var(--wui-empty-content-width, 480px);\n}\n\n.empty-title {\n /*\n * 图形自身在 40px 见方的框里还带一圈线条留白,视觉间隙因此比数值看着更大,\n * 收到 space-3(12px)才和标题读成一组。\n */\n margin-top: var(--wui-empty-title-margin-top, var(--wui-space-3, 12px));\n\n font-size: var(--wui-empty-title-font-size, 16px);\n font-weight: var(--wui-font-weight-semibold, 600);\n line-height: var(--wui-line-height-normal, 1.5);\n color: var(--wui-empty-title-color, var(--wui-color-text, #1b1b1b));\n overflow-wrap: anywhere;\n}\n\n.empty-description {\n margin-top: 6px;\n\n font-size: var(--wui-empty-description-font-size, 14px);\n line-height: var(--wui-line-height-relaxed, 1.6);\n color: var(--wui-empty-description-color, var(--wui-color-text-secondary, #6a6a6a));\n overflow-wrap: anywhere;\n}\n\n.empty-action {\n margin-top: var(--wui-empty-action-margin-top, var(--wui-space-5, 20px));\n}\n\n.is-hidden {\n display: none;\n}\n"],"mappings":""}
@@ -0,0 +1,6 @@
1
+ declare const _default: {
2
+ body: string;
3
+ width: number;
4
+ height: number;
5
+ };
6
+ export default _default;
@@ -0,0 +1,10 @@
1
+ //#region src/icons/generated/andrsrxn-inbox.ts
2
+ var e = {
3
+ body: "<g fill=\"none\"><path fill=\"currentColor\" d=\"M4.3 6.04c.48-1.25.72-1.87 1.23-2.23s1.18-.35 2.51-.35h8.08c1.36 0 2.04 0 2.56.36c.51.37.74 1.01 1.2 2.3l1.45 4.03c.43 1.22.65 1.83.35 2.25c-.3.43-.94.43-2.23.43h-.73c-.78 0-1.17 0-1.52.14s-.64.4-1.21.93l-.27.25c-.57.53-.85.8-1.2.94c-.36.14-.75.14-1.53.14H11c-.77 0-1.16 0-1.52-.14c-.35-.14-.63-.4-1.2-.94L8 13.9c-.57-.53-.85-.8-1.2-.93c-.36-.14-.75-.14-1.53-.14h-.66c-1.32 0-1.98 0-2.28-.44c-.3-.43-.06-1.04.4-2.28z\" opacity=\".2\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M3.05 8.05c.6-2.1.9-3.14 1.7-3.74s1.9-.6 4.07-.6h6.36c2.18 0 3.27 0 4.07.6s1.1 1.65 1.7 3.74l1.1 3.84c.12.4.18.61.2.82s.03.42.03.84v.99c0 2.83 0 4.24-.87 5.12c-.88.88-2.3.88-5.13.88H7.72c-2.83 0-4.25 0-5.13-.88s-.87-2.3-.87-5.12v-1c0-.41 0-.62.02-.83s.1-.41.2-.82z\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M22.05 12.83H19c-.97 0-1.45 0-1.9.14l-.07.03c-.44.15-.83.44-1.6 1.03l-.09.07c-.67.51-1.01.77-1.4.92l-.28.1c-.4.11-.82.11-1.67.11c-.8 0-1.21 0-1.6-.1l-.33-.11c-.37-.15-.69-.4-1.34-.88l-.16-.12a6 6 0 0 0-1.64-1.04c-.47-.15-.96-.15-1.95-.15H1.95\"/></g>",
4
+ width: 24,
5
+ height: 24
6
+ };
7
+ //#endregion
8
+ export { e as default };
9
+
10
+ //# sourceMappingURL=andrsrxn-inbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"andrsrxn-inbox.js","names":[],"sources":["../../../src/icons/generated/andrsrxn-inbox.ts"],"sourcesContent":["import type { IconifyIcon } from '@iconify/types'\n\nexport default {\n body: '<g fill=\"none\"><path fill=\"currentColor\" d=\"M4.3 6.04c.48-1.25.72-1.87 1.23-2.23s1.18-.35 2.51-.35h8.08c1.36 0 2.04 0 2.56.36c.51.37.74 1.01 1.2 2.3l1.45 4.03c.43 1.22.65 1.83.35 2.25c-.3.43-.94.43-2.23.43h-.73c-.78 0-1.17 0-1.52.14s-.64.4-1.21.93l-.27.25c-.57.53-.85.8-1.2.94c-.36.14-.75.14-1.53.14H11c-.77 0-1.16 0-1.52-.14c-.35-.14-.63-.4-1.2-.94L8 13.9c-.57-.53-.85-.8-1.2-.93c-.36-.14-.75-.14-1.53-.14h-.66c-1.32 0-1.98 0-2.28-.44c-.3-.43-.06-1.04.4-2.28z\" opacity=\".2\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M3.05 8.05c.6-2.1.9-3.14 1.7-3.74s1.9-.6 4.07-.6h6.36c2.18 0 3.27 0 4.07.6s1.1 1.65 1.7 3.74l1.1 3.84c.12.4.18.61.2.82s.03.42.03.84v.99c0 2.83 0 4.24-.87 5.12c-.88.88-2.3.88-5.13.88H7.72c-2.83 0-4.25 0-5.13-.88s-.87-2.3-.87-5.12v-1c0-.41 0-.62.02-.83s.1-.41.2-.82z\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M22.05 12.83H19c-.97 0-1.45 0-1.9.14l-.07.03c-.44.15-.83.44-1.6 1.03l-.09.07c-.67.51-1.01.77-1.4.92l-.28.1c-.4.11-.82.11-1.67.11c-.8 0-1.21 0-1.6-.1l-.33-.11c-.37-.15-.69-.4-1.34-.88l-.16-.12a6 6 0 0 0-1.64-1.04c-.47-.15-.96-.15-1.95-.15H1.95\"/></g>',\n width: 24,\n height: 24\n} satisfies IconifyIcon\n"],"mappings":";AAEA,IAAA,IAAe;CACb,MAAM;CACN,OAAO;CACP,QAAQ;AACV"}
@@ -1,3 +1,4 @@
1
+ export { default as andrsrxnInbox } from './generated/andrsrxn-inbox';
1
2
  export { default as lucideInbox } from './generated/lucide-inbox';
2
3
  export { default as lucideLoaderCircle } from './generated/lucide-loader-circle';
3
4
  export { default as lucideArrowUpToLine } from './generated/lucide-arrow-up-to-line';
@@ -1,74 +1,75 @@
1
- import e from "./generated/lucide-inbox.js";
2
- import t from "./generated/lucide-loader-circle.js";
3
- import n from "./generated/lucide-arrow-up-to-line.js";
4
- import r from "./generated/lucide-arrow-down-to-line.js";
5
- import i from "./generated/lucide-chevron-left.js";
6
- import a from "./generated/lucide-chevron-right.js";
7
- import o from "./generated/lucide-chevron-up.js";
8
- import s from "./generated/lucide-chevron-down.js";
9
- import c from "./generated/lucide-plus.js";
10
- import l from "./generated/lucide-minus.js";
11
- import u from "./generated/lucide-search.js";
12
- import d from "./generated/lucide-x.js";
13
- import f from "./generated/lucide-file.js";
14
- import p from "./generated/lucide-folder.js";
15
- import m from "./generated/lucide-copy.js";
16
- import h from "./generated/lucide-clipboard-paste.js";
17
- import g from "./generated/lucide-trash-2.js";
18
- import _ from "./generated/lucide-printer.js";
19
- import v from "./generated/lucide-settings.js";
20
- import y from "./generated/lucide-download.js";
21
- import b from "./generated/lucide-upload.js";
22
- import x from "./generated/lucide-undo-2.js";
23
- import S from "./generated/lucide-redo-2.js";
24
- import C from "./generated/lucide-scissors.js";
25
- import w from "./generated/jam-close-circle-f.js";
26
- import T from "./generated/lucide-check.js";
27
- import E from "./generated/lucide-info.js";
28
- import D from "./generated/lucide-triangle-alert.js";
29
- import O from "./generated/lucide-circle-alert.js";
30
- import k from "./generated/heroicons-check-16-solid.js";
31
- import A from "./generated/lucide-user.js";
32
- import j from "./generated/heroicons-x-mark-16-solid.js";
33
- import M from "./generated/lucide-star.js";
34
- import N from "./generated/lucide-heart.js";
35
- import P from "./generated/lucide-bell.js";
36
- import F from "./generated/lucide-mail.js";
37
- import I from "./generated/lucide-image.js";
38
- import L from "./generated/lucide-globe.js";
39
- import R from "./generated/radix-icons-panel-left-minimized.js";
40
- import z from "./generated/ooui-close.js";
41
- import B from "./generated/lucide-external-link.js";
42
- import V from "./generated/lucide-file-text.js";
43
- import H from "./generated/lucide-film.js";
44
- import U from "./generated/lucide-folder-open.js";
45
- import W from "./generated/lucide-layout-grid.js";
46
- import G from "./generated/lucide-music.js";
47
- import K from "./generated/lucide-package.js";
48
- import q from "./generated/lucide-pencil.js";
49
- import J from "./generated/lucide-refresh-cw.js";
50
- import Y from "./generated/lucide-tag.js";
51
- import X from "./generated/lucide-tags.js";
52
- import Z from "./generated/lucide-wrench.js";
53
- import Q from "./generated/lucide-sliders-horizontal.js";
54
- import $ from "./generated/lucide-link.js";
55
- import ee from "./generated/lucide-eye.js";
56
- import te from "./generated/lucide-clapperboard.js";
57
- import ne from "./generated/lucide-headphones.js";
58
- import re from "./generated/lucide-pen-line.js";
59
- import ie from "./generated/lucide-play.js";
60
- import ae from "./generated/lucide-list-filter.js";
61
- import oe from "./generated/tabler-sort-ascending-letters.js";
62
- import se from "./generated/lucide-code.js";
63
- import ce from "./generated/lucide-ellipsis-vertical.js";
64
- import le from "./generated/heroicons-bars-arrow-down-16-solid.js";
65
- import ue from "./generated/heroicons-bars-arrow-up-16-solid.js";
66
- import de from "./generated/lucide-list-restart.js";
67
- import fe from "./generated/radix-icons-reset.js";
68
- import pe from "./generated/akar-icons-check.js";
69
- import me from "./generated/bi-check.js";
70
- import he from "./generated/bi-check-lg.js";
71
- import ge from "./generated/akar-icons-circle-check.js";
72
- import _e from "./generated/fluent-tag-search-24-regular.js";
73
- import ve from "./generated/mdi-tag-search-outline.js";
74
- export { pe as akarIconsCheck, ge as akarIconsCircleCheck, me as biCheck, he as biCheckLg, _e as fluentTagSearch24Regular, le as heroiconsBarsArrowDown16Solid, ue as heroiconsBarsArrowUp16Solid, k as heroiconsCheck16Solid, j as heroiconsXMark16Solid, w as jamCloseCircleF, r as lucideArrowDownToLine, n as lucideArrowUpToLine, P as lucideBell, T as lucideCheck, s as lucideChevronDown, i as lucideChevronLeft, a as lucideChevronRight, o as lucideChevronUp, O as lucideCircleAlert, te as lucideClapperboard, h as lucideClipboardPaste, se as lucideCode, m as lucideCopy, y as lucideDownload, ce as lucideEllipsisVertical, B as lucideExternalLink, ee as lucideEye, f as lucideFile, V as lucideFileText, H as lucideFilm, p as lucideFolder, U as lucideFolderOpen, L as lucideGlobe, ne as lucideHeadphones, N as lucideHeart, I as lucideImage, e as lucideInbox, E as lucideInfo, W as lucideLayoutGrid, $ as lucideLink, ae as lucideListFilter, de as lucideListRestart, t as lucideLoaderCircle, F as lucideMail, l as lucideMinus, G as lucideMusic, K as lucidePackage, re as lucidePenLine, q as lucidePencil, ie as lucidePlay, c as lucidePlus, _ as lucidePrinter, S as lucideRedo2, J as lucideRefreshCw, C as lucideScissors, u as lucideSearch, v as lucideSettings, Q as lucideSlidersHorizontal, M as lucideStar, Y as lucideTag, X as lucideTags, g as lucideTrash2, D as lucideTriangleAlert, x as lucideUndo2, b as lucideUpload, A as lucideUser, Z as lucideWrench, d as lucideX, ve as mdiTagSearchOutline, z as oouiClose, R as radixIconsPanelLeftMinimized, fe as radixIconsReset, oe as tablerSortAscendingLetters };
1
+ import e from "./generated/andrsrxn-inbox.js";
2
+ import t from "./generated/lucide-inbox.js";
3
+ import n from "./generated/lucide-loader-circle.js";
4
+ import r from "./generated/lucide-arrow-up-to-line.js";
5
+ import i from "./generated/lucide-arrow-down-to-line.js";
6
+ import a from "./generated/lucide-chevron-left.js";
7
+ import o from "./generated/lucide-chevron-right.js";
8
+ import s from "./generated/lucide-chevron-up.js";
9
+ import c from "./generated/lucide-chevron-down.js";
10
+ import l from "./generated/lucide-plus.js";
11
+ import u from "./generated/lucide-minus.js";
12
+ import d from "./generated/lucide-search.js";
13
+ import f from "./generated/lucide-x.js";
14
+ import p from "./generated/lucide-file.js";
15
+ import m from "./generated/lucide-folder.js";
16
+ import h from "./generated/lucide-copy.js";
17
+ import g from "./generated/lucide-clipboard-paste.js";
18
+ import _ from "./generated/lucide-trash-2.js";
19
+ import v from "./generated/lucide-printer.js";
20
+ import y from "./generated/lucide-settings.js";
21
+ import b from "./generated/lucide-download.js";
22
+ import x from "./generated/lucide-upload.js";
23
+ import S from "./generated/lucide-undo-2.js";
24
+ import C from "./generated/lucide-redo-2.js";
25
+ import w from "./generated/lucide-scissors.js";
26
+ import T from "./generated/jam-close-circle-f.js";
27
+ import E from "./generated/lucide-check.js";
28
+ import D from "./generated/lucide-info.js";
29
+ import O from "./generated/lucide-triangle-alert.js";
30
+ import k from "./generated/lucide-circle-alert.js";
31
+ import A from "./generated/heroicons-check-16-solid.js";
32
+ import j from "./generated/lucide-user.js";
33
+ import M from "./generated/heroicons-x-mark-16-solid.js";
34
+ import N from "./generated/lucide-star.js";
35
+ import P from "./generated/lucide-heart.js";
36
+ import F from "./generated/lucide-bell.js";
37
+ import I from "./generated/lucide-mail.js";
38
+ import L from "./generated/lucide-image.js";
39
+ import R from "./generated/lucide-globe.js";
40
+ import z from "./generated/radix-icons-panel-left-minimized.js";
41
+ import B from "./generated/ooui-close.js";
42
+ import V from "./generated/lucide-external-link.js";
43
+ import H from "./generated/lucide-file-text.js";
44
+ import U from "./generated/lucide-film.js";
45
+ import W from "./generated/lucide-folder-open.js";
46
+ import G from "./generated/lucide-layout-grid.js";
47
+ import K from "./generated/lucide-music.js";
48
+ import q from "./generated/lucide-package.js";
49
+ import J from "./generated/lucide-pencil.js";
50
+ import Y from "./generated/lucide-refresh-cw.js";
51
+ import X from "./generated/lucide-tag.js";
52
+ import Z from "./generated/lucide-tags.js";
53
+ import Q from "./generated/lucide-wrench.js";
54
+ import $ from "./generated/lucide-sliders-horizontal.js";
55
+ import ee from "./generated/lucide-link.js";
56
+ import te from "./generated/lucide-eye.js";
57
+ import ne from "./generated/lucide-clapperboard.js";
58
+ import re from "./generated/lucide-headphones.js";
59
+ import ie from "./generated/lucide-pen-line.js";
60
+ import ae from "./generated/lucide-play.js";
61
+ import oe from "./generated/lucide-list-filter.js";
62
+ import se from "./generated/tabler-sort-ascending-letters.js";
63
+ import ce from "./generated/lucide-code.js";
64
+ import le from "./generated/lucide-ellipsis-vertical.js";
65
+ import ue from "./generated/heroicons-bars-arrow-down-16-solid.js";
66
+ import de from "./generated/heroicons-bars-arrow-up-16-solid.js";
67
+ import fe from "./generated/lucide-list-restart.js";
68
+ import pe from "./generated/radix-icons-reset.js";
69
+ import me from "./generated/akar-icons-check.js";
70
+ import he from "./generated/bi-check.js";
71
+ import ge from "./generated/bi-check-lg.js";
72
+ import _e from "./generated/akar-icons-circle-check.js";
73
+ import ve from "./generated/fluent-tag-search-24-regular.js";
74
+ import ye from "./generated/mdi-tag-search-outline.js";
75
+ export { me as akarIconsCheck, _e as akarIconsCircleCheck, e as andrsrxnInbox, he as biCheck, ge as biCheckLg, ve as fluentTagSearch24Regular, ue as heroiconsBarsArrowDown16Solid, de as heroiconsBarsArrowUp16Solid, A as heroiconsCheck16Solid, M as heroiconsXMark16Solid, T as jamCloseCircleF, i as lucideArrowDownToLine, r as lucideArrowUpToLine, F as lucideBell, E as lucideCheck, c as lucideChevronDown, a as lucideChevronLeft, o as lucideChevronRight, s as lucideChevronUp, k as lucideCircleAlert, ne as lucideClapperboard, g as lucideClipboardPaste, ce as lucideCode, h as lucideCopy, b as lucideDownload, le as lucideEllipsisVertical, V as lucideExternalLink, te as lucideEye, p as lucideFile, H as lucideFileText, U as lucideFilm, m as lucideFolder, W as lucideFolderOpen, R as lucideGlobe, re as lucideHeadphones, P as lucideHeart, L as lucideImage, t as lucideInbox, D as lucideInfo, G as lucideLayoutGrid, ee as lucideLink, oe as lucideListFilter, fe as lucideListRestart, n as lucideLoaderCircle, I as lucideMail, u as lucideMinus, K as lucideMusic, q as lucidePackage, ie as lucidePenLine, J as lucidePencil, ae as lucidePlay, l as lucidePlus, v as lucidePrinter, C as lucideRedo2, Y as lucideRefreshCw, w as lucideScissors, d as lucideSearch, y as lucideSettings, $ as lucideSlidersHorizontal, N as lucideStar, X as lucideTag, Z as lucideTags, _ as lucideTrash2, O as lucideTriangleAlert, S as lucideUndo2, x as lucideUpload, j as lucideUser, Q as lucideWrench, f as lucideX, ye as mdiTagSearchOutline, B as oouiClose, z as radixIconsPanelLeftMinimized, pe as radixIconsReset, se as tablerSortAscendingLetters };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@greypan/web-ui",
3
- "version": "11.1.0",
3
+ "version": "11.2.0",
4
4
  "description": "Lit-based web components for React, Vue, and vanilla JS",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -58,6 +58,7 @@
58
58
  "devDependencies": {
59
59
  "@greypan/tsconfig": "0.0.0",
60
60
  "@iconify-json/akar-icons": "^1.2.7",
61
+ "@iconify-json/andrsrxn": "^1.2.2",
61
62
  "@iconify-json/bi": "^1.2.7",
62
63
  "@iconify-json/fluent": "^1.2.58",
63
64
  "@iconify-json/jam": "^1.2.3",