@greypan/web-ui 8.1.0 → 9.1.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 +309 -135
- package/README.md +311 -135
- package/dist/assets/glass.js +1 -1
- package/dist/assets/glass.js.map +1 -1
- package/dist/assets/menu-portal.js +1 -1
- package/dist/assets/menu-portal.js.map +1 -1
- package/dist/assets/modal-surface.js +6 -0
- package/dist/assets/modal-surface.js.map +1 -0
- package/dist/assets/selection-control.js +1 -1
- package/dist/assets/selection-control.js.map +1 -1
- package/dist/assets/toast-containers.js +1 -1
- package/dist/assets/toast-containers.js.map +1 -1
- package/dist/components/autocomplete/index.d.ts +3 -2
- package/dist/components/autocomplete/index.js +40 -44
- package/dist/components/autocomplete/index.js.map +1 -1
- package/dist/components/autocomplete/style.js +1 -1
- package/dist/components/autocomplete/style.js.map +1 -1
- package/dist/components/avatar/index.js.map +1 -1
- package/dist/components/avatar/style.js +1 -1
- package/dist/components/avatar/style.js.map +1 -1
- package/dist/components/back-top/style.js +1 -1
- package/dist/components/back-top/style.js.map +1 -1
- package/dist/components/badge/style.js +1 -1
- package/dist/components/badge/style.js.map +1 -1
- package/dist/components/button/style.js +1 -1
- package/dist/components/button/style.js.map +1 -1
- package/dist/components/button-group/index.js +0 -1
- package/dist/components/button-group/index.js.map +1 -1
- package/dist/components/button-group/style.js +1 -1
- package/dist/components/button-group/style.js.map +1 -1
- package/dist/components/checkbox/index.js +4 -4
- package/dist/components/checkbox/index.js.map +1 -1
- package/dist/components/checkbox-group/style.js +1 -1
- package/dist/components/checkbox-group/style.js.map +1 -1
- package/dist/components/context-menu/index.d.ts +182 -3
- package/dist/components/context-menu/index.js +166 -91
- package/dist/components/context-menu/index.js.map +1 -1
- package/dist/components/context-menu/scrim.js +6 -0
- package/dist/components/context-menu/scrim.js.map +1 -0
- package/dist/components/context-menu/style.js +1 -1
- package/dist/components/context-menu/style.js.map +1 -1
- package/dist/components/dialog/index.d.ts +9 -0
- package/dist/components/dialog/index.js +68 -46
- package/dist/components/dialog/index.js.map +1 -1
- package/dist/components/dialog/style.js +1 -1
- package/dist/components/dialog/style.js.map +1 -1
- package/dist/components/drawer/index.d.ts +45 -0
- package/dist/components/drawer/index.js +122 -53
- package/dist/components/drawer/index.js.map +1 -1
- package/dist/components/drawer/style.js +1 -1
- package/dist/components/drawer/style.js.map +1 -1
- package/dist/components/dropdown/index.d.ts +12 -0
- package/dist/components/dropdown/index.js +13 -10
- package/dist/components/dropdown/index.js.map +1 -1
- package/dist/components/dropdown-divider/style.js +1 -1
- package/dist/components/dropdown-divider/style.js.map +1 -1
- package/dist/components/dropdown-header/style.js +1 -1
- package/dist/components/dropdown-header/style.js.map +1 -1
- package/dist/components/dropdown-item/style.js +1 -1
- package/dist/components/dropdown-item/style.js.map +1 -1
- package/dist/components/editable-text/index.d.ts +39 -0
- package/dist/components/editable-text/index.js +6 -2
- package/dist/components/editable-text/index.js.map +1 -1
- package/dist/components/empty/index.d.ts +21 -4
- package/dist/components/empty/index.js +37 -32
- package/dist/components/empty/index.js.map +1 -1
- package/dist/components/empty/style.js +1 -1
- package/dist/components/empty/style.js.map +1 -1
- package/dist/components/image-preview/index.js +75 -63
- package/dist/components/image-preview/index.js.map +1 -1
- package/dist/components/image-preview/style.js +1 -1
- package/dist/components/image-preview/style.js.map +1 -1
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.js +38 -37
- package/dist/components/input/style.js +1 -1
- package/dist/components/input/style.js.map +1 -1
- package/dist/components/input-number/style.js +1 -1
- package/dist/components/input-number/style.js.map +1 -1
- package/dist/components/layout/index.d.ts +21 -6
- package/dist/components/layout/index.js +47 -27
- package/dist/components/layout/index.js.map +1 -1
- package/dist/components/layout/style.js +1 -1
- package/dist/components/layout/style.js.map +1 -1
- package/dist/components/middle-ellipsis/index.d.ts +100 -0
- package/dist/components/middle-ellipsis/index.js +112 -0
- package/dist/components/middle-ellipsis/index.js.map +1 -0
- package/dist/components/middle-ellipsis/style.js +6 -0
- package/dist/components/middle-ellipsis/style.js.map +1 -0
- package/dist/components/middle-ellipsis/truncate.d.ts +62 -0
- package/dist/components/middle-ellipsis/truncate.js +45 -0
- package/dist/components/middle-ellipsis/truncate.js.map +1 -0
- package/dist/components/option/style.js +1 -1
- package/dist/components/option/style.js.map +1 -1
- package/dist/components/popover/index.js.map +1 -1
- package/dist/components/popover/style.js +1 -1
- package/dist/components/popover/style.js.map +1 -1
- package/dist/components/radio/style.js +1 -1
- package/dist/components/radio/style.js.map +1 -1
- package/dist/components/radio-group/style.js +1 -1
- package/dist/components/radio-group/style.js.map +1 -1
- package/dist/components/segmented/index.d.ts +5 -0
- package/dist/components/segmented/index.js +45 -28
- package/dist/components/segmented/index.js.map +1 -1
- package/dist/components/segmented/style.js +1 -1
- package/dist/components/segmented/style.js.map +1 -1
- package/dist/components/segmented-trigger/style.js +1 -1
- package/dist/components/segmented-trigger/style.js.map +1 -1
- package/dist/components/select/index.js +0 -1
- package/dist/components/select/index.js.map +1 -1
- package/dist/components/select/style.js +1 -1
- package/dist/components/select/style.js.map +1 -1
- package/dist/components/slider/style.js +1 -1
- package/dist/components/slider/style.js.map +1 -1
- package/dist/components/spinner/style.js +1 -1
- package/dist/components/spinner/style.js.map +1 -1
- package/dist/components/svg-draw-lines/index.js.map +1 -1
- package/dist/components/switch/style.js +1 -1
- package/dist/components/switch/style.js.map +1 -1
- package/dist/components/textarea/index.js +2 -2
- package/dist/components/textarea/index.js.map +1 -1
- package/dist/components/textarea/style.js +1 -1
- package/dist/components/textarea/style.js.map +1 -1
- package/dist/components/theme/style.js +1 -1
- package/dist/components/theme/style.js.map +1 -1
- package/dist/components/toast/style.js +1 -1
- package/dist/components/toast/style.js.map +1 -1
- package/dist/components/tooltip/index.js.map +1 -1
- package/dist/components/tooltip/style.js +1 -1
- package/dist/components/tooltip/style.js.map +1 -1
- package/dist/icons/generated/akar-icons-circle-check.d.ts +6 -0
- package/dist/icons/generated/akar-icons-circle-check.js +10 -0
- package/dist/icons/generated/akar-icons-circle-check.js.map +1 -0
- package/dist/icons/generated/bi-check-lg.d.ts +6 -0
- package/dist/icons/generated/bi-check-lg.js +10 -0
- package/dist/icons/generated/bi-check-lg.js.map +1 -0
- package/dist/icons/generated/fluent-tag-search-24-regular.d.ts +6 -0
- package/dist/icons/generated/fluent-tag-search-24-regular.js +10 -0
- package/dist/icons/generated/fluent-tag-search-24-regular.js.map +1 -0
- package/dist/icons/generated/mdi-tag-search-outline.d.ts +6 -0
- package/dist/icons/generated/mdi-tag-search-outline.js +10 -0
- package/dist/icons/generated/mdi-tag-search-outline.js.map +1 -0
- package/dist/icons/index.d.ts +4 -0
- package/dist/icons/index.js +5 -1
- package/dist/scrollbars/index.d.ts +33 -0
- package/dist/scrollbars/index.js +18 -0
- package/dist/scrollbars/index.js.map +1 -0
- package/dist/scrollbars/style.css +10 -0
- package/dist/shared/element-height/index.js +47 -0
- package/dist/shared/element-height/index.js.map +1 -0
- package/dist/shared/element-width/index.js +37 -0
- package/dist/shared/element-width/index.js.map +1 -0
- package/dist/shared/menu-portal/menu-portal.js +11 -11
- package/dist/shared/menu-portal/menu-portal.js.map +1 -1
- package/dist/shared/menu-portal/menu-tree.js +2 -2
- package/dist/shared/menu-portal/menu-tree.js.map +1 -1
- package/dist/shared/overlay/anchored-panel.js.map +1 -1
- package/dist/shared/overlay/native-dialog-presence.js +23 -11
- package/dist/shared/overlay/native-dialog-presence.js.map +1 -1
- package/dist/shared/overlay/nested-drawer-layers.js +30 -23
- package/dist/shared/overlay/nested-drawer-layers.js.map +1 -1
- package/dist/shared/scroll-lock/scroll-lock.js +3 -3
- package/dist/shared/scroll-lock/scroll-lock.js.map +1 -1
- package/package.json +19 -5
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/components/autocomplete/style.css?inline
|
|
2
|
-
var e = "*,:before,:after{box-sizing:border-box}:host{--wui-autocomplete-max-width:500px;display:inline-block}:host([disabled]){cursor:not-allowed;opacity:.4}.wui-autocomplete-inner{position:relative}.autocomplete-trigger{box-sizing:border-box;width:var(--wui-input-width,200px);min-width:var(--wui-control-size,36px);background:0 0;border:none;align-items:center;display:flex}.autocomplete-trigger[data-custom-trigger]{width:auto}.autocomplete-trigger web-ui-input{flex:1;min-width:0}::slotted([slot=trigger]){min-width:0}.autocomplete-trigger:focus-visible{outline:var(--wui-focus-ring-width,3px) solid var(--wui-color-focus-ring,#
|
|
2
|
+
var e = "*,:before,:after{box-sizing:border-box}:host{--wui-autocomplete-max-width:500px;display:inline-block}:host([disabled]){cursor:not-allowed;opacity:.4}.wui-autocomplete-inner{position:relative}.autocomplete-trigger{box-sizing:border-box;width:var(--wui-input-width,200px);min-width:var(--wui-control-size,36px);background:0 0;border:none;align-items:center;display:flex}.autocomplete-trigger[data-custom-trigger]{width:auto}.autocomplete-trigger web-ui-input{flex:1;min-width:0}::slotted([slot=trigger]){min-width:0}.autocomplete-trigger:focus-visible{outline:var(--wui-focus-ring-width,3px) solid var(--wui-color-focus-ring,color-mix(in srgb, var(--wui-color-accent,#08f) 40%, transparent));outline-offset:2px}:host([disabled]) .autocomplete-trigger web-ui-input{opacity:1}.autocomplete-overlay{--wui-option-check-display:none;--wui-internal-glass-shadow:var(--wui-shadow-panel,0 3px 9px #00000045);--wui-glass-corner-radius:var(--wui-radius-menu,18px);--wui-color-glass-ring:transparent;--wui-internal-duration-float-enter:var(--wui-duration-float-enter,.24s);--wui-internal-duration-float-exit:var(--wui-duration-float-exit,.16s);z-index:var(--wui-layer-inline-overlay,1);box-sizing:border-box;min-width:var(--wui-overlay-min-width,200px);max-width:var(--wui-autocomplete-max-width,500px);border-radius:var(--wui-radius-menu,18px);background-color:var(--wui-color-surface-menu,#fafafac2);position:absolute;overflow:hidden}.autocomplete-overlay.portal{z-index:var(--wui-layer-menu,100);position:fixed}.autocomplete-overlay.hidden{display:none}.autocomplete-scroll{max-height:var(--wui-autocomplete-max-height,200px);overflow-y:auto}.autocomplete-content{padding:var(--wui-space-1,4px)}::slotted(web-ui-option[data-filtered]),.autocomplete-content web-ui-option[data-filtered],:host([portal]) .autocomplete-overlay{display:none}.autocomplete-a11y-only,.autocomplete-a11y-listbox{white-space:nowrap;clip-path:inset(50%);border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}";
|
|
3
3
|
//#endregion
|
|
4
4
|
export { e as default };
|
|
5
5
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/autocomplete/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n --wui-autocomplete-max-width: 500px;\n display: inline-block;\n}\n\n:host([disabled]) {\n cursor: not-allowed;\n opacity: 0.4;\n}\n\n.wui-autocomplete-inner {\n /* 与 select 的 .wui-select-inner 对齐:为本地绝对定位面板提供包含块,\n 避免面板 offsetParent(BODY)与实际包含块(远端定位祖先,如 layout header)不一致导致定位偏移。 */\n position: relative;\n}\n\n/*\n * trigger 包装 div:持 combobox ARIA、slot[name=\"trigger\"] 与事件委托监听。\n * 玻璃胶囊由默认触发器 web-ui-input 自带(与重构前的 .input-wrapper 同一套 token\n * 与度量:--wui-input-width / --wui-control-size / --wui-radius-control),这里只定义\n * 容器宽度与自定义触发器时的自适应。\n */\n.autocomplete-trigger {\n display: flex;\n align-items: center;\n\n box-sizing: border-box;\n width: var(--wui-input-width, 200px);\n min-width: var(--wui-control-size, 36px);\n border: none;\n\n background: transparent;\n}\n\n
|
|
1
|
+
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/autocomplete/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n --wui-autocomplete-max-width: 500px;\n display: inline-block;\n}\n\n:host([disabled]) {\n cursor: not-allowed;\n opacity: 0.4;\n}\n\n.wui-autocomplete-inner {\n /* 与 select 的 .wui-select-inner 对齐:为本地绝对定位面板提供包含块,\n 避免面板 offsetParent(BODY)与实际包含块(远端定位祖先,如 layout header)不一致导致定位偏移。 */\n position: relative;\n}\n\n/*\n * trigger 包装 div:持 combobox ARIA、slot[name=\"trigger\"] 与事件委托监听。\n * 玻璃胶囊由默认触发器 web-ui-input 自带(与重构前的 .input-wrapper 同一套 token\n * 与度量:--wui-input-width / --wui-control-size / --wui-radius-control),这里只定义\n * 容器宽度与自定义触发器时的自适应。\n */\n.autocomplete-trigger {\n display: flex;\n align-items: center;\n\n box-sizing: border-box;\n width: var(--wui-input-width, 200px);\n min-width: var(--wui-control-size, 36px);\n border: none;\n\n background: transparent;\n}\n\n.autocomplete-trigger[data-custom-trigger] {\n width: auto;\n}\n\n/* 默认触发器填满容器:高度、内边距、玻璃底与 focus ring 由它自带 */\n.autocomplete-trigger web-ui-input {\n flex: 1;\n min-width: 0;\n}\n\n::slotted([slot='trigger']) {\n min-width: 0;\n}\n\n/* 自定义触发器场景下包装 div 可能成为 tab 位,补 focus ring(默认触发器自带) */\n.autocomplete-trigger:focus-visible {\n outline: var(--wui-focus-ring-width, 3px) solid\n var(--wui-color-focus-ring, color-mix(in srgb, var(--wui-color-accent, #08f) 40%, transparent));\n outline-offset: 2px;\n}\n\n/* 禁用态:宿主已整体降透明度,默认触发器自身的 disabled 降透明度在此抵消,\n 保持与重构前(宿主 × 内部 input 两层)一致的观感 */\n:host([disabled]) .autocomplete-trigger web-ui-input {\n opacity: 1;\n}\n\n.autocomplete-overlay {\n /* autocomplete 不表示选中状态;隐藏共享 option 的勾选图标及其布局占位 */\n --wui-option-check-display: none;\n --wui-internal-glass-shadow: var(--wui-shadow-panel, 0 3px 9px rgb(0 0 0 / 0.27));\n --wui-glass-corner-radius: var(--wui-radius-menu, 18px);\n\n /* 环底色转 transparent,宽面板的长边中段不留铺底,见 menu-portal.css 同处注释。 */\n --wui-color-glass-ring: transparent;\n --wui-internal-duration-float-enter: var(--wui-duration-float-enter, 240ms);\n --wui-internal-duration-float-exit: var(--wui-duration-float-exit, 160ms);\n position: absolute;\n z-index: var(--wui-layer-inline-overlay, 1);\n\n overflow: hidden;\n\n box-sizing: border-box;\n min-width: var(--wui-overlay-min-width, 200px);\n max-width: var(--wui-autocomplete-max-width, 500px);\n border-radius: var(--wui-radius-menu, 18px);\n\n /* 玻璃背景:wui-glass 在面板自身,这里覆盖其默认玻璃底为菜单表面色 */\n background-color: var(--wui-color-surface-menu, rgb(250 250 250 / 0.76));\n\n &.portal {\n position: fixed;\n z-index: var(--wui-layer-menu, 100);\n }\n\n &.hidden {\n display: none;\n }\n}\n\n.autocomplete-scroll {\n overflow-y: auto;\n max-height: var(--wui-autocomplete-max-height, 200px);\n}\n\n.autocomplete-content {\n padding: var(--wui-space-1, 4px);\n}\n\n/* 非匹配候选隐藏:本地模式经 slot 投影,portal 模式为面板直接子元素 */\n::slotted(web-ui-option[data-filtered]) {\n display: none;\n}\n\n.autocomplete-content web-ui-option[data-filtered] {\n display: none;\n}\n\n:host([portal]) .autocomplete-overlay {\n display: none;\n}\n\n/* Shadow DOM idref 不能跨越 Portal 或 light DOM;保留同根可访问的语义镜像。 */\n.autocomplete-a11y-only,\n.autocomplete-a11y-listbox {\n position: absolute;\n\n overflow: hidden;\n\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n border: 0;\n\n white-space: nowrap;\n\n clip-path: inset(50%);\n}\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/avatar/index.ts"],"sourcesContent":["import { html, LitElement, unsafeCSS } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { ifDefined } from 'lit/directives/if-defined.js'\n\n// 注册 web-ui-icon
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/avatar/index.ts"],"sourcesContent":["import { html, LitElement, unsafeCSS } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { ifDefined } from 'lit/directives/if-defined.js'\n\n// 注册 web-ui-icon:本组件模板直接渲染该标签,消费者模板里不会出现它,\n// 因此没有别处会引入。产物保留模块(build.rollupOptions.output.preserveModules)\n// 并由 package.json 的 sideEffects 保证这段副作用 import 不被 tree-shake 掉。\nimport '@/components/icon'\nimport glass from '@/assets/glass.css?inline'\nimport { lucideUser } from '@/icons'\nimport { normalizeLiteral } from '@/shared/normalize'\n\nimport style from './style.css?inline'\n\nconst ALLOWED_SHAPES = ['circle', 'square'] as const\n\n@customElement('web-ui-avatar')\nexport class WebUiAvatar extends LitElement {\n static override styles = [unsafeCSS(glass), unsafeCSS(style)]\n\n @property({ type: String, reflect: true })\n set src(value: string) {\n const old = this._src\n this._src = value\n if (old !== value) {\n this._imgError = false\n this.requestUpdate('src', old)\n }\n }\n\n get src(): string {\n return this._src\n }\n\n private _src = ''\n\n @property({ type: String, reflect: true }) alt = ''\n @property({ type: String, reflect: true }) name = ''\n @property({ type: Number, reflect: true }) size = 40\n\n @property({ type: String, reflect: true })\n set shape(value: string) {\n const normalized = normalizeLiteral(value, ALLOWED_SHAPES, 'circle')\n if (this._shape !== normalized) {\n const old = this._shape\n this._shape = normalized\n this.requestUpdate('shape', old)\n }\n // 外部 setAttribute 非法值后,宿主 attribute 与规范化后的值不同步,立即修正\n if (this.getAttribute('shape') !== normalized) {\n this.setAttribute('shape', normalized)\n }\n }\n\n get shape(): 'circle' | 'square' {\n return this._shape\n }\n\n private _shape: 'circle' | 'square' = 'circle'\n\n @state() private _imgError = false\n @state() private _hasDefaultSlot = false\n\n private _checkSlot() {\n const slot = this.shadowRoot?.querySelector('slot:not([name])')\n const has = slot instanceof HTMLSlotElement && slot.assignedElements().length > 0\n if (this._hasDefaultSlot !== has) {\n this._hasDefaultSlot = has\n }\n }\n\n private get _initials(): string {\n const words = this.name.trim().split(/\\s+/)\n return words\n .slice(0, 2)\n .map(w => Array.from(w)[0])\n .join('')\n .toUpperCase()\n }\n\n private get _iconSize(): number {\n return Math.round(this.size * 0.4)\n }\n\n private get _showImage(): boolean {\n return !!this.src && !this._imgError\n }\n\n private get _showFallback(): boolean {\n return !this._showImage && !this._hasDefaultSlot\n }\n\n private _onImgError() {\n this._imgError = true\n }\n\n private get _ariaLabel(): string | undefined {\n if (this.alt) return this.alt\n if (this.name) return this.name\n return undefined\n }\n\n override render() {\n const isDecorative = !this._ariaLabel\n\n return html`\n <div\n class=${classMap({ 'avatar-inner': true, 'wui-glass': this._showFallback })}\n role=${isDecorative ? 'presentation' : 'img'}\n aria-label=${ifDefined(this._ariaLabel)}\n aria-hidden=${isDecorative ? 'true' : undefined}\n style=\"width:${this.size}px;height:${this.size}px;--wui-avatar-size:${this.size}px\"\n >\n ${\n this._showImage\n ? html`<img\n class=\"avatar-img\"\n src=${this.src}\n alt=${ifDefined(this.alt || undefined)}\n @error=${this._onImgError}\n />`\n : ''\n }\n <slot @slotchange=${this._checkSlot}></slot>\n ${\n this._showFallback && this._initials\n ? html`<span class=\"avatar-fallback avatar-initials\">${this._initials}</span>`\n : ''\n }\n ${\n this._showFallback && !this._initials\n ? html`<span class=\"avatar-fallback\"\n ><web-ui-icon .icon=${lucideUser} .size=${this._iconSize}></web-ui-icon\n ></span>`\n : ''\n }\n </div>\n `\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-avatar': WebUiAvatar\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/components/avatar/style.css?inline
|
|
2
|
-
var e = "*,:before,:after{box-sizing:border-box}:host{line-height:0;display:inline-block}.avatar-inner{--wui-glass-corner-radius:calc(var(--wui-avatar-size,40px) / 2);border-radius:var(--wui-radius-control,calc(infinity * 1px));background-color:#e5e5e599;justify-content:center;align-items:center;display:inline-flex;position:relative;overflow:hidden}:host([shape=square]) .avatar-inner{--wui-glass-corner-radius:var(--wui-internal-avatar-square-radius,12px);border-radius:var(--wui-internal-avatar-square-radius,12px)}.avatar-img{object-fit:cover;width:100%;height:100%}.avatar-fallback{justify-content:center;align-items:center;display:flex;position:absolute;inset:0}slot{justify-content:center;align-items:center;line-height:1;display:flex;position:absolute;inset:0}.avatar-initials{-webkit-user-select:none;user-select:none;font-size:calc(var(--wui-avatar-size,40px) * .4);
|
|
2
|
+
var e = "*,:before,:after{box-sizing:border-box}:host{line-height:0;display:inline-block}.avatar-inner{--wui-glass-corner-radius:calc(var(--wui-avatar-size,40px) / 2);border-radius:var(--wui-radius-control,calc(infinity * 1px));background-color:#e5e5e599;justify-content:center;align-items:center;display:inline-flex;position:relative;overflow:hidden}:host([shape=square]) .avatar-inner{--wui-glass-corner-radius:var(--wui-internal-avatar-square-radius,12px);border-radius:var(--wui-internal-avatar-square-radius,12px)}.avatar-img{object-fit:cover;width:100%;height:100%}.avatar-fallback{justify-content:center;align-items:center;display:flex;position:absolute;inset:0}slot{justify-content:center;align-items:center;line-height:1;display:flex;position:absolute;inset:0}.avatar-initials{-webkit-user-select:none;user-select:none;font-size:calc(var(--wui-avatar-size,40px) * .4);font-weight:var(--wui-font-weight-medium,500);color:#1b1b1bb3;line-height:1}";
|
|
3
3
|
//#endregion
|
|
4
4
|
export { e as default };
|
|
5
5
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/avatar/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n display: inline-block;\n line-height: 0;\n}\n\n.avatar-inner {\n --wui-glass-corner-radius: calc(var(--wui-avatar-size, 40px) / 2);\n\n position: relative;\n\n overflow: hidden;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n\n border-radius: var(--wui-radius-control, calc(infinity * 1px));\n\n background-color: rgb(229 229 229 / 0.6);\n}\n\n:host([shape='square']) .avatar-inner {\n --wui-glass-corner-radius: var(--wui-internal-avatar-square-radius, 12px);\n\n border-radius: var(--wui-internal-avatar-square-radius, 12px);\n}\n\n.avatar-img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.avatar-fallback {\n position: absolute;\n inset: 0;\n\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\nslot {\n position: absolute;\n inset: 0;\n\n display: flex;\n align-items: center;\n justify-content: center;\n\n line-height: 1;\n}\n\n.avatar-initials {\n user-select: none;\n\n font-size: calc(var(--wui-avatar-size, 40px) * 0.4);\n font-weight: 500;\n line-height: 1;\n color: rgb(27 27 27 / 0.7);\n}\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/avatar/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n display: inline-block;\n line-height: 0;\n}\n\n.avatar-inner {\n --wui-glass-corner-radius: calc(var(--wui-avatar-size, 40px) / 2);\n\n position: relative;\n\n overflow: hidden;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n\n border-radius: var(--wui-radius-control, calc(infinity * 1px));\n\n background-color: rgb(229 229 229 / 0.6);\n}\n\n:host([shape='square']) .avatar-inner {\n --wui-glass-corner-radius: var(--wui-internal-avatar-square-radius, 12px);\n\n border-radius: var(--wui-internal-avatar-square-radius, 12px);\n}\n\n.avatar-img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.avatar-fallback {\n position: absolute;\n inset: 0;\n\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\nslot {\n position: absolute;\n inset: 0;\n\n display: flex;\n align-items: center;\n justify-content: center;\n\n line-height: 1;\n}\n\n.avatar-initials {\n user-select: none;\n\n font-size: calc(var(--wui-avatar-size, 40px) * 0.4);\n font-weight: var(--wui-font-weight-medium, 500);\n line-height: 1;\n color: rgb(27 27 27 / 0.7);\n}\n"],"mappings":""}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/components/back-top/style.css?inline
|
|
2
|
-
var e = "*,:before,:after{box-sizing:border-box}:host{display:block}:host([container-mode]){bottom:var(--wui-back-top-bottom,20px);position:sticky}.back-top-inner{pointer-events:none;position:var(--wui-back-top-position,fixed);z-index:var(--wui-back-top-z-index,var(--wui-layer-auxiliary,20));top:var(--wui-back-top-top,auto);right:var(--wui-back-top-right,20px);bottom:var(--wui-back-top-bottom,20px);left:var(--wui-back-top-left,auto);visibility:hidden;opacity:0}.back-top-inner .back-top-inner:focus-visible{border-radius:var(--wui-radius-control,calc(infinity * 1px));outline:var(--wui-focus-ring-width,3px) solid var(--wui-color-focus-ring,#
|
|
2
|
+
var e = "*,:before,:after{box-sizing:border-box}:host{display:block}:host([container-mode]){bottom:var(--wui-back-top-bottom,20px);position:sticky}.back-top-inner{pointer-events:none;position:var(--wui-back-top-position,fixed);z-index:var(--wui-back-top-z-index,var(--wui-layer-auxiliary,20));top:var(--wui-back-top-top,auto);right:var(--wui-back-top-right,20px);bottom:var(--wui-back-top-bottom,20px);left:var(--wui-back-top-left,auto);visibility:hidden;opacity:0}.back-top-inner .back-top-inner:focus-visible{border-radius:var(--wui-radius-control,calc(infinity * 1px));outline:var(--wui-focus-ring-width,3px) solid var(--wui-color-focus-ring,color-mix(in srgb, var(--wui-color-accent,#08f) 40%, transparent));outline-offset:2px}:host([container-mode]) .back-top-inner{margin-right:var(--wui-back-top-right,20px);margin-left:var(--wui-back-top-left,auto);position:static}:host([visible]) .back-top-inner{pointer-events:auto;visibility:visible;opacity:1}";
|
|
3
3
|
//#endregion
|
|
4
4
|
export { e as default };
|
|
5
5
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/back-top/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n display: block;\n}\n\n/* 容器模式:scrollTarget 为元素时按钮悬浮于容器底部(元素需置于容器内部),\n 横向偏移沿用 --wui-back-top-left/right,纵向沿用 --wui-back-top-bottom */\n:host([container-mode]) {\n position: sticky;\n bottom: var(--wui-back-top-bottom, 20px);\n}\n\n.back-top-inner {\n pointer-events: none;\n\n position: var(--wui-back-top-position, fixed);\n z-index: var(--wui-back-top-z-index, var(--wui-layer-auxiliary, 20));\n top: var(--wui-back-top-top, auto);\n right: var(--wui-back-top-right, 20px);\n bottom: var(--wui-back-top-bottom, 20px);\n left: var(--wui-back-top-left, auto);\n\n visibility: hidden;\n opacity: 0;\n\n .back-top-inner:focus-visible {\n border-radius: var(--wui-radius-control, calc(infinity * 1px));\n outline: var(--wui-focus-ring-width, 3px) solid
|
|
1
|
+
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/back-top/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n display: block;\n}\n\n/* 容器模式:scrollTarget 为元素时按钮悬浮于容器底部(元素需置于容器内部),\n 横向偏移沿用 --wui-back-top-left/right,纵向沿用 --wui-back-top-bottom */\n:host([container-mode]) {\n position: sticky;\n bottom: var(--wui-back-top-bottom, 20px);\n}\n\n.back-top-inner {\n pointer-events: none;\n\n position: var(--wui-back-top-position, fixed);\n z-index: var(--wui-back-top-z-index, var(--wui-layer-auxiliary, 20));\n top: var(--wui-back-top-top, auto);\n right: var(--wui-back-top-right, 20px);\n bottom: var(--wui-back-top-bottom, 20px);\n left: var(--wui-back-top-left, auto);\n\n visibility: hidden;\n opacity: 0;\n\n .back-top-inner:focus-visible {\n border-radius: var(--wui-radius-control, calc(infinity * 1px));\n outline: var(--wui-focus-ring-width, 3px) solid\n var(--wui-color-focus-ring, color-mix(in srgb, var(--wui-color-accent, #08f) 40%, transparent));\n outline-offset: 2px;\n }\n}\n\n:host([container-mode]) .back-top-inner {\n position: static;\n margin-right: var(--wui-back-top-right, 20px);\n margin-left: var(--wui-back-top-left, auto);\n}\n\n:host([visible]) .back-top-inner {\n pointer-events: auto;\n visibility: visible;\n opacity: 1;\n}\n"],"mappings":""}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/components/badge/style.css?inline
|
|
2
|
-
var e = "*,:before,:after{box-sizing:border-box}:host{-webkit-user-select:none;user-select:none;display:inline-block}.badge-wrapper{display:inline-flex}.badge-wrapper-fixed{position:relative}.badge{z-index:1;border:1px solid var(--wui-color-page,#fff);border-radius:var(--wui-radius-control,calc(infinity * 1px));
|
|
2
|
+
var e = "*,:before,:after{box-sizing:border-box}:host{-webkit-user-select:none;user-select:none;display:inline-block}.badge-wrapper{display:inline-flex}.badge-wrapper-fixed{position:relative}.badge{z-index:1;min-width:18px;height:18px;padding:0 var(--wui-space-1,4px);border:1px solid var(--wui-color-page,#fff);border-radius:var(--wui-radius-control,calc(infinity * 1px));font-size:var(--wui-font-size-caption,12px);font-weight:var(--wui-font-weight-medium,500);color:var(--wui-color-on-accent,#fff);white-space:nowrap;background-color:var(--wui-color-danger,#dc2626);justify-content:center;align-items:center;line-height:1;display:inline-flex}.badge-fixed{transform:translate(calc(var(--badge-x,50%) + var(--badge-offset-x,0px)), calc(var(--badge-y,-50%) + var(--badge-offset-y,0px)));position:absolute}:host([placement=top-right]) .badge{--badge-x:50%;--badge-y:-50%;top:0;right:0}:host([placement=top-left]) .badge{--badge-x:-50%;--badge-y:-50%;top:0;left:0}:host([placement=bottom-right]) .badge{--badge-x:50%;--badge-y:50%;bottom:0;right:0}:host([placement=bottom-left]) .badge{--badge-x:-50%;--badge-y:50%;bottom:0;left:0}.badge-dot{min-width:8px;height:8px;padding:0;font-size:0}.badge-fixed.badge-dot{--badge-x:40%;--badge-y:-40%}";
|
|
3
3
|
//#endregion
|
|
4
4
|
export { e as default };
|
|
5
5
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/badge/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n user-select: none;\n display: inline-block;\n}\n\n.badge-wrapper {\n display: inline-flex;\n}\n\n.badge-wrapper-fixed {\n position: relative;\n}\n\n.badge {\n z-index: 1;\n\n display: inline-flex;\n align-items: center;\n justify-content: center;\n\n min-width: 18px;\n height: 18px;\n padding: 0 4px;\n border: 1px solid var(--wui-color-page, #fff);\n border-radius: var(--wui-radius-control, calc(infinity * 1px));\n\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n color: var(--wui-color-on-accent, #fff);\n white-space: nowrap;\n\n background-color: var(--wui-color-danger, #dc2626);\n}\n\n.badge-fixed {\n position: absolute;\n transform: translate(\n calc(var(--badge-x, 50%) + var(--badge-offset-x, 0px)),\n calc(var(--badge-y, -50%) + var(--badge-offset-y, 0px))\n );\n}\n\n:host([placement='top-right']) .badge {\n --badge-x: 50%;\n --badge-y: -50%;\n top: 0;\n right: 0;\n}\n\n:host([placement='top-left']) .badge {\n --badge-x: -50%;\n --badge-y: -50%;\n top: 0;\n left: 0;\n}\n\n:host([placement='bottom-right']) .badge {\n --badge-x: 50%;\n --badge-y: 50%;\n right: 0;\n bottom: 0;\n}\n\n:host([placement='bottom-left']) .badge {\n --badge-x: -50%;\n --badge-y: 50%;\n bottom: 0;\n left: 0;\n}\n\n.badge-dot {\n min-width: 8px;\n height: 8px;\n padding: 0;\n font-size: 0;\n}\n\n.badge-fixed.badge-dot {\n --badge-x: 40%;\n --badge-y: -40%;\n}\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/badge/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n user-select: none;\n display: inline-block;\n}\n\n.badge-wrapper {\n display: inline-flex;\n}\n\n.badge-wrapper-fixed {\n position: relative;\n}\n\n.badge {\n z-index: 1;\n\n display: inline-flex;\n align-items: center;\n justify-content: center;\n\n min-width: 18px;\n height: 18px;\n padding: 0 var(--wui-space-1, 4px);\n border: 1px solid var(--wui-color-page, #fff);\n border-radius: var(--wui-radius-control, calc(infinity * 1px));\n\n font-size: var(--wui-font-size-caption, 12px);\n font-weight: var(--wui-font-weight-medium, 500);\n line-height: 1;\n color: var(--wui-color-on-accent, #fff);\n white-space: nowrap;\n\n background-color: var(--wui-color-danger, #dc2626);\n}\n\n.badge-fixed {\n position: absolute;\n transform: translate(\n calc(var(--badge-x, 50%) + var(--badge-offset-x, 0px)),\n calc(var(--badge-y, -50%) + var(--badge-offset-y, 0px))\n );\n}\n\n:host([placement='top-right']) .badge {\n --badge-x: 50%;\n --badge-y: -50%;\n top: 0;\n right: 0;\n}\n\n:host([placement='top-left']) .badge {\n --badge-x: -50%;\n --badge-y: -50%;\n top: 0;\n left: 0;\n}\n\n:host([placement='bottom-right']) .badge {\n --badge-x: 50%;\n --badge-y: 50%;\n right: 0;\n bottom: 0;\n}\n\n:host([placement='bottom-left']) .badge {\n --badge-x: -50%;\n --badge-y: 50%;\n bottom: 0;\n left: 0;\n}\n\n.badge-dot {\n min-width: 8px;\n height: 8px;\n padding: 0;\n font-size: 0;\n}\n\n.badge-fixed.badge-dot {\n --badge-x: 40%;\n --badge-y: -40%;\n}\n"],"mappings":""}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/components/button/style.css?inline
|
|
2
|
-
var e = "*,:before,:after{box-sizing:border-box}:host{justify-content:center;align-items:center;display:inline-flex;position:relative}:host([full]){width:100%;display:block}:host([disabled]){cursor:not-allowed}button{--wui-glass-corner-radius:calc(var(--wui-control-size,36px) / 2);cursor:default;-webkit-user-select:none;user-select:none;gap:var(--wui-button-gap,8px);box-sizing:border-box;width:var(--wui-button-width,max-content);min-width:var(--wui-control-size,36px);height:var(--wui-control-size,36px);padding:0 var(--wui-button-px,12px);border-radius:var(--wui-radius-control,calc(infinity * 1px));font:inherit;font-size:var(--wui-font-size,14px);color:var(--wui-button-color);white-space:nowrap;background-color:var(--wui-button-bg);border:none;justify-content:center;align-items:center;line-height:1;display:inline-flex;position:relative;overflow:clip}button:disabled{cursor:not-allowed;opacity:.4}button:focus-visible{outline:var(--wui-focus-ring-width,3px) solid var(--wui-color-focus-ring,#
|
|
2
|
+
var e = "*,:before,:after{box-sizing:border-box}:host{justify-content:center;align-items:center;display:inline-flex;position:relative}:host([full]){width:100%;display:block}:host([disabled]){cursor:not-allowed}button{--wui-glass-corner-radius:calc(var(--wui-control-size,36px) / 2);cursor:default;-webkit-user-select:none;user-select:none;gap:var(--wui-button-gap,var(--wui-space-2,8px));box-sizing:border-box;width:var(--wui-button-width,max-content);min-width:var(--wui-control-size,36px);height:var(--wui-control-size,36px);padding:0 var(--wui-button-px,var(--wui-space-3,12px));border-radius:var(--wui-radius-control,calc(infinity * 1px));font:inherit;font-size:var(--wui-font-size,14px);color:var(--wui-button-color);white-space:nowrap;background-color:var(--wui-button-bg);border:none;justify-content:center;align-items:center;line-height:1;display:inline-flex;position:relative;overflow:clip}button:disabled{cursor:not-allowed;opacity:.4}button:focus-visible{outline:var(--wui-focus-ring-width,3px) solid var(--wui-color-focus-ring,color-mix(in srgb, var(--wui-color-accent,#08f) 40%, transparent));outline-offset:2px}@media (hover:hover) and (pointer:fine){button:hover:not(:disabled){background-color:var(--wui-button-bg-hover)}}button:active:not(:disabled){background-color:var(--wui-button-bg-active)}:host([full]) button{width:100%;display:flex}:host([icon]) button{padding:0}:host([data-wui-pointer-focus]) button:focus-visible{outline-color:#0000}:host([variant=primary]){--wui-button-color:var(--wui-color-on-accent,#fff);--wui-button-bg:var(--wui-color-accent,#08f);--wui-button-bg-hover:color-mix(in srgb, var(--wui-button-bg,#08f) 88%, black);--wui-button-bg-active:color-mix(in srgb, var(--wui-button-bg,#08f) 76%, black)}:host([variant=secondary]){--wui-button-color:var(--wui-color-text,#1b1b1b);--wui-button-bg:var(--wui-color-surface-control,#dfdfdf);--wui-button-bg-hover:color-mix(in srgb, var(--wui-button-bg,#dfdfdf) 92%, black);--wui-button-bg-active:color-mix(in srgb, var(--wui-button-bg,#dfdfdf) 82%, black)}:host([variant=ghost]){--wui-button-color:var(--wui-color-text,#1b1b1b);--wui-button-bg:transparent;--wui-button-bg-hover:var(--wui-color-state-layer-hover,color-mix(in srgb, var(--wui-color-text,#1b1b1b) 6%, transparent));--wui-button-bg-active:var(--wui-color-state-layer-active,color-mix(in srgb, var(--wui-color-text,#1b1b1b) 15%, transparent))}:host([variant=danger]){--wui-button-color:var(--wui-color-danger,#dc2626);--wui-button-bg:color-mix(in srgb, var(--wui-color-danger,#dc2626) 18%, var(--wui-color-surface,#fff));--wui-button-bg-hover:color-mix(in srgb, var(--wui-color-danger,#dc2626) 26%, var(--wui-color-surface,#fff));--wui-button-bg-active:color-mix(in srgb, var(--wui-color-danger,#dc2626) 45%, var(--wui-color-surface,#fff))}:host([variant=glass]){--wui-button-color:var(--wui-color-text,#1b1b1b);--wui-button-bg:transparent;--wui-button-bg-hover:var(--wui-color-surface-glass-hover,color-mix(in srgb, var(--wui-color-text,#1b1b1b) 6%, var(--wui-color-surface-glass,#fafafa57)));--wui-button-bg-active:var(--wui-color-surface-glass-active,color-mix(in srgb, var(--wui-color-text,#1b1b1b) 15%, var(--wui-color-surface-glass,#fafafa57)))}button.is-grouped{--wui-button-bg:transparent;--wui-button-bg-hover:var(--wui-color-state-layer-hover,color-mix(in srgb, var(--wui-color-text,#1b1b1b) 6%, transparent));--wui-button-bg-active:var(--wui-color-state-layer-active,color-mix(in srgb, var(--wui-color-text,#1b1b1b) 15%, transparent))}.group-divider{z-index:1;width:1px;height:var(--wui-button-group-divider-length,20px);background-color:var(--wui-color-border,#0000001a);position:absolute;top:50%;right:-2px;transform:translateY(-50%)}.group-divider.vertical{width:var(--wui-button-group-divider-length,20px);height:1px;inset:auto auto -2px 50%;transform:translate(-50%)}";
|
|
3
3
|
//#endregion
|
|
4
4
|
export { e as default };
|
|
5
5
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/button/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n position: relative;\n\n /* inline-flex 让内层按钮在宿主内完全居中,避免继承的行高撑高宿主、导致图标偏移 */\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n:host([full]) {\n display: block;\n width: 100%;\n}\n\n:host([disabled]) {\n cursor: not-allowed;\n}\n\nbutton {\n --wui-glass-corner-radius: calc(var(--wui-control-size, 36px) / 2);\n cursor: default;\n user-select: none;\n\n position: relative;\n\n overflow: clip;\n display: inline-flex;\n gap: var(--wui-button-gap, 8px);\n align-items: center;\n justify-content: center;\n\n box-sizing: border-box;\n width: var(--wui-button-width, max-content);\n min-width: var(--wui-control-size, 36px);\n height: var(--wui-control-size, 36px);\n padding: 0 var(--wui-button-px, 12px);\n border: none;\n border-radius: var(--wui-radius-control, calc(infinity * 1px));\n\n /* 原生 button 不继承字体;显式继承以对齐宿主排版,避免 UA 默认 Arial 差异 */\n font: inherit;\n font-size: var(--wui-font-size, 14px);\n line-height: 1;\n color: var(--wui-button-color);\n white-space: nowrap;\n\n background-color: var(--wui-button-bg);\n\n &:disabled {\n cursor: not-allowed;\n opacity: 0.4;\n }\n\n &:focus-visible {\n outline: var(--wui-focus-ring-width, 3px) solid
|
|
1
|
+
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/button/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n position: relative;\n\n /* inline-flex 让内层按钮在宿主内完全居中,避免继承的行高撑高宿主、导致图标偏移 */\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n:host([full]) {\n display: block;\n width: 100%;\n}\n\n:host([disabled]) {\n cursor: not-allowed;\n}\n\nbutton {\n --wui-glass-corner-radius: calc(var(--wui-control-size, 36px) / 2);\n cursor: default;\n user-select: none;\n\n position: relative;\n\n overflow: clip;\n display: inline-flex;\n gap: var(--wui-button-gap, var(--wui-space-2, 8px));\n align-items: center;\n justify-content: center;\n\n box-sizing: border-box;\n width: var(--wui-button-width, max-content);\n min-width: var(--wui-control-size, 36px);\n height: var(--wui-control-size, 36px);\n padding: 0 var(--wui-button-px, var(--wui-space-3, 12px));\n border: none;\n border-radius: var(--wui-radius-control, calc(infinity * 1px));\n\n /* 原生 button 不继承字体;显式继承以对齐宿主排版,避免 UA 默认 Arial 差异 */\n font: inherit;\n font-size: var(--wui-font-size, 14px);\n line-height: 1;\n color: var(--wui-button-color);\n white-space: nowrap;\n\n background-color: var(--wui-button-bg);\n\n &:disabled {\n cursor: not-allowed;\n opacity: 0.4;\n }\n\n &:focus-visible {\n outline: var(--wui-focus-ring-width, 3px) solid\n var(--wui-color-focus-ring, color-mix(in srgb, var(--wui-color-accent, #08f) 40%, transparent));\n outline-offset: 2px;\n }\n}\n\n@media (hover: hover) and (pointer: fine) {\n button:hover:not(:disabled) {\n background-color: var(--wui-button-bg-hover);\n }\n}\n\nbutton:active:not(:disabled) {\n background-color: var(--wui-button-bg-active);\n}\n\n:host([full]) button {\n display: flex;\n width: 100%;\n}\n\n:host([icon]) button {\n padding: 0;\n}\n\n/* pointer-focus helper 把标记写到 shadow host 上;这里抑制 Shadow DOM 内按钮的 focus ring。 */\n:host([data-wui-pointer-focus]) button:focus-visible {\n outline-color: transparent;\n}\n\n:host([variant='primary']) {\n --wui-button-color: var(--wui-color-on-accent, #fff);\n --wui-button-bg: var(--wui-color-accent, #08f);\n --wui-button-bg-hover: color-mix(in srgb, var(--wui-button-bg, #08f) 88%, black);\n --wui-button-bg-active: color-mix(in srgb, var(--wui-button-bg, #08f) 76%, black);\n}\n\n:host([variant='secondary']) {\n --wui-button-color: var(--wui-color-text, #1b1b1b);\n --wui-button-bg: var(--wui-color-surface-control, #dfdfdf);\n --wui-button-bg-hover: color-mix(in srgb, var(--wui-button-bg, #dfdfdf) 92%, black);\n --wui-button-bg-active: color-mix(in srgb, var(--wui-button-bg, #dfdfdf) 82%, black);\n}\n\n:host([variant='ghost']) {\n --wui-button-color: var(--wui-color-text, #1b1b1b);\n --wui-button-bg: transparent;\n --wui-button-bg-hover: var(\n --wui-color-state-layer-hover,\n color-mix(in srgb, var(--wui-color-text, #1b1b1b) 6%, transparent)\n );\n --wui-button-bg-active: var(\n --wui-color-state-layer-active,\n color-mix(in srgb, var(--wui-color-text, #1b1b1b) 15%, transparent)\n );\n}\n\n:host([variant='danger']) {\n --wui-button-color: var(--wui-color-danger, #dc2626);\n --wui-button-bg: color-mix(in srgb, var(--wui-color-danger, #dc2626) 18%, var(--wui-color-surface, #fff));\n --wui-button-bg-hover: color-mix(in srgb, var(--wui-color-danger, #dc2626) 26%, var(--wui-color-surface, #fff));\n --wui-button-bg-active: color-mix(in srgb, var(--wui-color-danger, #dc2626) 45%, var(--wui-color-surface, #fff));\n}\n\n/* .wui-glass 样式由 @/assets/glass.css 提供 */\n:host([variant='glass']) {\n --wui-button-color: var(--wui-color-text, #1b1b1b);\n\n /* standalone glass 底色由 .wui-glass 提供;hover/active 需要还原玻璃底,避免被按钮状态色整块替换 */\n --wui-button-bg: transparent;\n --wui-button-bg-hover: var(\n --wui-color-surface-glass-hover,\n color-mix(in srgb, var(--wui-color-text, #1b1b1b) 6%, var(--wui-color-surface-glass, rgb(250 250 250 / 0.34)))\n );\n --wui-button-bg-active: var(\n --wui-color-surface-glass-active,\n color-mix(in srgb, var(--wui-color-text, #1b1b1b) 15%, var(--wui-color-surface-glass, rgb(250 250 250 / 0.34)))\n );\n}\n\nbutton.is-grouped {\n --wui-button-bg: transparent;\n --wui-button-bg-hover: var(\n --wui-color-state-layer-hover,\n color-mix(in srgb, var(--wui-color-text, #1b1b1b) 6%, transparent)\n );\n --wui-button-bg-active: var(\n --wui-color-state-layer-active,\n color-mix(in srgb, var(--wui-color-text, #1b1b1b) 15%, transparent)\n );\n}\n\n.group-divider {\n position: absolute;\n z-index: 1;\n top: 50%;\n right: -2px;\n transform: translateY(-50%);\n\n width: 1px;\n height: var(--wui-button-group-divider-length, 20px);\n\n background-color: var(--wui-color-border, rgb(0 0 0 / 0.1));\n}\n\n.group-divider.vertical {\n top: auto;\n right: auto;\n bottom: -2px;\n left: 50%;\n transform: translateX(-50%);\n\n width: var(--wui-button-group-divider-length, 20px);\n height: 1px;\n}\n"],"mappings":""}
|
|
@@ -2,7 +2,6 @@ import e from "../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorate
|
|
|
2
2
|
import t from "../../assets/glass.js";
|
|
3
3
|
import { GroupController as n, buttonGroupContextKey as r, defineGroupPresentation as i } from "../../shared/group-management/index.js";
|
|
4
4
|
import { normalizeLiteral as a } from "../../shared/normalize/index.js";
|
|
5
|
-
import "../button/index.js";
|
|
6
5
|
import o from "./style.js";
|
|
7
6
|
import { LitElement as s, html as c, unsafeCSS as l } from "lit";
|
|
8
7
|
import { customElement as u, property as d } from "lit/decorators.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/button-group/index.ts"],"sourcesContent":["import { html, LitElement, unsafeCSS } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/button-group/index.ts"],"sourcesContent":["import { html, LitElement, unsafeCSS } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\nimport glass from '@/assets/glass.css?inline'\nimport {\n buttonGroupContextKey,\n defineGroupPresentation,\n GroupController,\n type ButtonGroupContext\n} from '@/shared/group-management'\nimport { normalizeLiteral } from '@/shared/normalize'\n\nimport type { WebUiButton } from '../button'\n\nimport style from './style.css?inline'\n\nconst ALLOWED_DIRECTIONS = ['horizontal', 'vertical'] as const\n\n@customElement('web-ui-button-group')\nexport class WebUiButtonGroup extends LitElement {\n static override styles = [unsafeCSS(glass), unsafeCSS(style)]\n\n @property({ type: String, reflect: true })\n get direction(): 'horizontal' | 'vertical' {\n return this._direction\n }\n set direction(v: string) {\n const old = this._direction\n this._direction = normalizeLiteral(v, ALLOWED_DIRECTIONS, 'horizontal')\n this.requestUpdate('direction', old)\n }\n private _direction: 'horizontal' | 'vertical' = 'horizontal'\n\n private readonly _groupController = new GroupController(\n this,\n defineGroupPresentation<WebUiButton, ButtonGroupContext>({\n host: this,\n context: buttonGroupContextKey,\n getItems: () => [...this.querySelectorAll<WebUiButton>('web-ui-button')],\n getContext: (_, index, buttons) => ({\n direction: this.direction,\n isLast: index === buttons.length - 1\n })\n }).make()\n )\n\n override render() {\n return html`\n <div class=\"wui-glass wui-button-group-inner\">\n <slot></slot>\n </div>\n `\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-button-group': WebUiButtonGroup\n }\n}\n"],"mappings":";;;;;;;;AAgBA,IAAM,IAAqB,CAAC,cAAc,UAAU,GAGvC,IAAN,cAA+B,EAAW;;EAcX,aAFY,KAAA,aAAA,cAEZ,KAAA,mBAAA,IAAI,EACtC,MACA,EAAyD;GACvD,MAAM;GACN,SAAS;GACT,gBAAgB,CAAC,GAAG,KAAK,iBAA8B,eAAe,CAAC;GACvE,aAAa,GAAG,GAAO,OAAa;IAClC,WAAW,KAAK;IAChB,QAAQ,MAAU,EAAQ,SAAS;GACrC;EACF,CAAC,CAAC,CAAC,KAAK,CACV;;;EAxByB,KAAA,SAAA,CAAC,EAAU,CAAK,GAAG,EAAU,CAAK,CAAC;;CAE5D,IACI,YAAuC;EACzC,OAAO,KAAK;CACd;CACA,IAAI,UAAU,GAAW;EACvB,IAAM,IAAM,KAAK;EAEjB,AADA,KAAK,aAAa,EAAiB,GAAG,GAAoB,YAAY,GACtE,KAAK,cAAc,aAAa,CAAG;CACrC;CAgBA,SAAkB;EAChB,OAAO,CAAI;;;;;CAKb;AACF;AA/BG,EAAA,CAAA,EAAS;CAAE,MAAM;CAAQ,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,aAAA,IAAA,GAJ1C,IAAA,EAAA,CAAA,EAAc,qBAAqB,CAAA,GAAA,CAAA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/components/button-group/style.css?inline
|
|
2
|
-
var e = "*,:before,:after{box-sizing:border-box}:host{display:inline-block}.wui-button-group-inner{--wui-glass-corner-radius:calc(var(--wui-control-size,36px) / 2);flex-direction:var(--wui-button-group-flex-direction,row);width:max-content;height:var(--wui-control-size,36px);border-radius:var(--wui-radius-control,calc(infinity * 1px));align-items:center;
|
|
2
|
+
var e = "*,:before,:after{box-sizing:border-box}:host{display:inline-block}.wui-button-group-inner{--wui-glass-corner-radius:calc(var(--wui-control-size,36px) / 2);flex-direction:var(--wui-button-group-flex-direction,row);gap:var(--wui-space-1,4px);width:max-content;height:var(--wui-control-size,36px);padding:0 var(--wui-space-1,4px);border-radius:var(--wui-radius-control,calc(infinity * 1px));align-items:center;display:flex}:host([direction=vertical]){--wui-button-group-flex-direction:column}:host([direction=vertical]) .wui-button-group-inner{width:var(--wui-control-size,36px);height:auto;padding:var(--wui-space-1,4px) 0}";
|
|
3
3
|
//#endregion
|
|
4
4
|
export { e as default };
|
|
5
5
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/button-group/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n display: inline-block;\n}\n\n.wui-button-group-inner {\n --wui-glass-corner-radius: calc(var(--wui-control-size, 36px) / 2);\n\n display: flex;\n flex-direction: var(--wui-button-group-flex-direction, row);\n gap: 4px;\n align-items: center;\n\n width: max-content;\n height: var(--wui-control-size, 36px);\n padding: 0 4px;\n border-radius: var(--wui-radius-control, calc(infinity * 1px));\n}\n\n:host([direction='vertical']) {\n --wui-button-group-flex-direction: column;\n}\n\n:host([direction='vertical']) .wui-button-group-inner {\n width: var(--wui-control-size, 36px);\n height: auto;\n padding: 4px 0;\n}\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/button-group/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n display: inline-block;\n}\n\n.wui-button-group-inner {\n --wui-glass-corner-radius: calc(var(--wui-control-size, 36px) / 2);\n\n display: flex;\n flex-direction: var(--wui-button-group-flex-direction, row);\n gap: var(--wui-space-1, 4px);\n align-items: center;\n\n width: max-content;\n height: var(--wui-control-size, 36px);\n padding: 0 var(--wui-space-1, 4px);\n border-radius: var(--wui-radius-control, calc(infinity * 1px));\n}\n\n:host([direction='vertical']) {\n --wui-button-group-flex-direction: column;\n}\n\n:host([direction='vertical']) .wui-button-group-inner {\n width: var(--wui-control-size, 36px);\n height: auto;\n padding: var(--wui-space-1, 4px) 0;\n}\n"],"mappings":""}
|
|
@@ -5,9 +5,9 @@ import { installPointerFocusSuppression as n } from "../../shared/focus/pointer-
|
|
|
5
5
|
import { FormAssociated as r, FormAssociationController as i, defineFormAssociation as a } from "../../shared/form-association/index.js";
|
|
6
6
|
import { defineGroupManaged as o, selectionGroupContextKey as s } from "../../shared/group-management/index.js";
|
|
7
7
|
import { parseDuration as c } from "../../shared/theme/duration.js";
|
|
8
|
-
import
|
|
8
|
+
import l from "../../assets/selection-control.js";
|
|
9
|
+
import { prefersReducedMotion as u } from "../../shared/theme/reduced-motion.js";
|
|
9
10
|
import "../svg-draw-lines/index.js";
|
|
10
|
-
import u from "../../assets/selection-control.js";
|
|
11
11
|
import { LabelEmptinessController as d } from "../../shared/label-emptiness/index.js";
|
|
12
12
|
import f from "./style.js";
|
|
13
13
|
import { LitElement as p, html as m, unsafeCSS as h } from "lit";
|
|
@@ -45,7 +45,7 @@ var S = class extends r(p) {
|
|
|
45
45
|
}), this._drawDurationMs = 160;
|
|
46
46
|
}
|
|
47
47
|
static {
|
|
48
|
-
this.styles = [h(
|
|
48
|
+
this.styles = [h(l), h(f)];
|
|
49
49
|
}
|
|
50
50
|
get checked() {
|
|
51
51
|
return this._checked;
|
|
@@ -89,7 +89,7 @@ var S = class extends r(p) {
|
|
|
89
89
|
willUpdate(e) {
|
|
90
90
|
super.willUpdate(e), this._drawDurationMs = x(this);
|
|
91
91
|
let t = e.get("_checked");
|
|
92
|
-
typeof t == "boolean" && (this._retracting = t && !
|
|
92
|
+
typeof t == "boolean" && (this._retracting = t && !u(this));
|
|
93
93
|
}
|
|
94
94
|
updated(e) {
|
|
95
95
|
super.updated(e);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/checkbox/index.ts"],"sourcesContent":["import { html, LitElement, type PropertyValues, unsafeCSS } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\n\nimport '@/components/icon'\nimport '@/components/svg-draw-lines'\nimport selectionControl from '@/assets/selection-control.css?inline'\nimport { WebUiSvgDrawLines } from '@/components/svg-draw-lines'\nimport { akarIconsCheck } from '@/icons'\nimport { installPointerFocusSuppression } from '@/shared/focus/pointer-focus'\nimport { FormAssociated, defineFormAssociation, FormAssociationController } from '@/shared/form-association'\nimport { defineGroupManaged, selectionGroupContextKey, type SelectionGroupContext } from '@/shared/group-management'\nimport { LabelEmptinessController } from '@/shared/label-emptiness'\nimport { parseDuration } from '@/shared/theme/duration'\nimport { prefersReducedMotion } from '@/shared/theme/reduced-motion'\n\nimport style from './style.css?inline'\n\ninstallPointerFocusSuppression()\n\n/*\n * 描边时长取 `--wui-duration-trigger`,让勾和指示器底色那条 transition 落在同一拍。\n * 读不到 token 或格式不符时兜底 160,负值钳到 0。\n */\nfunction triggerDuration(el: HTMLElement): number {\n const parsed = parseDuration(getComputedStyle(el).getPropertyValue('--wui-duration-trigger'))\n return parsed === null ? 160 : Math.max(0, parsed)\n}\n\n@customElement('web-ui-checkbox')\nexport class WebUiCheckbox extends FormAssociated(LitElement) {\n static override styles = [unsafeCSS(selectionControl), unsafeCSS(style)]\n private readonly _groupManagement = defineGroupManaged<SelectionGroupContext>(this, {\n context: selectionGroupContextKey,\n requestUpdate: () => this.requestUpdate()\n }).make()\n\n @state() private _checked = false\n\n /** 描边收回期间把勾按在可见档,见 willUpdate。 */\n @state() private _retracting = false\n\n /** 标签没有可渲染内容(空槽位,或只挂着一个无障碍名)时收掉 gap,见 LabelEmptinessController。 */\n @state() private _labelEmpty = false\n\n get checked(): boolean {\n return this._checked\n }\n\n set checked(v: boolean) {\n const old = this._checked\n this._checked = v\n this._formAssociation.sync()\n this.requestUpdate('checked', old)\n }\n\n @property({ type: String }) value = ''\n @property({ type: String, reflect: true }) name = ''\n @property({ type: Boolean, reflect: true }) disabled = false\n @property({ type: Boolean, reflect: true }) required = false\n\n private get _isDisabled(): boolean {\n return (\n this.disabled || this._formAssociation.isFormDisabled() || this._groupManagement.getContext()?.disabled === true\n )\n }\n\n private get _isManagedByGroup(): boolean {\n return this._groupManagement.getContext() !== undefined\n }\n\n private readonly _formAssociation = defineFormAssociation<boolean>({\n host: this,\n initialize: () => {\n if (this.hasAttribute('checked')) this._checked = true\n },\n getState: () => this._checked,\n setState: checked => {\n this.checked = checked\n },\n getFormValue: () => (!this._isManagedByGroup && this._checked ? this.value || 'on' : null),\n getFormState: () => String(this._checked),\n restoreState: state => {\n if (typeof state === 'string') this.checked = state === 'true'\n },\n isStateManaged: () => this._isManagedByGroup,\n syncValidity: () => this._syncValidity()\n }).make()\n\n private readonly _formAssociationController = new FormAssociationController(this, this._formAssociation)\n\n private readonly _labelEmptiness = new LabelEmptinessController(this, '.wui-checkbox-label', empty => {\n this._labelEmpty = empty\n })\n\n @query('web-ui-svg-draw-lines') private readonly _drawLines?: WebUiSvgDrawLines\n\n /** 每次更新重读一次,交给内层描边的 duration 属性;见 willUpdate。 */\n private _drawDurationMs = 160\n\n private _syncValidity() {\n const internals = this._formAssociation.getInternals()\n if (!internals || typeof internals.setValidity !== 'function') return\n if (this._isDisabled || this._isManagedByGroup || !this.required || this._checked) {\n internals.setValidity({})\n return\n }\n internals.setValidity({ valueMissing: true }, '请选择此项')\n }\n\n private handleClick() {\n if (this._isDisabled) return\n const old = this._checked\n this._checked = !old\n this._formAssociation.sync()\n this.requestUpdate('checked', old)\n // group-managed 时事件不冒泡/不组合,由 group 统一派发一次 host 事件,避免同名事件外泄\n const opts: EventInit = this._isManagedByGroup\n ? { bubbles: false, composed: false }\n : { bubbles: true, composed: true }\n this.dispatchEvent(new Event('input', opts))\n this.dispatchEvent(new Event('change', opts))\n }\n\n private handleKeyDown(e: KeyboardEvent) {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n this.handleClick()\n }\n }\n\n /*\n * 收回期间勾要留在可见档,否则 160ms 淡出抢在描边收回之前把它藏掉。翻转放在 willUpdate:\n * 与 checked 同一次 update 落地,渲染后不再改状态。收回的终点是留在内联样式上的空白,所以这一位\n * 不需要在动画结束后复位,下一次勾选会清掉;reduced motion 下收回根本不跑,按住可见位就是把勾\n * 永久留在未勾选的框里,所以那里必须让位给淡出。\n */\n override willUpdate(changed: PropertyValues) {\n super.willUpdate(changed)\n this._drawDurationMs = triggerDuration(this)\n const wasChecked = changed.get('_checked')\n if (typeof wasChecked === 'boolean') {\n this._retracting = wasChecked && !prefersReducedMotion(this)\n }\n }\n\n /*\n * 挂载时就勾选是初始状态而非用户勾选,不画线:_checked 的字段初始化器在构造阶段写过一次,\n * Lit 对同一轮里已记录过旧值的键不再覆盖,所以首帧拿到的是 undefined,之后的每次真实切换才带\n * boolean 旧值——包括 group 在子项首帧前把选中态写回去那一种。\n */\n override updated(changed: PropertyValues) {\n super.updated(changed)\n const wasChecked = changed.get('_checked')\n if (typeof wasChecked !== 'boolean') return\n\n if (wasChecked) void this._drawLines?.replay({ reverse: true })\n else void this._drawLines?.replay()\n }\n\n override render() {\n const cls = {\n 'wui-checkbox': true,\n 'is-checked': this._checked,\n 'is-retracting': this._retracting,\n 'is-label-empty': this._labelEmpty,\n 'is-disabled': this._isDisabled\n }\n\n return html`\n <label\n class=${classMap(cls)}\n tabindex=${this._isDisabled ? '-1' : '0'}\n role=\"checkbox\"\n aria-checked=${String(this._checked)}\n aria-disabled=${String(this._isDisabled)}\n @click=${this.handleClick}\n @keydown=${this.handleKeyDown}\n >\n <span class=\"wui-checkbox-box\">\n <span class=\"wui-checkbox-icon\"\n ><web-ui-svg-draw-lines duration=${this._drawDurationMs} no-autoplay\n ><web-ui-icon .icon=${akarIconsCheck}></web-ui-icon></web-ui-svg-draw-lines\n ></span>\n </span>\n <span class=\"wui-checkbox-label\"><slot></slot></span>\n </label>\n `\n }\n\n declare readonly $events: {\n input: Event\n change: Event\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-checkbox': WebUiCheckbox\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/checkbox/index.ts"],"sourcesContent":["import { html, LitElement, type PropertyValues, unsafeCSS } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\n\nimport '@/components/icon'\nimport selectionControl from '@/assets/selection-control.css?inline'\nimport { WebUiSvgDrawLines } from '@/components/svg-draw-lines'\nimport { akarIconsCheck } from '@/icons'\nimport { installPointerFocusSuppression } from '@/shared/focus/pointer-focus'\nimport { FormAssociated, defineFormAssociation, FormAssociationController } from '@/shared/form-association'\nimport { defineGroupManaged, selectionGroupContextKey, type SelectionGroupContext } from '@/shared/group-management'\nimport { LabelEmptinessController } from '@/shared/label-emptiness'\nimport { parseDuration } from '@/shared/theme/duration'\nimport { prefersReducedMotion } from '@/shared/theme/reduced-motion'\n\nimport style from './style.css?inline'\n\ninstallPointerFocusSuppression()\n\n/*\n * 描边时长取 `--wui-duration-trigger`,让勾和指示器底色那条 transition 落在同一拍。\n * 读不到 token 或格式不符时兜底 160,负值钳到 0。\n */\nfunction triggerDuration(el: HTMLElement): number {\n const parsed = parseDuration(getComputedStyle(el).getPropertyValue('--wui-duration-trigger'))\n return parsed === null ? 160 : Math.max(0, parsed)\n}\n\n@customElement('web-ui-checkbox')\nexport class WebUiCheckbox extends FormAssociated(LitElement) {\n static override styles = [unsafeCSS(selectionControl), unsafeCSS(style)]\n private readonly _groupManagement = defineGroupManaged<SelectionGroupContext>(this, {\n context: selectionGroupContextKey,\n requestUpdate: () => this.requestUpdate()\n }).make()\n\n @state() private _checked = false\n\n /** 描边收回期间把勾按在可见档,见 willUpdate。 */\n @state() private _retracting = false\n\n /** 标签没有可渲染内容(空槽位,或只挂着一个无障碍名)时收掉 gap,见 LabelEmptinessController。 */\n @state() private _labelEmpty = false\n\n get checked(): boolean {\n return this._checked\n }\n\n set checked(v: boolean) {\n const old = this._checked\n this._checked = v\n this._formAssociation.sync()\n this.requestUpdate('checked', old)\n }\n\n @property({ type: String }) value = ''\n @property({ type: String, reflect: true }) name = ''\n @property({ type: Boolean, reflect: true }) disabled = false\n @property({ type: Boolean, reflect: true }) required = false\n\n private get _isDisabled(): boolean {\n return (\n this.disabled || this._formAssociation.isFormDisabled() || this._groupManagement.getContext()?.disabled === true\n )\n }\n\n private get _isManagedByGroup(): boolean {\n return this._groupManagement.getContext() !== undefined\n }\n\n private readonly _formAssociation = defineFormAssociation<boolean>({\n host: this,\n initialize: () => {\n if (this.hasAttribute('checked')) this._checked = true\n },\n getState: () => this._checked,\n setState: checked => {\n this.checked = checked\n },\n getFormValue: () => (!this._isManagedByGroup && this._checked ? this.value || 'on' : null),\n getFormState: () => String(this._checked),\n restoreState: state => {\n if (typeof state === 'string') this.checked = state === 'true'\n },\n isStateManaged: () => this._isManagedByGroup,\n syncValidity: () => this._syncValidity()\n }).make()\n\n private readonly _formAssociationController = new FormAssociationController(this, this._formAssociation)\n\n private readonly _labelEmptiness = new LabelEmptinessController(this, '.wui-checkbox-label', empty => {\n this._labelEmpty = empty\n })\n\n @query('web-ui-svg-draw-lines') private readonly _drawLines?: WebUiSvgDrawLines\n\n /** 每次更新重读一次,交给内层描边的 duration 属性;见 willUpdate。 */\n private _drawDurationMs = 160\n\n private _syncValidity() {\n const internals = this._formAssociation.getInternals()\n if (!internals || typeof internals.setValidity !== 'function') return\n if (this._isDisabled || this._isManagedByGroup || !this.required || this._checked) {\n internals.setValidity({})\n return\n }\n internals.setValidity({ valueMissing: true }, '请选择此项')\n }\n\n private handleClick() {\n if (this._isDisabled) return\n const old = this._checked\n this._checked = !old\n this._formAssociation.sync()\n this.requestUpdate('checked', old)\n // group-managed 时事件不冒泡/不组合,由 group 统一派发一次 host 事件,避免同名事件外泄\n const opts: EventInit = this._isManagedByGroup\n ? { bubbles: false, composed: false }\n : { bubbles: true, composed: true }\n this.dispatchEvent(new Event('input', opts))\n this.dispatchEvent(new Event('change', opts))\n }\n\n private handleKeyDown(e: KeyboardEvent) {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n this.handleClick()\n }\n }\n\n /*\n * 收回期间勾要留在可见档,否则 160ms 淡出抢在描边收回之前把它藏掉。翻转放在 willUpdate:\n * 与 checked 同一次 update 落地,渲染后不再改状态。收回的终点是留在内联样式上的空白,所以这一位\n * 不需要在动画结束后复位,下一次勾选会清掉;reduced motion 下收回根本不跑,按住可见位就是把勾\n * 永久留在未勾选的框里,所以那里必须让位给淡出。\n */\n override willUpdate(changed: PropertyValues) {\n super.willUpdate(changed)\n this._drawDurationMs = triggerDuration(this)\n const wasChecked = changed.get('_checked')\n if (typeof wasChecked === 'boolean') {\n this._retracting = wasChecked && !prefersReducedMotion(this)\n }\n }\n\n /*\n * 挂载时就勾选是初始状态而非用户勾选,不画线:_checked 的字段初始化器在构造阶段写过一次,\n * Lit 对同一轮里已记录过旧值的键不再覆盖,所以首帧拿到的是 undefined,之后的每次真实切换才带\n * boolean 旧值——包括 group 在子项首帧前把选中态写回去那一种。\n */\n override updated(changed: PropertyValues) {\n super.updated(changed)\n const wasChecked = changed.get('_checked')\n if (typeof wasChecked !== 'boolean') return\n\n if (wasChecked) void this._drawLines?.replay({ reverse: true })\n else void this._drawLines?.replay()\n }\n\n override render() {\n const cls = {\n 'wui-checkbox': true,\n 'is-checked': this._checked,\n 'is-retracting': this._retracting,\n 'is-label-empty': this._labelEmpty,\n 'is-disabled': this._isDisabled\n }\n\n return html`\n <label\n class=${classMap(cls)}\n tabindex=${this._isDisabled ? '-1' : '0'}\n role=\"checkbox\"\n aria-checked=${String(this._checked)}\n aria-disabled=${String(this._isDisabled)}\n @click=${this.handleClick}\n @keydown=${this.handleKeyDown}\n >\n <span class=\"wui-checkbox-box\">\n <span class=\"wui-checkbox-icon\"\n ><web-ui-svg-draw-lines duration=${this._drawDurationMs} no-autoplay\n ><web-ui-icon .icon=${akarIconsCheck}></web-ui-icon></web-ui-svg-draw-lines\n ></span>\n </span>\n <span class=\"wui-checkbox-label\"><slot></slot></span>\n </label>\n `\n }\n\n declare readonly $events: {\n input: Event\n change: Event\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-checkbox': WebUiCheckbox\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/components/checkbox-group/style.css?inline
|
|
2
|
-
var e = "*,:before,:after{box-sizing:border-box}:host{-webkit-user-select:none;user-select:none;gap:var(--wui-checkbox-group-gap,8px);flex-direction:column;display:inline-flex}.wui-checkbox-group{flex-direction:inherit;gap:inherit;display:flex}:host([direction=horizontal]){flex-direction:row}";
|
|
2
|
+
var e = "*,:before,:after{box-sizing:border-box}:host{-webkit-user-select:none;user-select:none;gap:var(--wui-checkbox-group-gap,var(--wui-space-2,8px));flex-direction:column;display:inline-flex}.wui-checkbox-group{flex-direction:inherit;gap:inherit;display:flex}:host([direction=horizontal]){flex-direction:row}";
|
|
3
3
|
//#endregion
|
|
4
4
|
export { e as default };
|
|
5
5
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/checkbox-group/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n user-select: none;\n display: inline-flex;\n flex-direction: column;\n gap: var(--wui-checkbox-group-gap, 8px);\n}\n\n.wui-checkbox-group {\n display: flex;\n flex-direction: inherit;\n gap: inherit;\n}\n\n:host([direction='horizontal']) {\n flex-direction: row;\n}\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/checkbox-group/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n user-select: none;\n display: inline-flex;\n flex-direction: column;\n gap: var(--wui-checkbox-group-gap, var(--wui-space-2, 8px));\n}\n\n.wui-checkbox-group {\n display: flex;\n flex-direction: inherit;\n gap: inherit;\n}\n\n:host([direction='horizontal']) {\n flex-direction: row;\n}\n"],"mappings":""}
|
|
@@ -3,13 +3,73 @@ export declare class WebUiContextMenu extends LitElement {
|
|
|
3
3
|
static styles: import('lit').CSSResult;
|
|
4
4
|
disabled: boolean;
|
|
5
5
|
noScrollLock: boolean;
|
|
6
|
+
/** opt-in:触屏长按打开菜单。默认关闭,鼠标路径靠原生 contextmenu,无需此属性。 */
|
|
7
|
+
longPress: boolean;
|
|
8
|
+
private _longPressDelay;
|
|
9
|
+
/**
|
|
10
|
+
* 走包内既有的 `normalizeNumber` 通道(与 `dropdown.offset`、`popover.offset` 同形)。
|
|
11
|
+
* 不能只靠 `Math.max(0, …)` 挡负数:`Math.max(0, NaN) === NaN`,而属性写错
|
|
12
|
+
* (`long-press-delay="abc"`)时 Lit 的 Number converter 给的正是 NaN,
|
|
13
|
+
* `setTimeout(fn, NaN)` 会立刻触发,长按就在 pointerdown 同一帧开菜单、绕过全部时长语义。
|
|
14
|
+
*/
|
|
15
|
+
get longPressDelay(): number;
|
|
16
|
+
set longPressDelay(v: number);
|
|
6
17
|
private _isOpen;
|
|
7
18
|
private _x;
|
|
8
19
|
private _y;
|
|
9
20
|
private _activeSubmenus;
|
|
10
21
|
private _activeSubmenuItems;
|
|
22
|
+
private _longPressTimer;
|
|
23
|
+
private _longPressOrigin;
|
|
24
|
+
/**
|
|
25
|
+
* 长按自行开菜单的时刻。浏览器会为**同一次触摸**补发两个事件,二者都属于
|
|
26
|
+
* 那一次意图,不是两次独立操作:
|
|
27
|
+
*
|
|
28
|
+
* - 原生 `contextmenu`:长按被识别时立刻派发,会重复打开(`_openAt` 走已开分支)。
|
|
29
|
+
* - 合成 `click`:`touchend` 之后由引擎补发,会把刚打开的菜单立刻 light-dismiss。
|
|
30
|
+
* 实测真实触控管线下的顺序为 pointerdown(9ms) → 长按开菜单(≈509ms) →
|
|
31
|
+
* touchend(1019ms) → click(1022ms),缺这一步菜单开了就被自己的补发事件关掉。
|
|
32
|
+
*
|
|
33
|
+
* 因此在窗口内吸收这两个补发事件;窗口由下一次 `pointerdown` 关闭。
|
|
34
|
+
*/
|
|
35
|
+
private _longPressOpenedAt;
|
|
11
36
|
private readonly _submenuPositionEpochs;
|
|
12
37
|
private _menu?;
|
|
38
|
+
/**
|
|
39
|
+
* 模态 scrim。菜单打开期间存在并处于 `showModal()` 状态,关闭时随面板一起移除。
|
|
40
|
+
*
|
|
41
|
+
* 面板必须**显式**挂进它(`createMenuPortalOverlay` 的第三参):`resolveOverlayContainer`
|
|
42
|
+
* 查的是 target 的**祖先**里有无已打开的 dialog,而 scrim 是面板的反方向,祖先发现查不到。
|
|
43
|
+
*/
|
|
44
|
+
private _scrim?;
|
|
45
|
+
/**
|
|
46
|
+
* 本次开启是否**水平居中于触发点**(触屏长按路径)。鼠标 / 键盘路径仍左上角对齐光标。
|
|
47
|
+
*
|
|
48
|
+
* 只切换 placement 的对齐量,不切换定位算法 —— 两条入口共用 `_positionMenu` 里的
|
|
49
|
+
* 同一套 `computePosition` + `flip` / `shift`,垂直契约(上缘对齐触发点、向下展开、
|
|
50
|
+
* 放不下翻到上方)完全一致。
|
|
51
|
+
*
|
|
52
|
+
* 触屏要居中:手指按下去的位置是「这块内容在这里」的意思,菜单在它正下方居中展开,
|
|
53
|
+
* 正是 iOS / Android 原生长按菜单的形态;左对齐会让菜单整体偏到手指右侧,看起来像
|
|
54
|
+
* 弹在了别的东西上面。
|
|
55
|
+
*
|
|
56
|
+
* 鼠标不居中:桌面右键的肌肉记忆是菜单**左上角**出现在光标处。更要紧的是居中会让光标
|
|
57
|
+
* 落在面板上缘正中 —— 也就是落在第一项的命中区里。后果是菜单一开就有项处于 hover 高亮,
|
|
58
|
+
* 并且紧接着再右键一次(想开子菜单)会打在菜单项上而不是空白处。`overlay-in-dialog`
|
|
59
|
+
* 里 `openAt(100, 400)` 那条用例钉的 `'top left'` 正是这条契约。
|
|
60
|
+
*
|
|
61
|
+
* 判据是**开启来源**(调用点显式传入),不靠运行时嗅探 pointerType 或视口宽度:
|
|
62
|
+
* 后两者会让同一块屏幕上的两种输入拿到两套布局,且与本组件 opt-in 的 `long-press`
|
|
63
|
+
* 属性不同源。
|
|
64
|
+
*/
|
|
65
|
+
private _centerOnPressPoint;
|
|
66
|
+
/**
|
|
67
|
+
* 本次关闭的来源,决定焦点归还走哪条路。语义见 `close()` 里的说明。
|
|
68
|
+
*
|
|
69
|
+
* 只有菜单项激活这一条需要抢在退场之前出顶层;点外面 / Escape / 程序式关闭一律
|
|
70
|
+
* 保留 dialog 默认效果 —— 那正是用户「回到原处」的期望。
|
|
71
|
+
*/
|
|
72
|
+
private _closeSource;
|
|
13
73
|
/** 根面板的开启会话句柄;未开启时为 null。查询走它。 */
|
|
14
74
|
private _menuHandle;
|
|
15
75
|
/**
|
|
@@ -26,8 +86,8 @@ export declare class WebUiContextMenu extends LitElement {
|
|
|
26
86
|
private readonly _menuItemAnchors;
|
|
27
87
|
private readonly _scrollLock;
|
|
28
88
|
private readonly _userOpenChange;
|
|
29
|
-
private _restoreFocusTarget?;
|
|
30
89
|
private _shouldOpenInstantly;
|
|
90
|
+
private _suppressInitialFocusVisible;
|
|
31
91
|
private _refreshScheduled;
|
|
32
92
|
private readonly _menuPositionGeneration;
|
|
33
93
|
private readonly _contentObserver;
|
|
@@ -51,12 +111,125 @@ export declare class WebUiContextMenu extends LitElement {
|
|
|
51
111
|
private readonly _closeFromUser;
|
|
52
112
|
private _scheduleRefresh;
|
|
53
113
|
private _refreshMenu;
|
|
114
|
+
/**
|
|
115
|
+
* 定位:**触屏长按与鼠标右键共用这一条 Floating UI 路径**。
|
|
116
|
+
*
|
|
117
|
+
* 两条入口现在只差「触发点的 x/y 从哪来」,布局契约完全一致:
|
|
118
|
+
* `bottom-start` 表达「面板上缘 == 触发点 y、向下展开」,水平以触发点 x 为基准。
|
|
119
|
+
* 之前有一条手写的贴底分支(先按点、再按视口下缘算 `top`),那是把「贴视口底」硬编码
|
|
120
|
+
* 成算术;真机反馈证明它错(菜单跑到屏幕最底部,与手指按下的位置完全脱节)。现在
|
|
121
|
+
* 落点交给 `flip` / `shift` 按**实际空间**决定,`placement` 只表达意图。
|
|
122
|
+
*
|
|
123
|
+
* 不再按「是否触屏」分流:窄视口的鼠标右键同样期望菜单贴着光标出现,按输入类型或视口
|
|
124
|
+
* 宽度分流会让同一块屏幕上的两种输入拿到两套布局。分流所需的 `_anchorAtPressPoint`
|
|
125
|
+
* 连同 `_positionMenuInViewport` / `_positionMenuAtPressPoint` 两个方法一起删掉 ——
|
|
126
|
+
* 面板恒为 open scrim `<dialog>` 的直接子节点(`createMenuPortalOverlay` 第三参传入
|
|
127
|
+
* scrim,`menu-portal.ts` 里 `container = scrim ?? …`),所以旧代码那条
|
|
128
|
+
* 「非 dialog 容器」的分支对 context-menu 本来就不可达。
|
|
129
|
+
*
|
|
130
|
+
* 算出来的 left/top 是**视口坐标**。面板是 `position: fixed`,而 scrim 刻意不带
|
|
131
|
+
* transform / filter / contain(见 style.css),因此不构成 fixed 的包含块 ——
|
|
132
|
+
* 坐标直接相对视口解析。这条等价关系由 style.css 的满屏声明保证,并由 R6 的
|
|
133
|
+
* 「scrim 无 transform/filter/contain」+ viewport-fit 的几何断言兜底。
|
|
134
|
+
*/
|
|
54
135
|
private _positionMenu;
|
|
55
|
-
|
|
136
|
+
/**
|
|
137
|
+
* 视口下缘的安全区高度(px)。
|
|
138
|
+
*
|
|
139
|
+
* 改按压点展开之后它**仍然必需**,而且不再只服务触屏:菜单默认从触发点向下长,触发点
|
|
140
|
+
* 落在屏幕下半部时面板下缘会进入 home indicator 区域。它现在折进 flip 与 shift 共用的
|
|
141
|
+
* 边界 padding(见 `_positionMenu`),不再需要单独一条 `maxBottom` 算术。
|
|
142
|
+
*
|
|
143
|
+
* 读宿主的自定义属性而不是 `env()`:自定义属性读回的是**计算后**的解析值,
|
|
144
|
+
* 而 `env()` 在 JS 里没有对应的求值入口,只能间接经由声明它的属性取。
|
|
145
|
+
* 属性未解析时 `parseFloat` 得 NaN,落到 0 —— 与 `env(..., 0px)` 的缺省一致。
|
|
146
|
+
*/
|
|
147
|
+
private _safeAreaBottom;
|
|
148
|
+
/**
|
|
149
|
+
* 写下面板坐标与进场 transform 的原点。
|
|
150
|
+
*
|
|
151
|
+
* 两个 origin 必传且**不**再回退成坐标比较:flip 会改变垂直方向,回退表达式
|
|
152
|
+
* `y < this._y ? 'bottom' : 'top'` 在「面板顶边与触发点重合」时两边都成立,等于随机取。
|
|
153
|
+
* 唯一调用方从 flip 后的 placement 与 shift 位移推出真实侧边,见 `_positionMenu`。
|
|
154
|
+
*/
|
|
56
155
|
private _applyMenuPosition;
|
|
156
|
+
/**
|
|
157
|
+
* 把焦点带进菜单的第一项。
|
|
158
|
+
*
|
|
159
|
+
* `attempt` 是重试计数:菜单项是刚被 `reconcileManagedMenuItems` 搬进来的自定义元素,
|
|
160
|
+
* 它们的 shadow(`.item-inner`)由各自的 Lit 更新**异步**渲染。`focusMenuItem()` 委托给
|
|
161
|
+
* 项的 `focusItem()`,那一刻 `.item-inner` 还不存在,于是**静默无操作** —— 不抛错、
|
|
162
|
+
* 也不留痕,只表现为「菜单开了但焦点没进去」。
|
|
163
|
+
*
|
|
164
|
+
* 所以这里不假设一次成功:调用后用 `findFocusedMenuItem` 复核,没落上就在下一帧再试,
|
|
165
|
+
* 最多 `FOCUS_FIRST_ITEM_ATTEMPTS` 次。上界是必要的 —— 菜单项若始终渲染不出来
|
|
166
|
+
* (空菜单、内容被外部换掉),不能让重试链一直跑下去。
|
|
167
|
+
*/
|
|
57
168
|
private _focusFirstItem;
|
|
58
169
|
private _setupMenuItems;
|
|
59
170
|
private _returnItemsToSlot;
|
|
171
|
+
/**
|
|
172
|
+
* 建 scrim 并让它进入模态态,返回容器供面板挂载。
|
|
173
|
+
*
|
|
174
|
+
* 每次开启都新建而不是复用:scrim 的生命周期必须与「这一次开启」严格同进同出。
|
|
175
|
+
* 复用一个 dialog 意味着上一轮的 `close()` 事件、`open` 属性与 UA 记下的焦点还原目标
|
|
176
|
+
* 会跨会话残留,而这些都不是本组件能重置的。
|
|
177
|
+
*/
|
|
178
|
+
private _openScrim;
|
|
179
|
+
/**
|
|
180
|
+
* scrim 的挂载点:**与面板在没有 scrim 时会落到的容器同源** —— 最近主题的 theme-owned
|
|
181
|
+
* overlay root。scrim 就是那个容器的替身(面板必须挂进 scrim,见 `updated()` 的顺序注释),
|
|
182
|
+
* 所以它得站在容器该站的位置上。
|
|
183
|
+
*
|
|
184
|
+
* 为什么不能在整棵 DOM 里随便挑位置:`--wui-color-*` 由 `<web-ui-theme>` 写在自己的 `:host`
|
|
185
|
+
* 上,只沿 DOM 树向下继承。scrim 若挂到 `document.body`,而 `<web-ui-theme>` 是 body 的**子节点**,
|
|
186
|
+
* 这条继承链就断了 —— 面板与 scrim 双双落回 `var(--wui-color-*, <浅色字面量>)` 的 fallback,
|
|
187
|
+
* 深色外观下菜单是一块浅色玻璃(app 侧的 `dark:` 变体也够不到它)。挂进 theme overlay root
|
|
188
|
+
* 之后,面板与 scrim 跟 dropdown / select 一样吃同一份 token。
|
|
189
|
+
*
|
|
190
|
+
* 无主题时保持历史行为挂在 `document.body`:那条路径本来就没有 token 作用域可继承,改用
|
|
191
|
+
* fallback overlay root 只会改变既有测试与消费者的观察面,不换来任何东西。
|
|
192
|
+
*/
|
|
193
|
+
private _scrimParent;
|
|
194
|
+
/**
|
|
195
|
+
* 关掉并摘除 scrim。幂等:关闭分支与 `disconnectedCallback` 都会调。
|
|
196
|
+
*
|
|
197
|
+
* `close()` 触发 UA 的焦点归还,**必须先于面板 `remove()`** —— 理由见 `_closeMenuAfterPresence`。
|
|
198
|
+
*/
|
|
199
|
+
private _closeScrim;
|
|
200
|
+
/**
|
|
201
|
+
* 只让 scrim 出顶层,不摘除元素。面板挂在 scrim 里,摘了就把退场动画一起摘掉。
|
|
202
|
+
*
|
|
203
|
+
* 提前出顶层是为了焦点(理由见 `close()`)。代价是这个尾巴上 scrim 已经在 top layer
|
|
204
|
+
* 之外:下层恢复可命中,且面板的层级退回普通流 —— 在「菜单开在 drawer/dialog 之上」
|
|
205
|
+
* 的场景里,退场动画会被下层的 top layer 盖住。
|
|
206
|
+
*
|
|
207
|
+
* 这条尾巴只有一次退场过渡的时长(默认 160ms),且只发生在菜单项激活时。
|
|
208
|
+
* 摘除仍在 `_closeScrim()`,那时面板已经走完。
|
|
209
|
+
*/
|
|
210
|
+
private _releaseScrimModality;
|
|
211
|
+
/**
|
|
212
|
+
* 点 scrim = 关菜单(Q12:必关,不给 prop 选项),与 dialog / drawer 的实现同形:
|
|
213
|
+
* 只有落点就是 scrim 本身才算「点外面」,落在面板(scrim 的后代)上不算。
|
|
214
|
+
*
|
|
215
|
+
* 落点判据之所以只能是这两个,是模态给的:菜单打开期间下层收不到命中,事件只可能
|
|
216
|
+
* 落在 scrim 或面板上,两者都由本组件判定。
|
|
217
|
+
*
|
|
218
|
+
* 更早的实现在 document 捕获阶段挂 click 监听,把「点外面」理解成「命中测试落在菜单
|
|
219
|
+
* 面板之外」—— 宿主 light DOM 的每一行都满足这个条件,于是判定与行激活成了同一个
|
|
220
|
+
* click 的两个后果,中间没有任何仲裁,下层目标先被激活。那条监听器连同它的实现已一并
|
|
221
|
+
* 删除:模态化之后它没有任何还能生效的场景,别再挂回来。
|
|
222
|
+
*/
|
|
223
|
+
private _onScrimClick;
|
|
224
|
+
/**
|
|
225
|
+
* Escape 的**唯一**关闭路径仍是共享仲裁者(`_overlay.requestClose` → `closeDeepestOrAll`),
|
|
226
|
+
* 它按层深决定是关最深子菜单还是关整张菜单。原生 dialog 自己也监听 Escape 并派发
|
|
227
|
+
* `cancel`,若放任默认行为,UA 会直接关掉 scrim —— 那条路径不经过组件状态机,
|
|
228
|
+
* 既可能漏派 `open-change`,也会把「关最深一层」的语义降级成「整张菜单没了」。
|
|
229
|
+
*
|
|
230
|
+
* 因此这里只吞掉默认行为,不重复关闭。仲裁者那条路径已经会走 `_closeFromUser()`。
|
|
231
|
+
*/
|
|
232
|
+
private _onScrimCancel;
|
|
60
233
|
private _closeMenuAfterPresence;
|
|
61
234
|
private _hideMenuItems;
|
|
62
235
|
private _openSubmenu;
|
|
@@ -65,10 +238,16 @@ export declare class WebUiContextMenu extends LitElement {
|
|
|
65
238
|
private _getItemLevel;
|
|
66
239
|
private _positionSubmenu;
|
|
67
240
|
private _dispatchChange;
|
|
241
|
+
private _onPointerDown;
|
|
242
|
+
private _onPointerMove;
|
|
243
|
+
private _onPointerUp;
|
|
244
|
+
private _onPointerCancel;
|
|
245
|
+
private _cancelLongPress;
|
|
246
|
+
/** 该事件是否是长按开菜单之后、浏览器为同一次触摸补发的事件。 */
|
|
247
|
+
private _isLongPressFollowUp;
|
|
68
248
|
private _onContextMenu;
|
|
69
249
|
private _onContextMenuOutside;
|
|
70
250
|
private _onKeydown;
|
|
71
|
-
private _onClickOutside;
|
|
72
251
|
private _onMenuClick;
|
|
73
252
|
private _getLevelContainer;
|
|
74
253
|
private _getLevelItems;
|