@yewdiel21/motion-kit 0.10.0 → 0.14.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.md +155 -93
- package/dist/auto/index.d.ts +53 -3
- package/dist/auto/index.js +101 -3
- package/dist/auto/index.js.map +1 -1
- package/dist/{chunk-IKQ5FODN.js → chunk-6P4P7NU6.js} +2 -218
- package/dist/chunk-6P4P7NU6.js.map +1 -0
- package/dist/chunk-CU6SXW3E.js +20334 -0
- package/dist/chunk-CU6SXW3E.js.map +1 -0
- package/dist/{chunk-XAKC2QY7.js → chunk-EY4BJKC4.js} +3 -28
- package/dist/chunk-EY4BJKC4.js.map +1 -0
- package/dist/chunk-QP4QJOEN.js +72 -0
- package/dist/chunk-QP4QJOEN.js.map +1 -0
- package/dist/css/components/activity-feed.css +240 -0
- package/dist/css/components/attachment.css +266 -0
- package/dist/css/components/breadcrumb.css +110 -0
- package/dist/css/components/chart-tooltip.css +168 -0
- package/dist/css/components/chart.css +296 -0
- package/dist/css/components/code-block.css +264 -0
- package/dist/css/components/color-area.css +82 -0
- package/dist/css/components/color-field.css +67 -0
- package/dist/css/components/color-picker.css +131 -0
- package/dist/css/components/color-slider.css +113 -0
- package/dist/css/components/command-search.css +252 -0
- package/dist/css/components/context-menu.css +23 -0
- package/dist/css/components/credit-card.css +288 -0
- package/dist/css/components/data-table.css +591 -0
- package/dist/css/components/date-range-picker.css +168 -0
- package/dist/css/components/date-time-picker.css +178 -0
- package/dist/css/components/drawer.css +58 -0
- package/dist/css/components/editable-table.css +201 -0
- package/dist/css/components/empty-state.css +61 -0
- package/dist/css/components/file-explorer.css +633 -0
- package/dist/css/components/filter-builder.css +232 -0
- package/dist/css/components/hold-confirm.css +87 -0
- package/dist/css/components/hover-card.css +13 -7
- package/dist/css/components/image-preview.css +195 -0
- package/dist/css/components/json-viewer.css +272 -0
- package/dist/css/components/like-button.css +78 -0
- package/dist/css/components/link-preview.css +275 -0
- package/dist/css/components/loading-button.css +77 -0
- package/dist/css/components/multi-select.css +267 -0
- package/dist/css/components/notification-bell.css +127 -0
- package/dist/css/components/password-strength.css +183 -0
- package/dist/css/components/popover.css +25 -0
- package/dist/css/components/progress.css +140 -0
- package/dist/css/components/questionnaire.css +217 -0
- package/dist/css/components/range-calendar.css +186 -0
- package/dist/css/components/range-slider.css +192 -0
- package/dist/css/components/resizable-panel.css +243 -0
- package/dist/css/components/rich-text-editor.css +284 -0
- package/dist/css/components/scratch-card.css +75 -0
- package/dist/css/components/skeleton.css +108 -0
- package/dist/css/components/split-view.css +19 -0
- package/dist/css/components/star-rating.css +80 -0
- package/dist/css/components/stat-card.css +164 -0
- package/dist/css/components/swipe-actions.css +105 -0
- package/dist/css/components/tag-input.css +244 -0
- package/dist/css/components/time-field.css +88 -0
- package/dist/css/components/timeline.css +219 -0
- package/dist/css/components/tooltip.css +79 -0
- package/dist/css/components/tree-view.css +210 -0
- package/dist/css/components/virtual-list.css +195 -0
- package/dist/css/tokens.css +185 -181
- package/dist/elements/index.d.ts +674 -5
- package/dist/elements/index.js +1361 -8
- package/dist/elements/index.js.map +1 -1
- package/dist/{engine-GDGwQnJE.d.ts → engine-Cn6IhE3z.d.ts} +1 -1
- package/dist/engine-QECQnGz1.d.ts +33 -0
- package/dist/index.css +9104 -189
- package/dist/index.d.ts +89 -5
- package/dist/index.js +243 -9
- package/dist/index.js.map +1 -1
- package/dist/react/index.d.ts +579 -23
- package/dist/react/index.js +2042 -7
- package/dist/react/index.js.map +1 -1
- package/dist/{reduced-BmBzKH94.d.ts → reduced-BBUusld6.d.ts} +9 -2
- package/dist/reveal-DEvp6U6T.d.ts +2381 -0
- package/dist/{store-DYb3tTsZ.d.ts → store-DjkTBX7f.d.ts} +2 -2
- package/package.json +1 -1
- package/registry.json +406 -1
- package/src/auto/auto-init.ts +98 -0
- package/src/components/activity-feed/README.md +56 -0
- package/src/components/activity-feed/activity-feed.css +239 -0
- package/src/components/activity-feed/element.ts +36 -0
- package/src/components/activity-feed/engine.ts +351 -0
- package/src/components/activity-feed/react.tsx +32 -0
- package/src/components/attachment/README.md +27 -0
- package/src/components/attachment/attachment.css +265 -0
- package/src/components/attachment/element.ts +50 -0
- package/src/components/attachment/engine.ts +469 -0
- package/src/components/attachment/react.tsx +65 -0
- package/src/components/breadcrumb/README.md +38 -0
- package/src/components/breadcrumb/breadcrumb.css +109 -0
- package/src/components/breadcrumb/element.ts +27 -0
- package/src/components/breadcrumb/engine.ts +249 -0
- package/src/components/breadcrumb/react.tsx +30 -0
- package/src/components/chart/README.md +24 -0
- package/src/components/chart/chart.css +295 -0
- package/src/components/chart/element.ts +41 -0
- package/src/components/chart/engine.ts +811 -0
- package/src/components/chart/react.tsx +50 -0
- package/src/components/chart-tooltip/README.md +53 -0
- package/src/components/chart-tooltip/chart-tooltip.css +167 -0
- package/src/components/chart-tooltip/element.ts +37 -0
- package/src/components/chart-tooltip/engine.ts +442 -0
- package/src/components/chart-tooltip/react.tsx +47 -0
- package/src/components/code-block/README.md +19 -0
- package/src/components/code-block/code-block.css +263 -0
- package/src/components/code-block/element.ts +34 -0
- package/src/components/code-block/engine.ts +254 -0
- package/src/components/code-block/highlight.ts +244 -0
- package/src/components/code-block/react.tsx +94 -0
- package/src/components/color-area/README.md +50 -0
- package/src/components/color-area/color-area.css +81 -0
- package/src/components/color-area/element.ts +26 -0
- package/src/components/color-area/engine.ts +246 -0
- package/src/components/color-area/react.tsx +42 -0
- package/src/components/color-field/README.md +43 -0
- package/src/components/color-field/color-field.css +66 -0
- package/src/components/color-field/element.ts +26 -0
- package/src/components/color-field/engine.ts +174 -0
- package/src/components/color-field/react.tsx +42 -0
- package/src/components/color-picker/README.md +45 -0
- package/src/components/color-picker/color-picker.css +130 -0
- package/src/components/color-picker/element.ts +45 -0
- package/src/components/color-picker/engine.ts +314 -0
- package/src/components/color-picker/react.tsx +47 -0
- package/src/components/color-slider/README.md +55 -0
- package/src/components/color-slider/color-slider.css +112 -0
- package/src/components/color-slider/element.ts +26 -0
- package/src/components/color-slider/engine.ts +234 -0
- package/src/components/color-slider/react.tsx +45 -0
- package/src/components/command-search/README.md +15 -0
- package/src/components/command-search/command-search.css +251 -0
- package/src/components/command-search/element.ts +36 -0
- package/src/components/command-search/engine.ts +356 -0
- package/src/components/command-search/match.ts +53 -0
- package/src/components/command-search/react.tsx +66 -0
- package/src/components/context-menu/README.md +31 -0
- package/src/components/context-menu/context-menu.css +22 -0
- package/src/components/context-menu/element.ts +40 -0
- package/src/components/context-menu/engine.ts +153 -0
- package/src/components/context-menu/react.tsx +57 -0
- package/src/components/credit-card/README.md +20 -0
- package/src/components/credit-card/card.ts +77 -0
- package/src/components/credit-card/credit-card.css +287 -0
- package/src/components/credit-card/element.ts +33 -0
- package/src/components/credit-card/engine.ts +410 -0
- package/src/components/credit-card/react.tsx +36 -0
- package/src/components/data-table/README.md +83 -0
- package/src/components/data-table/data-table.css +590 -0
- package/src/components/data-table/element.ts +54 -0
- package/src/components/data-table/engine.ts +1059 -0
- package/src/components/data-table/react.tsx +94 -0
- package/src/components/date-range-picker/README.md +51 -0
- package/src/components/date-range-picker/date-range-picker.css +167 -0
- package/src/components/date-range-picker/element.ts +52 -0
- package/src/components/date-range-picker/engine.ts +352 -0
- package/src/components/date-range-picker/react.tsx +57 -0
- package/src/components/date-time-picker/README.md +48 -0
- package/src/components/date-time-picker/date-time-picker.css +177 -0
- package/src/components/date-time-picker/element.ts +47 -0
- package/src/components/date-time-picker/engine.ts +350 -0
- package/src/components/date-time-picker/react.tsx +54 -0
- package/src/components/dialog/README.md +103 -102
- package/src/components/dialog/element.ts +123 -118
- package/src/components/dialog/engine.ts +449 -432
- package/src/components/drawer/README.md +28 -0
- package/src/components/drawer/drawer.css +57 -0
- package/src/components/drawer/element.ts +21 -0
- package/src/components/drawer/engine.ts +56 -0
- package/src/components/drawer/react.tsx +85 -0
- package/src/components/editable-table/README.md +67 -0
- package/src/components/editable-table/editable-table.css +200 -0
- package/src/components/editable-table/element.ts +45 -0
- package/src/components/editable-table/engine.ts +775 -0
- package/src/components/editable-table/react.tsx +79 -0
- package/src/components/empty-state/README.md +41 -0
- package/src/components/empty-state/element.ts +23 -0
- package/src/components/empty-state/empty-state.css +60 -0
- package/src/components/empty-state/engine.ts +232 -0
- package/src/components/empty-state/react.tsx +34 -0
- package/src/components/file-explorer/README.md +67 -0
- package/src/components/file-explorer/element.ts +39 -0
- package/src/components/file-explorer/engine.ts +1307 -0
- package/src/components/file-explorer/file-explorer.css +632 -0
- package/src/components/file-explorer/react.tsx +77 -0
- package/src/components/filter-builder/README.md +47 -0
- package/src/components/filter-builder/element.ts +34 -0
- package/src/components/filter-builder/engine.ts +365 -0
- package/src/components/filter-builder/filter-builder.css +231 -0
- package/src/components/filter-builder/react.tsx +36 -0
- package/src/components/hold-confirm/README.md +13 -0
- package/src/components/hold-confirm/element.ts +24 -0
- package/src/components/hold-confirm/engine.ts +216 -0
- package/src/components/hold-confirm/hold-confirm.css +86 -0
- package/src/components/hold-confirm/react.tsx +28 -0
- package/src/components/hover-card/README.md +6 -2
- package/src/components/hover-card/engine.ts +68 -6
- package/src/components/hover-card/hover-card.css +13 -7
- package/src/components/image-preview/README.md +16 -0
- package/src/components/image-preview/element.ts +26 -0
- package/src/components/image-preview/engine.ts +325 -0
- package/src/components/image-preview/image-preview.css +194 -0
- package/src/components/image-preview/react.tsx +43 -0
- package/src/components/json-viewer/README.md +56 -0
- package/src/components/json-viewer/element.ts +37 -0
- package/src/components/json-viewer/engine.ts +440 -0
- package/src/components/json-viewer/json-viewer.css +271 -0
- package/src/components/json-viewer/react.tsx +56 -0
- package/src/components/like-button/README.md +13 -0
- package/src/components/like-button/element.ts +47 -0
- package/src/components/like-button/engine.ts +145 -0
- package/src/components/like-button/like-button.css +77 -0
- package/src/components/like-button/react.tsx +39 -0
- package/src/components/link-preview/README.md +19 -0
- package/src/components/link-preview/element.ts +29 -0
- package/src/components/link-preview/engine.ts +192 -0
- package/src/components/link-preview/link-preview.css +274 -0
- package/src/components/link-preview/react.tsx +101 -0
- package/src/components/loading-button/README.md +45 -0
- package/src/components/loading-button/element.ts +34 -0
- package/src/components/loading-button/engine.ts +201 -0
- package/src/components/loading-button/loading-button.css +76 -0
- package/src/components/loading-button/react.tsx +43 -0
- package/src/components/multi-select/README.md +48 -0
- package/src/components/multi-select/element.ts +28 -0
- package/src/components/multi-select/engine.ts +294 -0
- package/src/components/multi-select/multi-select.css +266 -0
- package/src/components/multi-select/react.tsx +39 -0
- package/src/components/notification-bell/README.md +14 -0
- package/src/components/notification-bell/element.ts +48 -0
- package/src/components/notification-bell/engine.ts +202 -0
- package/src/components/notification-bell/notification-bell.css +126 -0
- package/src/components/notification-bell/react.tsx +57 -0
- package/src/components/password-strength/README.md +17 -0
- package/src/components/password-strength/element.ts +22 -0
- package/src/components/password-strength/engine.ts +212 -0
- package/src/components/password-strength/password-strength.css +182 -0
- package/src/components/password-strength/react.tsx +36 -0
- package/src/components/password-strength/score.ts +62 -0
- package/src/components/popover/README.md +44 -0
- package/src/components/popover/element.ts +31 -0
- package/src/components/popover/engine.ts +114 -0
- package/src/components/popover/popover.css +24 -0
- package/src/components/popover/react.tsx +50 -0
- package/src/components/progress/README.md +17 -0
- package/src/components/progress/element.ts +30 -0
- package/src/components/progress/engine.ts +173 -0
- package/src/components/progress/progress.css +139 -0
- package/src/components/progress/react.tsx +35 -0
- package/src/components/questionnaire/README.md +32 -0
- package/src/components/questionnaire/element.ts +118 -0
- package/src/components/questionnaire/engine.ts +255 -0
- package/src/components/questionnaire/questionnaire.css +216 -0
- package/src/components/questionnaire/react.tsx +140 -0
- package/src/components/range-calendar/README.md +58 -0
- package/src/components/range-calendar/element.ts +42 -0
- package/src/components/range-calendar/engine.ts +390 -0
- package/src/components/range-calendar/range-calendar.css +185 -0
- package/src/components/range-calendar/react.tsx +56 -0
- package/src/components/range-slider/README.md +23 -0
- package/src/components/range-slider/element.ts +53 -0
- package/src/components/range-slider/engine.ts +316 -0
- package/src/components/range-slider/range-slider.css +191 -0
- package/src/components/range-slider/react.tsx +66 -0
- package/src/components/resizable-panel/README.md +61 -0
- package/src/components/resizable-panel/element.ts +36 -0
- package/src/components/resizable-panel/engine.ts +551 -0
- package/src/components/resizable-panel/react.tsx +74 -0
- package/src/components/resizable-panel/resizable-panel.css +242 -0
- package/src/components/rich-text-editor/README.md +57 -0
- package/src/components/rich-text-editor/element.ts +34 -0
- package/src/components/rich-text-editor/engine.ts +673 -0
- package/src/components/rich-text-editor/react.tsx +60 -0
- package/src/components/rich-text-editor/rich-text-editor.css +283 -0
- package/src/components/scratch-card/README.md +15 -0
- package/src/components/scratch-card/element.ts +30 -0
- package/src/components/scratch-card/engine.ts +257 -0
- package/src/components/scratch-card/react.tsx +40 -0
- package/src/components/scratch-card/scratch-card.css +74 -0
- package/src/components/skeleton/README.md +15 -0
- package/src/components/skeleton/element.ts +32 -0
- package/src/components/skeleton/engine.ts +104 -0
- package/src/components/skeleton/react.tsx +41 -0
- package/src/components/skeleton/skeleton.css +107 -0
- package/src/components/split-view/README.md +50 -0
- package/src/components/split-view/element.ts +34 -0
- package/src/components/split-view/engine.ts +114 -0
- package/src/components/split-view/react.tsx +63 -0
- package/src/components/split-view/split-view.css +18 -0
- package/src/components/star-rating/README.md +14 -0
- package/src/components/star-rating/element.ts +26 -0
- package/src/components/star-rating/engine.ts +217 -0
- package/src/components/star-rating/react.tsx +33 -0
- package/src/components/star-rating/star-rating.css +79 -0
- package/src/components/stat-card/README.md +42 -0
- package/src/components/stat-card/element.ts +40 -0
- package/src/components/stat-card/engine.ts +283 -0
- package/src/components/stat-card/react.tsx +36 -0
- package/src/components/stat-card/stat-card.css +163 -0
- package/src/components/swipe-actions/README.md +19 -0
- package/src/components/swipe-actions/element.ts +26 -0
- package/src/components/swipe-actions/engine.ts +260 -0
- package/src/components/swipe-actions/react.tsx +80 -0
- package/src/components/swipe-actions/swipe-actions.css +104 -0
- package/src/components/tag-input/README.md +42 -0
- package/src/components/tag-input/element.ts +39 -0
- package/src/components/tag-input/engine.ts +313 -0
- package/src/components/tag-input/react.tsx +54 -0
- package/src/components/tag-input/tag-input.css +243 -0
- package/src/components/time-field/README.md +54 -0
- package/src/components/time-field/element.ts +38 -0
- package/src/components/time-field/engine.ts +110 -0
- package/src/components/time-field/react.tsx +45 -0
- package/src/components/time-field/time-field.css +87 -0
- package/src/components/timeline/README.md +57 -0
- package/src/components/timeline/element.ts +31 -0
- package/src/components/timeline/engine.ts +300 -0
- package/src/components/timeline/react.tsx +59 -0
- package/src/components/timeline/timeline.css +218 -0
- package/src/components/tooltip/README.md +46 -0
- package/src/components/tooltip/element.ts +22 -0
- package/src/components/tooltip/engine.ts +288 -0
- package/src/components/tooltip/react.tsx +30 -0
- package/src/components/tooltip/tooltip.css +78 -0
- package/src/components/tree-view/README.md +61 -0
- package/src/components/tree-view/element.ts +32 -0
- package/src/components/tree-view/engine.ts +569 -0
- package/src/components/tree-view/react.tsx +78 -0
- package/src/components/tree-view/tree-view.css +209 -0
- package/src/components/virtual-list/README.md +81 -0
- package/src/components/virtual-list/element.ts +42 -0
- package/src/components/virtual-list/engine.ts +678 -0
- package/src/components/virtual-list/react.tsx +101 -0
- package/src/components/virtual-list/virtual-list.css +194 -0
- package/src/core/chips.ts +196 -0
- package/src/core/color.ts +304 -0
- package/src/core/date-range.ts +67 -0
- package/src/core/dates.ts +11 -1
- package/src/core/files.ts +107 -0
- package/src/core/filter.ts +229 -0
- package/src/core/gsap.ts +80 -65
- package/src/core/listbox.ts +332 -0
- package/src/core/mark.ts +29 -0
- package/src/core/position.ts +89 -0
- package/src/core/relative-time.ts +77 -0
- package/src/core/segment-field.ts +373 -0
- package/src/core/segments.ts +153 -0
- package/src/core/tree.ts +116 -0
- package/src/core/virtual.ts +79 -0
- package/src/css/tokens.css +186 -182
- package/src/elements/index.ts +147 -0
- package/src/index.ts +72 -0
- package/src/motion/micro.ts +248 -0
- package/src/motion/sheet.ts +88 -65
- package/src/motion/surface.ts +9 -0
- package/src/react/index.ts +57 -0
- package/dist/chunk-IKQ5FODN.js.map +0 -1
- package/dist/chunk-J6OCFNGU.js +0 -177
- package/dist/chunk-J6OCFNGU.js.map +0 -1
- package/dist/chunk-TFNRIZHU.js +0 -3977
- package/dist/chunk-TFNRIZHU.js.map +0 -1
- package/dist/chunk-XAKC2QY7.js.map +0 -1
- package/dist/reveal-jsX-uwUz.d.ts +0 -625
|
@@ -1,432 +1,449 @@
|
|
|
1
|
-
import { gsap, EASE, registerMotion } from '../../core/gsap';
|
|
2
|
-
import { reduced } from '../../core/reduced';
|
|
3
|
-
import { createScope } from '../../core/scope';
|
|
4
|
-
import { TIMING } from '../../core/timing';
|
|
5
|
-
import { inert, warnOnce, type Cleanup, type Instance } from '../../core/types';
|
|
6
|
-
import { MORPH_STYLES, clearStyles } from '../../core/styles';
|
|
7
|
-
import { anchorSurface, clearAnchor } from '../../motion/anchor';
|
|
8
|
-
import { attachDragDismiss } from '../../motion/drag-dismiss';
|
|
9
|
-
import {
|
|
10
|
-
attachFloating,
|
|
11
|
-
dockWindow,
|
|
12
|
-
floatingAvailable,
|
|
13
|
-
forgetFloat,
|
|
14
|
-
liftWindow,
|
|
15
|
-
savedFloat,
|
|
16
|
-
unplaceWindow,
|
|
17
|
-
} from '../../motion/floating';
|
|
18
|
-
import { isMorphing, morphCloseWithGhost, morphOpen, releaseShared, showOrigin, stopMorph } from '../../motion/morph';
|
|
19
|
-
import { pushUnderlay, releaseUnderlay, sheetClose, sheetOpen } from '../../motion/sheet';
|
|
20
|
-
import { closeModal, fadeBackdrop, openModal } from '../../motion/surface';
|
|
21
|
-
|
|
22
|
-
/*
|
|
23
|
-
* Dialog on a native <dialog> (focus trap, Escape, top layer): the
|
|
24
|
-
* control that opened it turns into it and it folds back into that control
|
|
25
|
-
* (morph or liquid) over a backdrop tinted on the signature curve. It eases to
|
|
26
|
-
* new heights (auto-resize), can be dragged away (> 100 px) and, on desktop,
|
|
27
|
-
* lifted into a floating window by its handle. Parts: [data-mk-part] header,
|
|
28
|
-
* title, description, body, footer, close, handle.
|
|
29
|
-
*/
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
export type
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
let
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
if (
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
scope.attr(
|
|
140
|
-
}
|
|
141
|
-
const
|
|
142
|
-
if (
|
|
143
|
-
scope.attr(
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
element.
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
const
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
const
|
|
205
|
-
const
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
if (
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
if (
|
|
236
|
-
dialog.
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
if (
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
if (
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
if (sheet)
|
|
347
|
-
else
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
if (
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
if (
|
|
381
|
-
|
|
382
|
-
return;
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
},
|
|
431
|
-
|
|
432
|
-
|
|
1
|
+
import { gsap, EASE, registerMotion } from '../../core/gsap';
|
|
2
|
+
import { reduced } from '../../core/reduced';
|
|
3
|
+
import { createScope } from '../../core/scope';
|
|
4
|
+
import { TIMING } from '../../core/timing';
|
|
5
|
+
import { inert, warnOnce, type Cleanup, type Instance } from '../../core/types';
|
|
6
|
+
import { MORPH_STYLES, clearStyles } from '../../core/styles';
|
|
7
|
+
import { anchorSurface, clearAnchor } from '../../motion/anchor';
|
|
8
|
+
import { attachDragDismiss } from '../../motion/drag-dismiss';
|
|
9
|
+
import {
|
|
10
|
+
attachFloating,
|
|
11
|
+
dockWindow,
|
|
12
|
+
floatingAvailable,
|
|
13
|
+
forgetFloat,
|
|
14
|
+
liftWindow,
|
|
15
|
+
savedFloat,
|
|
16
|
+
unplaceWindow,
|
|
17
|
+
} from '../../motion/floating';
|
|
18
|
+
import { isMorphing, morphCloseWithGhost, morphOpen, releaseShared, showOrigin, stopMorph } from '../../motion/morph';
|
|
19
|
+
import { pushUnderlay, releaseUnderlay, sheetClose, sheetOpen, slideClose, slideOpen } from '../../motion/sheet';
|
|
20
|
+
import { closeModal, fadeBackdrop, openModal } from '../../motion/surface';
|
|
21
|
+
|
|
22
|
+
/*
|
|
23
|
+
* Dialog on a native <dialog> (focus trap, Escape, top layer): the
|
|
24
|
+
* control that opened it turns into it and it folds back into that control
|
|
25
|
+
* (morph or liquid) over a backdrop tinted on the signature curve. It eases to
|
|
26
|
+
* new heights (auto-resize), can be dragged away (> 100 px) and, on desktop,
|
|
27
|
+
* lifted into a floating window by its handle. Parts: [data-mk-part] header,
|
|
28
|
+
* title, description, body, footer, close, handle.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
/** drawer: slides in from its side (data-mk-drawer="left|right", see createDrawer). */
|
|
32
|
+
export type DialogVariant = 'morph' | 'liquid' | 'sheet' | 'drawer';
|
|
33
|
+
export type DialogPlacement = 'center' | 'anchor' | 'side';
|
|
34
|
+
|
|
35
|
+
export interface DialogLabels {
|
|
36
|
+
close?: string;
|
|
37
|
+
float?: string;
|
|
38
|
+
dock?: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface DialogOptions {
|
|
42
|
+
/** morph (default), liquid, or sheet: rises from the bottom and pushes [data-mk-underlay] back. */
|
|
43
|
+
variant?: DialogVariant;
|
|
44
|
+
placement?: DialogPlacement;
|
|
45
|
+
/** placement 'anchor': the box to place it against, read on open and resize (default: the opener's). */
|
|
46
|
+
anchor?: () => DOMRect | null | undefined;
|
|
47
|
+
/** Tinted backdrop; false leaves it transparent (menus). */
|
|
48
|
+
backdrop?: boolean;
|
|
49
|
+
closeOnBackdrop?: boolean;
|
|
50
|
+
/** Drag (or wheel) down to dismiss. */
|
|
51
|
+
drag?: boolean;
|
|
52
|
+
/** A key turns on the floating window (desktop) and remembers its place. */
|
|
53
|
+
float?: string | false;
|
|
54
|
+
autoResize?: boolean;
|
|
55
|
+
/** `[data-mk-open="<id>"]` buttons open it: true uses the dialog's id; a string names another id; false: none. */
|
|
56
|
+
triggers?: boolean | string;
|
|
57
|
+
/** Modal (default) or a non-modal dialog. */
|
|
58
|
+
modal?: boolean;
|
|
59
|
+
labels?: DialogLabels;
|
|
60
|
+
/** Grow the content with the surface (default). Menus turn it off and cascade their items instead. */
|
|
61
|
+
animateContent?: boolean;
|
|
62
|
+
onOpen?: () => void;
|
|
63
|
+
/** After it closed, whatever closed it. */
|
|
64
|
+
onClose?: () => void;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export interface DialogInstance extends Instance {
|
|
68
|
+
/** `origin`: the control it grows from; omitted, the focused control; null, none (scale-in). */
|
|
69
|
+
open(origin?: HTMLElement | null): void;
|
|
70
|
+
close(): void;
|
|
71
|
+
toggle(origin?: HTMLElement | null): void;
|
|
72
|
+
float(): void;
|
|
73
|
+
dock(): void;
|
|
74
|
+
readonly isOpen: boolean;
|
|
75
|
+
readonly isFloating: boolean;
|
|
76
|
+
readonly element: HTMLElement;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const DEFAULT_LABELS: Required<DialogLabels> = { close: 'Cerrar', float: 'Ventana flotante', dock: 'Volver a su sitio' };
|
|
80
|
+
const FIELDS = '[autofocus], input:not([type="hidden"]):not(:disabled), textarea:not(:disabled), select:not(:disabled)';
|
|
81
|
+
const CORNERS = ['tl', 'tr', 'bl', 'br'] as const;
|
|
82
|
+
let uid = 0;
|
|
83
|
+
|
|
84
|
+
const part = (dialog: HTMLElement, name: string) => dialog.querySelector<HTMLElement>(`[data-mk-part="${name}"]`);
|
|
85
|
+
|
|
86
|
+
export function createDialog(dialog: HTMLElement | null, options: DialogOptions = {}): DialogInstance {
|
|
87
|
+
if (!dialog) {
|
|
88
|
+
warnOnce('dialog: missing <dialog> element');
|
|
89
|
+
return inert({ open() {}, close() {}, toggle() {}, float() {}, dock() {}, isOpen: false, isFloating: false, element: null as unknown as HTMLElement });
|
|
90
|
+
}
|
|
91
|
+
registerMotion();
|
|
92
|
+
const {
|
|
93
|
+
variant = 'morph',
|
|
94
|
+
placement = 'center',
|
|
95
|
+
backdrop = true,
|
|
96
|
+
closeOnBackdrop = true,
|
|
97
|
+
drag = true,
|
|
98
|
+
float: floatKey = false,
|
|
99
|
+
autoResize = true,
|
|
100
|
+
triggers = true,
|
|
101
|
+
modal = true,
|
|
102
|
+
} = options;
|
|
103
|
+
const labels = { ...DEFAULT_LABELS, ...options.labels };
|
|
104
|
+
const liquid = variant === 'liquid';
|
|
105
|
+
const sheet = variant === 'sheet';
|
|
106
|
+
const drawer = variant === 'drawer';
|
|
107
|
+
const scope = createScope();
|
|
108
|
+
/** Effects that live while it is open. */
|
|
109
|
+
let session: Cleanup[] = [];
|
|
110
|
+
let opener: HTMLElement | null = null;
|
|
111
|
+
let isOpen = false;
|
|
112
|
+
let closing = false;
|
|
113
|
+
let floating = false;
|
|
114
|
+
/**
|
|
115
|
+
* Lifting and docking swap modal ↔ popover: the native `close` events they cause
|
|
116
|
+
* (queued, so they arrive later) are not the person closing it.
|
|
117
|
+
*/
|
|
118
|
+
let ownCloses = 0;
|
|
119
|
+
const closeNatively = () => {
|
|
120
|
+
if (!dialog.hasAttribute('open')) return;
|
|
121
|
+
ownCloses += 1;
|
|
122
|
+
closeModal(dialog as HTMLDialogElement);
|
|
123
|
+
};
|
|
124
|
+
let destroyed = false;
|
|
125
|
+
/** destroy() is under way: the page behind comes back at once. */
|
|
126
|
+
let tearingDown = false;
|
|
127
|
+
|
|
128
|
+
if (placement !== 'center') scope.attr(dialog, 'data-mk-placement', placement);
|
|
129
|
+
if (!backdrop) scope.attr(dialog, 'data-mk-backdrop', 'none');
|
|
130
|
+
scope.attr(dialog, 'data-mk-variant', variant);
|
|
131
|
+
const title = part(dialog, 'title');
|
|
132
|
+
if (title && !dialog.hasAttribute('aria-label') && !dialog.hasAttribute('aria-labelledby')) {
|
|
133
|
+
if (!title.id) scope.attr(title, 'id', `mk-dialog-title-${++uid}`);
|
|
134
|
+
scope.attr(dialog, 'aria-labelledby', title.id);
|
|
135
|
+
}
|
|
136
|
+
const description = part(dialog, 'description');
|
|
137
|
+
if (description && !dialog.hasAttribute('aria-describedby')) {
|
|
138
|
+
if (!description.id) scope.attr(description, 'id', `mk-dialog-description-${++uid}`);
|
|
139
|
+
scope.attr(dialog, 'aria-describedby', description.id);
|
|
140
|
+
}
|
|
141
|
+
const closeButton = part(dialog, 'close');
|
|
142
|
+
if (closeButton && !closeButton.hasAttribute('aria-label') && !closeButton.textContent?.trim()) {
|
|
143
|
+
scope.attr(closeButton, 'aria-label', labels.close);
|
|
144
|
+
}
|
|
145
|
+
const handle = floatKey ? part(dialog, 'handle') : null;
|
|
146
|
+
if (handle) {
|
|
147
|
+
scope.attr(handle, 'data-mk-no-drag', '');
|
|
148
|
+
scope.attr(handle, 'aria-pressed', 'false');
|
|
149
|
+
scope.attr(handle, 'aria-label', labels.float);
|
|
150
|
+
}
|
|
151
|
+
const corners: HTMLElement[] = [];
|
|
152
|
+
if (floatKey) {
|
|
153
|
+
for (const corner of CORNERS) {
|
|
154
|
+
const element = document.createElement('span');
|
|
155
|
+
element.className = 'mk-float-corner';
|
|
156
|
+
element.dataset.mkFloatCorner = corner;
|
|
157
|
+
element.dataset.mkNoDrag = '';
|
|
158
|
+
element.setAttribute('aria-hidden', 'true');
|
|
159
|
+
dialog.append(element);
|
|
160
|
+
corners.push(element);
|
|
161
|
+
}
|
|
162
|
+
scope.add(() => corners.forEach((corner) => corner.remove()));
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const emit = (type: string, cancelable = false, detail: Record<string, unknown> = {}) =>
|
|
166
|
+
dialog.dispatchEvent(new CustomEvent(type, { bubbles: true, cancelable, detail: { dialog, ...detail } }));
|
|
167
|
+
|
|
168
|
+
const endSession = () => {
|
|
169
|
+
for (const cleanup of session.splice(0).reverse()) cleanup();
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
const settleFloating = () => {
|
|
173
|
+
if (!floating) return;
|
|
174
|
+
floating = false;
|
|
175
|
+
if (typeof dialog.hidePopover === 'function' && dialog.hasAttribute('popover')) {
|
|
176
|
+
try {
|
|
177
|
+
dialog.hidePopover();
|
|
178
|
+
} catch {
|
|
179
|
+
// Already hidden.
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
dialog.removeAttribute('popover');
|
|
183
|
+
unplaceWindow(dialog);
|
|
184
|
+
if (handle) {
|
|
185
|
+
handle.setAttribute('aria-pressed', 'false');
|
|
186
|
+
handle.setAttribute('aria-label', labels.float);
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
/** Closed without our animation (owner, form[method=dialog], destroy). */
|
|
191
|
+
const closedQuietly = () => {
|
|
192
|
+
stopMorph(dialog);
|
|
193
|
+
endSession();
|
|
194
|
+
isOpen = false;
|
|
195
|
+
closing = false;
|
|
196
|
+
showOrigin(opener);
|
|
197
|
+
releaseShared(opener);
|
|
198
|
+
emit('mk:closed');
|
|
199
|
+
options.onClose?.();
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
const lift = () => {
|
|
203
|
+
if (!floatKey || floating || !isOpen || !floatingAvailable()) return;
|
|
204
|
+
const box = dialog.getBoundingClientRect();
|
|
205
|
+
const rect = savedFloat(floatKey) ?? { top: box.top, left: box.left, width: box.width, height: box.height };
|
|
206
|
+
const focused = document.activeElement;
|
|
207
|
+
// Its backdrop leaves as the window lifts off the page.
|
|
208
|
+
const backdropStyle = getComputedStyle(dialog, '::backdrop');
|
|
209
|
+
const veil = document.createElement('div');
|
|
210
|
+
veil.setAttribute('aria-hidden', 'true');
|
|
211
|
+
Object.assign(veil.style, {
|
|
212
|
+
position: 'fixed',
|
|
213
|
+
inset: '0',
|
|
214
|
+
background: backdropStyle.background || backdropStyle.backgroundColor,
|
|
215
|
+
backdropFilter: backdropStyle.backdropFilter,
|
|
216
|
+
pointerEvents: 'none',
|
|
217
|
+
});
|
|
218
|
+
closeNatively();
|
|
219
|
+
document.body.append(veil);
|
|
220
|
+
dialog.setAttribute('popover', 'manual');
|
|
221
|
+
if (typeof dialog.showPopover === 'function') dialog.showPopover();
|
|
222
|
+
else openModal(dialog, false);
|
|
223
|
+
liftWindow(dialog, rect);
|
|
224
|
+
gsap.to(veil, { opacity: 0, duration: reduced() ? 0 : TIMING.float.shadow, ease: EASE.signature, onComplete: () => veil.remove() });
|
|
225
|
+
floating = true;
|
|
226
|
+
if (handle) {
|
|
227
|
+
handle.setAttribute('aria-pressed', 'true');
|
|
228
|
+
handle.setAttribute('aria-label', labels.dock);
|
|
229
|
+
}
|
|
230
|
+
showOrigin(opener, { fade: true });
|
|
231
|
+
if (focused instanceof HTMLElement && dialog.contains(focused)) focused.focus();
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
const dock = () => {
|
|
235
|
+
if (!floatKey || !floating) return;
|
|
236
|
+
const box = dialog.getBoundingClientRect();
|
|
237
|
+
const focused = document.activeElement;
|
|
238
|
+
floating = false;
|
|
239
|
+
if (typeof dialog.hidePopover === 'function') dialog.hidePopover();
|
|
240
|
+
dialog.removeAttribute('popover');
|
|
241
|
+
closeNatively();
|
|
242
|
+
openModal(dialog, modal);
|
|
243
|
+
dockWindow(dialog, { top: box.top, left: box.left, width: box.width, height: box.height });
|
|
244
|
+
if (backdrop) void fadeBackdrop(dialog, 'in');
|
|
245
|
+
forgetFloat(floatKey);
|
|
246
|
+
if (handle) {
|
|
247
|
+
handle.setAttribute('aria-pressed', 'false');
|
|
248
|
+
handle.setAttribute('aria-label', labels.float);
|
|
249
|
+
}
|
|
250
|
+
if (focused instanceof HTMLElement && dialog.contains(focused)) focused.focus();
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
const anchorBox = () => (options.anchor ? options.anchor() : opener?.isConnected ? opener.getBoundingClientRect() : null);
|
|
254
|
+
|
|
255
|
+
const startSession = () => {
|
|
256
|
+
if (drawer && modal) {
|
|
257
|
+
const root = document.documentElement;
|
|
258
|
+
const overflow = root.style.overflow;
|
|
259
|
+
root.style.overflow = 'hidden';
|
|
260
|
+
session.push(() => {
|
|
261
|
+
root.style.overflow = overflow;
|
|
262
|
+
if (root.getAttribute('style') === '') root.removeAttribute('style');
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
if (sheet) {
|
|
266
|
+
const behind = [...document.querySelectorAll<HTMLElement>('[data-mk-underlay]')];
|
|
267
|
+
pushUnderlay(behind);
|
|
268
|
+
const root = document.documentElement;
|
|
269
|
+
const overflow = root.style.overflow;
|
|
270
|
+
root.style.overflow = 'hidden';
|
|
271
|
+
session.push(() => {
|
|
272
|
+
root.style.overflow = overflow;
|
|
273
|
+
if (root.getAttribute('style') === '') root.removeAttribute('style');
|
|
274
|
+
releaseUnderlay(behind, !tearingDown);
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
if (autoResize && typeof ResizeObserver === 'function') {
|
|
278
|
+
let last = dialog.offsetHeight;
|
|
279
|
+
let resizing: gsap.core.Tween | null = null;
|
|
280
|
+
const observer = new ResizeObserver(() => {
|
|
281
|
+
if (resizing?.isActive()) return;
|
|
282
|
+
const next = dialog.offsetHeight;
|
|
283
|
+
const previous = last;
|
|
284
|
+
last = next;
|
|
285
|
+
// A floating window's size is the person's, not its content's.
|
|
286
|
+
if (floating || Math.abs(next - previous) < 2 || !previous || isMorphing(dialog) || reduced()) return;
|
|
287
|
+
resizing = gsap.fromTo(
|
|
288
|
+
dialog,
|
|
289
|
+
{ height: previous },
|
|
290
|
+
{
|
|
291
|
+
height: next,
|
|
292
|
+
duration: TIMING.dialog.autoResize,
|
|
293
|
+
ease: EASE.signature,
|
|
294
|
+
clearProps: 'height',
|
|
295
|
+
onComplete: () => {
|
|
296
|
+
last = dialog.offsetHeight;
|
|
297
|
+
},
|
|
298
|
+
},
|
|
299
|
+
);
|
|
300
|
+
});
|
|
301
|
+
observer.observe(dialog);
|
|
302
|
+
session.push(() => {
|
|
303
|
+
observer.disconnect();
|
|
304
|
+
resizing?.kill();
|
|
305
|
+
clearStyles([dialog], ['height']);
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
if (drag) {
|
|
309
|
+
session.push(
|
|
310
|
+
attachDragDismiss(dialog, {
|
|
311
|
+
canDrag: () => !isMorphing(dialog) && !floating && !closing && isOpen,
|
|
312
|
+
onDismiss: () => close(true),
|
|
313
|
+
}),
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
if (placement === 'anchor') {
|
|
317
|
+
const onResize = () => {
|
|
318
|
+
if (isOpen && !floating) anchorSurface(dialog, anchorBox());
|
|
319
|
+
};
|
|
320
|
+
addEventListener('resize', onResize);
|
|
321
|
+
session.push(() => {
|
|
322
|
+
removeEventListener('resize', onResize);
|
|
323
|
+
clearAnchor(dialog);
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
if (floatKey && handle) {
|
|
327
|
+
session.push(attachFloating(dialog, { key: floatKey, handle, corners, isFloating: () => floating, float: lift, dock }));
|
|
328
|
+
const onResize = () => {
|
|
329
|
+
if (floating && !floatingAvailable()) dock();
|
|
330
|
+
};
|
|
331
|
+
addEventListener('resize', onResize);
|
|
332
|
+
session.push(() => removeEventListener('resize', onResize));
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
const open = (origin?: HTMLElement | null) => {
|
|
337
|
+
if (destroyed || isOpen) return;
|
|
338
|
+
const active = document.activeElement;
|
|
339
|
+
// undefined: the focused control (usually the one clicked); null: no opener at all.
|
|
340
|
+
opener = origin !== undefined ? origin : active instanceof HTMLElement && active !== document.body && !dialog.contains(active) ? active : null;
|
|
341
|
+
closing = false;
|
|
342
|
+
isOpen = true;
|
|
343
|
+
openModal(dialog, modal);
|
|
344
|
+
if (placement === 'anchor') anchorSurface(dialog, anchorBox());
|
|
345
|
+
if (backdrop && modal) void fadeBackdrop(dialog, 'in');
|
|
346
|
+
if (sheet) sheetOpen(dialog);
|
|
347
|
+
else if (drawer) slideOpen(dialog);
|
|
348
|
+
else morphOpen(dialog, opener, { hideOrigin: true, liquid, content: options.animateContent === false ? ':scope > :not(*)' : undefined });
|
|
349
|
+
startSession();
|
|
350
|
+
// Forms start at their first field (after showModal: a closed dialog cannot take focus).
|
|
351
|
+
dialog.querySelector<HTMLElement>(FIELDS)?.focus({ preventScroll: true });
|
|
352
|
+
emit('mk:open', false, { origin: opener });
|
|
353
|
+
options.onOpen?.();
|
|
354
|
+
};
|
|
355
|
+
|
|
356
|
+
/** Animated close: the dialog closes at once while an inert copy folds into the opener. */
|
|
357
|
+
const close = (inPlace = false) => {
|
|
358
|
+
if (destroyed || !isOpen || closing) return;
|
|
359
|
+
if (!emit('mk:close', true, { inPlace })) return;
|
|
360
|
+
closing = true;
|
|
361
|
+
// The copy is measured first: the session cleanup clears an anchored place.
|
|
362
|
+
if (sheet) sheetClose(dialog, { inPlace });
|
|
363
|
+
else if (drawer) slideClose(dialog);
|
|
364
|
+
else morphCloseWithGhost(dialog, opener, { inPlace, liquid });
|
|
365
|
+
endSession();
|
|
366
|
+
if (floating) settleFloating();
|
|
367
|
+
if (dialog.hasAttribute('open')) closeModal(dialog as HTMLDialogElement);
|
|
368
|
+
isOpen = false;
|
|
369
|
+
closing = false;
|
|
370
|
+
if (opener?.isConnected) opener.focus();
|
|
371
|
+
emit('mk:closed');
|
|
372
|
+
options.onClose?.();
|
|
373
|
+
};
|
|
374
|
+
|
|
375
|
+
scope.on(dialog, 'cancel', (event) => {
|
|
376
|
+
event.preventDefault();
|
|
377
|
+
close();
|
|
378
|
+
});
|
|
379
|
+
scope.on(dialog, 'close', () => {
|
|
380
|
+
if (ownCloses > 0) {
|
|
381
|
+
ownCloses -= 1;
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
// A native close we did not start (form method="dialog", dialog.close()).
|
|
385
|
+
if (!isOpen || closing) return;
|
|
386
|
+
closedQuietly();
|
|
387
|
+
});
|
|
388
|
+
scope.on(dialog, 'keydown', (event) => {
|
|
389
|
+
// A floating (non-modal) window still closes with Escape.
|
|
390
|
+
if ((event as KeyboardEvent).key === 'Escape' && floating) {
|
|
391
|
+
event.preventDefault();
|
|
392
|
+
close();
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
scope.on(dialog, 'click', (event) => {
|
|
396
|
+
const target = event.target as Element | null;
|
|
397
|
+
if (target?.closest('[data-mk-part="close"], [data-mk-close]') && dialog.contains(target)) {
|
|
398
|
+
close();
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
401
|
+
if (target !== dialog || !closeOnBackdrop || floating) return;
|
|
402
|
+
const mouse = event as MouseEvent;
|
|
403
|
+
const box = dialog.getBoundingClientRect();
|
|
404
|
+
if (mouse.clientX < box.left || mouse.clientX > box.right || mouse.clientY < box.top || mouse.clientY > box.bottom) close();
|
|
405
|
+
});
|
|
406
|
+
const triggerId = triggers === true ? dialog.id : triggers || '';
|
|
407
|
+
if (triggerId) {
|
|
408
|
+
const selector = `[data-mk-open="${typeof CSS !== 'undefined' && CSS.escape ? CSS.escape(triggerId) : triggerId}"]`;
|
|
409
|
+
scope.on(document, 'click', (event) => {
|
|
410
|
+
const trigger = (event.target as Element | null)?.closest<HTMLElement>(selector);
|
|
411
|
+
if (!trigger || dialog.contains(trigger)) return;
|
|
412
|
+
event.preventDefault();
|
|
413
|
+
if (isOpen) close();
|
|
414
|
+
else open(trigger);
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
dialog.dataset.mkReady = '';
|
|
418
|
+
|
|
419
|
+
return {
|
|
420
|
+
open,
|
|
421
|
+
close: () => close(),
|
|
422
|
+
toggle: (origin?: HTMLElement | null) => (isOpen ? close() : open(origin)),
|
|
423
|
+
float: lift,
|
|
424
|
+
dock,
|
|
425
|
+
get isOpen() {
|
|
426
|
+
return isOpen;
|
|
427
|
+
},
|
|
428
|
+
get isFloating() {
|
|
429
|
+
return floating;
|
|
430
|
+
},
|
|
431
|
+
element: dialog,
|
|
432
|
+
destroy() {
|
|
433
|
+
if (destroyed) return;
|
|
434
|
+
tearingDown = true;
|
|
435
|
+
if (isOpen) {
|
|
436
|
+
settleFloating();
|
|
437
|
+
closing = true;
|
|
438
|
+
if (dialog.hasAttribute('open')) closeModal(dialog as HTMLDialogElement);
|
|
439
|
+
closedQuietly();
|
|
440
|
+
}
|
|
441
|
+
destroyed = true;
|
|
442
|
+
endSession();
|
|
443
|
+
gsap.killTweensOf(dialog);
|
|
444
|
+
clearStyles([dialog], [...MORPH_STYLES, 'height']);
|
|
445
|
+
scope.dispose();
|
|
446
|
+
delete dialog.dataset.mkReady;
|
|
447
|
+
},
|
|
448
|
+
};
|
|
449
|
+
}
|