@greypan/web-ui 8.1.0 → 9.0.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 +246 -133
- package/README.md +246 -133
- 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/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 +167 -3
- package/dist/components/context-menu/index.js +162 -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 +61 -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 +116 -52
- 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 +9 -2
- 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.js +23 -23
- 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 +0 -3
- package/dist/components/layout/index.js +1 -1
- 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/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/shared/element-height/index.js +47 -0
- package/dist/shared/element-height/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 +6 -4
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/components/dialog/style.css?inline
|
|
2
|
-
var e = "*,:before,:after{box-sizing:border-box}:host{display:contents}dialog{transform:scale(var(--wui-dialog-scale-enter,1.1));box-sizing:border-box;width:min(90vw, var(--wui-dialog-width,360px));max-height:
|
|
2
|
+
var e = "*,:before,:after{box-sizing:border-box}:host{display:contents}dialog{transform:scale(var(--wui-dialog-scale-enter,1.1));box-sizing:border-box;width:min(90vw, var(--wui-dialog-width,360px));max-height:100vh;color:var(--wui-color-text,#1b1b1b);transition:transform var(--wui-duration-dialog-enter,.32s) var(--wui-ease-dialog,cubic-bezier(.2, 0, 0, 1));background:0 0;border:none;padding:0;font-family:inherit;position:fixed;overflow:visible}dialog::backdrop{opacity:0;background:var(--wui-dialog-overlay-bg,var(--wui-color-backdrop,#0000001f));transition:opacity var(--wui-duration-dialog-enter,.32s) var(--wui-ease-dialog,cubic-bezier(.2, 0, 0, 1))}@supports (height:100dvh){dialog{max-height:100dvh}}dialog:has(.desc){flex-direction:column;display:flex}dialog:focus,dialog:focus-visible{outline:none}dialog[open].is-visible{transform:scale(1)}dialog[open].is-closing{pointer-events:none;transition-duration:var(--wui-duration-dialog-exit,.26s)}dialog.is-closing::backdrop{transition-duration:var(--wui-duration-dialog-exit,.26s)}dialog[open].is-visible::backdrop{opacity:1}@media (prefers-reduced-motion:reduce){dialog,dialog[open].is-visible{transition-duration:var(--wui-duration-feedback,.1s);transform:none}}.wui-dialog-body{--wui-internal-glass-shadow:var(--wui-shadow-overlay,2px 16px 40px #0006);--wui-glass-corner-radius:var(--wui-radius-overlay,28px);padding:var(--wui-dialog-padding,var(--wui-space-5,20px) var(--wui-space-6,24px) var(--wui-space-6,24px));border-radius:var(--wui-radius-overlay,28px);opacity:0;background-color:var(--wui-dialog-bg,var(--wui-color-surface-overlay,#f8f8f8eb));-webkit-backdrop-filter:blur(0) saturate(160%) brightness(var(--wui-glass-brightness,1.06));backdrop-filter:blur(0) saturate(160%) brightness(var(--wui-glass-brightness,1.06));transition:opacity var(--wui-duration-dialog-enter,.32s) var(--wui-ease-dialog,cubic-bezier(.2, 0, 0, 1)), -webkit-backdrop-filter var(--wui-duration-dialog-enter,.32s) var(--wui-ease-dialog,cubic-bezier(.2, 0, 0, 1)), backdrop-filter var(--wui-duration-dialog-enter,.32s) var(--wui-ease-dialog,cubic-bezier(.2, 0, 0, 1))}.wui-dialog-body:has(.desc){grid-template-rows:auto minmax(0,1fr) auto;min-height:0;display:grid}dialog.is-closing .wui-dialog-body{transition-duration:var(--wui-duration-dialog-exit,.26s)}:host([closable]) .wui-dialog-body{position:relative}dialog[open].is-visible .wui-dialog-body{opacity:1;-webkit-backdrop-filter:blur(4px) saturate(160%) brightness(var(--wui-glass-brightness,1.06));backdrop-filter:blur(4px) saturate(160%) brightness(var(--wui-glass-brightness,1.06))}.wui-dialog-close-inline{flex:none}.wui-dialog-close-floating{z-index:3;top:var(--wui-dialog-close-top,var(--wui-space-4,16px));right:var(--wui-dialog-close-right,16px);position:absolute}.title-row{gap:var(--wui-space-3,12px);justify-content:space-between;align-items:flex-start;display:flex}@media (prefers-reduced-motion:reduce){dialog.is-closing .wui-dialog-body,dialog[open].is-visible .wui-dialog-body{transition-duration:var(--wui-duration-feedback,.1s)}}.title{margin:0 0 var(--wui-dialog-title-gap,var(--wui-space-4,16px));font-size:var(--wui-font-size-title,18px);font-weight:var(--wui-font-weight-semibold,600);line-height:var(--wui-line-height-tight,1.2);color:var(--wui-color-text,#1b1b1b);padding:0}.desc{min-height:0;max-height:calc(var(--wui-dialog-max-height,90vh) + var(--wui-dialog-desc-focus-padding,6px) * 2);margin-top:calc(-1 * var(--wui-dialog-desc-focus-padding,6px));margin-bottom:max(0px, calc(var(--wui-dialog-desc-gap,var(--wui-space-6,24px)) - var(--wui-dialog-desc-focus-padding,6px)));margin-inline:calc(-1 * var(--wui-dialog-desc-focus-padding,6px));padding-block:var(--wui-dialog-desc-focus-padding,6px);padding-inline:var(--wui-dialog-desc-focus-padding,6px);font-size:var(--wui-font-size,14px);line-height:var(--wui-line-height-normal,1.5);color:var(--wui-color-text,#1b1b1b);overflow:clip auto}@supports (height:100dvh){.desc{max-height:calc(var(--wui-dialog-max-height,min(90vh, 90dvh)) + var(--wui-dialog-desc-focus-padding,6px) * 2)}}.wui-dialog-footer{gap:var(--wui-dialog-footer-gap,10px);justify-content:var(--wui-dialog-footer-justify,flex-end);flex-direction:column;display:flex}.wui-dialog-footer ::slotted(web-ui-button){width:100%;display:flex}:host([horizontal]) .wui-dialog-footer{gap:var(--wui-space-3,12px);justify-content:var(--wui-dialog-footer-justify,center);flex-direction:row}:host([horizontal]) .wui-dialog-footer ::slotted(web-ui-button:not([full])){width:auto}:host([horizontal]) .wui-dialog-footer ::slotted(web-ui-button[full]){flex:1;min-width:0}";
|
|
3
3
|
//#endregion
|
|
4
4
|
export { e as default };
|
|
5
5
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/dialog/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n display: contents;\n}\n\ndialog {\n /* 必须显式 position: fixed:UA 的 dialog:modal 默认就是 fixed,但作者样式若出现\n position: relative(本轮单层重构曾引入)会把它覆盖回文档流——top layer 里的\n modal dialog 变成按文档流定位:渲染在页面顶部(用户看到的“残影”)且跟随页面\n 滚动(“没有固定居中”)。显式写死 fixed 防御未来任何作者类再覆盖。 */\n position: fixed;\n\n /* 本元素不参与 opacity 过渡:opacity < 1 会让 dialog 成为 backdrop root,后代\n backdrop-filter 在该过渡期间被整体禁用。玻璃卡片(.wui-dialog-body)自身\n opacity + backdrop-filter 插值过渡(own opacity 不禁用自身 blur,见下)。 */\n\n /* 进场由大到小收缩(1.1 → 1),退场反向。取消 .is-visible 后回落到本条起点值,\n enter/exit 共用同一 token。方向与浮动面板的 --wui-scale-enter 相反,故单独成 token。 */\n transform: scale(var(--wui-dialog-scale-enter, 1.1));\n\n overflow: visible;\n\n box-sizing: border-box;\n width: min(90vw, var(--wui-dialog-width, 360px));\n max-height: 90vh;\n max-height: min(90vh, 90dvh);\n padding: 0;\n border: none;\n\n font-family: inherit;\n color: var(--wui-color-text, #1b1b1b);\n\n background: transparent;\n\n transition: transform var(--wui-duration-dialog-enter, 320ms) var(--wui-ease-dialog, cubic-bezier(0.2, 0, 0, 1));\n\n &::backdrop {\n opacity: 0;\n background: var(--wui-dialog-overlay-bg, var(--wui-color-backdrop, rgb(0 0 0 / 0.12)));\n\n /* 与卡片共用同一条 dialog 缓动:用内置 ease 会让遮罩在卡片落位后才走完大半透明度。 */\n transition: opacity var(--wui-duration-dialog-enter, 320ms) var(--wui-ease-dialog, cubic-bezier(0.2, 0, 0, 1));\n }\n}\n\n/* 面板本身是模态表面,不作为可聚焦控件;Safari showModal() 会把焦点放到 dialog,不应画 UA ring。内部控件保留 focus ring。 */\ndialog:focus,\ndialog:focus-visible {\n outline: none;\n}\n\ndialog[open].is-visible {\n transform: scale(1);\n}\n\ndialog[open].is-closing {\n pointer-events: none;\n transition-duration: var(--wui-duration-dialog-exit, 260ms);\n}\n\ndialog.is-closing::backdrop {\n transition-duration: var(--wui-duration-dialog-exit, 260ms);\n}\n\ndialog[open].is-visible::backdrop {\n opacity: 1;\n}\n\n@media (prefers-reduced-motion: reduce) {\n dialog,\n dialog[open].is-visible {\n transform: none;\n transition-duration: var(--wui-duration-feedback, 100ms);\n }\n}\n\n/* ===== 玻璃卡片主体(样式由 glass.css 提供) ===== */\n\n/* 单层玻璃:卡片自身承担背景/阴影/backdrop-filter。blur(0px) ↔ blur(4px) 平滑插值\n (none↔blur 不可插值才是当年生硬跳变的根因),own opacity 过渡不禁用自身 blur,\n 因此卡片直接 opacity + backdrop-filter 同步过渡即可,无需双层。 */\n.wui-dialog-body {\n --wui-internal-glass-shadow: var(--wui-shadow-overlay, 2px 16px 40px rgb(0 0 0 / 0.4));\n --wui-glass-corner-radius: var(--wui-radius-overlay, 28px);\n padding: var(--wui-dialog-padding, 20px 24px 24px);\n border-radius: var(--wui-radius-overlay, 28px);\n\n opacity: 0;\n background-color: var(--wui-dialog-bg, var(--wui-color-surface-overlay, rgb(246 246 246 / 0.82)));\n backdrop-filter: blur(0) saturate(160%) brightness(var(--wui-glass-brightness, 1.06));\n\n /* transition 列表需手写 -webkit-backdrop-filter:lightningcss 不会在 transition\n 的 value 内追加 -webkit 项,而 iOS 16.4 上 blur 过渡依赖它(属性前缀会自动生成)。 */\n transition:\n opacity var(--wui-duration-dialog-enter, 320ms) var(--wui-ease-dialog, cubic-bezier(0.2, 0, 0, 1)),\n -webkit-backdrop-filter var(--wui-duration-dialog-enter, 320ms) var(--wui-ease-dialog, cubic-bezier(0.2, 0, 0, 1)),\n backdrop-filter var(--wui-duration-dialog-enter, 320ms) var(--wui-ease-dialog, cubic-bezier(0.2, 0, 0, 1));\n}\n\ndialog.is-closing .wui-dialog-body {\n transition-duration: var(--wui-duration-dialog-exit, 260ms);\n}\n\ndialog[open].is-visible .wui-dialog-body {\n opacity: 1;\n backdrop-filter: blur(4px) saturate(160%) brightness(var(--wui-glass-brightness, 1.06));\n}\n\n@media (prefers-reduced-motion: reduce) {\n dialog.is-closing .wui-dialog-body,\n dialog[open].is-visible .wui-dialog-body {\n transition-duration: var(--wui-duration-feedback, 100ms);\n }\n}\n\n.title {\n margin: 0 0 var(--wui-dialog-title-gap, 16px);\n padding: 0;\n\n font-size: 18px;\n font-weight: 600;\n line-height: 1.2;\n color: var(--wui-color-text, #1b1b1b);\n}\n\n.desc {\n margin: 0 0 var(--wui-dialog-desc-gap, 24px);\n padding: 0;\n\n font-size: 14px;\n line-height: 1.5;\n color: var(--wui-color-text, #1b1b1b);\n}\n\n.wui-dialog-footer {\n display: flex;\n flex-direction: column;\n gap: var(--wui-dialog-footer-gap, 10px);\n justify-content: var(--wui-dialog-footer-justify, flex-end);\n\n & ::slotted(web-ui-button) {\n display: flex;\n width: 100%;\n }\n}\n\n:host([horizontal]) .wui-dialog-footer {\n flex-direction: row;\n gap: 12px;\n justify-content: var(--wui-dialog-footer-justify, center);\n\n & ::slotted(web-ui-button:not([full])) {\n width: auto;\n }\n\n & ::slotted(web-ui-button[full]) {\n flex: 1;\n min-width: 0;\n }\n}\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/dialog/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n display: contents;\n}\n\ndialog {\n /* 必须显式 position: fixed:UA 的 dialog:modal 默认就是 fixed,但作者样式若出现\n position: relative(本轮单层重构曾引入)会把它覆盖回文档流——top layer 里的\n modal dialog 变成按文档流定位:渲染在页面顶部(用户看到的“残影”)且跟随页面\n 滚动(“没有固定居中”)。显式写死 fixed 防御未来任何作者类再覆盖。 */\n position: fixed;\n\n /* 本元素不参与 opacity 过渡:opacity < 1 会让 dialog 成为 backdrop root,后代\n backdrop-filter 在该过渡期间被整体禁用。玻璃卡片(.wui-dialog-body)自身\n opacity + backdrop-filter 插值过渡(own opacity 不禁用自身 blur,见下)。 */\n\n /* 进场由大到小收缩(1.1 → 1),退场反向。取消 .is-visible 后回落到本条起点值,\n enter/exit 共用同一 token。方向与浮动面板的 --wui-scale-enter 相反,故单独成 token。 */\n transform: scale(var(--wui-dialog-scale-enter, 1.1));\n\n overflow: visible;\n\n box-sizing: border-box;\n width: min(90vw, var(--wui-dialog-width, 360px));\n\n /* 整卡兜底:防卡片高过视口。真正的内容区上限在 .desc(见下),这里只接住\n 「视口本身很矮、chrome + 内容区上限也放不下」的情况。字面量而非 token,\n 免得与 .desc 抢同一个数值——共用时外层必然先触发(它是整卡约束),\n .desc 的 max-height 就成了永远轮不到的死约束。dvh 增强见文件末尾。 */\n max-height: 100vh;\n padding: 0;\n border: none;\n\n font-family: inherit;\n color: var(--wui-color-text, #1b1b1b);\n\n background: transparent;\n\n transition: transform var(--wui-duration-dialog-enter, 320ms) var(--wui-ease-dialog, cubic-bezier(0.2, 0, 0, 1));\n\n &::backdrop {\n opacity: 0;\n background: var(--wui-dialog-overlay-bg, var(--wui-color-backdrop, rgb(0 0 0 / 0.12)));\n\n /* 与卡片共用同一条 dialog 缓动:用内置 ease 会让遮罩在卡片落位后才走完大半透明度。 */\n transition: opacity var(--wui-duration-dialog-enter, 320ms) var(--wui-ease-dialog, cubic-bezier(0.2, 0, 0, 1));\n }\n}\n\n/* 动态视口高度兜底:移动端工具栏收放时不让 dialog 超出可见区域。\n 放在 @supports 内而非与上一条并列,是因为 var() 的回退值要到计算值阶段才替换;\n 不支持 dvh 的引擎会在该阶段拿到非法值,使整条声明变成 invalid-at-computed-value-time\n 而丢失 max-height。并列两条普通声明则由解析期丢弃,行为不同。dialog 这条是字面量,\n 并列也不会丢,但统一放在 @supports 内,免得两条规则看起来像两种不同的兜底策略。\n\n `.desc` 的 dvh 增强不在这里:它必须排在文件后面那条 `.desc` 规则之后才生效,\n 同特异度下靠后者胜。放在这里会被后面那条的 `90vh` 回退静默覆盖。 */\n@supports (height: 100dvh) {\n dialog {\n max-height: 100dvh;\n }\n}\n\n/* ===== 高度约束下移到内容区(chrome 由内容撑开) =====\n\n 宿主过去必须复述一个会变的 chrome 高度:AddDialog / RestoreDialog 都写\n `height: min(calc(82vh - 108px), calc(var(--wui-dialog-max-height, 560px) - 108px))`\n (改动前的写法,见 base b6b7eb34;这两处宿主已按新语义转换),\n 而那 108 里的 footer 一项就是 --wui-control-size——触摸端\n `@media (pointer: coarse)` 把它从 36px 抬到 40px,chrome 随之长高,宿主的常数立刻腐坏。\n\n 现在 header / footer 完全由内容撑开,上限只落在 .desc。修掉的是「宿主必须知道 chrome\n 才能让内容区滚起来」:改动前 .desc 既没有上限也没有 overflow,内容超高时直接把卡片\n 顶出 dialog 盒子,唯一能滚的地方是宿主自己用 `min(calc(82vh - 108px), …)` 之类的\n 内层 height 撑出来的那一块。现在上限与滚动都归 .desc,宿主不必再为「让它滚」而算。\n\n 但「宿主不再需要知道 chrome 多高」并不成立,改成这样写会误导后人。--wui-dialog-max-height\n 的语义是**内容区**上限:宿主若要给整卡定上限,仍然得自己量出 chrome 再从 token 里减掉\n (AddDialog / RestoreDialog 减 142,SettingsDialog 减 106,三处不能互相照抄)。把整卡\n 上限原样写进 token,卡片会比预期高出一个 chrome。\n\n 实测(Chromium + WebKit,见 __tests__/dialog-content-height.browser.spec.ts):本组 CSS\n 只对 **title 模式**生效——body 模式(走 slot=\"body\"、没有 .desc)的**卡片尺寸**不变。\n 但位置不保证:`dialog` 的整卡兜底从 min(90vh, 90dvh) 收紧到字面量 100vh,modal dialog\n 按自身盒子在视口里居中、卡片从盒子顶部起画,盒子更高 → 卡片在视口内上移。内容接近视口\n 高度时位移可观测(reviewer 实测 52px / 102px / 25.16px),只有内容远矮于视口时位移为 0\n (两个 demo 正是落在这一档,巧合而非保证)。 */\n\n/* dialog 不是 flex 容器时 .desc 的 height:100% 拿不到确定高度(:host 是 display:contents,\n dialog 自身默认 block),宿主的内层 grid 因此撑不满、两栏不等高。 */\ndialog:has(.desc) {\n display: flex;\n flex-direction: column;\n}\n\n/* 面板本身是模态表面,不作为可聚焦控件;Safari showModal() 会把焦点放到 dialog,不应画 UA ring。内部控件保留 focus ring。 */\ndialog:focus,\ndialog:focus-visible {\n outline: none;\n}\n\ndialog[open].is-visible {\n transform: scale(1);\n}\n\ndialog[open].is-closing {\n pointer-events: none;\n transition-duration: var(--wui-duration-dialog-exit, 260ms);\n}\n\ndialog.is-closing::backdrop {\n transition-duration: var(--wui-duration-dialog-exit, 260ms);\n}\n\ndialog[open].is-visible::backdrop {\n opacity: 1;\n}\n\n@media (prefers-reduced-motion: reduce) {\n dialog,\n dialog[open].is-visible {\n transform: none;\n transition-duration: var(--wui-duration-feedback, 100ms);\n }\n}\n\n/* ===== 玻璃卡片主体(样式由 glass.css 提供) ===== */\n\n/* 单层玻璃:卡片自身承担背景/阴影/backdrop-filter。blur(0px) ↔ blur(4px) 平滑插值\n (none↔blur 不可插值才是当年生硬跳变的根因),own opacity 过渡不禁用自身 blur,\n 因此卡片直接 opacity + backdrop-filter 同步过渡即可,无需双层。 */\n.wui-dialog-body {\n --wui-internal-glass-shadow: var(--wui-shadow-overlay, 2px 16px 40px rgb(0 0 0 / 0.4));\n --wui-glass-corner-radius: var(--wui-radius-overlay, 28px);\n padding: var(--wui-dialog-padding, var(--wui-space-5, 20px) var(--wui-space-6, 24px) var(--wui-space-6, 24px));\n border-radius: var(--wui-radius-overlay, 28px);\n\n opacity: 0;\n background-color: var(--wui-dialog-bg, var(--wui-color-surface-overlay, rgb(248 248 248 / 0.92)));\n backdrop-filter: blur(0) saturate(160%) brightness(var(--wui-glass-brightness, 1.06));\n\n /* transition 列表需手写 -webkit-backdrop-filter:lightningcss 不会在 transition\n 的 value 内追加 -webkit 项,而 iOS 16.4 上 blur 过渡依赖它(属性前缀会自动生成)。 */\n transition:\n opacity var(--wui-duration-dialog-enter, 320ms) var(--wui-ease-dialog, cubic-bezier(0.2, 0, 0, 1)),\n -webkit-backdrop-filter var(--wui-duration-dialog-enter, 320ms) var(--wui-ease-dialog, cubic-bezier(0.2, 0, 0, 1)),\n backdrop-filter var(--wui-duration-dialog-enter, 320ms) var(--wui-ease-dialog, cubic-bezier(0.2, 0, 0, 1));\n}\n\n/* 卡片改 grid 容器:title 与 footer 走 auto(内容撑开),.desc 走 minmax(0,1fr)。\n minmax 的 0 是 .desc 能收缩的前提;配合 .desc 的 min-height:0 与 overflow-y:auto,\n 内容超高时滚动发生在内容区内部,而不是把卡片顶出 dialog 盒子。\n\n 单列而非与基础 .wui-dialog-body 合并:`:has()` 的特异度高于类选择器,合并会让\n 「仅 title 模式变 grid」变成「所有模式都变 grid」,那会改掉 body 模式的几何\n (实测高内容 body 的卡片会从 3044 被夹到 896)。位置也受 stylelint\n no-descending-specificity 约束:须排在基础规则之后、dialog.is-closing 之前。 */\n.wui-dialog-body:has(.desc) {\n display: grid;\n grid-template-rows: auto minmax(0, 1fr) auto;\n\n /* 这条 min-height: 0 是承重的(`.desc` 那条不是):卡片是 `dialog` 这个 column flex\n 容器的 flex 项,`min-height: auto` 会把它垫到内容高度,视口的 100dvh 兜底就再也\n 夹不住。删掉后 token=5000px 时卡片实测 3154、dialog 896。 */\n min-height: 0;\n}\n\ndialog.is-closing .wui-dialog-body {\n transition-duration: var(--wui-duration-dialog-exit, 260ms);\n}\n\n:host([closable]) .wui-dialog-body {\n /*\n * body 模式的关闭按钮浮在卡片右上角,需要一个定位参照,所以显式重述一次\n * position: relative。\n *\n * 实际提供这个上下文的是卡片自带的 .wui-glass(glass.css 的 .wui-glass 已有\n * position: relative),所以这条声明目前是冗余的,写在这里是为了不依赖\n * glass.css 的内部实现——若哪天 glass 改成非定位元素,这条仍然兜得住。\n * 它不是本轮为 closable 建立的包含块边界:body 上的 wui-glass class 与\n * static styles 里的 glass 都早于本轮存在。\n */\n position: relative;\n}\n\ndialog[open].is-visible .wui-dialog-body {\n opacity: 1;\n backdrop-filter: blur(4px) saturate(160%) brightness(var(--wui-glass-brightness, 1.06));\n}\n\n/* inline:.title-row 的 flex 子项,与标题同行。 */\n.wui-dialog-close-inline {\n flex: none;\n}\n\n/* floating:body 模式下浮在卡片右上角。 */\n.wui-dialog-close-floating {\n position: absolute;\n z-index: 3;\n top: var(--wui-dialog-close-top, var(--wui-space-4, 16px));\n right: var(--wui-dialog-close-right, 16px);\n}\n\n/*\n * 标题行只在 closable 时出现,因此 .title 自身的 margin-bottom 语义不变:\n * 它仍由 .title-row 的行高承担,行高 = 标题外高(含 16px 下边距)。\n */\n.title-row {\n display: flex;\n gap: var(--wui-space-3, 12px);\n align-items: flex-start;\n justify-content: space-between;\n}\n\n@media (prefers-reduced-motion: reduce) {\n dialog.is-closing .wui-dialog-body,\n dialog[open].is-visible .wui-dialog-body {\n transition-duration: var(--wui-duration-feedback, 100ms);\n }\n}\n\n.title {\n margin: 0 0 var(--wui-dialog-title-gap, var(--wui-space-4, 16px));\n padding: 0;\n\n font-size: var(--wui-font-size-title, 18px);\n font-weight: var(--wui-font-weight-semibold, 600);\n line-height: var(--wui-line-height-tight, 1.2);\n color: var(--wui-color-text, #1b1b1b);\n}\n\n.desc {\n /* 横向显式 clip 而非留默认的 visible:一旦本轴成为滚动容器,另一轴的 visible 会被\n 计算成 auto,宿主内容横向溢出时就会多出一条不该出现的横向滚动条。\n Chromium / WebKit 实测:clip 与本规则下面的 auto 配对时计算值会降级成 hidden\n (仍可被脚本滚动)。Firefox ≥128 不做这个降级、保持 clip,但仓库的 browser-mode\n 项目只跑 chromium,这句未经本仓 CI 证实。两个引擎都不画横向滚动条,所以这里\n 只需要「不是 auto」;断言写成 not.toBe('auto') 而非 toBe('clip'),否则会在\n 降级的引擎上误报。 */\n overflow-x: clip;\n overflow-y: auto;\n\n /* 承重的是上面那条 `overflow-y: auto`:按 CSS Sizing 3,溢出轴不为 visible 的\n grid 项其自动最小尺寸就是 0,`.desc` 无需再显式归零(实测删掉本条测试仍全绿,\n 改成 `auto auto auto` 也一样)。这里保留是防御性的:哪天 `overflow-y` 被改回\n visible,显式归零仍在,minmax(0,1fr) 才不会被顶破。 */\n min-height: 0;\n\n /* 内容区上限 = token + ring 余量:token 语义是内容区高度,ring 不该从它里面扣。\n token 只挂在这里,不与 dialog 的 max-height 共用——共用时外层(整卡)必然先触发。 */\n max-height: calc(var(--wui-dialog-max-height, 90vh) + var(--wui-dialog-desc-focus-padding, 6px) * 2);\n\n /* ===== focus-ring 余量:四个轴一视同仁,成对负 margin 原样扣回 =====\n\n .desc 既是滚动容器又是裁剪盒(clip),贴在内容区任一沿的控件,其 ring\n (offset 2 + width 3 = 5px)会被 padding box 裁掉;留 6px 余 1px。少补任何一条轴,\n 那一侧的 ring 就会退化成 1px 残条——只补 `padding-block` 的那版,全宽控件的左右环\n 就是这样被裁掉的(改动前 `.desc` 没有 overflow,最近裁剪祖先是 NONE,所以这是本轮\n 新引入的裁剪,不是既有限制)。\n\n 四条 padding 各配一条等量负 margin,把这 12px×2 从外部间距里扣回去,border box\n 回到改动前的样子,content box 的宽/高也不变(负 margin 让盒子外扩,padding 原样\n 吃回去)。所以 title→内容、内容→footer、内容与卡片左右沿的视觉间距与改动前逐像素\n 相同,宿主内层 grid 的可用尺寸也不变——后者是横向余量最该守住的不变量,否则\n AddDialog 那种两栏 grid 的 drop zone 会换行(实测见\n __tests__/dialog-content-height.browser.spec.ts 的「focus-ring 余量覆盖四条轴」)。\n\n 取舍,是取舍不是疏漏:负 margin 让 `.desc` 的 border box 溢出滚动内容区,所以\n 底部那圈 ring 余量不随内容滚动——滚到最底时 footer 那一侧仍留得住 padding,而\n 内容末端到 `.desc` 下沿的 desc-gap 恒定,不跟着内容走。 */\n margin-top: calc(-1 * var(--wui-dialog-desc-focus-padding, 6px));\n\n /* margin-bottom 是「desc-gap 减去那对 padding-block」,两个都是公开 token:宿主把\n desc-gap 调到 focus-padding 以下就会算出负 margin(24/8 安全,4/2/0 会算出\n -2/-4/-6)。max() 兜住下界 0——那条路径下内容末端与 footer 会贴在一起,但盒模型\n 与 grid 行分配不进负值区间。\n\n 横向不需要同样的兜底:margin-inline 恒为 -focus-padding,没有第二个公开 token 参与\n 减法。它与卡片 inline padding(默认 24px)的关系是「focus-padding 不应超过该\n padding,否则 .desc 会横向溢出卡片」,由上面那段注释交代。 */\n margin-bottom: max(\n 0px,\n calc(var(--wui-dialog-desc-gap, var(--wui-space-6, 24px)) - var(--wui-dialog-desc-focus-padding, 6px))\n );\n margin-inline: calc(-1 * var(--wui-dialog-desc-focus-padding, 6px));\n padding-block: var(--wui-dialog-desc-focus-padding, 6px);\n padding-inline: var(--wui-dialog-desc-focus-padding, 6px);\n\n font-size: var(--wui-font-size, 14px);\n line-height: var(--wui-line-height-normal, 1.5);\n color: var(--wui-color-text, #1b1b1b);\n}\n\n/* `--wui-dialog-max-height` 是公开 token(README 有记录),语义是**内容区**高度。\n 默认值与整卡兜底同族(90vh / dvh),使未覆写的 dialog 视觉高度与改动前一致:\n 移动端 90vh 可能大于 90dvh(vh 取大视口高),少了 min() 内容区会探到工具栏下面。\n\n 必须紧跟在 `.desc` 之后而非文件开头的 @supports 块里:两者特异度相同(0,1,0),\n 靠后者胜。实测把本条挪到前面后,`.desc` 的计算值会退回 90vh。 */\n@supports (height: 100dvh) {\n .desc {\n max-height: calc(var(--wui-dialog-max-height, min(90vh, 90dvh)) + var(--wui-dialog-desc-focus-padding, 6px) * 2);\n }\n}\n\n.wui-dialog-footer {\n display: flex;\n flex-direction: column;\n gap: var(--wui-dialog-footer-gap, 10px);\n justify-content: var(--wui-dialog-footer-justify, flex-end);\n\n & ::slotted(web-ui-button) {\n display: flex;\n width: 100%;\n }\n}\n\n:host([horizontal]) .wui-dialog-footer {\n flex-direction: row;\n gap: var(--wui-space-3, 12px);\n justify-content: var(--wui-dialog-footer-justify, center);\n\n & ::slotted(web-ui-button:not([full])) {\n width: auto;\n }\n\n & ::slotted(web-ui-button[full]) {\n flex: 1;\n min-width: 0;\n }\n}\n"],"mappings":""}
|
|
@@ -37,6 +37,9 @@ export declare class WebUiDrawer extends LitElement {
|
|
|
37
37
|
private _hasHeaderSlot;
|
|
38
38
|
private _hasFooterSlot;
|
|
39
39
|
private readonly _userOpenChange;
|
|
40
|
+
private readonly _headerHeight;
|
|
41
|
+
private readonly _footerHeight;
|
|
42
|
+
private _setAvoidance;
|
|
40
43
|
private readonly _scrollLock;
|
|
41
44
|
private readonly _presence;
|
|
42
45
|
private readonly _nestedLayers;
|
|
@@ -63,6 +66,29 @@ export declare class WebUiDrawer extends LitElement {
|
|
|
63
66
|
private _isDragging;
|
|
64
67
|
private _syncDragInert;
|
|
65
68
|
private _cancelDragAwait;
|
|
69
|
+
/**
|
|
70
|
+
* 上下 placement 的 header / footer 自己接拖拽手势。
|
|
71
|
+
*
|
|
72
|
+
* 为什么不是「把热区铺到 header 上」:那样 header 里的控件会被透明命中层吞掉,
|
|
73
|
+
* 正是 A6 修掉的那条缺陷。这里改成事件层让开——控件照常收自己的事件,拖拽只在
|
|
74
|
+
* 「落点不是可点控件」时起手。
|
|
75
|
+
*
|
|
76
|
+
* 三道闸门任一不成立就不接管:
|
|
77
|
+
* 1. placement 必须是上下。左右 placement 的拖拽轴是 x,端头在竖边上,header
|
|
78
|
+
* 既不在可抓边缘上也不该起手(R4 的行为侧)。
|
|
79
|
+
* 2. 下层嵌套抽屉整套拖拽提示一起退场。热区与热边靠 CSS 的 pointer-events 退场,
|
|
80
|
+
* 事件层必须自己判同一条,否则 header 会成为唯一一条漏网的入口。
|
|
81
|
+
* 3. 落点路径里有可点控件就让开——控件优先于「这一块可拖」。
|
|
82
|
+
*/
|
|
83
|
+
private _handleSectionDragPointerDown;
|
|
84
|
+
/**
|
|
85
|
+
* 按下路径上是否出现可点控件。
|
|
86
|
+
*
|
|
87
|
+
* 走 composedPath 而不是 event.target:消费侧 slotted 控件与组件库自绘控件都各有
|
|
88
|
+
* shadow root,target 只给出最内层那个节点,沿 parentElement 上行会在 shadow 边界
|
|
89
|
+
* 断掉,控件自己那层反而看不见。
|
|
90
|
+
*/
|
|
91
|
+
private _isInteractivePath;
|
|
66
92
|
private _handleDragPointerDown;
|
|
67
93
|
private _trackSwipeCancel;
|
|
68
94
|
private _cancelActiveDrag;
|
|
@@ -81,6 +107,25 @@ export declare class WebUiDrawer extends LitElement {
|
|
|
81
107
|
disconnectedCallback(): void;
|
|
82
108
|
/** 「重挂载恢复」的调用方一半:模块刻意不观察 DOM 连接状态。 */
|
|
83
109
|
private _reclaimIfOpen;
|
|
110
|
+
/**
|
|
111
|
+
* 对账 header / footer slot 的有无,**只在真的变了时排一次更新**。
|
|
112
|
+
*
|
|
113
|
+
* 排更新是这条对账不可省的一半:`showHeader` 与 footer 的 `?hidden` 只在 render 里求值,
|
|
114
|
+
* 而 Lit 的 `connectedCallback` 只做 `enableUpdating(true)` 与 `setConnected(true)`,本身不排
|
|
115
|
+
* 更新。两条 slotchange 处理器也接不住这条路径——slotchange 只在**分配集合**变化时派发,
|
|
116
|
+
* 断连期间清空槽位内容时宿主节点本身没动,事件不触发(Chromium 实测)。
|
|
117
|
+
*
|
|
118
|
+
* 漏掉这一半的后果:断连前有 footer、重连时已清空的抽屉留下一节空的 footer。它在 style.css
|
|
119
|
+
* 的 padding 下仍有真实高度(实测 32px),于是底部一条点不动的死带,拖拽热区的让位量也照
|
|
120
|
+
* 它算而不归零。
|
|
121
|
+
*
|
|
122
|
+
* 判据取 light DOM 子节点而非 `slot.assignedNodes()`:首次连接时 shadow 尚未渲染,slot 元素
|
|
123
|
+
* 还不存在,那一侧会直接跳过(首次连接的 presence 由 `firstUpdated()` 与 slotchange 兜底);
|
|
124
|
+
* 这里要的正是重连对账——shadow root 跨断连保留,两侧都可用,但只有子节点扫描不依赖渲染
|
|
125
|
+
* 时序。「只在真变了才排」与两条 slotchange 处理器同一纪律,避免每次重连都多一次空渲染。
|
|
126
|
+
*/
|
|
127
|
+
private _resyncSlotPresence;
|
|
128
|
+
private _hasSlottedChild;
|
|
84
129
|
private _checkSlotContent;
|
|
85
130
|
private handleHeaderSlotChange;
|
|
86
131
|
private handleFooterSlotChange;
|
|
@@ -10,19 +10,46 @@ import { defineScrollLockLease as o } from "../../shared/scroll-lock/scroll-lock
|
|
|
10
10
|
import { prefersReducedMotion as s } from "../../shared/theme/reduced-motion.js";
|
|
11
11
|
import { UserChangeController as c } from "../../shared/events/user-change.js";
|
|
12
12
|
import { defineNativeDialogPresence as l } from "../../shared/overlay/native-dialog-presence.js";
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import p from "
|
|
17
|
-
import
|
|
18
|
-
import {
|
|
13
|
+
import { ElementHeightController as u } from "../../shared/element-height/index.js";
|
|
14
|
+
import { attachDragGesture as d } from "../../shared/gesture/drag-gesture.js";
|
|
15
|
+
import { dampOverscroll as f } from "../../shared/gesture/physics.js";
|
|
16
|
+
import { defineNestedDrawerLayers as p } from "../../shared/overlay/nested-drawer-layers.js";
|
|
17
|
+
import m from "./style.js";
|
|
18
|
+
import { LitElement as h, html as g, nothing as _, unsafeCSS as v } from "lit";
|
|
19
|
+
import { customElement as y, property as b } from "lit/decorators.js";
|
|
19
20
|
//#region src/components/drawer/index.ts
|
|
20
|
-
var
|
|
21
|
+
var x = [
|
|
21
22
|
"right",
|
|
22
23
|
"left",
|
|
23
24
|
"top",
|
|
24
25
|
"bottom"
|
|
25
|
-
],
|
|
26
|
+
], S = .5, C = 10, w = 500, T = 50, E = 10, D = 120, O = 10, k = [
|
|
27
|
+
"button",
|
|
28
|
+
"input",
|
|
29
|
+
"select",
|
|
30
|
+
"textarea",
|
|
31
|
+
"label",
|
|
32
|
+
"summary",
|
|
33
|
+
"a[href]",
|
|
34
|
+
"audio[controls]",
|
|
35
|
+
"video[controls]",
|
|
36
|
+
"[contenteditable]:not([contenteditable=\"false\"])",
|
|
37
|
+
"[tabindex]:not([tabindex=\"-1\"])",
|
|
38
|
+
"[role=\"button\"]",
|
|
39
|
+
"[role=\"link\"]",
|
|
40
|
+
"[role=\"checkbox\"]",
|
|
41
|
+
"[role=\"switch\"]",
|
|
42
|
+
"[role=\"radio\"]",
|
|
43
|
+
"[role=\"tab\"]",
|
|
44
|
+
"[role=\"menuitem\"]",
|
|
45
|
+
"[role=\"menuitemcheckbox\"]",
|
|
46
|
+
"[role=\"menuitemradio\"]",
|
|
47
|
+
"[role=\"option\"]",
|
|
48
|
+
"[role=\"textbox\"]",
|
|
49
|
+
"[role=\"combobox\"]",
|
|
50
|
+
"[role=\"slider\"]",
|
|
51
|
+
"[role=\"spinbutton\"]"
|
|
52
|
+
].join(","), A = 180, j = 420, M = "cubic-bezier(0.32, 0.72, 0, 1)", N = "cubic-bezier(0.22, 1.3, 0.36, 1)", P = 1, F = 80;
|
|
26
53
|
if (typeof CSS < "u" && "registerProperty" in CSS) {
|
|
27
54
|
try {
|
|
28
55
|
CSS.registerProperty({
|
|
@@ -40,6 +67,14 @@ if (typeof CSS < "u" && "registerProperty" in CSS) {
|
|
|
40
67
|
initialValue: "8px"
|
|
41
68
|
});
|
|
42
69
|
} catch {}
|
|
70
|
+
try {
|
|
71
|
+
CSS.registerProperty({
|
|
72
|
+
name: "--wui-drawer-nested-peek-base",
|
|
73
|
+
syntax: "<length>",
|
|
74
|
+
inherits: !0,
|
|
75
|
+
initialValue: "43.2px"
|
|
76
|
+
});
|
|
77
|
+
} catch {}
|
|
43
78
|
try {
|
|
44
79
|
CSS.registerProperty({
|
|
45
80
|
name: "--wui-internal-settle-duration",
|
|
@@ -49,13 +84,13 @@ if (typeof CSS < "u" && "registerProperty" in CSS) {
|
|
|
49
84
|
});
|
|
50
85
|
} catch {}
|
|
51
86
|
}
|
|
52
|
-
var
|
|
87
|
+
var I = class extends h {
|
|
53
88
|
constructor(...e) {
|
|
54
|
-
super(...e), this.open = !1, this.noScrollLock = !1, this.noBackdropClose = !1, this.controlled = !1, this._placement = "right", this.heading = "", this.closable = !1, this.headless = !1, this.dialogLabel = "", this.draggable = !1, this._hasHeaderSlot = !1, this._hasFooterSlot = !1, this._userOpenChange = new c(), this._scrollLock = o().make(), this._presence = l().make({
|
|
89
|
+
super(...e), this.open = !1, this.noScrollLock = !1, this.noBackdropClose = !1, this.controlled = !1, this._placement = "right", this.heading = "", this.closable = !1, this.headless = !1, this.dialogLabel = "", this.draggable = !1, this._hasHeaderSlot = !1, this._hasFooterSlot = !1, this._userOpenChange = new c(), this._headerHeight = new u(this, ".wui-drawer-header", (e) => this._setAvoidance("--wui-internal-drawer-header-inset", e)), this._footerHeight = new u(this, ".wui-drawer-footer", (e) => this._setAvoidance("--wui-internal-drawer-footer-inset", e)), this._scrollLock = o().make(), this._presence = l().make({
|
|
55
90
|
getDialog: () => this.dialog,
|
|
56
91
|
isConnected: () => this.isConnected,
|
|
57
92
|
isOpen: () => this.open
|
|
58
|
-
}), this._nestedLayers =
|
|
93
|
+
}), this._nestedLayers = p().make({
|
|
59
94
|
getDialog: () => this.dialog,
|
|
60
95
|
getPlacement: () => this._placement
|
|
61
96
|
}), this._overlay = a().make({
|
|
@@ -80,18 +115,21 @@ var P = class extends m {
|
|
|
80
115
|
}, this._backdropPress = null;
|
|
81
116
|
}
|
|
82
117
|
static {
|
|
83
|
-
this.styles = [
|
|
118
|
+
this.styles = [v(t), v(m)];
|
|
84
119
|
}
|
|
85
120
|
get placement() {
|
|
86
121
|
return this._placement;
|
|
87
122
|
}
|
|
88
123
|
set placement(e) {
|
|
89
124
|
let t = this._placement;
|
|
90
|
-
this._placement = r(e,
|
|
125
|
+
this._placement = r(e, x, "right"), this.requestUpdate("placement", t);
|
|
91
126
|
}
|
|
92
127
|
get dialog() {
|
|
93
128
|
return this.shadowRoot?.querySelector("dialog") ?? null;
|
|
94
129
|
}
|
|
130
|
+
_setAvoidance(e, t) {
|
|
131
|
+
this.style.setProperty(e, t > 0 ? `calc(${t}px + var(--wui-drawer-drag-zone-inset, var(--wui-space-1, 4px)))` : "0px");
|
|
132
|
+
}
|
|
95
133
|
get _dragAxis() {
|
|
96
134
|
return this._placement === "left" || this._placement === "right" ? "x" : "y";
|
|
97
135
|
}
|
|
@@ -108,7 +146,7 @@ var P = class extends m {
|
|
|
108
146
|
return e ? this._dragAxis === "x" ? e.offsetWidth : e.offsetHeight : 0;
|
|
109
147
|
}
|
|
110
148
|
_dragCloseThreshold(e) {
|
|
111
|
-
return Math.max(e *
|
|
149
|
+
return Math.max(e * S, C);
|
|
112
150
|
}
|
|
113
151
|
_readDrawerInset(e) {
|
|
114
152
|
let t = getComputedStyle(e).getPropertyValue("--wui-internal-drawer-inset"), n = Number.parseFloat(t);
|
|
@@ -126,6 +164,16 @@ var P = class extends m {
|
|
|
126
164
|
_cancelDragAwait() {
|
|
127
165
|
this._dragRequestTimer !== void 0 && (clearTimeout(this._dragRequestTimer), this._dragRequestTimer = void 0), this._dragAwaitWriteback = !1;
|
|
128
166
|
}
|
|
167
|
+
_handleSectionDragPointerDown(e) {
|
|
168
|
+
if (this._placement !== "top" && this._placement !== "bottom") return;
|
|
169
|
+
let t = (e.currentTarget?.closest(".wui-drawer-header, .wui-drawer-footer"))?.classList.contains("wui-drawer-header") ?? !1;
|
|
170
|
+
(this._placement !== "bottom" || t) && (this._placement === "top" && t || this.dialog?.classList.contains("is-nested-lower") || this._isInteractivePath(e) || this._handleDragPointerDown(e));
|
|
171
|
+
}
|
|
172
|
+
_isInteractivePath(e) {
|
|
173
|
+
let t = typeof e.composedPath == "function" ? e.composedPath() : [e.target];
|
|
174
|
+
for (let e of t) if (e instanceof Element && e.matches(k)) return !0;
|
|
175
|
+
return !1;
|
|
176
|
+
}
|
|
129
177
|
_handleDragPointerDown(e) {
|
|
130
178
|
if (!this.open || !this.draggable || this._isDragging() || e.isPrimary === !1) return;
|
|
131
179
|
let t = this.dialog;
|
|
@@ -133,18 +181,18 @@ var P = class extends m {
|
|
|
133
181
|
let n = getComputedStyle(t).transform, r = n && n !== "none" && typeof DOMMatrixReadOnly == "function" ? new DOMMatrixReadOnly(n)[this._dragAxis === "x" ? "m41" : "m42"] : 0;
|
|
134
182
|
this._abortSettle(), this._cancelDragAwait(), this._dragInitialOffset = r * this._dragCloseSign, this._dragOffset = this._dragInitialOffset;
|
|
135
183
|
let i = this._dragAxis === "x" ? e.clientX : e.clientY;
|
|
136
|
-
this._cancelBaseline = i, this._lastAxisPos = i, this._swipeIntentDisp = -1, this._swipeCancelled = !1, t.classList.add("is-dragging"), this._applyDragOffset(t, this._dragOffset), this._dragGesture =
|
|
184
|
+
this._cancelBaseline = i, this._lastAxisPos = i, this._swipeIntentDisp = -1, this._swipeCancelled = !1, t.classList.add("is-dragging"), this._applyDragOffset(t, this._dragOffset), this._dragGesture = d(e, {
|
|
137
185
|
axis: this._dragAxis,
|
|
138
186
|
calibrateOnFirstMove: !0,
|
|
139
187
|
onMove: (e) => {
|
|
140
188
|
let n = (this._dragAxis === "x" ? e.deltaX : e.deltaY) * this._dragCloseSign;
|
|
141
|
-
this._dragOffset = this._dragInitialOffset +
|
|
189
|
+
this._dragOffset = this._dragInitialOffset + f(n), this._trackSwipeCancel(this._dragAxis === "x" ? e.clientX : e.clientY, n);
|
|
142
190
|
let r = this._measureDragSize(), i = this._dragOffset - this._dragInitialOffset;
|
|
143
191
|
t.classList.toggle("is-drag-close", i > this._dragCloseThreshold(r)), this._applyDragOffset(t, this._dragOffset);
|
|
144
192
|
},
|
|
145
193
|
onEnd: (e) => {
|
|
146
194
|
this._dragGesture = null, this._syncDragInert(), t.classList.remove("is-dragging", "is-drag-close");
|
|
147
|
-
let n = this._measureDragSize(), r = (this._dragAxis === "x" ? e.velocityX : e.velocityY) * this._dragCloseSign, i = this._dragOffset - this._dragInitialOffset, a = e.duration > 0 ? i / Math.max(e.duration,
|
|
195
|
+
let n = this._measureDragSize(), r = (this._dragAxis === "x" ? e.velocityX : e.velocityY) * this._dragCloseSign, i = this._dragOffset - this._dragInitialOffset, a = e.duration > 0 ? i / Math.max(e.duration, T) * 1e3 : 0, o = i > 0 && a >= w && !this._swipeCancelled;
|
|
148
196
|
i > this._dragCloseThreshold(n) || o ? this._settleToClose(t, r) : this._settleRebound(t, r, this._dragOffset);
|
|
149
197
|
},
|
|
150
198
|
onCancel: () => {
|
|
@@ -159,7 +207,7 @@ var P = class extends m {
|
|
|
159
207
|
return;
|
|
160
208
|
}
|
|
161
209
|
let r = (e - this._cancelBaseline) * this._dragCloseSign;
|
|
162
|
-
r > this._dragCloseThreshold(this._measureDragSize()) ? this._swipeCancelled = !1 : this._swipeIntentDisp - r >=
|
|
210
|
+
r > this._dragCloseThreshold(this._measureDragSize()) ? this._swipeCancelled = !1 : this._swipeIntentDisp - r >= E && (this._swipeCancelled = !0);
|
|
163
211
|
}
|
|
164
212
|
_cancelActiveDrag() {
|
|
165
213
|
if (!this._isDragging()) return;
|
|
@@ -186,7 +234,7 @@ var P = class extends m {
|
|
|
186
234
|
e.classList.remove("is-dragging"), i();
|
|
187
235
|
return;
|
|
188
236
|
}
|
|
189
|
-
this._startSettle(e, r, 0, this._settleDuration(Math.abs(r - n), t),
|
|
237
|
+
this._startSettle(e, r, 0, this._settleDuration(Math.abs(r - n), t), M, i);
|
|
190
238
|
}
|
|
191
239
|
_settleRebound(e, t, n) {
|
|
192
240
|
this._dragOffset = 0;
|
|
@@ -197,16 +245,16 @@ var P = class extends m {
|
|
|
197
245
|
e.classList.remove("is-dragging"), r();
|
|
198
246
|
return;
|
|
199
247
|
}
|
|
200
|
-
this._startSettle(e, 0, 1, this._settleDuration(Math.abs(n), t),
|
|
248
|
+
this._startSettle(e, 0, 1, this._settleDuration(Math.abs(n), t), N, r);
|
|
201
249
|
}
|
|
202
250
|
_settleDuration(e, t) {
|
|
203
|
-
let n = e / Math.max(Math.abs(t),
|
|
204
|
-
return Math.min(
|
|
251
|
+
let n = e / Math.max(Math.abs(t), P) * 1e3;
|
|
252
|
+
return Math.min(j, Math.max(A, n));
|
|
205
253
|
}
|
|
206
254
|
_startSettle(e, t, n, r, i, a) {
|
|
207
255
|
this._abortSettle();
|
|
208
256
|
let o = this._dragCloseSign;
|
|
209
|
-
e.style.setProperty("--wui-internal-settle-duration", `${r}ms`), e.style.setProperty("--wui-internal-settle-easing", i), e.style.transform = this._dragAxis === "x" ? `translateX(${t * o}px)` : `translateY(${t * o}px)`, e.style.setProperty("--wui-internal-drag-backdrop-opacity", String(n)), e.classList.add("is-settling"), e.classList.remove("is-dragging"), this._settleFinish = a, this._settleTimer = setTimeout(() => this._finishSettle(), r +
|
|
257
|
+
e.style.setProperty("--wui-internal-settle-duration", `${r}ms`), e.style.setProperty("--wui-internal-settle-easing", i), e.style.transform = this._dragAxis === "x" ? `translateX(${t * o}px)` : `translateY(${t * o}px)`, e.style.setProperty("--wui-internal-drag-backdrop-opacity", String(n)), e.classList.add("is-settling"), e.classList.remove("is-dragging"), this._settleFinish = a, this._settleTimer = setTimeout(() => this._finishSettle(), r + F);
|
|
210
258
|
}
|
|
211
259
|
_finishSettle() {
|
|
212
260
|
let e = this._settleFinish;
|
|
@@ -218,10 +266,10 @@ var P = class extends m {
|
|
|
218
266
|
e && (e.classList.remove("is-settling"), e.style.removeProperty("--wui-internal-settle-duration"), e.style.removeProperty("--wui-internal-settle-easing"));
|
|
219
267
|
}
|
|
220
268
|
_closeFromDrag() {
|
|
221
|
-
this._closeFromUser(), this.controlled && (this._dragAwaitWriteback = !0, this._dragRequestTimer = setTimeout(this._handleDragWritebackTimeout,
|
|
269
|
+
this._closeFromUser(), this.controlled && (this._dragAwaitWriteback = !0, this._dragRequestTimer = setTimeout(this._handleDragWritebackTimeout, D));
|
|
222
270
|
}
|
|
223
271
|
connectedCallback() {
|
|
224
|
-
super.connectedCallback(), this.
|
|
272
|
+
super.connectedCallback(), this._resyncSlotPresence(), this._presence.reconcile(), this.open && this._nestedLayers.register(), this._syncScrollLock(), this._reclaimIfOpen();
|
|
225
273
|
}
|
|
226
274
|
firstUpdated() {
|
|
227
275
|
this._checkSlotContent("footer");
|
|
@@ -234,6 +282,13 @@ var P = class extends m {
|
|
|
234
282
|
let e = this.dialog;
|
|
235
283
|
e && (this._handle = this._overlay.claim(e, { ancestryFrom: this }), this._syncDragInert());
|
|
236
284
|
}
|
|
285
|
+
_resyncSlotPresence() {
|
|
286
|
+
let e = this._hasSlottedChild("header"), t = this._hasSlottedChild("footer");
|
|
287
|
+
(e !== this._hasHeaderSlot || t !== this._hasFooterSlot) && (this._hasHeaderSlot = e, this._hasFooterSlot = t, this.requestUpdate());
|
|
288
|
+
}
|
|
289
|
+
_hasSlottedChild(e) {
|
|
290
|
+
return Array.from(this.children).some((t) => t.getAttribute("slot") === e);
|
|
291
|
+
}
|
|
237
292
|
_checkSlotContent(e) {
|
|
238
293
|
let t = this.shadowRoot?.querySelector(`slot[name="${e}"]`);
|
|
239
294
|
if (!t) return;
|
|
@@ -262,7 +317,7 @@ var P = class extends m {
|
|
|
262
317
|
e && this._clearDragStyles(e);
|
|
263
318
|
}
|
|
264
319
|
if (this._presence.sync(this.open), this.open) {
|
|
265
|
-
this._nestedLayers.register();
|
|
320
|
+
window.getSelection()?.removeAllRanges(), this._nestedLayers.register();
|
|
266
321
|
let e = this.dialog;
|
|
267
322
|
e && (this._handle?.release(), this._handle = this._overlay.claim(e, { ancestryFrom: this }), this._syncDragInert());
|
|
268
323
|
} else this._nestedLayers.unregister(), this._handle?.release(), this._handle = null;
|
|
@@ -320,7 +375,7 @@ var P = class extends m {
|
|
|
320
375
|
handleBackdropClick(e) {
|
|
321
376
|
if (e.target !== e.currentTarget || this.noBackdropClose || this._isDragging() || e.detail === 0) return;
|
|
322
377
|
let t = this._backdropPress;
|
|
323
|
-
this._backdropPress = null, t && t.onMask && (Math.hypot(e.clientX - t.x, e.clientY - t.y) >
|
|
378
|
+
this._backdropPress = null, t && t.onMask && (Math.hypot(e.clientX - t.x, e.clientY - t.y) > O || this._closeFromUser());
|
|
324
379
|
}
|
|
325
380
|
emitOpenChange(e = this.open) {
|
|
326
381
|
i(this, e);
|
|
@@ -329,14 +384,14 @@ var P = class extends m {
|
|
|
329
384
|
this._scrollLock.sync(e && !this.noScrollLock);
|
|
330
385
|
}
|
|
331
386
|
render() {
|
|
332
|
-
let e = this._hasHeaderSlot || !!this.heading, t = this.dialogLabel.trim(), r = !t && !this.headless && e ? "wui-drawer-heading" :
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
` :
|
|
337
|
-
return
|
|
387
|
+
let e = this._hasHeaderSlot || !!this.heading, t = this.dialogLabel.trim(), r = !t && !this.headless && e ? "wui-drawer-heading" : _, i = this.placement === "top" || this.placement === "bottom", a = this.draggable ? g`
|
|
388
|
+
${i ? g`<div class="wui-drawer-drag-edge" @pointerdown=${this._handleDragPointerDown}></div>` : _}
|
|
389
|
+
<div class="wui-drawer-drag-zone" @pointerdown=${this._handleDragPointerDown}></div>
|
|
390
|
+
<div class="wui-drawer-drag-bar"></div>
|
|
391
|
+
` : _;
|
|
392
|
+
return g`
|
|
338
393
|
<dialog
|
|
339
|
-
aria-label=${t ||
|
|
394
|
+
aria-label=${t || _}
|
|
340
395
|
aria-labelledby=${r}
|
|
341
396
|
@cancel=${this.handleCancel}
|
|
342
397
|
@close=${this.handleNativeClose}
|
|
@@ -345,21 +400,30 @@ var P = class extends m {
|
|
|
345
400
|
@keydown=${this.handleKeydown}
|
|
346
401
|
@transitionend=${this.handleTransitionEnd}
|
|
347
402
|
>
|
|
348
|
-
${this.headless ?
|
|
403
|
+
${this.headless ? g`<slot></slot>${a}` : g`
|
|
349
404
|
<div class="wui-drawer-body wui-glass">
|
|
350
|
-
<div
|
|
405
|
+
<div
|
|
406
|
+
class="wui-drawer-header"
|
|
407
|
+
id="wui-drawer-heading"
|
|
408
|
+
?hidden=${!e}
|
|
409
|
+
@pointerdown=${this._handleSectionDragPointerDown}
|
|
410
|
+
>
|
|
351
411
|
<slot name="header" @slotchange=${this.handleHeaderSlotChange}>
|
|
352
|
-
${this.heading ?
|
|
412
|
+
${this.heading ? g`<span class="wui-drawer-heading">${this.heading}</span>` : _}
|
|
353
413
|
</slot>
|
|
354
414
|
</div>
|
|
355
415
|
<div class="wui-drawer-content">
|
|
356
416
|
<slot></slot>
|
|
357
417
|
</div>
|
|
358
|
-
<div
|
|
418
|
+
<div
|
|
419
|
+
class="wui-drawer-footer"
|
|
420
|
+
?hidden=${!this._hasFooterSlot}
|
|
421
|
+
@pointerdown=${this._handleSectionDragPointerDown}
|
|
422
|
+
>
|
|
359
423
|
<slot name="footer" @slotchange=${this.handleFooterSlotChange}></slot>
|
|
360
424
|
</div>
|
|
361
425
|
</div>
|
|
362
|
-
${this.closable ?
|
|
426
|
+
${this.closable ? g`
|
|
363
427
|
<web-ui-button
|
|
364
428
|
class="wui-drawer-close"
|
|
365
429
|
@click=${this._closeFromUser}
|
|
@@ -370,44 +434,44 @@ var P = class extends m {
|
|
|
370
434
|
>
|
|
371
435
|
<web-ui-icon size="14" .icon=${n}></web-ui-icon>
|
|
372
436
|
</web-ui-button>
|
|
373
|
-
` :
|
|
374
|
-
${
|
|
437
|
+
` : _}
|
|
438
|
+
${a}
|
|
375
439
|
`}
|
|
376
440
|
</dialog>
|
|
377
441
|
`;
|
|
378
442
|
}
|
|
379
443
|
};
|
|
380
|
-
e([
|
|
444
|
+
e([b({
|
|
381
445
|
type: Boolean,
|
|
382
446
|
reflect: !0
|
|
383
|
-
})],
|
|
447
|
+
})], I.prototype, "open", void 0), e([b({
|
|
384
448
|
type: Boolean,
|
|
385
449
|
reflect: !0,
|
|
386
450
|
attribute: "no-scroll-lock"
|
|
387
|
-
})],
|
|
451
|
+
})], I.prototype, "noScrollLock", void 0), e([b({
|
|
388
452
|
type: Boolean,
|
|
389
453
|
reflect: !0,
|
|
390
454
|
attribute: "no-backdrop-close"
|
|
391
|
-
})],
|
|
455
|
+
})], I.prototype, "noBackdropClose", void 0), e([b({
|
|
392
456
|
type: Boolean,
|
|
393
457
|
reflect: !0
|
|
394
|
-
})],
|
|
458
|
+
})], I.prototype, "controlled", void 0), e([b({
|
|
395
459
|
type: String,
|
|
396
460
|
reflect: !0
|
|
397
|
-
})],
|
|
461
|
+
})], I.prototype, "placement", null), e([b({ type: String })], I.prototype, "heading", void 0), e([b({
|
|
398
462
|
type: Boolean,
|
|
399
463
|
reflect: !0
|
|
400
|
-
})],
|
|
464
|
+
})], I.prototype, "closable", void 0), e([b({
|
|
401
465
|
type: Boolean,
|
|
402
466
|
reflect: !0
|
|
403
|
-
})],
|
|
467
|
+
})], I.prototype, "headless", void 0), e([b({
|
|
404
468
|
type: String,
|
|
405
469
|
attribute: "dialog-label"
|
|
406
|
-
})],
|
|
470
|
+
})], I.prototype, "dialogLabel", void 0), e([b({
|
|
407
471
|
type: Boolean,
|
|
408
472
|
reflect: !0
|
|
409
|
-
})],
|
|
473
|
+
})], I.prototype, "draggable", void 0), I = e([y("web-ui-drawer")], I);
|
|
410
474
|
//#endregion
|
|
411
|
-
export {
|
|
475
|
+
export { I as WebUiDrawer };
|
|
412
476
|
|
|
413
477
|
//# sourceMappingURL=index.js.map
|