@greypan/web-ui 11.2.0 → 12.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 +79 -68
- package/README.md +81 -72
- package/dist/_virtual/_@oxc-project_runtime@0.155.0/helpers/esm/decorate.js +8 -0
- package/dist/assets/menu-portal.js +3 -4
- package/dist/assets/menu-portal.js.map +1 -1
- package/dist/assets/modal-surface.js +3 -4
- package/dist/assets/modal-surface.js.map +1 -1
- package/dist/assets/overlay-motion.js +3 -4
- package/dist/assets/overlay-motion.js.map +1 -1
- package/dist/assets/scrollbar.js +5 -0
- package/dist/assets/scrollbar.js.map +1 -0
- package/dist/assets/selection-control.js +3 -4
- package/dist/assets/selection-control.js.map +1 -1
- package/dist/assets/toast-containers.js +3 -4
- package/dist/assets/toast-containers.js.map +1 -1
- package/dist/classes/glass.js +3 -4
- package/dist/classes/glass.js.map +1 -1
- package/dist/classes/glow.js +3 -4
- package/dist/classes/glow.js.map +1 -1
- package/dist/components/autocomplete/index.d.ts +485 -483
- package/dist/components/autocomplete/index.d.ts.map +1 -0
- package/dist/components/autocomplete/index.js +475 -267
- package/dist/components/autocomplete/index.js.map +1 -1
- package/dist/components/autocomplete/style.js +3 -4
- package/dist/components/autocomplete/style.js.map +1 -1
- package/dist/components/avatar/index.d.ts +26 -24
- package/dist/components/avatar/index.d.ts.map +1 -0
- package/dist/components/avatar/index.js +72 -52
- package/dist/components/avatar/index.js.map +1 -1
- package/dist/components/avatar/style.js +3 -4
- package/dist/components/avatar/style.js.map +1 -1
- package/dist/components/back-top/index.d.ts +30 -27
- package/dist/components/back-top/index.d.ts.map +1 -0
- package/dist/components/back-top/index.js +96 -62
- package/dist/components/back-top/index.js.map +1 -1
- package/dist/components/back-top/style.js +3 -4
- package/dist/components/back-top/style.js.map +1 -1
- package/dist/components/badge/index.d.ts +32 -26
- package/dist/components/badge/index.d.ts.map +1 -0
- package/dist/components/badge/index.js +116 -74
- package/dist/components/badge/index.js.map +1 -1
- package/dist/components/badge/style.js +3 -4
- package/dist/components/badge/style.js.map +1 -1
- package/dist/components/button/index.d.ts +392 -390
- package/dist/components/button/index.d.ts.map +1 -0
- package/dist/components/button/index.js +108 -74
- package/dist/components/button/index.js.map +1 -1
- package/dist/components/button/style.js +3 -4
- package/dist/components/button/style.js.map +1 -1
- package/dist/components/button-group/index.d.ts +14 -13
- package/dist/components/button-group/index.d.ts.map +1 -0
- package/dist/components/button-group/index.js +43 -33
- package/dist/components/button-group/index.js.map +1 -1
- package/dist/components/button-group/style.js +3 -4
- package/dist/components/button-group/style.js.map +1 -1
- package/dist/components/checkbox/index.d.ts +399 -397
- package/dist/components/checkbox/index.d.ts.map +1 -0
- package/dist/components/checkbox/index.js +103 -74
- package/dist/components/checkbox/index.js.map +1 -1
- package/dist/components/checkbox/style.js +3 -4
- package/dist/components/checkbox/style.js.map +1 -1
- package/dist/components/checkbox-group/index.d.ts +397 -396
- package/dist/components/checkbox-group/index.d.ts.map +1 -0
- package/dist/components/checkbox-group/index.js +92 -70
- package/dist/components/checkbox-group/index.js.map +1 -1
- package/dist/components/checkbox-group/style.js +3 -4
- package/dist/components/checkbox-group/style.js.map +1 -1
- package/dist/components/collapse/index.d.ts +72 -71
- package/dist/components/collapse/index.d.ts.map +1 -0
- package/dist/components/collapse/index.js +225 -130
- package/dist/components/collapse/index.js.map +1 -1
- package/dist/components/collapse/style.js +3 -4
- package/dist/components/collapse/style.js.map +1 -1
- package/dist/components/context-menu/index.d.ts +307 -310
- package/dist/components/context-menu/index.d.ts.map +1 -0
- package/dist/components/context-menu/index.js +685 -270
- package/dist/components/context-menu/index.js.map +1 -1
- package/dist/components/context-menu/scrim.js +3 -4
- package/dist/components/context-menu/scrim.js.map +1 -1
- package/dist/components/context-menu/style.js +3 -4
- package/dist/components/context-menu/style.js.map +1 -1
- package/dist/components/dialog/index.d.ts +87 -78
- package/dist/components/dialog/index.d.ts.map +1 -0
- package/dist/components/dialog/index.js +183 -88
- package/dist/components/dialog/index.js.map +1 -1
- package/dist/components/dialog/style.js +3 -4
- package/dist/components/dialog/style.js.map +1 -1
- package/dist/components/drawer/index.d.ts +159 -150
- package/dist/components/drawer/index.d.ts.map +1 -0
- package/dist/components/drawer/index.js +503 -242
- package/dist/components/drawer/index.js.map +1 -1
- package/dist/components/drawer/style.js +3 -4
- package/dist/components/drawer/style.js.map +1 -1
- package/dist/components/dropdown/index.d.ts +125 -124
- package/dist/components/dropdown/index.d.ts.map +1 -0
- package/dist/components/dropdown/index.js +556 -328
- package/dist/components/dropdown/index.js.map +1 -1
- package/dist/components/dropdown/style.js +3 -4
- package/dist/components/dropdown/style.js.map +1 -1
- package/dist/components/dropdown-divider/index.d.ts +7 -6
- package/dist/components/dropdown-divider/index.d.ts.map +1 -0
- package/dist/components/dropdown-divider/index.js +10 -11
- package/dist/components/dropdown-divider/index.js.map +1 -1
- package/dist/components/dropdown-divider/style.js +3 -4
- package/dist/components/dropdown-divider/style.js.map +1 -1
- package/dist/components/dropdown-header/index.d.ts +7 -6
- package/dist/components/dropdown-header/index.d.ts.map +1 -0
- package/dist/components/dropdown-header/index.js +10 -11
- package/dist/components/dropdown-header/index.js.map +1 -1
- package/dist/components/dropdown-header/style.js +3 -4
- package/dist/components/dropdown-header/style.js.map +1 -1
- package/dist/components/dropdown-item/index.d.ts +13 -11
- package/dist/components/dropdown-item/index.d.ts.map +1 -0
- package/dist/components/dropdown-item/index.js +32 -25
- package/dist/components/dropdown-item/index.js.map +1 -1
- package/dist/components/dropdown-item/style.js +3 -4
- package/dist/components/dropdown-item/style.js.map +1 -1
- package/dist/components/editable-text/index.d.ts +506 -505
- package/dist/components/editable-text/index.d.ts.map +1 -0
- package/dist/components/editable-text/index.js +281 -127
- package/dist/components/editable-text/index.js.map +1 -1
- package/dist/components/editable-text/style.js +3 -4
- package/dist/components/editable-text/style.js.map +1 -1
- package/dist/components/empty/index.d.ts +17 -15
- package/dist/components/empty/index.d.ts.map +1 -0
- package/dist/components/empty/index.js +66 -37
- package/dist/components/empty/index.js.map +1 -1
- package/dist/components/empty/style.js +3 -4
- package/dist/components/empty/style.js.map +1 -1
- package/dist/components/icon/index.d.ts +12 -11
- package/dist/components/icon/index.d.ts.map +1 -0
- package/dist/components/icon/index.js +34 -27
- package/dist/components/icon/index.js.map +1 -1
- package/dist/components/icon/style.js +3 -4
- package/dist/components/icon/style.js.map +1 -1
- package/dist/components/image-preview/index.d.ts +58 -44
- package/dist/components/image-preview/index.d.ts.map +1 -0
- package/dist/components/image-preview/index.js +536 -265
- package/dist/components/image-preview/index.js.map +1 -1
- package/dist/components/image-preview/style.js +3 -4
- package/dist/components/image-preview/style.js.map +1 -1
- package/dist/components/index.d.ts +46 -43
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +41 -41
- package/dist/components/input/index.d.ts +418 -413
- package/dist/components/input/index.d.ts.map +1 -0
- package/dist/components/input/index.js +148 -84
- package/dist/components/input/index.js.map +1 -1
- package/dist/components/input/style.js +3 -4
- package/dist/components/input/style.js.map +1 -1
- package/dist/components/input-number/index.d.ts +453 -447
- package/dist/components/input-number/index.d.ts.map +1 -0
- package/dist/components/input-number/index.js +484 -292
- package/dist/components/input-number/index.js.map +1 -1
- package/dist/components/input-number/style.js +3 -4
- package/dist/components/input-number/style.js.map +1 -1
- package/dist/components/layout/index.d.ts +110 -87
- package/dist/components/layout/index.d.ts.map +1 -0
- package/dist/components/layout/index.js +238 -144
- package/dist/components/layout/index.js.map +1 -1
- package/dist/components/layout/style.js +3 -4
- package/dist/components/layout/style.js.map +1 -1
- package/dist/components/middle-ellipsis/index.d.ts +93 -92
- package/dist/components/middle-ellipsis/index.d.ts.map +1 -0
- package/dist/components/middle-ellipsis/index.js +261 -107
- package/dist/components/middle-ellipsis/index.js.map +1 -1
- package/dist/components/middle-ellipsis/style.js +3 -4
- package/dist/components/middle-ellipsis/style.js.map +1 -1
- package/dist/components/middle-ellipsis/truncate.js +60 -30
- package/dist/components/middle-ellipsis/truncate.js.map +1 -1
- package/dist/components/option/index.d.ts +20 -18
- package/dist/components/option/index.d.ts.map +1 -0
- package/dist/components/option/index.js +53 -40
- package/dist/components/option/index.js.map +1 -1
- package/dist/components/option/style.js +3 -4
- package/dist/components/option/style.js.map +1 -1
- package/dist/components/popover/index.d.ts +69 -68
- package/dist/components/popover/index.d.ts.map +1 -0
- package/dist/components/popover/index.js +221 -104
- package/dist/components/popover/index.js.map +1 -1
- package/dist/components/popover/style.js +3 -4
- package/dist/components/popover/style.js.map +1 -1
- package/dist/components/radio/index.d.ts +396 -395
- package/dist/components/radio/index.d.ts.map +1 -0
- package/dist/components/radio/index.js +91 -62
- package/dist/components/radio/index.js.map +1 -1
- package/dist/components/radio/interaction.js +10 -11
- package/dist/components/radio/interaction.js.map +1 -1
- package/dist/components/radio/style.js +3 -4
- package/dist/components/radio/style.js.map +1 -1
- package/dist/components/radio-group/index.d.ts +417 -416
- package/dist/components/radio-group/index.d.ts.map +1 -0
- package/dist/components/radio-group/index.js +307 -207
- package/dist/components/radio-group/index.js.map +1 -1
- package/dist/components/radio-group/style.js +3 -4
- package/dist/components/radio-group/style.js.map +1 -1
- package/dist/components/segmented/index.d.ts +408 -402
- package/dist/components/segmented/index.d.ts.map +1 -0
- package/dist/components/segmented/index.js +267 -158
- package/dist/components/segmented/index.js.map +1 -1
- package/dist/components/segmented/style.js +3 -4
- package/dist/components/segmented/style.js.map +1 -1
- package/dist/components/segmented-trigger/index.d.ts +18 -17
- package/dist/components/segmented-trigger/index.d.ts.map +1 -0
- package/dist/components/segmented-trigger/index.js +45 -36
- package/dist/components/segmented-trigger/index.js.map +1 -1
- package/dist/components/segmented-trigger/style.js +3 -4
- package/dist/components/segmented-trigger/style.js.map +1 -1
- package/dist/components/select/index.d.ts +450 -448
- package/dist/components/select/index.d.ts.map +1 -0
- package/dist/components/select/index.js +342 -188
- package/dist/components/select/index.js.map +1 -1
- package/dist/components/select/style.js +3 -4
- package/dist/components/select/style.js.map +1 -1
- package/dist/components/slider/index.d.ts +428 -427
- package/dist/components/slider/index.d.ts.map +1 -0
- package/dist/components/slider/index.js +308 -216
- package/dist/components/slider/index.js.map +1 -1
- package/dist/components/slider/style.js +3 -4
- package/dist/components/slider/style.js.map +1 -1
- package/dist/components/spinner/index.d.ts +39 -38
- package/dist/components/spinner/index.d.ts.map +1 -0
- package/dist/components/spinner/index.js +118 -65
- package/dist/components/spinner/index.js.map +1 -1
- package/dist/components/spinner/style.js +3 -4
- package/dist/components/spinner/style.js.map +1 -1
- package/dist/components/svg-draw-lines/index.d.ts +40 -39
- package/dist/components/svg-draw-lines/index.d.ts.map +1 -0
- package/dist/components/svg-draw-lines/index.js +189 -106
- package/dist/components/svg-draw-lines/index.js.map +1 -1
- package/dist/components/svg-draw-lines/style.js +3 -4
- package/dist/components/svg-draw-lines/style.js.map +1 -1
- package/dist/components/switch/index.d.ts +411 -409
- package/dist/components/switch/index.d.ts.map +1 -0
- package/dist/components/switch/index.js +193 -106
- package/dist/components/switch/index.js.map +1 -1
- package/dist/components/switch/style.js +3 -4
- package/dist/components/switch/style.js.map +1 -1
- package/dist/components/textarea/index.d.ts +430 -425
- package/dist/components/textarea/index.d.ts.map +1 -0
- package/dist/components/textarea/index.js +187 -100
- package/dist/components/textarea/index.js.map +1 -1
- package/dist/components/textarea/style.js +3 -4
- package/dist/components/textarea/style.js.map +1 -1
- package/dist/components/theme/index.d.ts +45 -44
- package/dist/components/theme/index.d.ts.map +1 -0
- package/dist/components/theme/index.js +268 -161
- package/dist/components/theme/index.js.map +1 -1
- package/dist/components/theme/style.js +3 -4
- package/dist/components/theme/style.js.map +1 -1
- package/dist/components/toast/index.d.ts +4 -3
- package/dist/components/toast/index.js +3 -3
- package/dist/components/toast/manager.d.ts +9 -8
- package/dist/components/toast/manager.d.ts.map +1 -0
- package/dist/components/toast/manager.js +215 -119
- package/dist/components/toast/manager.js.map +1 -1
- package/dist/components/toast/style.js +3 -4
- package/dist/components/toast/style.js.map +1 -1
- package/dist/components/toast/toast.d.ts +75 -71
- package/dist/components/toast/toast.d.ts.map +1 -0
- package/dist/components/toast/toast.js +203 -96
- package/dist/components/toast/toast.js.map +1 -1
- package/dist/components/toast/types.d.ts +10 -9
- package/dist/components/toast/types.d.ts.map +1 -0
- package/dist/components/tooltip/index.d.ts +72 -62
- package/dist/components/tooltip/index.d.ts.map +1 -0
- package/dist/components/tooltip/index.js +251 -93
- package/dist/components/tooltip/index.js.map +1 -1
- package/dist/components/tooltip/style.js +3 -4
- package/dist/components/tooltip/style.js.map +1 -1
- package/dist/icons/generated/akar-icons-check.d.ts +5 -4
- package/dist/icons/generated/akar-icons-check.d.ts.map +1 -0
- package/dist/icons/generated/akar-icons-check.js +3 -4
- package/dist/icons/generated/akar-icons-check.js.map +1 -1
- package/dist/icons/generated/akar-icons-circle-check.d.ts +5 -4
- package/dist/icons/generated/akar-icons-circle-check.d.ts.map +1 -0
- package/dist/icons/generated/akar-icons-circle-check.js +3 -4
- package/dist/icons/generated/akar-icons-circle-check.js.map +1 -1
- package/dist/icons/generated/andrsrxn-inbox.d.ts +5 -4
- package/dist/icons/generated/andrsrxn-inbox.d.ts.map +1 -0
- package/dist/icons/generated/andrsrxn-inbox.js +3 -4
- package/dist/icons/generated/andrsrxn-inbox.js.map +1 -1
- package/dist/icons/generated/bi-check-lg.d.ts +5 -4
- package/dist/icons/generated/bi-check-lg.d.ts.map +1 -0
- package/dist/icons/generated/bi-check-lg.js +3 -4
- package/dist/icons/generated/bi-check-lg.js.map +1 -1
- package/dist/icons/generated/bi-check.d.ts +5 -4
- package/dist/icons/generated/bi-check.d.ts.map +1 -0
- package/dist/icons/generated/bi-check.js +3 -4
- package/dist/icons/generated/bi-check.js.map +1 -1
- package/dist/icons/generated/fluent-tag-search-24-regular.d.ts +5 -4
- package/dist/icons/generated/fluent-tag-search-24-regular.d.ts.map +1 -0
- package/dist/icons/generated/fluent-tag-search-24-regular.js +3 -4
- package/dist/icons/generated/fluent-tag-search-24-regular.js.map +1 -1
- package/dist/icons/generated/heroicons-bars-arrow-down-16-solid.d.ts +5 -4
- package/dist/icons/generated/heroicons-bars-arrow-down-16-solid.d.ts.map +1 -0
- package/dist/icons/generated/heroicons-bars-arrow-down-16-solid.js +3 -4
- package/dist/icons/generated/heroicons-bars-arrow-down-16-solid.js.map +1 -1
- package/dist/icons/generated/heroicons-bars-arrow-up-16-solid.d.ts +5 -4
- package/dist/icons/generated/heroicons-bars-arrow-up-16-solid.d.ts.map +1 -0
- package/dist/icons/generated/heroicons-bars-arrow-up-16-solid.js +3 -4
- package/dist/icons/generated/heroicons-bars-arrow-up-16-solid.js.map +1 -1
- package/dist/icons/generated/heroicons-check-16-solid.d.ts +5 -4
- package/dist/icons/generated/heroicons-check-16-solid.d.ts.map +1 -0
- package/dist/icons/generated/heroicons-check-16-solid.js +3 -4
- package/dist/icons/generated/heroicons-check-16-solid.js.map +1 -1
- package/dist/icons/generated/heroicons-x-mark-16-solid.d.ts +5 -4
- package/dist/icons/generated/heroicons-x-mark-16-solid.d.ts.map +1 -0
- package/dist/icons/generated/heroicons-x-mark-16-solid.js +3 -4
- package/dist/icons/generated/heroicons-x-mark-16-solid.js.map +1 -1
- package/dist/icons/generated/jam-close-circle-f.d.ts +7 -6
- package/dist/icons/generated/jam-close-circle-f.d.ts.map +1 -0
- package/dist/icons/generated/jam-close-circle-f.js +3 -4
- package/dist/icons/generated/jam-close-circle-f.js.map +1 -1
- package/dist/icons/generated/lucide-arrow-down-to-line.d.ts +5 -4
- package/dist/icons/generated/lucide-arrow-down-to-line.d.ts.map +1 -0
- package/dist/icons/generated/lucide-arrow-down-to-line.js +3 -4
- package/dist/icons/generated/lucide-arrow-down-to-line.js.map +1 -1
- package/dist/icons/generated/lucide-arrow-up-to-line.d.ts +5 -4
- package/dist/icons/generated/lucide-arrow-up-to-line.d.ts.map +1 -0
- package/dist/icons/generated/lucide-arrow-up-to-line.js +3 -4
- package/dist/icons/generated/lucide-arrow-up-to-line.js.map +1 -1
- package/dist/icons/generated/lucide-bell.d.ts +5 -4
- package/dist/icons/generated/lucide-bell.d.ts.map +1 -0
- package/dist/icons/generated/lucide-bell.js +3 -4
- package/dist/icons/generated/lucide-bell.js.map +1 -1
- package/dist/icons/generated/lucide-check.d.ts +5 -4
- package/dist/icons/generated/lucide-check.d.ts.map +1 -0
- package/dist/icons/generated/lucide-check.js +3 -4
- package/dist/icons/generated/lucide-check.js.map +1 -1
- package/dist/icons/generated/lucide-chevron-down.d.ts +5 -4
- package/dist/icons/generated/lucide-chevron-down.d.ts.map +1 -0
- package/dist/icons/generated/lucide-chevron-down.js +3 -4
- package/dist/icons/generated/lucide-chevron-down.js.map +1 -1
- package/dist/icons/generated/lucide-chevron-left.d.ts +5 -4
- package/dist/icons/generated/lucide-chevron-left.d.ts.map +1 -0
- package/dist/icons/generated/lucide-chevron-left.js +3 -4
- package/dist/icons/generated/lucide-chevron-left.js.map +1 -1
- package/dist/icons/generated/lucide-chevron-right.d.ts +5 -4
- package/dist/icons/generated/lucide-chevron-right.d.ts.map +1 -0
- package/dist/icons/generated/lucide-chevron-right.js +3 -4
- package/dist/icons/generated/lucide-chevron-right.js.map +1 -1
- package/dist/icons/generated/lucide-chevron-up.d.ts +5 -4
- package/dist/icons/generated/lucide-chevron-up.d.ts.map +1 -0
- package/dist/icons/generated/lucide-chevron-up.js +3 -4
- package/dist/icons/generated/lucide-chevron-up.js.map +1 -1
- package/dist/icons/generated/lucide-circle-alert.d.ts +5 -4
- package/dist/icons/generated/lucide-circle-alert.d.ts.map +1 -0
- package/dist/icons/generated/lucide-circle-alert.js +3 -4
- package/dist/icons/generated/lucide-circle-alert.js.map +1 -1
- package/dist/icons/generated/lucide-clapperboard.d.ts +5 -4
- package/dist/icons/generated/lucide-clapperboard.d.ts.map +1 -0
- package/dist/icons/generated/lucide-clapperboard.js +3 -4
- package/dist/icons/generated/lucide-clapperboard.js.map +1 -1
- package/dist/icons/generated/lucide-clipboard-paste.d.ts +5 -4
- package/dist/icons/generated/lucide-clipboard-paste.d.ts.map +1 -0
- package/dist/icons/generated/lucide-clipboard-paste.js +3 -4
- package/dist/icons/generated/lucide-clipboard-paste.js.map +1 -1
- package/dist/icons/generated/lucide-code.d.ts +5 -4
- package/dist/icons/generated/lucide-code.d.ts.map +1 -0
- package/dist/icons/generated/lucide-code.js +3 -4
- package/dist/icons/generated/lucide-code.js.map +1 -1
- package/dist/icons/generated/lucide-copy.d.ts +5 -4
- package/dist/icons/generated/lucide-copy.d.ts.map +1 -0
- package/dist/icons/generated/lucide-copy.js +3 -4
- package/dist/icons/generated/lucide-copy.js.map +1 -1
- package/dist/icons/generated/lucide-download.d.ts +5 -4
- package/dist/icons/generated/lucide-download.d.ts.map +1 -0
- package/dist/icons/generated/lucide-download.js +3 -4
- package/dist/icons/generated/lucide-download.js.map +1 -1
- package/dist/icons/generated/lucide-ellipsis-vertical.d.ts +5 -4
- package/dist/icons/generated/lucide-ellipsis-vertical.d.ts.map +1 -0
- package/dist/icons/generated/lucide-ellipsis-vertical.js +3 -4
- package/dist/icons/generated/lucide-ellipsis-vertical.js.map +1 -1
- package/dist/icons/generated/lucide-external-link.d.ts +5 -4
- package/dist/icons/generated/lucide-external-link.d.ts.map +1 -0
- package/dist/icons/generated/lucide-external-link.js +3 -4
- package/dist/icons/generated/lucide-external-link.js.map +1 -1
- package/dist/icons/generated/lucide-eye.d.ts +5 -4
- package/dist/icons/generated/lucide-eye.d.ts.map +1 -0
- package/dist/icons/generated/lucide-eye.js +3 -4
- package/dist/icons/generated/lucide-eye.js.map +1 -1
- package/dist/icons/generated/lucide-file-text.d.ts +5 -4
- package/dist/icons/generated/lucide-file-text.d.ts.map +1 -0
- package/dist/icons/generated/lucide-file-text.js +3 -4
- package/dist/icons/generated/lucide-file-text.js.map +1 -1
- package/dist/icons/generated/lucide-file.d.ts +5 -4
- package/dist/icons/generated/lucide-file.d.ts.map +1 -0
- package/dist/icons/generated/lucide-file.js +3 -4
- package/dist/icons/generated/lucide-file.js.map +1 -1
- package/dist/icons/generated/lucide-film.d.ts +5 -4
- package/dist/icons/generated/lucide-film.d.ts.map +1 -0
- package/dist/icons/generated/lucide-film.js +3 -4
- package/dist/icons/generated/lucide-film.js.map +1 -1
- package/dist/icons/generated/lucide-folder-open.d.ts +5 -4
- package/dist/icons/generated/lucide-folder-open.d.ts.map +1 -0
- package/dist/icons/generated/lucide-folder-open.js +3 -4
- package/dist/icons/generated/lucide-folder-open.js.map +1 -1
- package/dist/icons/generated/lucide-folder.d.ts +5 -4
- package/dist/icons/generated/lucide-folder.d.ts.map +1 -0
- package/dist/icons/generated/lucide-folder.js +3 -4
- package/dist/icons/generated/lucide-folder.js.map +1 -1
- package/dist/icons/generated/lucide-globe.d.ts +5 -4
- package/dist/icons/generated/lucide-globe.d.ts.map +1 -0
- package/dist/icons/generated/lucide-globe.js +3 -4
- package/dist/icons/generated/lucide-globe.js.map +1 -1
- package/dist/icons/generated/lucide-headphones.d.ts +5 -4
- package/dist/icons/generated/lucide-headphones.d.ts.map +1 -0
- package/dist/icons/generated/lucide-headphones.js +3 -4
- package/dist/icons/generated/lucide-headphones.js.map +1 -1
- package/dist/icons/generated/lucide-heart.d.ts +5 -4
- package/dist/icons/generated/lucide-heart.d.ts.map +1 -0
- package/dist/icons/generated/lucide-heart.js +3 -4
- package/dist/icons/generated/lucide-heart.js.map +1 -1
- package/dist/icons/generated/lucide-image.d.ts +5 -4
- package/dist/icons/generated/lucide-image.d.ts.map +1 -0
- package/dist/icons/generated/lucide-image.js +3 -4
- package/dist/icons/generated/lucide-image.js.map +1 -1
- package/dist/icons/generated/lucide-inbox.d.ts +5 -4
- package/dist/icons/generated/lucide-inbox.d.ts.map +1 -0
- package/dist/icons/generated/lucide-inbox.js +3 -4
- package/dist/icons/generated/lucide-inbox.js.map +1 -1
- package/dist/icons/generated/lucide-info.d.ts +5 -4
- package/dist/icons/generated/lucide-info.d.ts.map +1 -0
- package/dist/icons/generated/lucide-info.js +3 -4
- package/dist/icons/generated/lucide-info.js.map +1 -1
- package/dist/icons/generated/lucide-layout-grid.d.ts +5 -4
- package/dist/icons/generated/lucide-layout-grid.d.ts.map +1 -0
- package/dist/icons/generated/lucide-layout-grid.js +3 -4
- package/dist/icons/generated/lucide-layout-grid.js.map +1 -1
- package/dist/icons/generated/lucide-link.d.ts +5 -4
- package/dist/icons/generated/lucide-link.d.ts.map +1 -0
- package/dist/icons/generated/lucide-link.js +3 -4
- package/dist/icons/generated/lucide-link.js.map +1 -1
- package/dist/icons/generated/lucide-list-filter.d.ts +5 -4
- package/dist/icons/generated/lucide-list-filter.d.ts.map +1 -0
- package/dist/icons/generated/lucide-list-filter.js +3 -4
- package/dist/icons/generated/lucide-list-filter.js.map +1 -1
- package/dist/icons/generated/lucide-list-restart.d.ts +5 -4
- package/dist/icons/generated/lucide-list-restart.d.ts.map +1 -0
- package/dist/icons/generated/lucide-list-restart.js +3 -4
- package/dist/icons/generated/lucide-list-restart.js.map +1 -1
- package/dist/icons/generated/lucide-loader-circle.d.ts +5 -4
- package/dist/icons/generated/lucide-loader-circle.d.ts.map +1 -0
- package/dist/icons/generated/lucide-loader-circle.js +3 -4
- package/dist/icons/generated/lucide-loader-circle.js.map +1 -1
- package/dist/icons/generated/lucide-mail.d.ts +5 -4
- package/dist/icons/generated/lucide-mail.d.ts.map +1 -0
- package/dist/icons/generated/lucide-mail.js +3 -4
- package/dist/icons/generated/lucide-mail.js.map +1 -1
- package/dist/icons/generated/lucide-minus.d.ts +5 -4
- package/dist/icons/generated/lucide-minus.d.ts.map +1 -0
- package/dist/icons/generated/lucide-minus.js +3 -4
- package/dist/icons/generated/lucide-minus.js.map +1 -1
- package/dist/icons/generated/lucide-music.d.ts +5 -4
- package/dist/icons/generated/lucide-music.d.ts.map +1 -0
- package/dist/icons/generated/lucide-music.js +3 -4
- package/dist/icons/generated/lucide-music.js.map +1 -1
- package/dist/icons/generated/lucide-package.d.ts +5 -4
- package/dist/icons/generated/lucide-package.d.ts.map +1 -0
- package/dist/icons/generated/lucide-package.js +3 -4
- package/dist/icons/generated/lucide-package.js.map +1 -1
- package/dist/icons/generated/lucide-pen-line.d.ts +5 -4
- package/dist/icons/generated/lucide-pen-line.d.ts.map +1 -0
- package/dist/icons/generated/lucide-pen-line.js +3 -4
- package/dist/icons/generated/lucide-pen-line.js.map +1 -1
- package/dist/icons/generated/lucide-pencil.d.ts +5 -4
- package/dist/icons/generated/lucide-pencil.d.ts.map +1 -0
- package/dist/icons/generated/lucide-pencil.js +3 -4
- package/dist/icons/generated/lucide-pencil.js.map +1 -1
- package/dist/icons/generated/lucide-play.d.ts +5 -4
- package/dist/icons/generated/lucide-play.d.ts.map +1 -0
- package/dist/icons/generated/lucide-play.js +3 -4
- package/dist/icons/generated/lucide-play.js.map +1 -1
- package/dist/icons/generated/lucide-plus.d.ts +5 -4
- package/dist/icons/generated/lucide-plus.d.ts.map +1 -0
- package/dist/icons/generated/lucide-plus.js +3 -4
- package/dist/icons/generated/lucide-plus.js.map +1 -1
- package/dist/icons/generated/lucide-printer.d.ts +5 -4
- package/dist/icons/generated/lucide-printer.d.ts.map +1 -0
- package/dist/icons/generated/lucide-printer.js +3 -4
- package/dist/icons/generated/lucide-printer.js.map +1 -1
- package/dist/icons/generated/lucide-redo-2.d.ts +5 -4
- package/dist/icons/generated/lucide-redo-2.d.ts.map +1 -0
- package/dist/icons/generated/lucide-redo-2.js +3 -4
- package/dist/icons/generated/lucide-redo-2.js.map +1 -1
- package/dist/icons/generated/lucide-refresh-cw.d.ts +5 -4
- package/dist/icons/generated/lucide-refresh-cw.d.ts.map +1 -0
- package/dist/icons/generated/lucide-refresh-cw.js +3 -4
- package/dist/icons/generated/lucide-refresh-cw.js.map +1 -1
- package/dist/icons/generated/lucide-scissors.d.ts +5 -4
- package/dist/icons/generated/lucide-scissors.d.ts.map +1 -0
- package/dist/icons/generated/lucide-scissors.js +3 -4
- package/dist/icons/generated/lucide-scissors.js.map +1 -1
- package/dist/icons/generated/lucide-search.d.ts +5 -4
- package/dist/icons/generated/lucide-search.d.ts.map +1 -0
- package/dist/icons/generated/lucide-search.js +3 -4
- package/dist/icons/generated/lucide-search.js.map +1 -1
- package/dist/icons/generated/lucide-settings.d.ts +5 -4
- package/dist/icons/generated/lucide-settings.d.ts.map +1 -0
- package/dist/icons/generated/lucide-settings.js +3 -4
- package/dist/icons/generated/lucide-settings.js.map +1 -1
- package/dist/icons/generated/lucide-sliders-horizontal.d.ts +5 -4
- package/dist/icons/generated/lucide-sliders-horizontal.d.ts.map +1 -0
- package/dist/icons/generated/lucide-sliders-horizontal.js +3 -4
- package/dist/icons/generated/lucide-sliders-horizontal.js.map +1 -1
- package/dist/icons/generated/lucide-star.d.ts +5 -4
- package/dist/icons/generated/lucide-star.d.ts.map +1 -0
- package/dist/icons/generated/lucide-star.js +3 -4
- package/dist/icons/generated/lucide-star.js.map +1 -1
- package/dist/icons/generated/lucide-tag.d.ts +5 -4
- package/dist/icons/generated/lucide-tag.d.ts.map +1 -0
- package/dist/icons/generated/lucide-tag.js +3 -4
- package/dist/icons/generated/lucide-tag.js.map +1 -1
- package/dist/icons/generated/lucide-tags.d.ts +5 -4
- package/dist/icons/generated/lucide-tags.d.ts.map +1 -0
- package/dist/icons/generated/lucide-tags.js +3 -4
- package/dist/icons/generated/lucide-tags.js.map +1 -1
- package/dist/icons/generated/lucide-trash-2.d.ts +5 -4
- package/dist/icons/generated/lucide-trash-2.d.ts.map +1 -0
- package/dist/icons/generated/lucide-trash-2.js +3 -4
- package/dist/icons/generated/lucide-trash-2.js.map +1 -1
- package/dist/icons/generated/lucide-triangle-alert.d.ts +5 -4
- package/dist/icons/generated/lucide-triangle-alert.d.ts.map +1 -0
- package/dist/icons/generated/lucide-triangle-alert.js +3 -4
- package/dist/icons/generated/lucide-triangle-alert.js.map +1 -1
- package/dist/icons/generated/lucide-undo-2.d.ts +5 -4
- package/dist/icons/generated/lucide-undo-2.d.ts.map +1 -0
- package/dist/icons/generated/lucide-undo-2.js +3 -4
- package/dist/icons/generated/lucide-undo-2.js.map +1 -1
- package/dist/icons/generated/lucide-upload.d.ts +5 -4
- package/dist/icons/generated/lucide-upload.d.ts.map +1 -0
- package/dist/icons/generated/lucide-upload.js +3 -4
- package/dist/icons/generated/lucide-upload.js.map +1 -1
- package/dist/icons/generated/lucide-user.d.ts +5 -4
- package/dist/icons/generated/lucide-user.d.ts.map +1 -0
- package/dist/icons/generated/lucide-user.js +3 -4
- package/dist/icons/generated/lucide-user.js.map +1 -1
- package/dist/icons/generated/lucide-wrench.d.ts +5 -4
- package/dist/icons/generated/lucide-wrench.d.ts.map +1 -0
- package/dist/icons/generated/lucide-wrench.js +3 -4
- package/dist/icons/generated/lucide-wrench.js.map +1 -1
- package/dist/icons/generated/lucide-x.d.ts +5 -4
- package/dist/icons/generated/lucide-x.d.ts.map +1 -0
- package/dist/icons/generated/lucide-x.js +3 -4
- package/dist/icons/generated/lucide-x.js.map +1 -1
- package/dist/icons/generated/mdi-tag-search-outline.d.ts +5 -4
- package/dist/icons/generated/mdi-tag-search-outline.d.ts.map +1 -0
- package/dist/icons/generated/mdi-tag-search-outline.js +3 -4
- package/dist/icons/generated/mdi-tag-search-outline.js.map +1 -1
- package/dist/icons/generated/ooui-close.d.ts +5 -4
- package/dist/icons/generated/ooui-close.d.ts.map +1 -0
- package/dist/icons/generated/ooui-close.js +3 -4
- package/dist/icons/generated/ooui-close.js.map +1 -1
- package/dist/icons/generated/radix-icons-panel-left-minimized.d.ts +5 -4
- package/dist/icons/generated/radix-icons-panel-left-minimized.d.ts.map +1 -0
- package/dist/icons/generated/radix-icons-panel-left-minimized.js +3 -4
- package/dist/icons/generated/radix-icons-panel-left-minimized.js.map +1 -1
- package/dist/icons/generated/radix-icons-reset.d.ts +5 -4
- package/dist/icons/generated/radix-icons-reset.d.ts.map +1 -0
- package/dist/icons/generated/radix-icons-reset.js +3 -4
- package/dist/icons/generated/radix-icons-reset.js.map +1 -1
- package/dist/icons/generated/tabler-sort-ascending-letters.d.ts +5 -4
- package/dist/icons/generated/tabler-sort-ascending-letters.d.ts.map +1 -0
- package/dist/icons/generated/tabler-sort-ascending-letters.js +3 -4
- package/dist/icons/generated/tabler-sort-ascending-letters.js.map +1 -1
- package/dist/icons/index.d.ts +75 -74
- package/dist/icons/index.js +75 -75
- package/dist/shared/element-height/index.js +51 -25
- package/dist/shared/element-height/index.js.map +1 -1
- package/dist/shared/element-width/index.js +39 -24
- package/dist/shared/element-width/index.js.map +1 -1
- package/dist/shared/events/user-change.js +14 -8
- package/dist/shared/events/user-change.js.map +1 -1
- package/dist/shared/focus/pointer-focus.js +56 -30
- package/dist/shared/focus/pointer-focus.js.map +1 -1
- package/dist/shared/focus/tabbable.js +96 -0
- package/dist/shared/focus/tabbable.js.map +1 -0
- package/dist/shared/form-association/field-id.js +13 -6
- package/dist/shared/form-association/field-id.js.map +1 -1
- package/dist/shared/form-association/index.js +75 -42
- package/dist/shared/form-association/index.js.map +1 -1
- package/dist/shared/gesture/drag-gesture.js +239 -99
- package/dist/shared/gesture/drag-gesture.js.map +1 -1
- package/dist/shared/gesture/physics.js +49 -16
- package/dist/shared/gesture/physics.js.map +1 -1
- package/dist/shared/gesture/pinch-gesture.js +111 -60
- package/dist/shared/gesture/pinch-gesture.js.map +1 -1
- package/dist/shared/group-management/index.js +181 -84
- package/dist/shared/group-management/index.js.map +1 -1
- package/dist/shared/label-emptiness/index.js +45 -26
- package/dist/shared/label-emptiness/index.js.map +1 -1
- package/dist/shared/locale/builtin-labels.js +38 -0
- package/dist/shared/locale/builtin-labels.js.map +1 -0
- package/dist/shared/menu-behavior/index.js +113 -60
- package/dist/shared/menu-behavior/index.js.map +1 -1
- package/dist/shared/menu-portal/menu-portal.js +47 -26
- package/dist/shared/menu-portal/menu-portal.js.map +1 -1
- package/dist/shared/menu-portal/menu-tree.js +132 -75
- package/dist/shared/menu-portal/menu-tree.js.map +1 -1
- package/dist/shared/normalize/index.js +16 -7
- package/dist/shared/normalize/index.js.map +1 -1
- package/dist/shared/open-state/index.js +7 -8
- package/dist/shared/open-state/index.js.map +1 -1
- package/dist/shared/option-portal/combobox-shell.js +121 -56
- package/dist/shared/option-portal/combobox-shell.js.map +1 -1
- package/dist/shared/option-portal/index.js +65 -44
- package/dist/shared/option-portal/index.js.map +1 -1
- package/dist/shared/overlay/anchored-panel.js +75 -40
- package/dist/shared/overlay/anchored-panel.js.map +1 -1
- package/dist/shared/overlay/native-dialog-presence.js +116 -52
- package/dist/shared/overlay/native-dialog-presence.js.map +1 -1
- package/dist/shared/overlay/nested-drawer-layers.js +76 -46
- package/dist/shared/overlay/nested-drawer-layers.js.map +1 -1
- package/dist/shared/overlay/open-overlay.js +240 -136
- package/dist/shared/overlay/open-overlay.js.map +1 -1
- package/dist/shared/overlay/overlay-root.js +33 -24
- package/dist/shared/overlay/overlay-root.js.map +1 -1
- package/dist/shared/overlay/overlay.js +109 -66
- package/dist/shared/overlay/overlay.js.map +1 -1
- package/dist/shared/overlay/placement-props.js +9 -4
- package/dist/shared/overlay/placement-props.js.map +1 -1
- package/dist/shared/overlay/portal.d.ts +2 -0
- package/dist/shared/overlay/portal.d.ts.map +1 -0
- package/dist/shared/overlay/portal.js +202 -117
- package/dist/shared/overlay/portal.js.map +1 -1
- package/dist/shared/overlay/positioning-generation.js +9 -10
- package/dist/shared/overlay/positioning-generation.js.map +1 -1
- package/dist/shared/overlay/presence.js +43 -21
- package/dist/shared/overlay/presence.js.map +1 -1
- package/dist/shared/overlay/theme-overlay-scope.js +22 -19
- package/dist/shared/overlay/theme-overlay-scope.js.map +1 -1
- package/dist/shared/scroll-lock/scroll-lock.js +49 -15
- package/dist/shared/scroll-lock/scroll-lock.js.map +1 -1
- package/dist/shared/theme/duration.js +13 -6
- package/dist/shared/theme/duration.js.map +1 -1
- package/dist/shared/theme/reduced-motion.js +14 -9
- package/dist/shared/theme/reduced-motion.js.map +1 -1
- package/dist/shared/theme/root-sync.js +85 -32
- package/dist/shared/theme/root-sync.js.map +1 -1
- package/dist/shared/visible-area/index.js +81 -37
- package/dist/shared/visible-area/index.js.map +1 -1
- package/dist/types/iconify.d.ts +1 -1
- package/dist/types/iconify.js +0 -0
- package/dist/types/react.d.ts +8 -10
- package/dist/types/react.d.ts.map +1 -0
- package/dist/types/react.js +0 -0
- package/dist/types/utils.d.ts +8 -13
- package/dist/types/utils.d.ts.map +1 -0
- package/dist/types/utils.js +0 -0
- package/dist/types/vue.d.ts +9 -13
- package/dist/types/vue.d.ts.map +1 -0
- package/dist/types/vue.js +0 -0
- package/dist/vite/index.d.ts +1 -0
- package/dist/vite/index.d.ts.map +1 -0
- package/dist/vite/index.js +30 -4
- package/dist/vite/index.js.map +1 -1
- package/package.json +10 -23
- package/dist/_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorate.js +0 -9
- package/dist/components/middle-ellipsis/truncate.d.ts +0 -62
- package/dist/components/radio/interaction.d.ts +0 -4
- package/dist/scrollbars/index.d.ts +0 -33
- package/dist/scrollbars/index.js +0 -18
- package/dist/scrollbars/index.js.map +0 -1
- package/dist/scrollbars/internal.js +0 -6
- package/dist/scrollbars/internal.js.map +0 -1
- package/dist/scrollbars/style.css +0 -10
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anchored-panel.js","names":[],"sources":["../../../src/shared/overlay/anchored-panel.ts"],"sourcesContent":["import { definePlugin } from '@greypan/js-kit'\n\nimport type { OpenOverlay, OpenOverlayHandle, OverlayArbitration } from './open-overlay'\nimport { defineOverlay, type OverlayApi, type OverlayOptions } from './overlay'\nimport type { OverlayPortal } from './portal'\nimport { hideOverlayPresence, showOverlayPresence } from './presence'\n\nexport interface AnchoredPanelOptions {\n getAnchor(): HTMLElement | null\n getLocalPanel(): HTMLElement | null\n getPositioning(): OverlayOptions\n isPortal(): boolean\n createPortal(): OverlayPortal\n /**\n * 承载「本 panel 是一次开启态 overlay」的实例:登记与 Escape
|
|
1
|
+
{"version":3,"file":"anchored-panel.js","names":[],"sources":["../../../src/shared/overlay/anchored-panel.ts"],"sourcesContent":["import { definePlugin } from '@greypan/js-kit'\n\nimport type { OpenOverlay, OpenOverlayHandle, OverlayArbitration } from './open-overlay'\nimport { defineOverlay, type OverlayApi, type OverlayOptions } from './overlay'\nimport type { OverlayPortal } from './portal'\nimport { hideOverlayPresence, showOverlayPresence } from './presence'\n\nexport interface AnchoredPanelOptions {\n getAnchor(): HTMLElement | null\n getLocalPanel(): HTMLElement | null\n getPositioning(): OverlayOptions\n isPortal(): boolean\n createPortal(): OverlayPortal\n /**\n * 承载「本 panel 是一次开启态 overlay」的实例:登记与 Escape 归属由它完成,本模块不\n * 自己维护逻辑父子关系。\n *\n * 必须是**调用方持有的那个实例**(而不是这里新建一个)——调用方同时要用它的帧\n * 事务入口,两个实例会让「我开着吗」重新分裂。\n */\n openOverlay: OpenOverlay\n /** 本 panel 与 Escape 仲裁的关系。tooltip 传 `none`;缺省 `escape`。 */\n arbitration?: OverlayArbitration\n}\n\n/**\n * 管理锚定 panel 的本地/Portal 容器、定位器和可中断 presence。\n * 内容迁移与交互语义由各组件保留,避免把不同组件的 public contract 混入此模块。\n */\nexport interface AnchoredPanelApi {\n getPanel(): HTMLElement | null\n /**\n * 当前在场会话的 handle;没有任何在场会话时为 `null`。\n * 查询(`contains` / `containsEvent` / `hasFocusWithin`)与 `setInert` 都走它,\n * 调用方因此不必持有 panel 引用,也不知道存在全局注册表。\n * 退场等待期间仍是同一个 handle(暂缓仲裁),动画播完或重新 `open()` 才换人。\n */\n getHandle(): OpenOverlayHandle | null\n open(isInstant?: boolean): void\n close(isStillOpen: () => boolean): Promise<boolean>\n updatePosition(): void\n reconfigure(isOpen: boolean): void\n dispose(): void\n}\n\nexport const defineAnchoredPanel = () =>\n definePlugin<AnchoredPanelApi, AnchoredPanelOptions>(ctx => {\n let overlay: OverlayApi | undefined\n let portal: OverlayPortal | undefined\n let handle: OpenOverlayHandle | null = null\n\n const getPanel = () => portal?.panel ?? ctx.getLocalPanel()\n\n const releaseHandle = () => {\n handle?.release()\n handle = null\n }\n\n const disposePortal = () => {\n if (!portal) return\n portal.restoreContent()\n portal.remove()\n portal = undefined\n overlay = undefined\n }\n\n const getOrCreatePanel = (): HTMLElement | null => {\n if (!ctx.isPortal()) return ctx.getLocalPanel()\n portal ??= ctx.createPortal()\n return portal.panel\n }\n\n const ensureOverlay = (anchor: HTMLElement, panel: HTMLElement) => {\n if (overlay) {\n overlay.updateAnchor(anchor)\n overlay.update(ctx.getPositioning())\n return\n }\n overlay = defineOverlay().make({ anchor, overlay: panel, ...ctx.getPositioning() })\n }\n\n const open = (isInstant = false) => {\n const anchor = ctx.getAnchor()\n if (!anchor) return\n const panel = getOrCreatePanel()\n if (!panel) return\n // portal panel 与宿主物理分离;本地 panel 也可能隔着 shadow 边界。\n // 以 anchor 祖先链寻找最近的已开启 overlay,建立统一逻辑父子关系。\n // claim ⟺ open:重复 open 视为新的一次开启,旧会话整体作废。\n releaseHandle()\n handle = ctx.openOverlay.claim(panel, { arbitration: ctx.arbitration, ancestryFrom: anchor })\n ensureOverlay(anchor, panel)\n overlay?.open()\n showOverlayPresence(panel, { isInstant })\n }\n\n const dispose = () => {\n overlay?.dispose()\n overlay = undefined\n releaseHandle()\n disposePortal()\n }\n\n return {\n getPanel() {\n return getPanel()\n },\n\n getHandle() {\n return handle\n },\n\n open,\n\n async close(isStillOpen) {\n /*\n * 第三态「可见但暂缓仲裁」:退场等待期间 panel 仍在场,登记不撤,但不再走关闭\n * 入口——它已经在关的路上了。撤销推迟到动画结束,或被 `open()` 以新会话取代。\n *\n * 若在这里立即 `releaseHandle()`,两条提前返回的路径都会把还看得见的 panel\n * 留在未登记状态:未登记即不参与「谁是最内层」的仲裁,直到下一次 `open()` 才\n * 恢复(issue #138)。\n *\n * 暂缓层只是兜底候选:仍在开启的外层永远优先。否则「内层关掉后立刻再按一次\n * Escape」会被退场动画吞掉,外层永远等不到自己那一次——issue #120 的契约。\n *\n * 退场被打断时 `showOverlayPresence` 已把 panel 带回场,`open()` 同时重新 claim\n * (与「重复 open 视为新的一次开启」同一条路径),本条 `close()` 随后的\n * `return false` 不碰那个新 handle。\n *\n * 走到 `isStillOpen()` 时退场已经播完:panel 已 `hidden`。此刻宿主仍认为开着,\n * 是 panel 状态与宿主状态不一致的那一格——把层交还仲裁而不是继续暂缓。继续暂缓的\n * 前提是「panel 可见」,而这里 panel 已经看不见了:一个隐藏的 panel 无限吞掉 Escape,\n * 用户再也没有按键路径把这个状态收敛掉(按一次 Escape 走宿主的关闭入口,宿主\n * 回写 open=false 后由随后的 close() 正常收尾)。登记仍然不撤,「宿主认为开着\n * 就不掉出仲裁」的 #138 语义不变。\n */\n handle?.deferArbitration()\n overlay?.close()\n const panel = getPanel()\n if (panel && !(await hideOverlayPresence(panel))) return false\n if (isStillOpen()) {\n handle?.deferArbitration(false)\n return false\n }\n releaseHandle()\n disposePortal()\n return true\n },\n\n updatePosition() {\n overlay?.update(ctx.getPositioning())\n },\n\n reconfigure(isOpen) {\n const shouldAnimate = getPanel()?.dataset.wuiPresence === 'entering'\n dispose()\n if (isOpen) open(!shouldAnimate)\n },\n\n dispose\n }\n })\n"],"mappings":";;;;AA6CA,MAAa,4BACX,cAAqD,QAAO;CAC1D,IAAI;CACJ,IAAI;CACJ,IAAI,SAAmC;CAEvC,MAAM,iBAAiB,QAAQ,SAAS,IAAI,cAAc;CAE1D,MAAM,sBAAsB;EAC1B,QAAQ,QAAQ;EAChB,SAAS;CACX;CAEA,MAAM,sBAAsB;EAC1B,IAAI,CAAC,QAAQ;EACb,OAAO,eAAe;EACtB,OAAO,OAAO;EACd,SAAS,KAAA;EACT,UAAU,KAAA;CACZ;CAEA,MAAM,yBAA6C;EACjD,IAAI,CAAC,IAAI,SAAS,GAAG,OAAO,IAAI,cAAc;EAC9C,WAAW,IAAI,aAAa;EAC5B,OAAO,OAAO;CAChB;CAEA,MAAM,iBAAiB,QAAqB,UAAuB;EACjE,IAAI,SAAS;GACX,QAAQ,aAAa,MAAM;GAC3B,QAAQ,OAAO,IAAI,eAAe,CAAC;GACnC;EACF;EACA,UAAU,cAAc,CAAC,CAAC,KAAK;GAAE;GAAQ,SAAS;GAAO,GAAG,IAAI,eAAe;EAAE,CAAC;CACpF;CAEA,MAAM,QAAQ,YAAY,UAAU;EAClC,MAAM,SAAS,IAAI,UAAU;EAC7B,IAAI,CAAC,QAAQ;EACb,MAAM,QAAQ,iBAAiB;EAC/B,IAAI,CAAC,OAAO;EAIZ,cAAc;EACd,SAAS,IAAI,YAAY,MAAM,OAAO;GAAE,aAAa,IAAI;GAAa,cAAc;EAAO,CAAC;EAC5F,cAAc,QAAQ,KAAK;EAC3B,SAAS,KAAK;EACd,oBAAoB,OAAO,EAAE,UAAU,CAAC;CAC1C;CAEA,MAAM,gBAAgB;EACpB,SAAS,QAAQ;EACjB,UAAU,KAAA;EACV,cAAc;EACd,cAAc;CAChB;CAEA,OAAO;EACL,WAAW;GACT,OAAO,SAAS;EAClB;EAEA,YAAY;GACV,OAAO;EACT;EAEA;EAEA,MAAM,MAAM,aAAa;GAuBvB,QAAQ,iBAAiB;GACzB,SAAS,MAAM;GACf,MAAM,QAAQ,SAAS;GACvB,IAAI,SAAS,CAAE,MAAM,oBAAoB,KAAK,GAAI,OAAO;GACzD,IAAI,YAAY,GAAG;IACjB,QAAQ,iBAAiB,KAAK;IAC9B,OAAO;GACT;GACA,cAAc;GACd,cAAc;GACd,OAAO;EACT;EAEA,iBAAiB;GACf,SAAS,OAAO,IAAI,eAAe,CAAC;EACtC;EAEA,YAAY,QAAQ;GAClB,MAAM,gBAAgB,SAAS,CAAC,EAAE,QAAQ,gBAAgB;GAC1D,QAAQ;GACR,IAAI,QAAQ,KAAK,CAAC,aAAa;EACjC;EAEA;CACF;AACF,CAAC"}
|
|
@@ -1,78 +1,142 @@
|
|
|
1
|
-
import { getTransitionDuration
|
|
2
|
-
import { definePlugin
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
let
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
1
|
+
import { getTransitionDuration } from "./presence.js";
|
|
2
|
+
import { definePlugin } from "@greypan/js-kit";
|
|
3
|
+
// src/shared/overlay/native-dialog-presence.ts
|
|
4
|
+
const defineNativeDialogPresence = () => definePlugin((ctx) => {
|
|
5
|
+
let closeFallbackTimer;
|
|
6
|
+
let openFrame;
|
|
7
|
+
let isClosing = false;
|
|
8
|
+
let selfClosePending = false;
|
|
9
|
+
const clearCloseFallback = () => {
|
|
10
|
+
if (closeFallbackTimer === void 0) return;
|
|
11
|
+
clearTimeout(closeFallbackTimer);
|
|
12
|
+
closeFallbackTimer = void 0;
|
|
13
|
+
};
|
|
14
|
+
const cancelOpenFrame = () => {
|
|
15
|
+
if (openFrame === void 0) return;
|
|
16
|
+
cancelAnimationFrame(openFrame);
|
|
17
|
+
openFrame = void 0;
|
|
18
|
+
};
|
|
19
|
+
const finishClosing = () => {
|
|
20
|
+
const dialog = ctx.getDialog();
|
|
21
|
+
if (!dialog || !isClosing || ctx.isOpen()) return;
|
|
22
|
+
clearCloseFallback();
|
|
23
|
+
isClosing = false;
|
|
24
|
+
dialog.classList.remove("is-closing", "is-visible");
|
|
25
|
+
if (dialog.open) {
|
|
26
|
+
selfClosePending = true;
|
|
27
|
+
dialog.close?.();
|
|
21
28
|
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
};
|
|
30
|
+
const startOpening = () => {
|
|
31
|
+
const dialog = ctx.getDialog();
|
|
32
|
+
if (!dialog) return;
|
|
33
|
+
isClosing = false;
|
|
34
|
+
clearCloseFallback();
|
|
35
|
+
dialog.classList.remove("is-closing");
|
|
36
|
+
if (!dialog.open) try {
|
|
37
|
+
dialog.showModal?.();
|
|
38
|
+
} catch {}
|
|
39
|
+
dialog.offsetWidth;
|
|
40
|
+
cancelOpenFrame();
|
|
41
|
+
openFrame = requestAnimationFrame(() => {
|
|
42
|
+
openFrame = void 0;
|
|
43
|
+
if (!ctx.isConnected() || !ctx.isOpen() || !dialog.open) return;
|
|
44
|
+
dialog.classList.add("is-visible");
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
const startClosingTransition = (dialog) => {
|
|
48
|
+
dialog.offsetWidth;
|
|
49
|
+
dialog.classList.add("is-closing");
|
|
50
|
+
dialog.classList.remove("is-visible");
|
|
51
|
+
clearCloseFallback();
|
|
52
|
+
closeFallbackTimer = setTimeout(() => finishClosing(), getTransitionDuration(dialog) + 80);
|
|
53
|
+
};
|
|
54
|
+
const startClosing = () => {
|
|
55
|
+
const dialog = ctx.getDialog();
|
|
56
|
+
if (!dialog?.open) return;
|
|
57
|
+
const hasPendingOpenFrame = openFrame !== void 0;
|
|
58
|
+
cancelOpenFrame();
|
|
59
|
+
isClosing = true;
|
|
60
|
+
if (dialog.classList.contains("is-visible")) {
|
|
61
|
+
startClosingTransition(dialog);
|
|
30
62
|
return;
|
|
31
63
|
}
|
|
32
|
-
if (!
|
|
33
|
-
|
|
64
|
+
if (!hasPendingOpenFrame) {
|
|
65
|
+
finishClosing();
|
|
34
66
|
return;
|
|
35
67
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
68
|
+
openFrame = requestAnimationFrame(() => {
|
|
69
|
+
openFrame = void 0;
|
|
70
|
+
if (!isClosing || ctx.isOpen() || !dialog.open) return;
|
|
71
|
+
const transition = dialog.style.getPropertyValue("transition");
|
|
72
|
+
const transitionPriority = dialog.style.getPropertyPriority("transition");
|
|
73
|
+
dialog.style.setProperty("transition", "none", "important");
|
|
74
|
+
dialog.classList.add("is-visible");
|
|
75
|
+
dialog.offsetWidth;
|
|
76
|
+
if (transition) dialog.style.setProperty("transition", transition, transitionPriority);
|
|
77
|
+
else dialog.style.removeProperty("transition");
|
|
78
|
+
openFrame = requestAnimationFrame(() => {
|
|
79
|
+
openFrame = void 0;
|
|
80
|
+
if (!isClosing || ctx.isOpen() || !dialog.open) return;
|
|
81
|
+
startClosingTransition(dialog);
|
|
41
82
|
});
|
|
42
83
|
});
|
|
43
|
-
}
|
|
84
|
+
};
|
|
85
|
+
const isInTopLayer = (dialog) => {
|
|
44
86
|
try {
|
|
45
|
-
return
|
|
87
|
+
return dialog.matches(":modal");
|
|
46
88
|
} catch {
|
|
47
|
-
return
|
|
89
|
+
return false;
|
|
48
90
|
}
|
|
49
91
|
};
|
|
50
92
|
return {
|
|
51
|
-
sync(
|
|
52
|
-
|
|
93
|
+
sync(open) {
|
|
94
|
+
if (open) startOpening();
|
|
95
|
+
else startClosing();
|
|
53
96
|
},
|
|
54
97
|
reconcile() {
|
|
55
|
-
|
|
56
|
-
if (
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
98
|
+
const dialog = ctx.getDialog();
|
|
99
|
+
if (!dialog) return;
|
|
100
|
+
if (!ctx.isOpen()) {
|
|
101
|
+
cancelOpenFrame();
|
|
102
|
+
clearCloseFallback();
|
|
103
|
+
isClosing = false;
|
|
104
|
+
if (dialog.open) {
|
|
105
|
+
selfClosePending = true;
|
|
106
|
+
dialog.close();
|
|
60
107
|
}
|
|
61
|
-
|
|
108
|
+
dialog.classList.remove("is-closing", "is-visible");
|
|
109
|
+
return;
|
|
62
110
|
}
|
|
111
|
+
if (dialog.open && !isInTopLayer(dialog)) {
|
|
112
|
+
selfClosePending = true;
|
|
113
|
+
dialog.close();
|
|
114
|
+
}
|
|
115
|
+
startOpening();
|
|
63
116
|
},
|
|
64
|
-
handleTransitionEnd(
|
|
65
|
-
|
|
117
|
+
handleTransitionEnd(event) {
|
|
118
|
+
if (event.target !== ctx.getDialog() || event.propertyName !== "transform") return;
|
|
119
|
+
finishClosing();
|
|
66
120
|
},
|
|
67
121
|
handleNativeClose() {
|
|
68
|
-
|
|
122
|
+
if (selfClosePending) {
|
|
123
|
+
selfClosePending = false;
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
cancelOpenFrame();
|
|
127
|
+
clearCloseFallback();
|
|
128
|
+
isClosing = false;
|
|
129
|
+
ctx.getDialog()?.classList.remove("is-closing", "is-visible");
|
|
130
|
+
return false;
|
|
69
131
|
},
|
|
70
132
|
dispose() {
|
|
71
|
-
|
|
133
|
+
cancelOpenFrame();
|
|
134
|
+
clearCloseFallback();
|
|
135
|
+
isClosing = false;
|
|
136
|
+
selfClosePending = false;
|
|
72
137
|
}
|
|
73
138
|
};
|
|
74
139
|
});
|
|
75
|
-
|
|
76
|
-
export { n as defineNativeDialogPresence };
|
|
140
|
+
export { defineNativeDialogPresence };
|
|
77
141
|
|
|
78
142
|
//# sourceMappingURL=native-dialog-presence.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"native-dialog-presence.js","names":[],"sources":["../../../src/shared/overlay/native-dialog-presence.ts"],"sourcesContent":["import { definePlugin } from '@greypan/js-kit'\n\nimport { getTransitionDuration } from './presence'\n\nexport interface NativeDialogPresenceOptions {\n getDialog(): HTMLDialogElement | null\n isConnected(): boolean\n isOpen(): boolean\n}\n\nexport interface NativeDialogPresenceApi {\n sync(open: boolean): void\n /**\n * 重挂载对账:宿主在打开态被移出文档再接回时调用。\n *\n * 平台行为(Chromium/WebKit 实测):`<dialog>` 随宿主移出文档时脱离 top layer,\n * 但 `open` 属性残留。此时 `sync(true)` 救不回来——`startOpening` 的\n * `if (!dialog.open)` 守卫会跳过 `showModal`,而直接对残留 open 的 dialog 调\n * `showModal` 会抛 `InvalidStateError`;且排队的 `close` 事件若被消费方当成\n * 外部关闭,会把 `open` 误置为 false。本方法先标记 self-close 再真正 close,\n * 随后走 `startOpening`(此刻 open 属性已清,`showModal` 正常执行,排队的\n * `close` 事件由 `handleNativeClose` 消费),dialog 因此同步回到 top layer。\n */\n reconcile(): void\n handleTransitionEnd(event: TransitionEvent): void\n /**\n * 处理原生 dialog 的 `close` 事件。\n *\n * 返回 `true` 表示该事件是本模块自己 `finishClosing → dialog.close()` 排队的\n * 异步事件(正常时序在本关闭会话内到达,快速重开时在重开后到达的过期事件),\n * 消费方不应把它当成外部关闭;返回 `false` 表示真实的外部关闭\n * (如表单 method=\"dialog\"、宿主程序化 dialog.close()),消费方需自行恢复状态。\n */\n handleNativeClose(): boolean\n dispose(): void\n}\n\n// 管理原生 dialog 保持在 top layer 直至退出动画完成的生命周期。\nexport const defineNativeDialogPresence = () =>\n definePlugin<NativeDialogPresenceApi, NativeDialogPresenceOptions>(ctx => {\n let closeFallbackTimer: ReturnType<typeof setTimeout> | undefined\n let openFrame: number | undefined\n let isClosing = false\n // 由本模块 finishClosing 主动 dialog.close() 时置 true。原生 dialog 的 close 事件\n // 是异步任务(queue a task),可能在之后任意时刻才到达:正常时序在本关闭会话内\n // 到达(消费方 open 已为 false,本就该忽略);快速「关闭→重开」时它在重新打开\n // 之后才到达,若消费方把它当成外部关闭,会把刚重开的 dialog 关掉——这是 drawer\n // 连续 toggle 后丢失过渡动画(重开即被误关)的根因。置位后由消费方的\n // handleNativeClose 经 handleNativeClose() 消费;消费方 open 为 false 提前返回时\n // 也必须调用一次以消费标志,避免泄漏到下一次真实关闭。\n let selfClosePending = false\n\n const clearCloseFallback = () => {\n if (closeFallbackTimer === undefined) return\n clearTimeout(closeFallbackTimer)\n closeFallbackTimer = undefined\n }\n\n const cancelOpenFrame = () => {\n if (openFrame === undefined) return\n cancelAnimationFrame(openFrame)\n openFrame = undefined\n }\n\n const finishClosing = () => {\n const dialog = ctx.getDialog()\n if (!dialog || !isClosing || ctx.isOpen()) return\n clearCloseFallback()\n isClosing = false\n dialog.classList.remove('is-closing', 'is-visible')\n if (dialog.open) {\n selfClosePending = true\n dialog.close?.()\n }\n }\n\n const startOpening = () => {\n const dialog = ctx.getDialog()\n if (!dialog) return\n isClosing = false\n clearCloseFallback()\n dialog.classList.remove('is-closing')\n if (!dialog.open) {\n try {\n // 并发多个 modal dialog(nested drawer 场景)在规范中合法;\n // 此 try/catch 为防御性兜底(如对已在 top layer 的 dialog 重复 showModal\n // 会抛 InvalidStateError),失败时由下方 rAF 回调的 dialog.open 判断中止动画。\n dialog.showModal?.()\n } catch {\n // 保留未打开状态\n }\n }\n // 强制计算初始 top-layer 布局,确保 Safari 等浏览器在下一帧切换 class 时\n // 有稳定的 transition 起点,而不是偶发跳过进场过渡。\n void dialog.offsetWidth\n\n cancelOpenFrame()\n openFrame = requestAnimationFrame(() => {\n openFrame = undefined\n if (!ctx.isConnected() || !ctx.isOpen() || !dialog.open) return\n dialog.classList.add('is-visible')\n })\n }\n\n const startClosingTransition = (dialog: HTMLDialogElement) => {\n // WebKit may coalesce class changes in the same style scope and skip the transition\n // when the previous computed state has not been submitted yet.\n void dialog.offsetWidth\n dialog.classList.add('is-closing')\n dialog.classList.remove('is-visible')\n clearCloseFallback()\n closeFallbackTimer = setTimeout(() => finishClosing(), getTransitionDuration(dialog) + 80)\n }\n\n const startClosing = () => {\n const dialog = ctx.getDialog()\n if (!dialog?.open) return\n const hasPendingOpenFrame = openFrame !== undefined\n cancelOpenFrame()\n isClosing = true\n if (dialog.classList.contains('is-visible')) {\n startClosingTransition(dialog)\n return\n }\n if (!hasPendingOpenFrame) {\n finishClosing()\n return\n }\n\n // 关闭可能先于打开路径的首个 rAF 到达。先用一帧补齐可见态并强制提交布局,\n // 再用下一帧切换 closing,让退出 transition 有稳定的起点。进场 transition\n // 不能参与这次布局提交,否则当前 transform 仍停在闭合起点。\n openFrame = requestAnimationFrame(() => {\n openFrame = undefined\n if (!isClosing || ctx.isOpen() || !dialog.open) return\n const transition = dialog.style.getPropertyValue('transition')\n const transitionPriority = dialog.style.getPropertyPriority('transition')\n dialog.style.setProperty('transition', 'none', 'important')\n dialog.classList.add('is-visible')\n void dialog.offsetWidth\n if (transition) {\n dialog.style.setProperty('transition', transition, transitionPriority)\n } else {\n dialog.style.removeProperty('transition')\n }\n openFrame = requestAnimationFrame(() => {\n openFrame = undefined\n if (!isClosing || ctx.isOpen() || !dialog.open) return\n startClosingTransition(dialog)\n })\n })\n }\n\n // jsdom 的选择器引擎不认识 :modal(可能抛错);抛错按「不在 top layer」处理,\n // reconcile 随之走 close+showModal 的收敛路径,行为仍正确。\n const isInTopLayer = (dialog: HTMLDialogElement): boolean => {\n try {\n return dialog.matches(':modal')\n } catch {\n return false\n }\n }\n\n return {\n sync(open) {\n if (open) startOpening()\n else startClosing()\n },\n\n reconcile() {\n const dialog = ctx.getDialog()\n if (!dialog) return\n\n if (!ctx.isOpen()) {\n // 宿主在断连期间被置为关闭(或关闭动画被 disconnect 打断):\n // updated() 在断连时被跳过,inner dialog 可能仍残留 open 属性与\n // is-visible/is-closing class,补一次强制收敛到关闭态。\n cancelOpenFrame()\n clearCloseFallback()\n isClosing = false\n if (dialog.open) {\n selfClosePending = true\n dialog.close()\n }\n dialog.classList.remove('is-closing', 'is-visible')\n return\n }\n\n // 打开态重挂载:open 属性残留但已脱离 top layer 时,必须先真关闭再重开。\n if (dialog.open && !isInTopLayer(dialog)) {\n selfClosePending = true\n dialog.close()\n }\n startOpening()\n },\n\n handleTransitionEnd(event) {\n if (event.target !== ctx.getDialog() || event.propertyName !== 'transform') return\n finishClosing()\n },\n\n handleNativeClose() {\n if (selfClosePending) {\n // 我们自己的 dialog.close() 排队的事件:正常时序在本会话内到达、快速重开\n // 时是上一会话的过期事件——两种情况本模块都已在 finishClosing 完成全部清理,\n // 消费标志并让调用方跳过外部关闭处理即可。\n selfClosePending = false\n return true\n }\n // 真实的外部关闭:重置打开/关闭状态,等待消费方恢复(如 open=false)。\n cancelOpenFrame()\n clearCloseFallback()\n isClosing = false\n ctx.getDialog()?.classList.remove('is-closing', 'is-visible')\n return false\n },\n\n dispose() {\n cancelOpenFrame()\n clearCloseFallback()\n isClosing = false\n selfClosePending = false\n }\n }\n })\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"native-dialog-presence.js","names":[],"sources":["../../../src/shared/overlay/native-dialog-presence.ts"],"sourcesContent":["import { definePlugin } from '@greypan/js-kit'\n\nimport { getTransitionDuration } from './presence'\n\nexport interface NativeDialogPresenceOptions {\n getDialog(): HTMLDialogElement | null\n isConnected(): boolean\n isOpen(): boolean\n}\n\nexport interface NativeDialogPresenceApi {\n sync(open: boolean): void\n /**\n * 重挂载对账:宿主在打开态被移出文档再接回时调用。\n *\n * 平台行为(Chromium/WebKit 实测):`<dialog>` 随宿主移出文档时脱离 top layer,\n * 但 `open` 属性残留。此时 `sync(true)` 救不回来——`startOpening` 的\n * `if (!dialog.open)` 守卫会跳过 `showModal`,而直接对残留 open 的 dialog 调\n * `showModal` 会抛 `InvalidStateError`;且排队的 `close` 事件若被消费方当成\n * 外部关闭,会把 `open` 误置为 false。本方法先标记 self-close 再真正 close,\n * 随后走 `startOpening`(此刻 open 属性已清,`showModal` 正常执行,排队的\n * `close` 事件由 `handleNativeClose` 消费),dialog 因此同步回到 top layer。\n */\n reconcile(): void\n handleTransitionEnd(event: TransitionEvent): void\n /**\n * 处理原生 dialog 的 `close` 事件。\n *\n * 返回 `true` 表示该事件是本模块自己 `finishClosing → dialog.close()` 排队的\n * 异步事件(正常时序在本关闭会话内到达,快速重开时在重开后到达的过期事件),\n * 消费方不应把它当成外部关闭;返回 `false` 表示真实的外部关闭\n * (如表单 method=\"dialog\"、宿主程序化 dialog.close()),消费方需自行恢复状态。\n */\n handleNativeClose(): boolean\n dispose(): void\n}\n\n// 管理原生 dialog 保持在 top layer 直至退出动画完成的生命周期。\nexport const defineNativeDialogPresence = () =>\n definePlugin<NativeDialogPresenceApi, NativeDialogPresenceOptions>(ctx => {\n let closeFallbackTimer: ReturnType<typeof setTimeout> | undefined\n let openFrame: number | undefined\n let isClosing = false\n // 由本模块 finishClosing 主动 dialog.close() 时置 true。原生 dialog 的 close 事件\n // 是异步任务(queue a task),可能在之后任意时刻才到达:正常时序在本关闭会话内\n // 到达(消费方 open 已为 false,本就该忽略);快速「关闭→重开」时它在重新打开\n // 之后才到达,若消费方把它当成外部关闭,会把刚重开的 dialog 关掉——这是 drawer\n // 连续 toggle 后丢失过渡动画(重开即被误关)的根因。置位后由消费方的\n // handleNativeClose 经 handleNativeClose() 消费;消费方 open 为 false 提前返回时\n // 也必须调用一次以消费标志,避免泄漏到下一次真实关闭。\n let selfClosePending = false\n\n const clearCloseFallback = () => {\n if (closeFallbackTimer === undefined) return\n clearTimeout(closeFallbackTimer)\n closeFallbackTimer = undefined\n }\n\n const cancelOpenFrame = () => {\n if (openFrame === undefined) return\n cancelAnimationFrame(openFrame)\n openFrame = undefined\n }\n\n const finishClosing = () => {\n const dialog = ctx.getDialog()\n if (!dialog || !isClosing || ctx.isOpen()) return\n clearCloseFallback()\n isClosing = false\n dialog.classList.remove('is-closing', 'is-visible')\n if (dialog.open) {\n selfClosePending = true\n dialog.close?.()\n }\n }\n\n const startOpening = () => {\n const dialog = ctx.getDialog()\n if (!dialog) return\n isClosing = false\n clearCloseFallback()\n dialog.classList.remove('is-closing')\n if (!dialog.open) {\n try {\n // 并发多个 modal dialog(nested drawer 场景)在规范中合法;\n // 此 try/catch 为防御性兜底(如对已在 top layer 的 dialog 重复 showModal\n // 会抛 InvalidStateError),失败时由下方 rAF 回调的 dialog.open 判断中止动画。\n dialog.showModal?.()\n } catch {\n // 保留未打开状态\n }\n }\n // 强制计算初始 top-layer 布局,确保 Safari 等浏览器在下一帧切换 class 时\n // 有稳定的 transition 起点,而不是偶发跳过进场过渡。\n void dialog.offsetWidth\n\n cancelOpenFrame()\n openFrame = requestAnimationFrame(() => {\n openFrame = undefined\n if (!ctx.isConnected() || !ctx.isOpen() || !dialog.open) return\n dialog.classList.add('is-visible')\n })\n }\n\n const startClosingTransition = (dialog: HTMLDialogElement) => {\n // WebKit may coalesce class changes in the same style scope and skip the transition\n // when the previous computed state has not been submitted yet.\n void dialog.offsetWidth\n dialog.classList.add('is-closing')\n dialog.classList.remove('is-visible')\n clearCloseFallback()\n closeFallbackTimer = setTimeout(() => finishClosing(), getTransitionDuration(dialog) + 80)\n }\n\n const startClosing = () => {\n const dialog = ctx.getDialog()\n if (!dialog?.open) return\n const hasPendingOpenFrame = openFrame !== undefined\n cancelOpenFrame()\n isClosing = true\n if (dialog.classList.contains('is-visible')) {\n startClosingTransition(dialog)\n return\n }\n if (!hasPendingOpenFrame) {\n finishClosing()\n return\n }\n\n // 关闭可能先于打开路径的首个 rAF 到达。先用一帧补齐可见态并强制提交布局,\n // 再用下一帧切换 closing,让退出 transition 有稳定的起点。进场 transition\n // 不能参与这次布局提交,否则当前 transform 仍停在闭合起点。\n openFrame = requestAnimationFrame(() => {\n openFrame = undefined\n if (!isClosing || ctx.isOpen() || !dialog.open) return\n const transition = dialog.style.getPropertyValue('transition')\n const transitionPriority = dialog.style.getPropertyPriority('transition')\n dialog.style.setProperty('transition', 'none', 'important')\n dialog.classList.add('is-visible')\n void dialog.offsetWidth\n if (transition) {\n dialog.style.setProperty('transition', transition, transitionPriority)\n } else {\n dialog.style.removeProperty('transition')\n }\n openFrame = requestAnimationFrame(() => {\n openFrame = undefined\n if (!isClosing || ctx.isOpen() || !dialog.open) return\n startClosingTransition(dialog)\n })\n })\n }\n\n // jsdom 的选择器引擎不认识 :modal(可能抛错);抛错按「不在 top layer」处理,\n // reconcile 随之走 close+showModal 的收敛路径,行为仍正确。\n const isInTopLayer = (dialog: HTMLDialogElement): boolean => {\n try {\n return dialog.matches(':modal')\n } catch {\n return false\n }\n }\n\n return {\n sync(open) {\n if (open) startOpening()\n else startClosing()\n },\n\n reconcile() {\n const dialog = ctx.getDialog()\n if (!dialog) return\n\n if (!ctx.isOpen()) {\n // 宿主在断连期间被置为关闭(或关闭动画被 disconnect 打断):\n // updated() 在断连时被跳过,inner dialog 可能仍残留 open 属性与\n // is-visible/is-closing class,补一次强制收敛到关闭态。\n cancelOpenFrame()\n clearCloseFallback()\n isClosing = false\n if (dialog.open) {\n selfClosePending = true\n dialog.close()\n }\n dialog.classList.remove('is-closing', 'is-visible')\n return\n }\n\n // 打开态重挂载:open 属性残留但已脱离 top layer 时,必须先真关闭再重开。\n if (dialog.open && !isInTopLayer(dialog)) {\n selfClosePending = true\n dialog.close()\n }\n startOpening()\n },\n\n handleTransitionEnd(event) {\n if (event.target !== ctx.getDialog() || event.propertyName !== 'transform') return\n finishClosing()\n },\n\n handleNativeClose() {\n if (selfClosePending) {\n // 我们自己的 dialog.close() 排队的事件:正常时序在本会话内到达、快速重开\n // 时是上一会话的过期事件——两种情况本模块都已在 finishClosing 完成全部清理,\n // 消费标志并让调用方跳过外部关闭处理即可。\n selfClosePending = false\n return true\n }\n // 真实的外部关闭:重置打开/关闭状态,等待消费方恢复(如 open=false)。\n cancelOpenFrame()\n clearCloseFallback()\n isClosing = false\n ctx.getDialog()?.classList.remove('is-closing', 'is-visible')\n return false\n },\n\n dispose() {\n cancelOpenFrame()\n clearCloseFallback()\n isClosing = false\n selfClosePending = false\n }\n }\n })\n"],"mappings":"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"}
|
|
@@ -1,65 +1,95 @@
|
|
|
1
|
-
import { definePlugin
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import { definePlugin } from "@greypan/js-kit";
|
|
2
|
+
// src/shared/overlay/nested-drawer-layers.ts
|
|
3
|
+
const DEPTH_VARIABLE = "--wui-internal-drawer-nested-depth";
|
|
4
|
+
const NESTED_SCALE = .95;
|
|
5
|
+
const PEEK_BASE_VARIABLE = "--wui-drawer-nested-peek-base";
|
|
6
|
+
const NESTED_PEEK_BASE_FALLBACK = 43.2;
|
|
7
|
+
const NESTED_PEEK_BASE_QUERY = "(width <= 640px)";
|
|
8
|
+
const entries = /* @__PURE__ */ new Set();
|
|
9
|
+
let documentListenerAttached = false;
|
|
10
|
+
let peekBaseQuery = null;
|
|
11
|
+
function readPeekBase(dialog) {
|
|
12
|
+
const raw = getComputedStyle(dialog).getPropertyValue(PEEK_BASE_VARIABLE);
|
|
13
|
+
const parsed = Number.parseFloat(raw);
|
|
14
|
+
return Number.isFinite(parsed) ? parsed : NESTED_PEEK_BASE_FALLBACK;
|
|
7
15
|
}
|
|
8
|
-
function
|
|
9
|
-
|
|
16
|
+
function handlePeekBaseChange() {
|
|
17
|
+
if (entries.size > 0) applyLayers();
|
|
10
18
|
}
|
|
11
|
-
function
|
|
12
|
-
|
|
13
|
-
for (
|
|
14
|
-
|
|
15
|
-
if (!
|
|
16
|
-
|
|
19
|
+
function applyLayers() {
|
|
20
|
+
const openEntries = [];
|
|
21
|
+
for (const entry of entries) {
|
|
22
|
+
const dialog = entry.dialog;
|
|
23
|
+
if (!dialog.isConnected || !dialog.open) {
|
|
24
|
+
entries.delete(entry);
|
|
17
25
|
continue;
|
|
18
26
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
entry
|
|
22
|
-
dialog
|
|
23
|
-
size
|
|
27
|
+
const size = entry.placement() === "left" || entry.placement() === "right" ? dialog.offsetWidth : dialog.offsetHeight;
|
|
28
|
+
openEntries.push({
|
|
29
|
+
entry,
|
|
30
|
+
dialog,
|
|
31
|
+
size
|
|
24
32
|
});
|
|
25
33
|
}
|
|
26
|
-
|
|
27
|
-
for (let i = 0; i <
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
34
|
+
const total = openEntries.length;
|
|
35
|
+
for (let i = 0; i < total; i++) {
|
|
36
|
+
const { dialog, size } = openEntries[i];
|
|
37
|
+
const depth = total - 1 - i;
|
|
38
|
+
const scale = Math.pow(NESTED_SCALE, depth);
|
|
39
|
+
const shrink = size * (1 - scale) / 2;
|
|
40
|
+
let aboveMaxSize = 0;
|
|
41
|
+
for (let j = i + 1; j < total; j++) if (openEntries[j].size > aboveMaxSize) aboveMaxSize = openEntries[j].size;
|
|
42
|
+
const sizeDiff = Math.max(0, aboveMaxSize - size);
|
|
43
|
+
const peek = readPeekBase(dialog) * Math.log(depth + 1);
|
|
44
|
+
const shift = depth > 0 ? shrink + sizeDiff + peek : 0;
|
|
45
|
+
dialog.style.setProperty(DEPTH_VARIABLE, String(depth));
|
|
46
|
+
dialog.style.setProperty("--wui-internal-drawer-nested-scale", scale.toFixed(4));
|
|
47
|
+
dialog.style.setProperty("--wui-internal-drawer-nested-shift", `${shift.toFixed(2)}px`);
|
|
48
|
+
if (depth > 0) dialog.classList.add("is-nested-lower");
|
|
49
|
+
else dialog.classList.remove("is-nested-lower");
|
|
32
50
|
}
|
|
33
51
|
}
|
|
34
|
-
function
|
|
35
|
-
|
|
52
|
+
function handleAnyDialogClose(event) {
|
|
53
|
+
if (!(event.target instanceof HTMLDialogElement)) return;
|
|
54
|
+
if (entries.size > 0) applyLayers();
|
|
36
55
|
}
|
|
37
|
-
function
|
|
38
|
-
|
|
56
|
+
function ensureDocumentListener() {
|
|
57
|
+
if (documentListenerAttached) return;
|
|
58
|
+
document.addEventListener("close", handleAnyDialogClose, true);
|
|
59
|
+
if (typeof window.matchMedia === "function") {
|
|
60
|
+
peekBaseQuery = window.matchMedia(NESTED_PEEK_BASE_QUERY);
|
|
61
|
+
peekBaseQuery.addEventListener("change", handlePeekBaseChange);
|
|
62
|
+
}
|
|
63
|
+
documentListenerAttached = true;
|
|
39
64
|
}
|
|
40
|
-
|
|
65
|
+
const defineNestedDrawerLayers = () => definePlugin((ctx) => ({
|
|
41
66
|
register() {
|
|
42
|
-
|
|
43
|
-
if (
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
67
|
+
const dialog = ctx.getDialog();
|
|
68
|
+
if (!dialog) return;
|
|
69
|
+
for (const entry of entries) if (entry.dialog === dialog) entries.delete(entry);
|
|
70
|
+
ensureDocumentListener();
|
|
71
|
+
entries.add({
|
|
72
|
+
dialog,
|
|
73
|
+
placement: () => ctx.getPlacement()
|
|
74
|
+
});
|
|
75
|
+
applyLayers();
|
|
50
76
|
},
|
|
51
77
|
unregister() {
|
|
52
|
-
|
|
53
|
-
for (
|
|
54
|
-
|
|
78
|
+
const dialog = ctx.getDialog();
|
|
79
|
+
for (const entry of entries) if (entry.dialog === dialog) entries.delete(entry);
|
|
80
|
+
if (entries.size > 0) applyLayers();
|
|
55
81
|
},
|
|
56
82
|
dispose() {
|
|
57
|
-
|
|
58
|
-
for (
|
|
59
|
-
|
|
83
|
+
const dialog = ctx.getDialog();
|
|
84
|
+
for (const entry of entries) if (entry.dialog === dialog) entries.delete(entry);
|
|
85
|
+
if (entries.size === 0 && documentListenerAttached) {
|
|
86
|
+
document.removeEventListener("close", handleAnyDialogClose, true);
|
|
87
|
+
peekBaseQuery?.removeEventListener("change", handlePeekBaseChange);
|
|
88
|
+
peekBaseQuery = null;
|
|
89
|
+
documentListenerAttached = false;
|
|
90
|
+
}
|
|
60
91
|
}
|
|
61
92
|
}));
|
|
62
|
-
|
|
63
|
-
export { i as NESTED_PEEK_BASE_FALLBACK, r as PEEK_BASE_VARIABLE, m as defineNestedDrawerLayers };
|
|
93
|
+
export { NESTED_PEEK_BASE_FALLBACK, PEEK_BASE_VARIABLE, defineNestedDrawerLayers };
|
|
64
94
|
|
|
65
95
|
//# sourceMappingURL=nested-drawer-layers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nested-drawer-layers.js","names":[],"sources":["../../../src/shared/overlay/nested-drawer-layers.ts"],"sourcesContent":["/*\n * Nested drawer 层序管理:\n * 每打开一层 modal drawer,其下所有已打开的 drawer 按 0.95^n 缩放并向\n * 屏幕内侧平移,在顶层 drawer 后方露出阶梯式卡片边缘(peeking edge);顶层全尺寸。\n *\n * 层序来源是原生 top layer 本身:depth = 在自身 showModal 之前已打开的\n * modal dialog 数。上层关闭通过 document 捕获阶段的 `close` 事件感知\n * (原生 close 事件不冒泡,但捕获阶段在 document 上可观察所有 target),\n * 底层重算 depth 后由 CSS transition 平滑回弹。\n *\n * 视觉规格:\n * - scale = 0.95^depth\n * - 堆叠总宽度随层数按对数曲线增长:T(n) = base · ln(n)。\n * shift = shrink + sizeDiff + base · ln(depth + 1)(向屏幕内侧偏移,露出阶梯卡片边缘)。\n * ln(1) = 0,单层不受影响;层数越多每层新增的露边越少,堆叠总宽不随层数线性膨胀。\n * base 读自公开 token `--wui-drawer-nested-peek-base`(注册项的 initialValue 是桌面\n * 基准的唯一真相源,窄视口基准由 drawer 的媒体查询覆盖),消费方可整体改写层叠观感。\n * - 过渡 transform 450ms cubic-bezier(0.22, 1, 0.36, 1)\n *\n * 拖拽与释放后的收尾期间 JS 直接写 dialog.style.transform(优先级高于本机制的\n * CSS 变量组合),顶层才有拖拽,故无冲突。\n */\n\nimport { definePlugin } from '@greypan/js-kit'\n\nconst DEPTH_VARIABLE = '--wui-internal-drawer-nested-depth'\nconst NESTED_SCALE = 0.95\nexport const PEEK_BASE_VARIABLE = '--wui-drawer-nested-peek-base'\n/*\n * 注册项 initialValue 的镜像,**不是**第二真相源:真实基准由 drawer/index.ts 的\n * `CSS.registerProperty` 决定,浏览器里 computed style 永远有值,走不到这个兜底。\n * 保留它只为 jsdom——那里没有 registerProperty,getComputedStyle 返回空串,\n * 层序数学仍需要有定义的基准。浏览器 spec 有一条断言把两者钉在一起,防止漂移。\n */\nexport const NESTED_PEEK_BASE_FALLBACK = 43.2\n/*\n * 与 drawer/style.css 里 `@media (width <= 640px)` 同一条断点:跨越断点时媒体查询会\n * 换掉基准,已打开的堆叠要重算,否则会停留在旧断点的露边宽度上。\n */\nconst NESTED_PEEK_BASE_QUERY = '(width <= 640px)'\n\ninterface NestedDrawerEntry {\n dialog: HTMLDialogElement\n placement: () => 'right' | 'left' | 'top' | 'bottom'\n}\n\nconst entries = new Set<NestedDrawerEntry>()\n\nlet documentListenerAttached = false\nlet peekBaseQuery: MediaQueryList | null = null\n\nfunction readPeekBase(dialog: HTMLDialogElement): number {\n const raw = getComputedStyle(dialog).getPropertyValue(PEEK_BASE_VARIABLE)\n const parsed = Number.parseFloat(raw)\n return Number.isFinite(parsed) ? parsed : NESTED_PEEK_BASE_FALLBACK\n}\n\nfunction handlePeekBaseChange() {\n if (entries.size > 0) applyLayers()\n}\n\nfunction applyLayers() {\n const openEntries: Array<{\n entry: NestedDrawerEntry\n dialog: HTMLDialogElement\n size: number\n }> = []\n\n for (const entry of entries) {\n const dialog = entry.dialog\n if (!dialog.isConnected || !dialog.open) {\n entries.delete(entry)\n continue\n }\n const size =\n entry.placement() === 'left' || entry.placement() === 'right' ? dialog.offsetWidth : dialog.offsetHeight\n openEntries.push({ entry, dialog, size })\n }\n\n const total = openEntries.length\n for (let i = 0; i < total; i++) {\n const { dialog, size } = openEntries[i]\n // 注册顺序:先打开的在前 (index 小),后打开的在后 (index 大)。\n // depth = 在我之后打开的 drawer 数量 = (total - 1) - i\n const depth = total - 1 - i\n const scale = Math.pow(NESTED_SCALE, depth)\n const shrink = (size * (1 - scale)) / 2\n\n // 检查所有排在我之后的上层 drawer 的最大尺寸(若上层更宽,补偿宽度差确保露边)\n let aboveMaxSize = 0\n for (let j = i + 1; j < total; j++) {\n if (openEntries[j].size > aboveMaxSize) {\n aboveMaxSize = openEntries[j].size\n }\n }\n const sizeDiff = Math.max(0, aboveMaxSize - size)\n // 逐层读基准:消费方可以给某一层单独换基准,不必所有层共用一个值。\n const peek = readPeekBase(dialog) * Math.log(depth + 1)\n // depth 0 显式归零:单层 drawer 的偏移不依赖 ln(1) 的浮点结果,也不依赖基准是否被改写。\n const shift = depth > 0 ? shrink + sizeDiff + peek : 0\n\n dialog.style.setProperty(DEPTH_VARIABLE, String(depth))\n dialog.style.setProperty('--wui-internal-drawer-nested-scale', scale.toFixed(4))\n dialog.style.setProperty('--wui-internal-drawer-nested-shift', `${shift.toFixed(2)}px`)\n if (depth > 0) {\n dialog.classList.add('is-nested-lower')\n } else {\n dialog.classList.remove('is-nested-lower')\n }\n }\n}\n\nfunction handleAnyDialogClose(event: Event) {\n if (!(event.target instanceof HTMLDialogElement)) return\n // 上层(或任意层)关闭后,重算所有存活 drawer 的 depth。\n if (entries.size > 0) applyLayers()\n}\n\nfunction ensureDocumentListener() {\n if (documentListenerAttached) return\n document.addEventListener('close', handleAnyDialogClose, true)\n // jsdom 等无 matchMedia 的环境:媒体查询换不掉基准,但打开/关闭路径仍会重算。\n if (typeof window.matchMedia === 'function') {\n peekBaseQuery = window.matchMedia(NESTED_PEEK_BASE_QUERY)\n peekBaseQuery.addEventListener('change', handlePeekBaseChange)\n }\n documentListenerAttached = true\n}\n\nexport interface NestedDrawerLayerOptions {\n getDialog(): HTMLDialogElement | null\n getPlacement(): 'right' | 'left' | 'top' | 'bottom'\n}\n\nexport interface NestedDrawerLayerApi {\n /** dialog 进入 top layer(打开动画就绪)后调用,纳入层序管理。 */\n register(): void\n /** 关闭流程开始时调用:移出层序并触发底层回弹。 */\n unregister(): void\n dispose(): void\n}\n\nexport const defineNestedDrawerLayers = () =>\n definePlugin<NestedDrawerLayerApi, NestedDrawerLayerOptions>(ctx => ({\n register() {\n const dialog = ctx.getDialog()\n if (!dialog) return\n // 幂等保护:重挂载对账与 updated() 的 open 分支可能对同一 dialog 先后各调\n // 一次 register,重复条目会让 applyLayers 把同一层计两次。\n for (const entry of entries) {\n if (entry.dialog === dialog) entries.delete(entry)\n }\n ensureDocumentListener()\n entries.add({ dialog, placement: () => ctx.getPlacement() })\n applyLayers()\n },\n\n unregister() {\n const dialog = ctx.getDialog()\n for (const entry of entries) {\n if (entry.dialog === dialog) entries.delete(entry)\n }\n // 移除后重算剩余层(顶层关闭 → 次层回到 depth 0)。\n if (entries.size > 0) applyLayers()\n },\n\n dispose() {\n const dialog = ctx.getDialog()\n for (const entry of entries) {\n if (entry.dialog === dialog) entries.delete(entry)\n }\n if (entries.size === 0 && documentListenerAttached) {\n document.removeEventListener('close', handleAnyDialogClose, true)\n peekBaseQuery?.removeEventListener('change', handlePeekBaseChange)\n peekBaseQuery = null\n documentListenerAttached = false\n }\n }\n }))\n"],"mappings":";;AAyBA,
|
|
1
|
+
{"version":3,"file":"nested-drawer-layers.js","names":[],"sources":["../../../src/shared/overlay/nested-drawer-layers.ts"],"sourcesContent":["/*\n * Nested drawer 层序管理:\n * 每打开一层 modal drawer,其下所有已打开的 drawer 按 0.95^n 缩放并向\n * 屏幕内侧平移,在顶层 drawer 后方露出阶梯式卡片边缘(peeking edge);顶层全尺寸。\n *\n * 层序来源是原生 top layer 本身:depth = 在自身 showModal 之前已打开的\n * modal dialog 数。上层关闭通过 document 捕获阶段的 `close` 事件感知\n * (原生 close 事件不冒泡,但捕获阶段在 document 上可观察所有 target),\n * 底层重算 depth 后由 CSS transition 平滑回弹。\n *\n * 视觉规格:\n * - scale = 0.95^depth\n * - 堆叠总宽度随层数按对数曲线增长:T(n) = base · ln(n)。\n * shift = shrink + sizeDiff + base · ln(depth + 1)(向屏幕内侧偏移,露出阶梯卡片边缘)。\n * ln(1) = 0,单层不受影响;层数越多每层新增的露边越少,堆叠总宽不随层数线性膨胀。\n * base 读自公开 token `--wui-drawer-nested-peek-base`(注册项的 initialValue 是桌面\n * 基准的唯一真相源,窄视口基准由 drawer 的媒体查询覆盖),消费方可整体改写层叠观感。\n * - 过渡 transform 450ms cubic-bezier(0.22, 1, 0.36, 1)\n *\n * 拖拽与释放后的收尾期间 JS 直接写 dialog.style.transform(优先级高于本机制的\n * CSS 变量组合),顶层才有拖拽,故无冲突。\n */\n\nimport { definePlugin } from '@greypan/js-kit'\n\nconst DEPTH_VARIABLE = '--wui-internal-drawer-nested-depth'\nconst NESTED_SCALE = 0.95\nexport const PEEK_BASE_VARIABLE = '--wui-drawer-nested-peek-base'\n/*\n * 注册项 initialValue 的镜像,**不是**第二真相源:真实基准由 drawer/index.ts 的\n * `CSS.registerProperty` 决定,浏览器里 computed style 永远有值,走不到这个兜底。\n * 保留它只为 jsdom——那里没有 registerProperty,getComputedStyle 返回空串,\n * 层序数学仍需要有定义的基准。浏览器 spec 有一条断言把两者钉在一起,防止漂移。\n */\nexport const NESTED_PEEK_BASE_FALLBACK = 43.2\n/*\n * 与 drawer/style.css 里 `@media (width <= 640px)` 同一条断点:跨越断点时媒体查询会\n * 换掉基准,已打开的堆叠要重算,否则会停留在旧断点的露边宽度上。\n */\nconst NESTED_PEEK_BASE_QUERY = '(width <= 640px)'\n\ninterface NestedDrawerEntry {\n dialog: HTMLDialogElement\n placement: () => 'right' | 'left' | 'top' | 'bottom'\n}\n\nconst entries = new Set<NestedDrawerEntry>()\n\nlet documentListenerAttached = false\nlet peekBaseQuery: MediaQueryList | null = null\n\nfunction readPeekBase(dialog: HTMLDialogElement): number {\n const raw = getComputedStyle(dialog).getPropertyValue(PEEK_BASE_VARIABLE)\n const parsed = Number.parseFloat(raw)\n return Number.isFinite(parsed) ? parsed : NESTED_PEEK_BASE_FALLBACK\n}\n\nfunction handlePeekBaseChange() {\n if (entries.size > 0) applyLayers()\n}\n\nfunction applyLayers() {\n const openEntries: Array<{\n entry: NestedDrawerEntry\n dialog: HTMLDialogElement\n size: number\n }> = []\n\n for (const entry of entries) {\n const dialog = entry.dialog\n if (!dialog.isConnected || !dialog.open) {\n entries.delete(entry)\n continue\n }\n const size =\n entry.placement() === 'left' || entry.placement() === 'right' ? dialog.offsetWidth : dialog.offsetHeight\n openEntries.push({ entry, dialog, size })\n }\n\n const total = openEntries.length\n for (let i = 0; i < total; i++) {\n const { dialog, size } = openEntries[i]\n // 注册顺序:先打开的在前 (index 小),后打开的在后 (index 大)。\n // depth = 在我之后打开的 drawer 数量 = (total - 1) - i\n const depth = total - 1 - i\n const scale = Math.pow(NESTED_SCALE, depth)\n const shrink = (size * (1 - scale)) / 2\n\n // 检查所有排在我之后的上层 drawer 的最大尺寸(若上层更宽,补偿宽度差确保露边)\n let aboveMaxSize = 0\n for (let j = i + 1; j < total; j++) {\n if (openEntries[j].size > aboveMaxSize) {\n aboveMaxSize = openEntries[j].size\n }\n }\n const sizeDiff = Math.max(0, aboveMaxSize - size)\n // 逐层读基准:消费方可以给某一层单独换基准,不必所有层共用一个值。\n const peek = readPeekBase(dialog) * Math.log(depth + 1)\n // depth 0 显式归零:单层 drawer 的偏移不依赖 ln(1) 的浮点结果,也不依赖基准是否被改写。\n const shift = depth > 0 ? shrink + sizeDiff + peek : 0\n\n dialog.style.setProperty(DEPTH_VARIABLE, String(depth))\n dialog.style.setProperty('--wui-internal-drawer-nested-scale', scale.toFixed(4))\n dialog.style.setProperty('--wui-internal-drawer-nested-shift', `${shift.toFixed(2)}px`)\n if (depth > 0) {\n dialog.classList.add('is-nested-lower')\n } else {\n dialog.classList.remove('is-nested-lower')\n }\n }\n}\n\nfunction handleAnyDialogClose(event: Event) {\n if (!(event.target instanceof HTMLDialogElement)) return\n // 上层(或任意层)关闭后,重算所有存活 drawer 的 depth。\n if (entries.size > 0) applyLayers()\n}\n\nfunction ensureDocumentListener() {\n if (documentListenerAttached) return\n document.addEventListener('close', handleAnyDialogClose, true)\n // jsdom 等无 matchMedia 的环境:媒体查询换不掉基准,但打开/关闭路径仍会重算。\n if (typeof window.matchMedia === 'function') {\n peekBaseQuery = window.matchMedia(NESTED_PEEK_BASE_QUERY)\n peekBaseQuery.addEventListener('change', handlePeekBaseChange)\n }\n documentListenerAttached = true\n}\n\nexport interface NestedDrawerLayerOptions {\n getDialog(): HTMLDialogElement | null\n getPlacement(): 'right' | 'left' | 'top' | 'bottom'\n}\n\nexport interface NestedDrawerLayerApi {\n /** dialog 进入 top layer(打开动画就绪)后调用,纳入层序管理。 */\n register(): void\n /** 关闭流程开始时调用:移出层序并触发底层回弹。 */\n unregister(): void\n dispose(): void\n}\n\nexport const defineNestedDrawerLayers = () =>\n definePlugin<NestedDrawerLayerApi, NestedDrawerLayerOptions>(ctx => ({\n register() {\n const dialog = ctx.getDialog()\n if (!dialog) return\n // 幂等保护:重挂载对账与 updated() 的 open 分支可能对同一 dialog 先后各调\n // 一次 register,重复条目会让 applyLayers 把同一层计两次。\n for (const entry of entries) {\n if (entry.dialog === dialog) entries.delete(entry)\n }\n ensureDocumentListener()\n entries.add({ dialog, placement: () => ctx.getPlacement() })\n applyLayers()\n },\n\n unregister() {\n const dialog = ctx.getDialog()\n for (const entry of entries) {\n if (entry.dialog === dialog) entries.delete(entry)\n }\n // 移除后重算剩余层(顶层关闭 → 次层回到 depth 0)。\n if (entries.size > 0) applyLayers()\n },\n\n dispose() {\n const dialog = ctx.getDialog()\n for (const entry of entries) {\n if (entry.dialog === dialog) entries.delete(entry)\n }\n if (entries.size === 0 && documentListenerAttached) {\n document.removeEventListener('close', handleAnyDialogClose, true)\n peekBaseQuery?.removeEventListener('change', handlePeekBaseChange)\n peekBaseQuery = null\n documentListenerAttached = false\n }\n }\n }))\n"],"mappings":"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"}
|