From d674052aa39f561cd198a842658dd40a3d203c83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Denis=20=F0=9F=8E=83=20Khripkov?= Date: Thu, 19 Dec 2024 18:43:39 +0300 Subject: [PATCH 1/6] feat: add side-effects; --- .changeset/nervous-ants-learn.md | 33 ++++++++++++++++++++++ bin/build.sh | 2 +- packages/base-modal/package.json | 4 ++- packages/drawer/package.json | 1 + packages/form-control/package.json | 1 + packages/notification-manager/package.json | 1 + packages/notification/package.json | 1 + packages/number-input/package.json | 1 + packages/pagination/package.json | 1 + packages/pass-code-v1/package.json | 1 + packages/pass-code/package.json | 1 + packages/password-input/package.json | 1 + packages/pattern-lock-v1/package.json | 1 + packages/pattern-lock/package.json | 1 + packages/popover/package.json | 1 + packages/popup-sheet/package.json | 1 + packages/portal/package.json | 1 + packages/product-cover/package.json | 1 + packages/pure-cell/package.json | 1 + packages/radio-group/package.json | 1 + packages/radio/package.json | 1 + packages/segmented-control/package.json | 1 + packages/shared/package.json | 1 + packages/skeleton/package.json | 1 + packages/slider-input/package.json | 1 + packages/status-badge/package.json | 1 + packages/stepped-progress-bar/package.json | 1 + packages/switch/package.json | 1 + packages/system-message/package.json | 1 + packages/time-input/package.json | 1 + packages/with-suffix/package.json | 1 + 31 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 .changeset/nervous-ants-learn.md diff --git a/.changeset/nervous-ants-learn.md b/.changeset/nervous-ants-learn.md new file mode 100644 index 0000000000..14795869f3 --- /dev/null +++ b/.changeset/nervous-ants-learn.md @@ -0,0 +1,33 @@ +--- +'@alfalab/core-components-drawer': patch +'@alfalab/core-components-form-control': patch +'@alfalab/core-components-notification': patch +'@alfalab/core-components-notification-manager': patch +'@alfalab/core-components-number-input': patch +'@alfalab/core-components-pagination': patch +'@alfalab/core-components-pass-code': patch +'@alfalab/core-components-pass-code-v1': patch +'@alfalab/core-components-password-input': patch +'@alfalab/core-components-pattern-lock': patch +'@alfalab/core-components-pattern-lock-v1': patch +'@alfalab/core-components-popover': patch +'@alfalab/core-components-popup-sheet': patch +'@alfalab/core-components-portal': patch +'@alfalab/core-components-product-cover': patch +'@alfalab/core-components-pure-cell': patch +'@alfalab/core-components-radio': patch +'@alfalab/core-components-radio-group': patch +'@alfalab/core-components-segmented-control': patch +'@alfalab/core-components-shared': patch +'@alfalab/core-components-skeleton': patch +'@alfalab/core-components-slider-input': patch +'@alfalab/core-components-status-badge': patch +'@alfalab/core-components-stepped-progress-bar': patch +'@alfalab/core-components-switch': patch +'@alfalab/core-components-system-message': patch +'@alfalab/core-components-time-input': patch +'@alfalab/core-components-with-suffix': patch +--- + +- Добавлено "sideEffects": false, чтобы бандлер лучше делал тришейк. +- В SideEffect пакета base-modal добавлена зависимость от полифила. diff --git a/bin/build.sh b/bin/build.sh index 05c0159095..dfd2e40d64 100755 --- a/bin/build.sh +++ b/bin/build.sh @@ -26,7 +26,7 @@ lerna exec --scope @alfalab/core-components-themes -- node $(pwd)/bin/build-them lerna exec --scope @alfalab/core-components-vars -- node $(pwd)/bin/export-css-custom-properties-as-js-vars.js # собираю все подпакеты с компонентами -lerna exec --concurrency $CONCURRENCY \ +lerna exec --scope @alfalab/core-components-base-modal \ --ignore @alfalab/core-components-codemod \ -- $(pwd)/bin/rollup.sh diff --git a/packages/base-modal/package.json b/packages/base-modal/package.json index b1c6d7c9bf..634e2e12d3 100644 --- a/packages/base-modal/package.json +++ b/packages/base-modal/package.json @@ -10,7 +10,9 @@ "access": "public", "directory": "dist" }, - "sideEffects": false, + "sideEffects": [ + "matches-polyfill.*" + ], "dependencies": { "@alfalab/core-components-backdrop": "^3.4.3", "@alfalab/core-components-global-store": "^2.1.0", diff --git a/packages/drawer/package.json b/packages/drawer/package.json index 94a5de42f0..9046ac14e5 100644 --- a/packages/drawer/package.json +++ b/packages/drawer/package.json @@ -10,6 +10,7 @@ "access": "public", "directory": "dist" }, + "sideEffects": false, "peerDependencies": { "react": "^16.9.0 || ^17.0.1 || ^18.0.0", "react-dom": "^16.9.0 || ^17.0.1 || ^18.0.0" diff --git a/packages/form-control/package.json b/packages/form-control/package.json index 14de9999fd..0f8c289b7a 100644 --- a/packages/form-control/package.json +++ b/packages/form-control/package.json @@ -10,6 +10,7 @@ "access": "public", "directory": "dist" }, + "sideEffects": false, "peerDependencies": { "react": "^16.9.0 || ^17.0.1 || ^18.0.0", "react-dom": "^16.9.0 || ^17.0.1 || ^18.0.0" diff --git a/packages/notification-manager/package.json b/packages/notification-manager/package.json index 0a3a4f4153..29b3b2f203 100644 --- a/packages/notification-manager/package.json +++ b/packages/notification-manager/package.json @@ -10,6 +10,7 @@ "access": "public", "directory": "dist" }, + "sideEffects": false, "peerDependencies": { "react": "^16.9.0 || ^17.0.1 || ^18.0.0" }, diff --git a/packages/notification/package.json b/packages/notification/package.json index 4e44e40541..75029dc83f 100644 --- a/packages/notification/package.json +++ b/packages/notification/package.json @@ -10,6 +10,7 @@ "access": "public", "directory": "dist" }, + "sideEffects": false, "peerDependencies": { "react": "^16.9.0 || ^17.0.1 || ^18.0.0" }, diff --git a/packages/number-input/package.json b/packages/number-input/package.json index 7d99bafd19..77eea639fa 100644 --- a/packages/number-input/package.json +++ b/packages/number-input/package.json @@ -10,6 +10,7 @@ "access": "public", "directory": "dist" }, + "sideEffects": false, "peerDependencies": { "react": "^16.9.0 || ^17.0.1 || ^18.0.0" }, diff --git a/packages/pagination/package.json b/packages/pagination/package.json index 25706f03dd..a94f0bea9a 100644 --- a/packages/pagination/package.json +++ b/packages/pagination/package.json @@ -10,6 +10,7 @@ "access": "public", "directory": "dist" }, + "sideEffects": false, "peerDependencies": { "react": "^16.9.0 || ^17.0.1 || ^18.0.0", "react-dom": "^16.9.0 || ^17.0.1 || ^18.0.0" diff --git a/packages/pass-code-v1/package.json b/packages/pass-code-v1/package.json index 0b67f2a0c3..a2ca60babb 100644 --- a/packages/pass-code-v1/package.json +++ b/packages/pass-code-v1/package.json @@ -10,6 +10,7 @@ "access": "public", "directory": "dist" }, + "sideEffects": false, "peerDependencies": { "react": "^16.9.0 || ^17.0.1 || ^18.0.0", "react-dom": "^16.9.0 || ^17.0.1 || ^18.0.0" diff --git a/packages/pass-code/package.json b/packages/pass-code/package.json index 334dbec0b3..5dad207e06 100644 --- a/packages/pass-code/package.json +++ b/packages/pass-code/package.json @@ -10,6 +10,7 @@ "access": "public", "directory": "dist" }, + "sideEffects": false, "peerDependencies": { "react": "^16.9.0 || ^17.0.1 || ^18.0.0", "react-dom": "^16.9.0 || ^17.0.1 || ^18.0.0" diff --git a/packages/password-input/package.json b/packages/password-input/package.json index 7f974f8925..668cabfbad 100644 --- a/packages/password-input/package.json +++ b/packages/password-input/package.json @@ -10,6 +10,7 @@ "access": "public", "directory": "dist" }, + "sideEffects": false, "peerDependencies": { "react": "^16.9.0 || ^17.0.1 || ^18.0.0", "react-dom": "^16.9.0 || ^17.0.1 || ^18.0.0" diff --git a/packages/pattern-lock-v1/package.json b/packages/pattern-lock-v1/package.json index 4f9c61fda1..b770b9dfea 100644 --- a/packages/pattern-lock-v1/package.json +++ b/packages/pattern-lock-v1/package.json @@ -10,6 +10,7 @@ "access": "public", "directory": "dist" }, + "sideEffects": false, "peerDependencies": { "react": "^16.9.0 || ^17.0.1 || ^18.0.0", "react-dom": "^16.9.0 || ^17.0.1 || ^18.0.0" diff --git a/packages/pattern-lock/package.json b/packages/pattern-lock/package.json index fe5f7fed77..5390ca392e 100644 --- a/packages/pattern-lock/package.json +++ b/packages/pattern-lock/package.json @@ -10,6 +10,7 @@ "access": "public", "directory": "dist" }, + "sideEffects": false, "peerDependencies": { "react": "^16.9.0 || ^17.0.1 || ^18.0.0", "react-dom": "^16.9.0 || ^17.0.1 || ^18.0.0" diff --git a/packages/popover/package.json b/packages/popover/package.json index b9c169e3c4..c45f68e92b 100644 --- a/packages/popover/package.json +++ b/packages/popover/package.json @@ -10,6 +10,7 @@ "access": "public", "directory": "dist" }, + "sideEffects": false, "peerDependencies": { "react": "^16.9.0 || ^17.0.1 || ^18.0.0", "react-dom": "^16.9.0 || ^17.0.1 || ^18.0.0" diff --git a/packages/popup-sheet/package.json b/packages/popup-sheet/package.json index c8519a40a8..f3c8e6646a 100644 --- a/packages/popup-sheet/package.json +++ b/packages/popup-sheet/package.json @@ -10,6 +10,7 @@ "access": "public", "directory": "dist" }, + "sideEffects": false, "peerDependencies": { "react": "^16.9.0 || ^17.0.1 || ^18.0.0", "react-dom": "^16.9.0 || ^17.0.1 || ^18.0.0" diff --git a/packages/portal/package.json b/packages/portal/package.json index 75e43c1c04..9069bdc518 100644 --- a/packages/portal/package.json +++ b/packages/portal/package.json @@ -10,6 +10,7 @@ "access": "public", "directory": "dist" }, + "sideEffects": false, "peerDependencies": { "react": "^16.9.0 || ^17.0.1 || ^18.0.0", "react-dom": "^16.9.0 || ^17.0.1 || ^18.0.0" diff --git a/packages/product-cover/package.json b/packages/product-cover/package.json index 8fcdb0bc53..db33b9fece 100644 --- a/packages/product-cover/package.json +++ b/packages/product-cover/package.json @@ -10,6 +10,7 @@ "access": "public", "directory": "dist" }, + "sideEffects": false, "peerDependencies": { "react": "^16.9.0 || ^17.0.1 || ^18.0.0", "react-dom": "^16.9.0 || ^17.0.1 || ^18.0.0" diff --git a/packages/pure-cell/package.json b/packages/pure-cell/package.json index d30b26e13e..8067dce96f 100644 --- a/packages/pure-cell/package.json +++ b/packages/pure-cell/package.json @@ -10,6 +10,7 @@ "access": "public", "directory": "dist" }, + "sideEffects": false, "peerDependencies": { "react": "^16.9.0 || ^17.0.1 || ^18.0.0", "react-dom": "^16.9.0 || ^17.0.1 || ^18.0.0" diff --git a/packages/radio-group/package.json b/packages/radio-group/package.json index efeeccfb2e..1715157ecd 100644 --- a/packages/radio-group/package.json +++ b/packages/radio-group/package.json @@ -10,6 +10,7 @@ "access": "public", "directory": "dist" }, + "sideEffects": false, "peerDependencies": { "react": "^16.9.0 || ^17.0.1 || ^18.0.0", "react-dom": "^16.9.0 || ^17.0.1 || ^18.0.0" diff --git a/packages/radio/package.json b/packages/radio/package.json index 8696655b42..88508233f0 100644 --- a/packages/radio/package.json +++ b/packages/radio/package.json @@ -10,6 +10,7 @@ "access": "public", "directory": "dist" }, + "sideEffects": false, "peerDependencies": { "react": "^16.9.0 || ^17.0.1 || ^18.0.0", "react-dom": "^16.9.0 || ^17.0.1 || ^18.0.0" diff --git a/packages/segmented-control/package.json b/packages/segmented-control/package.json index f1f8872b9c..e59ab0f4d0 100644 --- a/packages/segmented-control/package.json +++ b/packages/segmented-control/package.json @@ -10,6 +10,7 @@ "access": "public", "directory": "dist" }, + "sideEffects": false, "peerDependencies": { "react": "^16.9.0 || ^17.0.1 || ^18.0.0", "react-dom": "^16.9.0 || ^17.0.1 || ^18.0.0" diff --git a/packages/shared/package.json b/packages/shared/package.json index fbd2d7cd3a..9b50ea9b19 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -10,6 +10,7 @@ "access": "public", "directory": "dist" }, + "sideEffects": false, "peerDependencies": { "react": ">=16.8.0" }, diff --git a/packages/skeleton/package.json b/packages/skeleton/package.json index 6e29f5d997..56dec35373 100644 --- a/packages/skeleton/package.json +++ b/packages/skeleton/package.json @@ -10,6 +10,7 @@ "access": "public", "directory": "dist" }, + "sideEffects": false, "peerDependencies": { "react": "^16.9.0 || ^17.0.1 || ^18.0.0", "react-dom": "^16.9.0 || ^17.0.1 || ^18.0.0" diff --git a/packages/slider-input/package.json b/packages/slider-input/package.json index 2469d15d48..1293cd8f3a 100644 --- a/packages/slider-input/package.json +++ b/packages/slider-input/package.json @@ -10,6 +10,7 @@ "access": "public", "directory": "dist" }, + "sideEffects": false, "peerDependencies": { "react": "^16.9.0 || ^17.0.1 || ^18.0.0", "react-dom": "^16.9.0 || ^17.0.1 || ^18.0.0" diff --git a/packages/status-badge/package.json b/packages/status-badge/package.json index 2d89b06965..a1efc9d016 100644 --- a/packages/status-badge/package.json +++ b/packages/status-badge/package.json @@ -10,6 +10,7 @@ "access": "public", "directory": "dist" }, + "sideEffects": false, "peerDependencies": { "react": ">=16.8.0" }, diff --git a/packages/stepped-progress-bar/package.json b/packages/stepped-progress-bar/package.json index 1677d534da..e2f5a0694d 100644 --- a/packages/stepped-progress-bar/package.json +++ b/packages/stepped-progress-bar/package.json @@ -10,6 +10,7 @@ "access": "public", "directory": "dist" }, + "sideEffects": false, "peerDependencies": { "react": "^16.9.0 || ^17.0.1 || ^18.0.0" }, diff --git a/packages/switch/package.json b/packages/switch/package.json index 8600288461..54a70ae015 100644 --- a/packages/switch/package.json +++ b/packages/switch/package.json @@ -11,6 +11,7 @@ "access": "public", "directory": "dist" }, + "sideEffects": false, "peerDependencies": { "react": "^16.9.0 || ^17.0.1 || ^18.0.0" }, diff --git a/packages/system-message/package.json b/packages/system-message/package.json index 7d9313900b..4608ab866c 100644 --- a/packages/system-message/package.json +++ b/packages/system-message/package.json @@ -10,6 +10,7 @@ "access": "public", "directory": "dist" }, + "sideEffects": false, "peerDependencies": { "react": ">=16.8.0" }, diff --git a/packages/time-input/package.json b/packages/time-input/package.json index 36dbafc852..710b699681 100644 --- a/packages/time-input/package.json +++ b/packages/time-input/package.json @@ -10,6 +10,7 @@ "access": "public", "directory": "dist" }, + "sideEffects": false, "peerDependencies": { "react": "^16.9.0 || ^17.0.1 || ^18.0.0", "react-dom": "^16.9.0 || ^17.0.1 || ^18.0.0" diff --git a/packages/with-suffix/package.json b/packages/with-suffix/package.json index c47c13cbde..471688c5ef 100644 --- a/packages/with-suffix/package.json +++ b/packages/with-suffix/package.json @@ -10,6 +10,7 @@ "access": "public", "directory": "dist" }, + "sideEffects": false, "peerDependencies": { "react": "^16.9.0 || ^17.0.1 || ^18.0.0" }, From cedb18481c0c518bb4a4c97d4042f13fc674747b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Denis=20=F0=9F=8E=83=20Khripkov?= Date: Thu, 19 Dec 2024 18:47:30 +0300 Subject: [PATCH 2/6] fix: rollback build; --- bin/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/build.sh b/bin/build.sh index dfd2e40d64..05c0159095 100755 --- a/bin/build.sh +++ b/bin/build.sh @@ -26,7 +26,7 @@ lerna exec --scope @alfalab/core-components-themes -- node $(pwd)/bin/build-them lerna exec --scope @alfalab/core-components-vars -- node $(pwd)/bin/export-css-custom-properties-as-js-vars.js # собираю все подпакеты с компонентами -lerna exec --scope @alfalab/core-components-base-modal \ +lerna exec --concurrency $CONCURRENCY \ --ignore @alfalab/core-components-codemod \ -- $(pwd)/bin/rollup.sh From ba948d48d9469da1d7e8f27c97548c6d87f95d8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Denis=20=F0=9F=8E=83=20Khripkov?= Date: Fri, 20 Dec 2024 00:21:09 +0300 Subject: [PATCH 3/6] fix: rollback; --- .changeset/nervous-ants-learn.md | 3 +- .../base-modal/dist_side_poly/Component.d.ts | 159 +++++ .../base-modal/dist_side_poly/Component.js | 287 ++++++++ .../dist_side_poly/cssm/Component.d.ts | 159 +++++ .../dist_side_poly/cssm/Component.js | 286 ++++++++ .../cssm/helpers/lockScroll.d.ts | 5 + .../dist_side_poly/cssm/helpers/lockScroll.js | 28 + .../base-modal/dist_side_poly/cssm/index.d.ts | 3 + .../base-modal/dist_side_poly/cssm/index.js | 21 + .../dist_side_poly/cssm/index.module.css | 70 ++ .../dist_side_poly/cssm/matches-polyfill.d.ts | 1 + .../dist_side_poly/cssm/matches-polyfill.js | 20 + .../base-modal/dist_side_poly/cssm/utils.d.ts | 6 + .../base-modal/dist_side_poly/cssm/utils.js | 99 +++ .../dist_side_poly/esm/Component.d.ts | 159 +++++ .../dist_side_poly/esm/Component.js | 275 ++++++++ .../esm/helpers/lockScroll.d.ts | 5 + .../dist_side_poly/esm/helpers/lockScroll.js | 21 + .../base-modal/dist_side_poly/esm/index.css | 71 ++ .../base-modal/dist_side_poly/esm/index.d.ts | 3 + .../base-modal/dist_side_poly/esm/index.js | 3 + .../dist_side_poly/esm/matches-polyfill.d.ts | 1 + .../dist_side_poly/esm/matches-polyfill.js | 18 + .../base-modal/dist_side_poly/esm/utils.d.ts | 6 + .../base-modal/dist_side_poly/esm/utils.js | 91 +++ .../dist_side_poly/helpers/lockScroll.d.ts | 5 + .../dist_side_poly/helpers/lockScroll.js | 28 + packages/base-modal/dist_side_poly/index.css | 71 ++ packages/base-modal/dist_side_poly/index.d.ts | 3 + packages/base-modal/dist_side_poly/index.js | 21 + .../dist_side_poly/matches-polyfill.d.ts | 1 + .../dist_side_poly/matches-polyfill.js | 20 + .../dist_side_poly/modern/Component.d.ts | 159 +++++ .../dist_side_poly/modern/Component.js | 269 +++++++ .../modern/helpers/lockScroll.d.ts | 5 + .../modern/helpers/lockScroll.js | 21 + .../dist_side_poly/modern/index.css | 71 ++ .../dist_side_poly/modern/index.d.ts | 3 + .../base-modal/dist_side_poly/modern/index.js | 3 + .../modern/matches-polyfill.d.ts | 1 + .../dist_side_poly/modern/matches-polyfill.js | 18 + .../dist_side_poly/modern/utils.d.ts | 6 + .../base-modal/dist_side_poly/modern/utils.js | 87 +++ .../dist_side_poly/moderncssm/Component.d.ts | 159 +++++ .../dist_side_poly/moderncssm/Component.js | 267 +++++++ .../moderncssm/helpers/lockScroll.d.ts | 5 + .../moderncssm/helpers/lockScroll.js | 21 + .../dist_side_poly/moderncssm/index.d.ts | 3 + .../dist_side_poly/moderncssm/index.js | 3 + .../moderncssm/index.module.css | 71 ++ .../moderncssm/matches-polyfill.d.ts | 1 + .../moderncssm/matches-polyfill.js | 18 + .../dist_side_poly/moderncssm/utils.d.ts | 6 + .../dist_side_poly/moderncssm/utils.js | 87 +++ .../base-modal/dist_side_poly/package.json | 37 + .../dist_side_poly/src/Component.tsx | 654 ++++++++++++++++++ .../dist_side_poly/src/helpers/lockScroll.ts | 24 + .../dist_side_poly/src/index.module.css | 71 ++ .../base-modal/dist_side_poly/src/index.ts | 3 + .../dist_side_poly/src/matches-polyfill.ts | 19 + .../base-modal/dist_side_poly/src/utils.ts | 106 +++ packages/base-modal/dist_side_poly/utils.d.ts | 6 + packages/base-modal/dist_side_poly/utils.js | 99 +++ packages/base-modal/package.json | 4 +- packages/form-control/package.json | 1 - packages/gap/package.json | 1 - 66 files changed, 4251 insertions(+), 7 deletions(-) create mode 100644 packages/base-modal/dist_side_poly/Component.d.ts create mode 100644 packages/base-modal/dist_side_poly/Component.js create mode 100644 packages/base-modal/dist_side_poly/cssm/Component.d.ts create mode 100644 packages/base-modal/dist_side_poly/cssm/Component.js create mode 100644 packages/base-modal/dist_side_poly/cssm/helpers/lockScroll.d.ts create mode 100644 packages/base-modal/dist_side_poly/cssm/helpers/lockScroll.js create mode 100644 packages/base-modal/dist_side_poly/cssm/index.d.ts create mode 100644 packages/base-modal/dist_side_poly/cssm/index.js create mode 100644 packages/base-modal/dist_side_poly/cssm/index.module.css create mode 100644 packages/base-modal/dist_side_poly/cssm/matches-polyfill.d.ts create mode 100644 packages/base-modal/dist_side_poly/cssm/matches-polyfill.js create mode 100644 packages/base-modal/dist_side_poly/cssm/utils.d.ts create mode 100644 packages/base-modal/dist_side_poly/cssm/utils.js create mode 100644 packages/base-modal/dist_side_poly/esm/Component.d.ts create mode 100644 packages/base-modal/dist_side_poly/esm/Component.js create mode 100644 packages/base-modal/dist_side_poly/esm/helpers/lockScroll.d.ts create mode 100644 packages/base-modal/dist_side_poly/esm/helpers/lockScroll.js create mode 100644 packages/base-modal/dist_side_poly/esm/index.css create mode 100644 packages/base-modal/dist_side_poly/esm/index.d.ts create mode 100644 packages/base-modal/dist_side_poly/esm/index.js create mode 100644 packages/base-modal/dist_side_poly/esm/matches-polyfill.d.ts create mode 100644 packages/base-modal/dist_side_poly/esm/matches-polyfill.js create mode 100644 packages/base-modal/dist_side_poly/esm/utils.d.ts create mode 100644 packages/base-modal/dist_side_poly/esm/utils.js create mode 100644 packages/base-modal/dist_side_poly/helpers/lockScroll.d.ts create mode 100644 packages/base-modal/dist_side_poly/helpers/lockScroll.js create mode 100644 packages/base-modal/dist_side_poly/index.css create mode 100644 packages/base-modal/dist_side_poly/index.d.ts create mode 100644 packages/base-modal/dist_side_poly/index.js create mode 100644 packages/base-modal/dist_side_poly/matches-polyfill.d.ts create mode 100644 packages/base-modal/dist_side_poly/matches-polyfill.js create mode 100644 packages/base-modal/dist_side_poly/modern/Component.d.ts create mode 100644 packages/base-modal/dist_side_poly/modern/Component.js create mode 100644 packages/base-modal/dist_side_poly/modern/helpers/lockScroll.d.ts create mode 100644 packages/base-modal/dist_side_poly/modern/helpers/lockScroll.js create mode 100644 packages/base-modal/dist_side_poly/modern/index.css create mode 100644 packages/base-modal/dist_side_poly/modern/index.d.ts create mode 100644 packages/base-modal/dist_side_poly/modern/index.js create mode 100644 packages/base-modal/dist_side_poly/modern/matches-polyfill.d.ts create mode 100644 packages/base-modal/dist_side_poly/modern/matches-polyfill.js create mode 100644 packages/base-modal/dist_side_poly/modern/utils.d.ts create mode 100644 packages/base-modal/dist_side_poly/modern/utils.js create mode 100644 packages/base-modal/dist_side_poly/moderncssm/Component.d.ts create mode 100644 packages/base-modal/dist_side_poly/moderncssm/Component.js create mode 100644 packages/base-modal/dist_side_poly/moderncssm/helpers/lockScroll.d.ts create mode 100644 packages/base-modal/dist_side_poly/moderncssm/helpers/lockScroll.js create mode 100644 packages/base-modal/dist_side_poly/moderncssm/index.d.ts create mode 100644 packages/base-modal/dist_side_poly/moderncssm/index.js create mode 100644 packages/base-modal/dist_side_poly/moderncssm/index.module.css create mode 100644 packages/base-modal/dist_side_poly/moderncssm/matches-polyfill.d.ts create mode 100644 packages/base-modal/dist_side_poly/moderncssm/matches-polyfill.js create mode 100644 packages/base-modal/dist_side_poly/moderncssm/utils.d.ts create mode 100644 packages/base-modal/dist_side_poly/moderncssm/utils.js create mode 100644 packages/base-modal/dist_side_poly/package.json create mode 100644 packages/base-modal/dist_side_poly/src/Component.tsx create mode 100644 packages/base-modal/dist_side_poly/src/helpers/lockScroll.ts create mode 100644 packages/base-modal/dist_side_poly/src/index.module.css create mode 100644 packages/base-modal/dist_side_poly/src/index.ts create mode 100644 packages/base-modal/dist_side_poly/src/matches-polyfill.ts create mode 100644 packages/base-modal/dist_side_poly/src/utils.ts create mode 100644 packages/base-modal/dist_side_poly/utils.d.ts create mode 100644 packages/base-modal/dist_side_poly/utils.js diff --git a/.changeset/nervous-ants-learn.md b/.changeset/nervous-ants-learn.md index 14795869f3..fd8c4a7508 100644 --- a/.changeset/nervous-ants-learn.md +++ b/.changeset/nervous-ants-learn.md @@ -29,5 +29,4 @@ '@alfalab/core-components-with-suffix': patch --- -- Добавлено "sideEffects": false, чтобы бандлер лучше делал тришейк. -- В SideEffect пакета base-modal добавлена зависимость от полифила. +Добавлено "sideEffects": false, чтобы бандлер лучше делал тришейк. diff --git a/packages/base-modal/dist_side_poly/Component.d.ts b/packages/base-modal/dist_side_poly/Component.d.ts new file mode 100644 index 0000000000..44533e4e97 --- /dev/null +++ b/packages/base-modal/dist_side_poly/Component.d.ts @@ -0,0 +1,159 @@ +/// +/// +import React from 'react'; +import { ComponentType, KeyboardEvent, MouseEvent, MutableRefObject, ReactNode, Ref } from "react"; +import { TransitionProps } from 'react-transition-group/Transition'; +import { BackdropProps } from "@alfalab/core-components-backdrop"; +import { PortalProps } from "@alfalab/core-components-portal"; +type BaseModalProps = { + /** + * Контент + */ + children?: ReactNode; + /** + * Компонент бэкдропа + */ + Backdrop?: ComponentType; + /** + * Свойства для Бэкдропа + */ + backdropProps?: Partial & Record; + /** + * Нода, компонент или функция возвращающая их + * + * Контейнер к которому будут добавляться порталы + */ + container?: PortalProps['getPortalContainer']; + /** + * Отключает автоматический перевод фокуса на модалку при открытии + * @default false + */ + disableAutoFocus?: boolean; + /** + * Отключает ловушку фокуса + * @default false + */ + disableFocusLock?: boolean; + /** + * Отключает восстановление фокуса на предыдущем элементе после закрытия модалки + * @default false + */ + disableRestoreFocus?: boolean; + /** + * Отключает вызов `callback` при нажатии Escape + * @default false + */ + disableEscapeKeyDown?: boolean; + /** + * Отключает вызов `callback` при клике на бэкдроп + * @default false + */ + disableBackdropClick?: boolean; + /** + * Отключает блокировку скролла при открытии модального окна + * @default false + */ + disableBlockingScroll?: boolean; + /** + * Содержимое модалки всегда в DOM + * @default false + */ + keepMounted?: boolean; + /** + * Управление видимостью модалки + */ + open: boolean; + /** + * Дополнительный класс + */ + className?: string; + /** + * Дополнительный класс + */ + contentClassName?: string; + /** + * Дополнительные пропсы на dialog wrapper + */ + wrapperProps?: React.DetailedHTMLProps, HTMLDivElement>; + /** + * Дополнительные пропсы на обертку контента + */ + contentProps?: React.DetailedHTMLProps, HTMLDivElement>; + /** + * Дополнительные пропсы на компонентную обертку контента + */ + componentDivProps?: React.DetailedHTMLProps, HTMLDivElement>; + /** + * Дополнительный класс для обертки (Modal) + */ + wrapperClassName?: string; + /** + * Обработчик скролла контента + */ + scrollHandler?: 'wrapper' | 'content' | MutableRefObject; + /** + * Пропсы для анимации (CSSTransition) + */ + transitionProps?: Partial; + /** + * Рендерить ли в контейнер через портал. + * @default true + */ + usePortal?: boolean; + /** + * Обработчик события нажатия на бэкдроп + */ + onBackdropClick?: (event: MouseEvent) => void; + /** + * Обработчик события нажатия на Escape + * + * Если `disableEscapeKeyDown` - false и модальное окно в фокусе + */ + onEscapeKeyDown?: (event: KeyboardEvent) => void; + /** + * Обработчик закрытия + */ + onClose?: (event: MouseEvent | KeyboardEvent, reason?: 'backdropClick' | 'escapeKeyDown' | 'closerClick') => void; + /** + * Обработчик события onEntered компонента Transition + */ + onMount?: () => void; + /** + * Обработчик события onExited компонента Transition + */ + onUnmount?: () => void; + /** + * Идентификатор для систем автоматизированного тестирования + */ + dataTestId?: string; + /** + * z-index компонента + */ + zIndex?: number; + /** + * Реф, который должен быть установлен компонентной области + */ + componentRef?: MutableRefObject; + /** + * Блокирует скролл когда модальное окно открыто. Работает только на iOS. + */ + iOSLock?: boolean; +}; +type BaseModalContext = { + parentRef: React.RefObject; + componentRef: React.RefObject; + hasFooter?: boolean; + hasHeader?: boolean; + hasScroll?: boolean; + headerHighlighted?: boolean; + footerHighlighted?: boolean; + headerOffset?: number; + setHeaderOffset: (offset: number) => void; + contentRef: Ref; + setHasHeader: (exists: boolean) => void; + setHasFooter: (exists: boolean) => void; + onClose: Required['onClose']; +}; +declare const BaseModalContext: React.Context; +declare const BaseModal: React.ForwardRefExoticComponent>; +export { BaseModalProps, BaseModalContext, BaseModal }; diff --git a/packages/base-modal/dist_side_poly/Component.js b/packages/base-modal/dist_side_poly/Component.js new file mode 100644 index 0000000000..6f368d202f --- /dev/null +++ b/packages/base-modal/dist_side_poly/Component.js @@ -0,0 +1,287 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +var tslib = require('tslib'); +var React = require('react'); +var FocusLock = require('react-focus-lock'); +var mergeRefs = require('react-merge-refs'); +var reactTransitionGroup = require('react-transition-group'); +var resizeObserver = require('@juggle/resize-observer'); +var cn = require('classnames'); +var coreComponentsBackdrop = require('@alfalab/core-components-backdrop'); +var coreComponentsPortal = require('@alfalab/core-components-portal'); +var coreComponentsShared = require('@alfalab/core-components-shared'); +var coreComponentsStack = require('@alfalab/core-components-stack'); +var stackContext = require('@alfalab/stack-context'); +var helpers_lockScroll = require('./helpers/lockScroll.js'); +var utils = require('./utils.js'); +require('./matches-polyfill.js'); + +function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; } + +var React__default = /*#__PURE__*/_interopDefaultCompat(React); +var FocusLock__default = /*#__PURE__*/_interopDefaultCompat(FocusLock); +var mergeRefs__default = /*#__PURE__*/_interopDefaultCompat(mergeRefs); +var cn__default = /*#__PURE__*/_interopDefaultCompat(cn); + +var styles = {"component":"base-modal__component_1y6m8","wrapper":"base-modal__wrapper_1y6m8","content":"base-modal__content_1y6m8","hidden":"base-modal__hidden_1y6m8","backdrop":"base-modal__backdrop_1y6m8","appear":"base-modal__appear_1y6m8","enter":"base-modal__enter_1y6m8","appearActive":"base-modal__appearActive_1y6m8","enterActive":"base-modal__enterActive_1y6m8","exit":"base-modal__exit_1y6m8","exitActive":"base-modal__exitActive_1y6m8","exitDone":"base-modal__exitDone_1y6m8"}; +require('./index.css') + +// eslint-disable-next-line @typescript-eslint/no-redeclare +var BaseModalContext = React__default.default.createContext({ + parentRef: { current: null }, + componentRef: { current: null }, + hasFooter: false, + hasHeader: false, + hasScroll: false, + headerHighlighted: false, + footerHighlighted: false, + headerOffset: 0, + setHeaderOffset: function () { return null; }, + contentRef: function () { return null; }, + setHasHeader: function () { return null; }, + setHasFooter: function () { return null; }, + onClose: function () { return null; }, +}); +var BaseModal = React.forwardRef(function (_a, ref) { + var open = _a.open, container = _a.container, children = _a.children, _b = _a.scrollHandler, scrollHandler = _b === void 0 ? 'wrapper' : _b, _c = _a.Backdrop, Backdrop = _c === void 0 ? coreComponentsBackdrop.Backdrop : _c, _d = _a.backdropProps, backdropProps = _d === void 0 ? {} : _d, _e = _a.transitionProps, transitionProps = _e === void 0 ? {} : _e, disableBackdropClick = _a.disableBackdropClick, _f = _a.disableAutoFocus, disableAutoFocus = _f === void 0 ? false : _f, _g = _a.disableFocusLock, disableFocusLock = _g === void 0 ? false : _g, _h = _a.disableEscapeKeyDown, disableEscapeKeyDown = _h === void 0 ? false : _h, _j = _a.disableRestoreFocus, disableRestoreFocus = _j === void 0 ? false : _j, _k = _a.disableBlockingScroll, disableBlockingScroll = _k === void 0 ? false : _k, _l = _a.keepMounted, keepMounted = _l === void 0 ? false : _l, className = _a.className, contentClassName = _a.contentClassName, wrapperProps = _a.wrapperProps, contentProps = _a.contentProps, componentDivProps = _a.componentDivProps, wrapperClassName = _a.wrapperClassName, onBackdropClick = _a.onBackdropClick, onClose = _a.onClose, onEscapeKeyDown = _a.onEscapeKeyDown, onMount = _a.onMount, onUnmount = _a.onUnmount, dataTestId = _a.dataTestId, _m = _a.zIndex, zIndex = _m === void 0 ? stackContext.stackingOrder.MODAL : _m, _o = _a.componentRef, componentRef = _o === void 0 ? null : _o, _p = _a.usePortal, usePortal = _p === void 0 ? true : _p, _q = _a.iOSLock, iOSLock = _q === void 0 ? false : _q; + var _r = React.useState(null), exited = _r[0], setExited = _r[1]; + var _s = React.useState(false), hasScroll = _s[0], setHasScroll = _s[1]; + var _t = React.useState(false), hasHeader = _t[0], setHasHeader = _t[1]; + var _u = React.useState(false), hasFooter = _u[0], setHasFooter = _u[1]; + var _v = React.useState(false), headerHighlighted = _v[0], setHeaderHighlighted = _v[1]; + var _w = React.useState(false), footerHighlighted = _w[0], setFooterHighlighted = _w[1]; + var _x = React.useState(0), headerOffset = _x[0], setHeaderOffset = _x[1]; + var componentNodeRef = React.useRef(null); + var wrapperRef = React.useRef(null); + var scrollableNodeRef = React.useRef(null); + var contentNodeRef = React.useRef(null); + var restoreContainerStylesRef = React.useRef(null); + var mouseDownTarget = React.useRef(); + var resizeObserverRef = React.useRef(); + var checkToHasScrollBar = function () { + if (scrollableNodeRef.current) { + var scrollExists = utils.hasScrollbar(scrollableNodeRef.current); + setFooterHighlighted(scrollExists); + setHasScroll(scrollExists); + } + }; + var isExited = exited || exited === null; + var shouldRender = keepMounted || open || !isExited; + var getContainer = React.useCallback(function () { return (container ? container() : document.body); }, [container]); + var addResizeHandle = React.useCallback(function () { + if (!resizeObserverRef.current) + return; + if (scrollableNodeRef.current) { + resizeObserverRef.current.observe(scrollableNodeRef.current); + } + if (contentNodeRef.current) { + resizeObserverRef.current.observe(contentNodeRef.current); + } + }, []); + var removeResizeHandle = React.useCallback(function () { var _a; return (_a = resizeObserverRef.current) === null || _a === void 0 ? void 0 : _a.disconnect(); }, []); + var contentRef = React.useCallback(function (node) { + if (node !== null) { + contentNodeRef.current = node; + if (resizeObserverRef.current) { + resizeObserverRef.current.observe(node); + } + checkToHasScrollBar(); + } + }, []); + var handleScroll = React.useCallback(function () { + if (!scrollableNodeRef.current || !componentNodeRef.current) + return; + if (hasHeader) { + setHeaderHighlighted(!utils.isScrolledToTop(scrollableNodeRef.current) && + componentNodeRef.current.getBoundingClientRect().top - headerOffset <= 1); + } + if (hasFooter) { + setFooterHighlighted(!utils.isScrolledToBottom(scrollableNodeRef.current) && + componentNodeRef.current.getBoundingClientRect().bottom >= + window.innerHeight - 1); + } + }, [hasFooter, hasHeader, headerOffset]); + var handleClose = React.useCallback(function (event, reason) { + if (iOSLock && coreComponentsShared.os.isIOS()) { + helpers_lockScroll.unlockScroll(); + } + if (onClose) { + onClose(event, reason); + } + if (reason === 'backdropClick' && onBackdropClick) { + onBackdropClick(event); + } + if (reason === 'escapeKeyDown' && onEscapeKeyDown) { + onEscapeKeyDown(event); + } + return null; + }, [onBackdropClick, onClose, onEscapeKeyDown, iOSLock]); + var handleBackdropMouseDown = function (event) { + var _a; + var clickedOnScrollbar = false; + var clientWidth = (_a = event.target) === null || _a === void 0 ? void 0 : _a.clientWidth; + if (event.clientX && clientWidth) { + // Устанавливаем смещение для абсолютно спозиционированного скроллбара в OSX в 17px. + var offset = coreComponentsShared.browser.getScrollbarSize() === 0 ? 17 : 0; + clickedOnScrollbar = event.clientX + offset > clientWidth; + } + if (!disableBackdropClick && !clickedOnScrollbar) { + mouseDownTarget.current = event.target; + } + }; + var handleBackdropMouseUp = function (event) { + if (!disableBackdropClick && + event.target === wrapperRef.current && + mouseDownTarget.current === wrapperRef.current) { + handleClose(event, 'backdropClick'); + } + mouseDownTarget.current = undefined; + }; + var handleKeyDown = React.useCallback(function (event) { + /* + * Чтобы сохранить дефолтное поведение элементов и событий форм, + * обработчик не устанавливает event.preventDefault() + */ + if (event.key !== 'Escape') { + return; + } + // Если есть обработчик escape на body + event.stopPropagation(); + if (!disableEscapeKeyDown && handleClose) { + handleClose(event, 'escapeKeyDown'); + } + }, [disableEscapeKeyDown, handleClose]); + var getScrollHandler = React.useCallback(function () { + if (scrollHandler === 'wrapper') + return wrapperRef.current; + if (scrollHandler === 'content') + return componentNodeRef.current; + return scrollHandler.current || wrapperRef.current; + }, [scrollHandler]); + var handleEntered = React.useCallback(function (node, isAppearing) { + scrollableNodeRef.current = getScrollHandler(); + addResizeHandle(); + if (scrollableNodeRef.current) { + scrollableNodeRef.current.addEventListener('scroll', handleScroll); + handleScroll(); + } + if (transitionProps.onEntered) { + transitionProps.onEntered(node, isAppearing); + } + if (onMount) + onMount(); + }, [addResizeHandle, getScrollHandler, handleScroll, onMount, transitionProps]); + var handleExited = React.useCallback(function (node) { + removeResizeHandle(); + setExited(true); + if (scrollableNodeRef.current) { + scrollableNodeRef.current.removeEventListener('scroll', handleScroll); + } + if (transitionProps.onExited) { + transitionProps.onExited(node); + } + if (onUnmount) + onUnmount(); + if (restoreContainerStylesRef.current) { + restoreContainerStylesRef.current(); + } + }, [handleScroll, onUnmount, removeResizeHandle, transitionProps]); + React.useEffect(function () { + if (open && isExited) { + if (!disableBlockingScroll) { + var el_1 = getContainer(); + var shouldIOSLock = iOSLock && coreComponentsShared.os.isIOS(); + utils.handleContainer(el_1, shouldIOSLock); + if (shouldIOSLock) { + helpers_lockScroll.syncHeight(); + helpers_lockScroll.lockScroll(); + } + restoreContainerStylesRef.current = function () { + restoreContainerStylesRef.current = null; + utils.restoreContainerStyles(el_1); + }; + } + setExited(false); + } + if (!open) { + helpers_lockScroll.unlockScroll(); + } + }, [getContainer, open, disableBlockingScroll, isExited, iOSLock]); + React.useEffect(function () { + var ResizeObserver = window.ResizeObserver || resizeObserver.ResizeObserver; + resizeObserverRef.current = new ResizeObserver(checkToHasScrollBar); + return function () { + if (restoreContainerStylesRef.current) { + restoreContainerStylesRef.current(); + } + if (resizeObserverRef.current) { + resizeObserverRef.current.disconnect(); + } + }; + }, []); + React.useEffect(function () { + var _a; + if (disableAutoFocus || !open) + return; + (_a = wrapperRef.current) === null || _a === void 0 ? void 0 : _a.focus(); + }, [open, disableAutoFocus]); + var contextValue = React.useMemo(function () { return ({ + parentRef: wrapperRef, + componentRef: componentNodeRef, + hasHeader: hasHeader, + hasFooter: hasFooter, + hasScroll: hasScroll, + headerHighlighted: headerHighlighted, + footerHighlighted: footerHighlighted, + headerOffset: headerOffset, + setHeaderOffset: setHeaderOffset, + contentRef: contentRef, + setHasHeader: setHasHeader, + setHasFooter: setHasFooter, + onClose: handleClose, + }); }, [ + contentRef, + hasHeader, + hasFooter, + hasScroll, + headerHighlighted, + footerHighlighted, + headerOffset, + setHeaderOffset, + handleClose, + ]); + var renderContent = function () { return (React__default.default.createElement(coreComponentsStack.Stack, { value: zIndex }, function (computedZIndex) { + var _a; + return (React__default.default.createElement(BaseModalContext.Provider, { value: contextValue }, + React__default.default.createElement(FocusLock__default.default, { disabled: disableFocusLock || !open, returnFocus: !disableRestoreFocus }, + Backdrop && (React__default.default.createElement(Backdrop, tslib.__assign({}, backdropProps, { className: cn__default.default(backdropProps.className, styles.backdrop), open: open, style: { + zIndex: computedZIndex, + } }))), + React__default.default.createElement("div", tslib.__assign({}, wrapperProps, { role: 'dialog', className: cn__default.default(styles.wrapper, wrapperClassName, wrapperProps === null || wrapperProps === void 0 ? void 0 : wrapperProps.className, (_a = {}, + _a[styles.hidden] = !open && isExited, + _a)), ref: mergeRefs__default.default([ + ref, + wrapperRef, + wrapperProps === null || wrapperProps === void 0 ? void 0 : wrapperProps.ref, + ]), onKeyDown: handleKeyDown, onMouseDown: handleBackdropMouseDown, onMouseUp: handleBackdropMouseUp, tabIndex: -1, "data-test-id": dataTestId, style: { + zIndex: computedZIndex, + } }), + React__default.default.createElement(reactTransitionGroup.CSSTransition, tslib.__assign({ appear: true, timeout: 200, classNames: styles, nodeRef: componentNodeRef }, transitionProps, { in: open, onEntered: handleEntered, onExited: handleExited }), + React__default.default.createElement("div", tslib.__assign({}, componentDivProps, { className: cn__default.default(styles.component, className, componentDivProps === null || componentDivProps === void 0 ? void 0 : componentDivProps.className), ref: mergeRefs__default.default([ + componentRef, + componentNodeRef, + (componentDivProps === null || componentDivProps === void 0 ? void 0 : componentDivProps.ref) || null, + ]) }), + React__default.default.createElement("div", tslib.__assign({}, contentProps, { className: cn__default.default(styles.content, contentClassName, contentProps === null || contentProps === void 0 ? void 0 : contentProps.className) }), children))))))); + })); }; + if (!shouldRender) + return null; + return usePortal ? (React__default.default.createElement(coreComponentsPortal.Portal, { getPortalContainer: container, immediateMount: true }, renderContent())) : (renderContent()); +}); +BaseModal.displayName = 'BaseModal'; +BaseModalContext.displayName = 'BaseModalContext'; + +exports.BaseModal = BaseModal; +exports.BaseModalContext = BaseModalContext; diff --git a/packages/base-modal/dist_side_poly/cssm/Component.d.ts b/packages/base-modal/dist_side_poly/cssm/Component.d.ts new file mode 100644 index 0000000000..44533e4e97 --- /dev/null +++ b/packages/base-modal/dist_side_poly/cssm/Component.d.ts @@ -0,0 +1,159 @@ +/// +/// +import React from 'react'; +import { ComponentType, KeyboardEvent, MouseEvent, MutableRefObject, ReactNode, Ref } from "react"; +import { TransitionProps } from 'react-transition-group/Transition'; +import { BackdropProps } from "@alfalab/core-components-backdrop"; +import { PortalProps } from "@alfalab/core-components-portal"; +type BaseModalProps = { + /** + * Контент + */ + children?: ReactNode; + /** + * Компонент бэкдропа + */ + Backdrop?: ComponentType; + /** + * Свойства для Бэкдропа + */ + backdropProps?: Partial & Record; + /** + * Нода, компонент или функция возвращающая их + * + * Контейнер к которому будут добавляться порталы + */ + container?: PortalProps['getPortalContainer']; + /** + * Отключает автоматический перевод фокуса на модалку при открытии + * @default false + */ + disableAutoFocus?: boolean; + /** + * Отключает ловушку фокуса + * @default false + */ + disableFocusLock?: boolean; + /** + * Отключает восстановление фокуса на предыдущем элементе после закрытия модалки + * @default false + */ + disableRestoreFocus?: boolean; + /** + * Отключает вызов `callback` при нажатии Escape + * @default false + */ + disableEscapeKeyDown?: boolean; + /** + * Отключает вызов `callback` при клике на бэкдроп + * @default false + */ + disableBackdropClick?: boolean; + /** + * Отключает блокировку скролла при открытии модального окна + * @default false + */ + disableBlockingScroll?: boolean; + /** + * Содержимое модалки всегда в DOM + * @default false + */ + keepMounted?: boolean; + /** + * Управление видимостью модалки + */ + open: boolean; + /** + * Дополнительный класс + */ + className?: string; + /** + * Дополнительный класс + */ + contentClassName?: string; + /** + * Дополнительные пропсы на dialog wrapper + */ + wrapperProps?: React.DetailedHTMLProps, HTMLDivElement>; + /** + * Дополнительные пропсы на обертку контента + */ + contentProps?: React.DetailedHTMLProps, HTMLDivElement>; + /** + * Дополнительные пропсы на компонентную обертку контента + */ + componentDivProps?: React.DetailedHTMLProps, HTMLDivElement>; + /** + * Дополнительный класс для обертки (Modal) + */ + wrapperClassName?: string; + /** + * Обработчик скролла контента + */ + scrollHandler?: 'wrapper' | 'content' | MutableRefObject; + /** + * Пропсы для анимации (CSSTransition) + */ + transitionProps?: Partial; + /** + * Рендерить ли в контейнер через портал. + * @default true + */ + usePortal?: boolean; + /** + * Обработчик события нажатия на бэкдроп + */ + onBackdropClick?: (event: MouseEvent) => void; + /** + * Обработчик события нажатия на Escape + * + * Если `disableEscapeKeyDown` - false и модальное окно в фокусе + */ + onEscapeKeyDown?: (event: KeyboardEvent) => void; + /** + * Обработчик закрытия + */ + onClose?: (event: MouseEvent | KeyboardEvent, reason?: 'backdropClick' | 'escapeKeyDown' | 'closerClick') => void; + /** + * Обработчик события onEntered компонента Transition + */ + onMount?: () => void; + /** + * Обработчик события onExited компонента Transition + */ + onUnmount?: () => void; + /** + * Идентификатор для систем автоматизированного тестирования + */ + dataTestId?: string; + /** + * z-index компонента + */ + zIndex?: number; + /** + * Реф, который должен быть установлен компонентной области + */ + componentRef?: MutableRefObject; + /** + * Блокирует скролл когда модальное окно открыто. Работает только на iOS. + */ + iOSLock?: boolean; +}; +type BaseModalContext = { + parentRef: React.RefObject; + componentRef: React.RefObject; + hasFooter?: boolean; + hasHeader?: boolean; + hasScroll?: boolean; + headerHighlighted?: boolean; + footerHighlighted?: boolean; + headerOffset?: number; + setHeaderOffset: (offset: number) => void; + contentRef: Ref; + setHasHeader: (exists: boolean) => void; + setHasFooter: (exists: boolean) => void; + onClose: Required['onClose']; +}; +declare const BaseModalContext: React.Context; +declare const BaseModal: React.ForwardRefExoticComponent>; +export { BaseModalProps, BaseModalContext, BaseModal }; diff --git a/packages/base-modal/dist_side_poly/cssm/Component.js b/packages/base-modal/dist_side_poly/cssm/Component.js new file mode 100644 index 0000000000..924c025d3d --- /dev/null +++ b/packages/base-modal/dist_side_poly/cssm/Component.js @@ -0,0 +1,286 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +var tslib = require('tslib'); +var React = require('react'); +var FocusLock = require('react-focus-lock'); +var mergeRefs = require('react-merge-refs'); +var reactTransitionGroup = require('react-transition-group'); +var resizeObserver = require('@juggle/resize-observer'); +var cn = require('classnames'); +var coreComponentsBackdrop = require('@alfalab/core-components-backdrop/cssm'); +var coreComponentsPortal = require('@alfalab/core-components-portal/cssm'); +var coreComponentsShared = require('@alfalab/core-components-shared/cssm'); +var coreComponentsStack = require('@alfalab/core-components-stack/cssm'); +var stackContext = require('@alfalab/stack-context'); +var helpers_lockScroll = require('./helpers/lockScroll.js'); +var utils = require('./utils.js'); +var styles = require('./index.module.css'); +require('./matches-polyfill.js'); + +function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; } + +var React__default = /*#__PURE__*/_interopDefaultCompat(React); +var FocusLock__default = /*#__PURE__*/_interopDefaultCompat(FocusLock); +var mergeRefs__default = /*#__PURE__*/_interopDefaultCompat(mergeRefs); +var cn__default = /*#__PURE__*/_interopDefaultCompat(cn); +var styles__default = /*#__PURE__*/_interopDefaultCompat(styles); + +// eslint-disable-next-line @typescript-eslint/no-redeclare +var BaseModalContext = React__default.default.createContext({ + parentRef: { current: null }, + componentRef: { current: null }, + hasFooter: false, + hasHeader: false, + hasScroll: false, + headerHighlighted: false, + footerHighlighted: false, + headerOffset: 0, + setHeaderOffset: function () { return null; }, + contentRef: function () { return null; }, + setHasHeader: function () { return null; }, + setHasFooter: function () { return null; }, + onClose: function () { return null; }, +}); +var BaseModal = React.forwardRef(function (_a, ref) { + var open = _a.open, container = _a.container, children = _a.children, _b = _a.scrollHandler, scrollHandler = _b === void 0 ? 'wrapper' : _b, _c = _a.Backdrop, Backdrop = _c === void 0 ? coreComponentsBackdrop.Backdrop : _c, _d = _a.backdropProps, backdropProps = _d === void 0 ? {} : _d, _e = _a.transitionProps, transitionProps = _e === void 0 ? {} : _e, disableBackdropClick = _a.disableBackdropClick, _f = _a.disableAutoFocus, disableAutoFocus = _f === void 0 ? false : _f, _g = _a.disableFocusLock, disableFocusLock = _g === void 0 ? false : _g, _h = _a.disableEscapeKeyDown, disableEscapeKeyDown = _h === void 0 ? false : _h, _j = _a.disableRestoreFocus, disableRestoreFocus = _j === void 0 ? false : _j, _k = _a.disableBlockingScroll, disableBlockingScroll = _k === void 0 ? false : _k, _l = _a.keepMounted, keepMounted = _l === void 0 ? false : _l, className = _a.className, contentClassName = _a.contentClassName, wrapperProps = _a.wrapperProps, contentProps = _a.contentProps, componentDivProps = _a.componentDivProps, wrapperClassName = _a.wrapperClassName, onBackdropClick = _a.onBackdropClick, onClose = _a.onClose, onEscapeKeyDown = _a.onEscapeKeyDown, onMount = _a.onMount, onUnmount = _a.onUnmount, dataTestId = _a.dataTestId, _m = _a.zIndex, zIndex = _m === void 0 ? stackContext.stackingOrder.MODAL : _m, _o = _a.componentRef, componentRef = _o === void 0 ? null : _o, _p = _a.usePortal, usePortal = _p === void 0 ? true : _p, _q = _a.iOSLock, iOSLock = _q === void 0 ? false : _q; + var _r = React.useState(null), exited = _r[0], setExited = _r[1]; + var _s = React.useState(false), hasScroll = _s[0], setHasScroll = _s[1]; + var _t = React.useState(false), hasHeader = _t[0], setHasHeader = _t[1]; + var _u = React.useState(false), hasFooter = _u[0], setHasFooter = _u[1]; + var _v = React.useState(false), headerHighlighted = _v[0], setHeaderHighlighted = _v[1]; + var _w = React.useState(false), footerHighlighted = _w[0], setFooterHighlighted = _w[1]; + var _x = React.useState(0), headerOffset = _x[0], setHeaderOffset = _x[1]; + var componentNodeRef = React.useRef(null); + var wrapperRef = React.useRef(null); + var scrollableNodeRef = React.useRef(null); + var contentNodeRef = React.useRef(null); + var restoreContainerStylesRef = React.useRef(null); + var mouseDownTarget = React.useRef(); + var resizeObserverRef = React.useRef(); + var checkToHasScrollBar = function () { + if (scrollableNodeRef.current) { + var scrollExists = utils.hasScrollbar(scrollableNodeRef.current); + setFooterHighlighted(scrollExists); + setHasScroll(scrollExists); + } + }; + var isExited = exited || exited === null; + var shouldRender = keepMounted || open || !isExited; + var getContainer = React.useCallback(function () { return (container ? container() : document.body); }, [container]); + var addResizeHandle = React.useCallback(function () { + if (!resizeObserverRef.current) + return; + if (scrollableNodeRef.current) { + resizeObserverRef.current.observe(scrollableNodeRef.current); + } + if (contentNodeRef.current) { + resizeObserverRef.current.observe(contentNodeRef.current); + } + }, []); + var removeResizeHandle = React.useCallback(function () { var _a; return (_a = resizeObserverRef.current) === null || _a === void 0 ? void 0 : _a.disconnect(); }, []); + var contentRef = React.useCallback(function (node) { + if (node !== null) { + contentNodeRef.current = node; + if (resizeObserverRef.current) { + resizeObserverRef.current.observe(node); + } + checkToHasScrollBar(); + } + }, []); + var handleScroll = React.useCallback(function () { + if (!scrollableNodeRef.current || !componentNodeRef.current) + return; + if (hasHeader) { + setHeaderHighlighted(!utils.isScrolledToTop(scrollableNodeRef.current) && + componentNodeRef.current.getBoundingClientRect().top - headerOffset <= 1); + } + if (hasFooter) { + setFooterHighlighted(!utils.isScrolledToBottom(scrollableNodeRef.current) && + componentNodeRef.current.getBoundingClientRect().bottom >= + window.innerHeight - 1); + } + }, [hasFooter, hasHeader, headerOffset]); + var handleClose = React.useCallback(function (event, reason) { + if (iOSLock && coreComponentsShared.os.isIOS()) { + helpers_lockScroll.unlockScroll(); + } + if (onClose) { + onClose(event, reason); + } + if (reason === 'backdropClick' && onBackdropClick) { + onBackdropClick(event); + } + if (reason === 'escapeKeyDown' && onEscapeKeyDown) { + onEscapeKeyDown(event); + } + return null; + }, [onBackdropClick, onClose, onEscapeKeyDown, iOSLock]); + var handleBackdropMouseDown = function (event) { + var _a; + var clickedOnScrollbar = false; + var clientWidth = (_a = event.target) === null || _a === void 0 ? void 0 : _a.clientWidth; + if (event.clientX && clientWidth) { + // Устанавливаем смещение для абсолютно спозиционированного скроллбара в OSX в 17px. + var offset = coreComponentsShared.browser.getScrollbarSize() === 0 ? 17 : 0; + clickedOnScrollbar = event.clientX + offset > clientWidth; + } + if (!disableBackdropClick && !clickedOnScrollbar) { + mouseDownTarget.current = event.target; + } + }; + var handleBackdropMouseUp = function (event) { + if (!disableBackdropClick && + event.target === wrapperRef.current && + mouseDownTarget.current === wrapperRef.current) { + handleClose(event, 'backdropClick'); + } + mouseDownTarget.current = undefined; + }; + var handleKeyDown = React.useCallback(function (event) { + /* + * Чтобы сохранить дефолтное поведение элементов и событий форм, + * обработчик не устанавливает event.preventDefault() + */ + if (event.key !== 'Escape') { + return; + } + // Если есть обработчик escape на body + event.stopPropagation(); + if (!disableEscapeKeyDown && handleClose) { + handleClose(event, 'escapeKeyDown'); + } + }, [disableEscapeKeyDown, handleClose]); + var getScrollHandler = React.useCallback(function () { + if (scrollHandler === 'wrapper') + return wrapperRef.current; + if (scrollHandler === 'content') + return componentNodeRef.current; + return scrollHandler.current || wrapperRef.current; + }, [scrollHandler]); + var handleEntered = React.useCallback(function (node, isAppearing) { + scrollableNodeRef.current = getScrollHandler(); + addResizeHandle(); + if (scrollableNodeRef.current) { + scrollableNodeRef.current.addEventListener('scroll', handleScroll); + handleScroll(); + } + if (transitionProps.onEntered) { + transitionProps.onEntered(node, isAppearing); + } + if (onMount) + onMount(); + }, [addResizeHandle, getScrollHandler, handleScroll, onMount, transitionProps]); + var handleExited = React.useCallback(function (node) { + removeResizeHandle(); + setExited(true); + if (scrollableNodeRef.current) { + scrollableNodeRef.current.removeEventListener('scroll', handleScroll); + } + if (transitionProps.onExited) { + transitionProps.onExited(node); + } + if (onUnmount) + onUnmount(); + if (restoreContainerStylesRef.current) { + restoreContainerStylesRef.current(); + } + }, [handleScroll, onUnmount, removeResizeHandle, transitionProps]); + React.useEffect(function () { + if (open && isExited) { + if (!disableBlockingScroll) { + var el_1 = getContainer(); + var shouldIOSLock = iOSLock && coreComponentsShared.os.isIOS(); + utils.handleContainer(el_1, shouldIOSLock); + if (shouldIOSLock) { + helpers_lockScroll.syncHeight(); + helpers_lockScroll.lockScroll(); + } + restoreContainerStylesRef.current = function () { + restoreContainerStylesRef.current = null; + utils.restoreContainerStyles(el_1); + }; + } + setExited(false); + } + if (!open) { + helpers_lockScroll.unlockScroll(); + } + }, [getContainer, open, disableBlockingScroll, isExited, iOSLock]); + React.useEffect(function () { + var ResizeObserver = window.ResizeObserver || resizeObserver.ResizeObserver; + resizeObserverRef.current = new ResizeObserver(checkToHasScrollBar); + return function () { + if (restoreContainerStylesRef.current) { + restoreContainerStylesRef.current(); + } + if (resizeObserverRef.current) { + resizeObserverRef.current.disconnect(); + } + }; + }, []); + React.useEffect(function () { + var _a; + if (disableAutoFocus || !open) + return; + (_a = wrapperRef.current) === null || _a === void 0 ? void 0 : _a.focus(); + }, [open, disableAutoFocus]); + var contextValue = React.useMemo(function () { return ({ + parentRef: wrapperRef, + componentRef: componentNodeRef, + hasHeader: hasHeader, + hasFooter: hasFooter, + hasScroll: hasScroll, + headerHighlighted: headerHighlighted, + footerHighlighted: footerHighlighted, + headerOffset: headerOffset, + setHeaderOffset: setHeaderOffset, + contentRef: contentRef, + setHasHeader: setHasHeader, + setHasFooter: setHasFooter, + onClose: handleClose, + }); }, [ + contentRef, + hasHeader, + hasFooter, + hasScroll, + headerHighlighted, + footerHighlighted, + headerOffset, + setHeaderOffset, + handleClose, + ]); + var renderContent = function () { return (React__default.default.createElement(coreComponentsStack.Stack, { value: zIndex }, function (computedZIndex) { + var _a; + return (React__default.default.createElement(BaseModalContext.Provider, { value: contextValue }, + React__default.default.createElement(FocusLock__default.default, { disabled: disableFocusLock || !open, returnFocus: !disableRestoreFocus }, + Backdrop && (React__default.default.createElement(Backdrop, tslib.__assign({}, backdropProps, { className: cn__default.default(backdropProps.className, styles__default.default.backdrop), open: open, style: { + zIndex: computedZIndex, + } }))), + React__default.default.createElement("div", tslib.__assign({}, wrapperProps, { role: 'dialog', className: cn__default.default(styles__default.default.wrapper, wrapperClassName, wrapperProps === null || wrapperProps === void 0 ? void 0 : wrapperProps.className, (_a = {}, + _a[styles__default.default.hidden] = !open && isExited, + _a)), ref: mergeRefs__default.default([ + ref, + wrapperRef, + wrapperProps === null || wrapperProps === void 0 ? void 0 : wrapperProps.ref, + ]), onKeyDown: handleKeyDown, onMouseDown: handleBackdropMouseDown, onMouseUp: handleBackdropMouseUp, tabIndex: -1, "data-test-id": dataTestId, style: { + zIndex: computedZIndex, + } }), + React__default.default.createElement(reactTransitionGroup.CSSTransition, tslib.__assign({ appear: true, timeout: 200, classNames: styles__default.default, nodeRef: componentNodeRef }, transitionProps, { in: open, onEntered: handleEntered, onExited: handleExited }), + React__default.default.createElement("div", tslib.__assign({}, componentDivProps, { className: cn__default.default(styles__default.default.component, className, componentDivProps === null || componentDivProps === void 0 ? void 0 : componentDivProps.className), ref: mergeRefs__default.default([ + componentRef, + componentNodeRef, + (componentDivProps === null || componentDivProps === void 0 ? void 0 : componentDivProps.ref) || null, + ]) }), + React__default.default.createElement("div", tslib.__assign({}, contentProps, { className: cn__default.default(styles__default.default.content, contentClassName, contentProps === null || contentProps === void 0 ? void 0 : contentProps.className) }), children))))))); + })); }; + if (!shouldRender) + return null; + return usePortal ? (React__default.default.createElement(coreComponentsPortal.Portal, { getPortalContainer: container, immediateMount: true }, renderContent())) : (renderContent()); +}); +BaseModal.displayName = 'BaseModal'; +BaseModalContext.displayName = 'BaseModalContext'; + +exports.BaseModal = BaseModal; +exports.BaseModalContext = BaseModalContext; diff --git a/packages/base-modal/dist_side_poly/cssm/helpers/lockScroll.d.ts b/packages/base-modal/dist_side_poly/cssm/helpers/lockScroll.d.ts new file mode 100644 index 0000000000..80e91475f8 --- /dev/null +++ b/packages/base-modal/dist_side_poly/cssm/helpers/lockScroll.d.ts @@ -0,0 +1,5 @@ +declare const isScrollLocked: () => boolean; +declare const lockScroll: () => void; +declare const unlockScroll: () => void; +declare const syncHeight: () => void; +export { isScrollLocked, lockScroll, unlockScroll, syncHeight }; diff --git a/packages/base-modal/dist_side_poly/cssm/helpers/lockScroll.js b/packages/base-modal/dist_side_poly/cssm/helpers/lockScroll.js new file mode 100644 index 0000000000..5eea467f5b --- /dev/null +++ b/packages/base-modal/dist_side_poly/cssm/helpers/lockScroll.js @@ -0,0 +1,28 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +/** + * Хелпер для блокирования скроллинга в iOS + * В проекте используется overflow: hidden для блокировки, но в некоторых случаях этого недостаточно. Данный хелпер призван решать эту проблему + */ +var scrollY; +var isScrollLocked = function () { return document.body.classList.contains('is-locked'); }; +var lockScroll = function () { + scrollY = window.scrollY; + document.body.classList.add('is-locked'); +}; +var unlockScroll = function () { + if (!isScrollLocked()) + return; + document.body.classList.remove('is-locked'); + window.scrollTo(0, scrollY); +}; +var syncHeight = function () { + document.body.style.setProperty('--window-inner-scrollY', "".concat(window.scrollY, "px")); +}; + +exports.isScrollLocked = isScrollLocked; +exports.lockScroll = lockScroll; +exports.syncHeight = syncHeight; +exports.unlockScroll = unlockScroll; diff --git a/packages/base-modal/dist_side_poly/cssm/index.d.ts b/packages/base-modal/dist_side_poly/cssm/index.d.ts new file mode 100644 index 0000000000..61ae91968a --- /dev/null +++ b/packages/base-modal/dist_side_poly/cssm/index.d.ts @@ -0,0 +1,3 @@ +export * from "./Component"; +export * from "./utils"; +export * from "./helpers/lockScroll"; diff --git a/packages/base-modal/dist_side_poly/cssm/index.js b/packages/base-modal/dist_side_poly/cssm/index.js new file mode 100644 index 0000000000..cf4a09932b --- /dev/null +++ b/packages/base-modal/dist_side_poly/cssm/index.js @@ -0,0 +1,21 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +var Component = require('./Component.js'); +var utils = require('./utils.js'); +var helpers_lockScroll = require('./helpers/lockScroll.js'); + + + +exports.BaseModal = Component.BaseModal; +exports.BaseModalContext = Component.BaseModalContext; +exports.handleContainer = utils.handleContainer; +exports.hasScrollbar = utils.hasScrollbar; +exports.isScrolledToBottom = utils.isScrolledToBottom; +exports.isScrolledToTop = utils.isScrolledToTop; +exports.restoreContainerStyles = utils.restoreContainerStyles; +exports.isScrollLocked = helpers_lockScroll.isScrollLocked; +exports.lockScroll = helpers_lockScroll.lockScroll; +exports.syncHeight = helpers_lockScroll.syncHeight; +exports.unlockScroll = helpers_lockScroll.unlockScroll; diff --git a/packages/base-modal/dist_side_poly/cssm/index.module.css b/packages/base-modal/dist_side_poly/cssm/index.module.css new file mode 100644 index 0000000000..0723c8d479 --- /dev/null +++ b/packages/base-modal/dist_side_poly/cssm/index.module.css @@ -0,0 +1,70 @@ +:root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ +} /* deprecated */ :root { + --color-light-modal-bg-primary: #fff; /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ +} :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ +} :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ +} :root { + + /* Hard */ + + /* Up */ + + /* Hard up */ +} :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ + + /* новые значения, используйте их */ +} :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ + + /* новые значения, используйте их */ + --gap-0: 0; +} :root { +} :root { +} /* сбрасывает синюю подсветку при нажатии */ :root { + --window-inner-scrollY: 10px; /* fallback value to prevent ci error */ +} body:global(.is-locked) { + margin-top: calc(var(--window-inner-scrollY) * -1); + position: fixed; + overflow: hidden; +} .component { + position: relative; + box-sizing: border-box; + background: var(--color-light-modal-bg-primary); + margin: auto; + flex-shrink: 0; +} .wrapper { + position: fixed; + top: var(--gap-0); + left: var(--gap-0); + right: var(--gap-0); + bottom: var(--gap-0); + + overflow: auto; + display: flex; + flex-direction: column; + align-items: center; + outline: 0; + overscroll-behavior: none; +} .content { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + flex: 1; +} .hidden { + display: none; +} .backdrop { + z-index: 0; +} .appear, +.enter { + opacity: 0; +} .appearActive, +.enterActive { + opacity: 1; + transition: opacity 200ms ease-in; +} .exit { + opacity: 1; +} .exitActive, +.exitDone { + opacity: 0; + transition: opacity 200ms ease-out; +} diff --git a/packages/base-modal/dist_side_poly/cssm/matches-polyfill.d.ts b/packages/base-modal/dist_side_poly/cssm/matches-polyfill.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/packages/base-modal/dist_side_poly/cssm/matches-polyfill.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/base-modal/dist_side_poly/cssm/matches-polyfill.js b/packages/base-modal/dist_side_poly/cssm/matches-polyfill.js new file mode 100644 index 0000000000..e36a0cd0b7 --- /dev/null +++ b/packages/base-modal/dist_side_poly/cssm/matches-polyfill.js @@ -0,0 +1,20 @@ +'use strict'; + +/* eslint-disable */ +// @ts-nocheck +if (typeof window !== 'undefined') { + if (Element && !Element.prototype.matches) { + Element.prototype.matches = + Element.prototype.matchesSelector || + Element.prototype.mozMatchesSelector || + Element.prototype.msMatchesSelector || + Element.prototype.oMatchesSelector || + Element.prototype.webkitMatchesSelector || + function (s) { + var matches = (this.document || this.ownerDocument).querySelectorAll(s); + var i = matches.length; + while (--i >= 0 && matches.item(i) !== this) { } + return i > -1; + }; + } +} diff --git a/packages/base-modal/dist_side_poly/cssm/utils.d.ts b/packages/base-modal/dist_side_poly/cssm/utils.d.ts new file mode 100644 index 0000000000..75401779bb --- /dev/null +++ b/packages/base-modal/dist_side_poly/cssm/utils.d.ts @@ -0,0 +1,6 @@ +declare function isScrolledToTop(target: HTMLElement): boolean; +declare function isScrolledToBottom(target: HTMLElement): boolean; +declare function hasScrollbar(target: HTMLElement): boolean; +declare const restoreContainerStyles: (container: HTMLElement) => void; +declare const handleContainer: (container?: HTMLElement, shouldIOSLock?: boolean) => void; +export { isScrolledToTop, isScrolledToBottom, hasScrollbar, restoreContainerStyles, handleContainer }; diff --git a/packages/base-modal/dist_side_poly/cssm/utils.js b/packages/base-modal/dist_side_poly/cssm/utils.js new file mode 100644 index 0000000000..0754e95b42 --- /dev/null +++ b/packages/base-modal/dist_side_poly/cssm/utils.js @@ -0,0 +1,99 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +var coreComponentsGlobalStore = require('@alfalab/core-components-global-store/cssm'); +var coreComponentsShared = require('@alfalab/core-components-shared/cssm'); + +function isScrolledToTop(target) { + return target.scrollTop <= 0; +} +function isScrolledToBottom(target) { + return target.scrollHeight - target.offsetHeight <= target.scrollTop; +} +function hasScrollbar(target) { + return target.scrollHeight > target.clientHeight; +} +var isOverflowing = function (container) { + if (document.body === container) { + return window.innerWidth > document.documentElement.clientWidth; + } + return container.scrollHeight > container.clientHeight; +}; +var getPaddingRight = function (node) { + return parseInt(window.getComputedStyle(node).paddingRight, 10) || 0; +}; +var restoreContainerStyles = function (container) { + var modalRestoreStyles = coreComponentsGlobalStore.getModalStore().getRestoreStyles(); + var index = modalRestoreStyles.findIndex(function (s) { return s.container === container; }); + var existingStyles = modalRestoreStyles[index]; + if (!existingStyles) + return; + existingStyles.modals -= 1; + if (existingStyles.modals <= 0) { + modalRestoreStyles.splice(index, 1); + existingStyles.styles.forEach(function (_a) { + var value = _a.value, el = _a.el, key = _a.key; + if (value) { + el.style.setProperty(key, value); + } + else { + el.style.removeProperty(key); + } + }); + } +}; +var handleContainer = function (container, shouldIOSLock) { + if (shouldIOSLock === void 0) { shouldIOSLock = false; } + if (!container) + return; + var modalRestoreStyles = coreComponentsGlobalStore.getModalStore().getRestoreStyles(); + var existingStyles = modalRestoreStyles.find(function (s) { return s.container === container; }); + if (existingStyles) { + existingStyles.modals += 1; + return; + } + var containerStyles = []; + if (isOverflowing(container)) { + // Вычисляет размер до применения `overflow hidden` для избежания скачков + var scrollbarSize = coreComponentsShared.browser.getScrollbarSize(); + containerStyles.push({ + value: container.style.paddingRight, + key: 'padding-right', + el: container, + }); + // Вычисляем стили, чтобы получить реальный `padding` c шириной сколлбара + // eslint-disable-next-line no-param-reassign + container.style.paddingRight = "".concat(getPaddingRight(container) + scrollbarSize, "px"); + } + var parent = container.parentElement; + var scrollContainer = + // TODO: заменить на optional chaining + parent && + parent.nodeName === 'HTML' && + window.getComputedStyle(parent).overflowY === 'scroll' + ? parent + : container; + // Блокируем скролл даже если отсутствует скроллбар + if (scrollContainer.style.overflow !== 'hidden') { + containerStyles.push({ + value: scrollContainer.style.overflow, + key: 'overflow', + el: scrollContainer, + }); + } + if (!shouldIOSLock) { + scrollContainer.style.overflow = 'hidden'; + } + modalRestoreStyles.push({ + container: container, + modals: 1, + styles: containerStyles, + }); +}; + +exports.handleContainer = handleContainer; +exports.hasScrollbar = hasScrollbar; +exports.isScrolledToBottom = isScrolledToBottom; +exports.isScrolledToTop = isScrolledToTop; +exports.restoreContainerStyles = restoreContainerStyles; diff --git a/packages/base-modal/dist_side_poly/esm/Component.d.ts b/packages/base-modal/dist_side_poly/esm/Component.d.ts new file mode 100644 index 0000000000..44533e4e97 --- /dev/null +++ b/packages/base-modal/dist_side_poly/esm/Component.d.ts @@ -0,0 +1,159 @@ +/// +/// +import React from 'react'; +import { ComponentType, KeyboardEvent, MouseEvent, MutableRefObject, ReactNode, Ref } from "react"; +import { TransitionProps } from 'react-transition-group/Transition'; +import { BackdropProps } from "@alfalab/core-components-backdrop"; +import { PortalProps } from "@alfalab/core-components-portal"; +type BaseModalProps = { + /** + * Контент + */ + children?: ReactNode; + /** + * Компонент бэкдропа + */ + Backdrop?: ComponentType; + /** + * Свойства для Бэкдропа + */ + backdropProps?: Partial & Record; + /** + * Нода, компонент или функция возвращающая их + * + * Контейнер к которому будут добавляться порталы + */ + container?: PortalProps['getPortalContainer']; + /** + * Отключает автоматический перевод фокуса на модалку при открытии + * @default false + */ + disableAutoFocus?: boolean; + /** + * Отключает ловушку фокуса + * @default false + */ + disableFocusLock?: boolean; + /** + * Отключает восстановление фокуса на предыдущем элементе после закрытия модалки + * @default false + */ + disableRestoreFocus?: boolean; + /** + * Отключает вызов `callback` при нажатии Escape + * @default false + */ + disableEscapeKeyDown?: boolean; + /** + * Отключает вызов `callback` при клике на бэкдроп + * @default false + */ + disableBackdropClick?: boolean; + /** + * Отключает блокировку скролла при открытии модального окна + * @default false + */ + disableBlockingScroll?: boolean; + /** + * Содержимое модалки всегда в DOM + * @default false + */ + keepMounted?: boolean; + /** + * Управление видимостью модалки + */ + open: boolean; + /** + * Дополнительный класс + */ + className?: string; + /** + * Дополнительный класс + */ + contentClassName?: string; + /** + * Дополнительные пропсы на dialog wrapper + */ + wrapperProps?: React.DetailedHTMLProps, HTMLDivElement>; + /** + * Дополнительные пропсы на обертку контента + */ + contentProps?: React.DetailedHTMLProps, HTMLDivElement>; + /** + * Дополнительные пропсы на компонентную обертку контента + */ + componentDivProps?: React.DetailedHTMLProps, HTMLDivElement>; + /** + * Дополнительный класс для обертки (Modal) + */ + wrapperClassName?: string; + /** + * Обработчик скролла контента + */ + scrollHandler?: 'wrapper' | 'content' | MutableRefObject; + /** + * Пропсы для анимации (CSSTransition) + */ + transitionProps?: Partial; + /** + * Рендерить ли в контейнер через портал. + * @default true + */ + usePortal?: boolean; + /** + * Обработчик события нажатия на бэкдроп + */ + onBackdropClick?: (event: MouseEvent) => void; + /** + * Обработчик события нажатия на Escape + * + * Если `disableEscapeKeyDown` - false и модальное окно в фокусе + */ + onEscapeKeyDown?: (event: KeyboardEvent) => void; + /** + * Обработчик закрытия + */ + onClose?: (event: MouseEvent | KeyboardEvent, reason?: 'backdropClick' | 'escapeKeyDown' | 'closerClick') => void; + /** + * Обработчик события onEntered компонента Transition + */ + onMount?: () => void; + /** + * Обработчик события onExited компонента Transition + */ + onUnmount?: () => void; + /** + * Идентификатор для систем автоматизированного тестирования + */ + dataTestId?: string; + /** + * z-index компонента + */ + zIndex?: number; + /** + * Реф, который должен быть установлен компонентной области + */ + componentRef?: MutableRefObject; + /** + * Блокирует скролл когда модальное окно открыто. Работает только на iOS. + */ + iOSLock?: boolean; +}; +type BaseModalContext = { + parentRef: React.RefObject; + componentRef: React.RefObject; + hasFooter?: boolean; + hasHeader?: boolean; + hasScroll?: boolean; + headerHighlighted?: boolean; + footerHighlighted?: boolean; + headerOffset?: number; + setHeaderOffset: (offset: number) => void; + contentRef: Ref; + setHasHeader: (exists: boolean) => void; + setHasFooter: (exists: boolean) => void; + onClose: Required['onClose']; +}; +declare const BaseModalContext: React.Context; +declare const BaseModal: React.ForwardRefExoticComponent>; +export { BaseModalProps, BaseModalContext, BaseModal }; diff --git a/packages/base-modal/dist_side_poly/esm/Component.js b/packages/base-modal/dist_side_poly/esm/Component.js new file mode 100644 index 0000000000..c608f5fc5c --- /dev/null +++ b/packages/base-modal/dist_side_poly/esm/Component.js @@ -0,0 +1,275 @@ +import { __assign } from 'tslib'; +import React, { forwardRef, useState, useRef, useCallback, useEffect, useMemo } from 'react'; +import FocusLock from 'react-focus-lock'; +import mergeRefs from 'react-merge-refs'; +import { CSSTransition } from 'react-transition-group'; +import { ResizeObserver } from '@juggle/resize-observer'; +import cn from 'classnames'; +import { Backdrop } from '@alfalab/core-components-backdrop/esm'; +import { Portal } from '@alfalab/core-components-portal/esm'; +import { os, browser } from '@alfalab/core-components-shared/esm'; +import { Stack } from '@alfalab/core-components-stack/esm'; +import { stackingOrder } from '@alfalab/stack-context'; +import { unlockScroll, syncHeight, lockScroll } from './helpers/lockScroll.js'; +import { isScrolledToTop, isScrolledToBottom, handleContainer, restoreContainerStyles, hasScrollbar } from './utils.js'; +import './matches-polyfill.js'; + +var styles = {"component":"base-modal__component_1y6m8","wrapper":"base-modal__wrapper_1y6m8","content":"base-modal__content_1y6m8","hidden":"base-modal__hidden_1y6m8","backdrop":"base-modal__backdrop_1y6m8","appear":"base-modal__appear_1y6m8","enter":"base-modal__enter_1y6m8","appearActive":"base-modal__appearActive_1y6m8","enterActive":"base-modal__enterActive_1y6m8","exit":"base-modal__exit_1y6m8","exitActive":"base-modal__exitActive_1y6m8","exitDone":"base-modal__exitDone_1y6m8"}; +require('./index.css') + +// eslint-disable-next-line @typescript-eslint/no-redeclare +var BaseModalContext = React.createContext({ + parentRef: { current: null }, + componentRef: { current: null }, + hasFooter: false, + hasHeader: false, + hasScroll: false, + headerHighlighted: false, + footerHighlighted: false, + headerOffset: 0, + setHeaderOffset: function () { return null; }, + contentRef: function () { return null; }, + setHasHeader: function () { return null; }, + setHasFooter: function () { return null; }, + onClose: function () { return null; }, +}); +var BaseModal = forwardRef(function (_a, ref) { + var open = _a.open, container = _a.container, children = _a.children, _b = _a.scrollHandler, scrollHandler = _b === void 0 ? 'wrapper' : _b, _c = _a.Backdrop, Backdrop$1 = _c === void 0 ? Backdrop : _c, _d = _a.backdropProps, backdropProps = _d === void 0 ? {} : _d, _e = _a.transitionProps, transitionProps = _e === void 0 ? {} : _e, disableBackdropClick = _a.disableBackdropClick, _f = _a.disableAutoFocus, disableAutoFocus = _f === void 0 ? false : _f, _g = _a.disableFocusLock, disableFocusLock = _g === void 0 ? false : _g, _h = _a.disableEscapeKeyDown, disableEscapeKeyDown = _h === void 0 ? false : _h, _j = _a.disableRestoreFocus, disableRestoreFocus = _j === void 0 ? false : _j, _k = _a.disableBlockingScroll, disableBlockingScroll = _k === void 0 ? false : _k, _l = _a.keepMounted, keepMounted = _l === void 0 ? false : _l, className = _a.className, contentClassName = _a.contentClassName, wrapperProps = _a.wrapperProps, contentProps = _a.contentProps, componentDivProps = _a.componentDivProps, wrapperClassName = _a.wrapperClassName, onBackdropClick = _a.onBackdropClick, onClose = _a.onClose, onEscapeKeyDown = _a.onEscapeKeyDown, onMount = _a.onMount, onUnmount = _a.onUnmount, dataTestId = _a.dataTestId, _m = _a.zIndex, zIndex = _m === void 0 ? stackingOrder.MODAL : _m, _o = _a.componentRef, componentRef = _o === void 0 ? null : _o, _p = _a.usePortal, usePortal = _p === void 0 ? true : _p, _q = _a.iOSLock, iOSLock = _q === void 0 ? false : _q; + var _r = useState(null), exited = _r[0], setExited = _r[1]; + var _s = useState(false), hasScroll = _s[0], setHasScroll = _s[1]; + var _t = useState(false), hasHeader = _t[0], setHasHeader = _t[1]; + var _u = useState(false), hasFooter = _u[0], setHasFooter = _u[1]; + var _v = useState(false), headerHighlighted = _v[0], setHeaderHighlighted = _v[1]; + var _w = useState(false), footerHighlighted = _w[0], setFooterHighlighted = _w[1]; + var _x = useState(0), headerOffset = _x[0], setHeaderOffset = _x[1]; + var componentNodeRef = useRef(null); + var wrapperRef = useRef(null); + var scrollableNodeRef = useRef(null); + var contentNodeRef = useRef(null); + var restoreContainerStylesRef = useRef(null); + var mouseDownTarget = useRef(); + var resizeObserverRef = useRef(); + var checkToHasScrollBar = function () { + if (scrollableNodeRef.current) { + var scrollExists = hasScrollbar(scrollableNodeRef.current); + setFooterHighlighted(scrollExists); + setHasScroll(scrollExists); + } + }; + var isExited = exited || exited === null; + var shouldRender = keepMounted || open || !isExited; + var getContainer = useCallback(function () { return (container ? container() : document.body); }, [container]); + var addResizeHandle = useCallback(function () { + if (!resizeObserverRef.current) + return; + if (scrollableNodeRef.current) { + resizeObserverRef.current.observe(scrollableNodeRef.current); + } + if (contentNodeRef.current) { + resizeObserverRef.current.observe(contentNodeRef.current); + } + }, []); + var removeResizeHandle = useCallback(function () { var _a; return (_a = resizeObserverRef.current) === null || _a === void 0 ? void 0 : _a.disconnect(); }, []); + var contentRef = useCallback(function (node) { + if (node !== null) { + contentNodeRef.current = node; + if (resizeObserverRef.current) { + resizeObserverRef.current.observe(node); + } + checkToHasScrollBar(); + } + }, []); + var handleScroll = useCallback(function () { + if (!scrollableNodeRef.current || !componentNodeRef.current) + return; + if (hasHeader) { + setHeaderHighlighted(!isScrolledToTop(scrollableNodeRef.current) && + componentNodeRef.current.getBoundingClientRect().top - headerOffset <= 1); + } + if (hasFooter) { + setFooterHighlighted(!isScrolledToBottom(scrollableNodeRef.current) && + componentNodeRef.current.getBoundingClientRect().bottom >= + window.innerHeight - 1); + } + }, [hasFooter, hasHeader, headerOffset]); + var handleClose = useCallback(function (event, reason) { + if (iOSLock && os.isIOS()) { + unlockScroll(); + } + if (onClose) { + onClose(event, reason); + } + if (reason === 'backdropClick' && onBackdropClick) { + onBackdropClick(event); + } + if (reason === 'escapeKeyDown' && onEscapeKeyDown) { + onEscapeKeyDown(event); + } + return null; + }, [onBackdropClick, onClose, onEscapeKeyDown, iOSLock]); + var handleBackdropMouseDown = function (event) { + var _a; + var clickedOnScrollbar = false; + var clientWidth = (_a = event.target) === null || _a === void 0 ? void 0 : _a.clientWidth; + if (event.clientX && clientWidth) { + // Устанавливаем смещение для абсолютно спозиционированного скроллбара в OSX в 17px. + var offset = browser.getScrollbarSize() === 0 ? 17 : 0; + clickedOnScrollbar = event.clientX + offset > clientWidth; + } + if (!disableBackdropClick && !clickedOnScrollbar) { + mouseDownTarget.current = event.target; + } + }; + var handleBackdropMouseUp = function (event) { + if (!disableBackdropClick && + event.target === wrapperRef.current && + mouseDownTarget.current === wrapperRef.current) { + handleClose(event, 'backdropClick'); + } + mouseDownTarget.current = undefined; + }; + var handleKeyDown = useCallback(function (event) { + /* + * Чтобы сохранить дефолтное поведение элементов и событий форм, + * обработчик не устанавливает event.preventDefault() + */ + if (event.key !== 'Escape') { + return; + } + // Если есть обработчик escape на body + event.stopPropagation(); + if (!disableEscapeKeyDown && handleClose) { + handleClose(event, 'escapeKeyDown'); + } + }, [disableEscapeKeyDown, handleClose]); + var getScrollHandler = useCallback(function () { + if (scrollHandler === 'wrapper') + return wrapperRef.current; + if (scrollHandler === 'content') + return componentNodeRef.current; + return scrollHandler.current || wrapperRef.current; + }, [scrollHandler]); + var handleEntered = useCallback(function (node, isAppearing) { + scrollableNodeRef.current = getScrollHandler(); + addResizeHandle(); + if (scrollableNodeRef.current) { + scrollableNodeRef.current.addEventListener('scroll', handleScroll); + handleScroll(); + } + if (transitionProps.onEntered) { + transitionProps.onEntered(node, isAppearing); + } + if (onMount) + onMount(); + }, [addResizeHandle, getScrollHandler, handleScroll, onMount, transitionProps]); + var handleExited = useCallback(function (node) { + removeResizeHandle(); + setExited(true); + if (scrollableNodeRef.current) { + scrollableNodeRef.current.removeEventListener('scroll', handleScroll); + } + if (transitionProps.onExited) { + transitionProps.onExited(node); + } + if (onUnmount) + onUnmount(); + if (restoreContainerStylesRef.current) { + restoreContainerStylesRef.current(); + } + }, [handleScroll, onUnmount, removeResizeHandle, transitionProps]); + useEffect(function () { + if (open && isExited) { + if (!disableBlockingScroll) { + var el_1 = getContainer(); + var shouldIOSLock = iOSLock && os.isIOS(); + handleContainer(el_1, shouldIOSLock); + if (shouldIOSLock) { + syncHeight(); + lockScroll(); + } + restoreContainerStylesRef.current = function () { + restoreContainerStylesRef.current = null; + restoreContainerStyles(el_1); + }; + } + setExited(false); + } + if (!open) { + unlockScroll(); + } + }, [getContainer, open, disableBlockingScroll, isExited, iOSLock]); + useEffect(function () { + var ResizeObserver$1 = window.ResizeObserver || ResizeObserver; + resizeObserverRef.current = new ResizeObserver$1(checkToHasScrollBar); + return function () { + if (restoreContainerStylesRef.current) { + restoreContainerStylesRef.current(); + } + if (resizeObserverRef.current) { + resizeObserverRef.current.disconnect(); + } + }; + }, []); + useEffect(function () { + var _a; + if (disableAutoFocus || !open) + return; + (_a = wrapperRef.current) === null || _a === void 0 ? void 0 : _a.focus(); + }, [open, disableAutoFocus]); + var contextValue = useMemo(function () { return ({ + parentRef: wrapperRef, + componentRef: componentNodeRef, + hasHeader: hasHeader, + hasFooter: hasFooter, + hasScroll: hasScroll, + headerHighlighted: headerHighlighted, + footerHighlighted: footerHighlighted, + headerOffset: headerOffset, + setHeaderOffset: setHeaderOffset, + contentRef: contentRef, + setHasHeader: setHasHeader, + setHasFooter: setHasFooter, + onClose: handleClose, + }); }, [ + contentRef, + hasHeader, + hasFooter, + hasScroll, + headerHighlighted, + footerHighlighted, + headerOffset, + setHeaderOffset, + handleClose, + ]); + var renderContent = function () { return (React.createElement(Stack, { value: zIndex }, function (computedZIndex) { + var _a; + return (React.createElement(BaseModalContext.Provider, { value: contextValue }, + React.createElement(FocusLock, { disabled: disableFocusLock || !open, returnFocus: !disableRestoreFocus }, + Backdrop$1 && (React.createElement(Backdrop$1, __assign({}, backdropProps, { className: cn(backdropProps.className, styles.backdrop), open: open, style: { + zIndex: computedZIndex, + } }))), + React.createElement("div", __assign({}, wrapperProps, { role: 'dialog', className: cn(styles.wrapper, wrapperClassName, wrapperProps === null || wrapperProps === void 0 ? void 0 : wrapperProps.className, (_a = {}, + _a[styles.hidden] = !open && isExited, + _a)), ref: mergeRefs([ + ref, + wrapperRef, + wrapperProps === null || wrapperProps === void 0 ? void 0 : wrapperProps.ref, + ]), onKeyDown: handleKeyDown, onMouseDown: handleBackdropMouseDown, onMouseUp: handleBackdropMouseUp, tabIndex: -1, "data-test-id": dataTestId, style: { + zIndex: computedZIndex, + } }), + React.createElement(CSSTransition, __assign({ appear: true, timeout: 200, classNames: styles, nodeRef: componentNodeRef }, transitionProps, { in: open, onEntered: handleEntered, onExited: handleExited }), + React.createElement("div", __assign({}, componentDivProps, { className: cn(styles.component, className, componentDivProps === null || componentDivProps === void 0 ? void 0 : componentDivProps.className), ref: mergeRefs([ + componentRef, + componentNodeRef, + (componentDivProps === null || componentDivProps === void 0 ? void 0 : componentDivProps.ref) || null, + ]) }), + React.createElement("div", __assign({}, contentProps, { className: cn(styles.content, contentClassName, contentProps === null || contentProps === void 0 ? void 0 : contentProps.className) }), children))))))); + })); }; + if (!shouldRender) + return null; + return usePortal ? (React.createElement(Portal, { getPortalContainer: container, immediateMount: true }, renderContent())) : (renderContent()); +}); +BaseModal.displayName = 'BaseModal'; +BaseModalContext.displayName = 'BaseModalContext'; + +export { BaseModal, BaseModalContext }; diff --git a/packages/base-modal/dist_side_poly/esm/helpers/lockScroll.d.ts b/packages/base-modal/dist_side_poly/esm/helpers/lockScroll.d.ts new file mode 100644 index 0000000000..80e91475f8 --- /dev/null +++ b/packages/base-modal/dist_side_poly/esm/helpers/lockScroll.d.ts @@ -0,0 +1,5 @@ +declare const isScrollLocked: () => boolean; +declare const lockScroll: () => void; +declare const unlockScroll: () => void; +declare const syncHeight: () => void; +export { isScrollLocked, lockScroll, unlockScroll, syncHeight }; diff --git a/packages/base-modal/dist_side_poly/esm/helpers/lockScroll.js b/packages/base-modal/dist_side_poly/esm/helpers/lockScroll.js new file mode 100644 index 0000000000..dfab01bb42 --- /dev/null +++ b/packages/base-modal/dist_side_poly/esm/helpers/lockScroll.js @@ -0,0 +1,21 @@ +/** + * Хелпер для блокирования скроллинга в iOS + * В проекте используется overflow: hidden для блокировки, но в некоторых случаях этого недостаточно. Данный хелпер призван решать эту проблему + */ +var scrollY; +var isScrollLocked = function () { return document.body.classList.contains('is-locked'); }; +var lockScroll = function () { + scrollY = window.scrollY; + document.body.classList.add('is-locked'); +}; +var unlockScroll = function () { + if (!isScrollLocked()) + return; + document.body.classList.remove('is-locked'); + window.scrollTo(0, scrollY); +}; +var syncHeight = function () { + document.body.style.setProperty('--window-inner-scrollY', "".concat(window.scrollY, "px")); +}; + +export { isScrollLocked, lockScroll, syncHeight, unlockScroll }; diff --git a/packages/base-modal/dist_side_poly/esm/index.css b/packages/base-modal/dist_side_poly/esm/index.css new file mode 100644 index 0000000000..717db4385d --- /dev/null +++ b/packages/base-modal/dist_side_poly/esm/index.css @@ -0,0 +1,71 @@ +/* hash: 5nduy */ +:root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ +} /* deprecated */ :root { + --color-light-modal-bg-primary: #fff; /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ +} :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ +} :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ +} :root { + + /* Hard */ + + /* Up */ + + /* Hard up */ +} :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ + + /* новые значения, используйте их */ +} :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ + + /* новые значения, используйте их */ + --gap-0: 0; +} :root { +} :root { +} /* сбрасывает синюю подсветку при нажатии */ :root { + --window-inner-scrollY: 10px; /* fallback value to prevent ci error */ +} body.is-locked { + margin-top: calc(var(--window-inner-scrollY) * -1); + position: fixed; + overflow: hidden; +} .base-modal__component_1y6m8 { + position: relative; + box-sizing: border-box; + background: var(--color-light-modal-bg-primary); + margin: auto; + flex-shrink: 0; +} .base-modal__wrapper_1y6m8 { + position: fixed; + top: var(--gap-0); + left: var(--gap-0); + right: var(--gap-0); + bottom: var(--gap-0); + + overflow: auto; + display: flex; + flex-direction: column; + align-items: center; + outline: 0; + overscroll-behavior: none; +} .base-modal__content_1y6m8 { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + flex: 1; +} .base-modal__hidden_1y6m8 { + display: none; +} .base-modal__backdrop_1y6m8 { + z-index: 0; +} .base-modal__appear_1y6m8, +.base-modal__enter_1y6m8 { + opacity: 0; +} .base-modal__appearActive_1y6m8, +.base-modal__enterActive_1y6m8 { + opacity: 1; + transition: opacity 200ms ease-in; +} .base-modal__exit_1y6m8 { + opacity: 1; +} .base-modal__exitActive_1y6m8, +.base-modal__exitDone_1y6m8 { + opacity: 0; + transition: opacity 200ms ease-out; +} diff --git a/packages/base-modal/dist_side_poly/esm/index.d.ts b/packages/base-modal/dist_side_poly/esm/index.d.ts new file mode 100644 index 0000000000..61ae91968a --- /dev/null +++ b/packages/base-modal/dist_side_poly/esm/index.d.ts @@ -0,0 +1,3 @@ +export * from "./Component"; +export * from "./utils"; +export * from "./helpers/lockScroll"; diff --git a/packages/base-modal/dist_side_poly/esm/index.js b/packages/base-modal/dist_side_poly/esm/index.js new file mode 100644 index 0000000000..ee07c7a608 --- /dev/null +++ b/packages/base-modal/dist_side_poly/esm/index.js @@ -0,0 +1,3 @@ +export { BaseModal, BaseModalContext } from './Component.js'; +export { handleContainer, hasScrollbar, isScrolledToBottom, isScrolledToTop, restoreContainerStyles } from './utils.js'; +export { isScrollLocked, lockScroll, syncHeight, unlockScroll } from './helpers/lockScroll.js'; diff --git a/packages/base-modal/dist_side_poly/esm/matches-polyfill.d.ts b/packages/base-modal/dist_side_poly/esm/matches-polyfill.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/packages/base-modal/dist_side_poly/esm/matches-polyfill.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/base-modal/dist_side_poly/esm/matches-polyfill.js b/packages/base-modal/dist_side_poly/esm/matches-polyfill.js new file mode 100644 index 0000000000..46744867fc --- /dev/null +++ b/packages/base-modal/dist_side_poly/esm/matches-polyfill.js @@ -0,0 +1,18 @@ +/* eslint-disable */ +// @ts-nocheck +if (typeof window !== 'undefined') { + if (Element && !Element.prototype.matches) { + Element.prototype.matches = + Element.prototype.matchesSelector || + Element.prototype.mozMatchesSelector || + Element.prototype.msMatchesSelector || + Element.prototype.oMatchesSelector || + Element.prototype.webkitMatchesSelector || + function (s) { + var matches = (this.document || this.ownerDocument).querySelectorAll(s); + var i = matches.length; + while (--i >= 0 && matches.item(i) !== this) { } + return i > -1; + }; + } +} diff --git a/packages/base-modal/dist_side_poly/esm/utils.d.ts b/packages/base-modal/dist_side_poly/esm/utils.d.ts new file mode 100644 index 0000000000..75401779bb --- /dev/null +++ b/packages/base-modal/dist_side_poly/esm/utils.d.ts @@ -0,0 +1,6 @@ +declare function isScrolledToTop(target: HTMLElement): boolean; +declare function isScrolledToBottom(target: HTMLElement): boolean; +declare function hasScrollbar(target: HTMLElement): boolean; +declare const restoreContainerStyles: (container: HTMLElement) => void; +declare const handleContainer: (container?: HTMLElement, shouldIOSLock?: boolean) => void; +export { isScrolledToTop, isScrolledToBottom, hasScrollbar, restoreContainerStyles, handleContainer }; diff --git a/packages/base-modal/dist_side_poly/esm/utils.js b/packages/base-modal/dist_side_poly/esm/utils.js new file mode 100644 index 0000000000..248cf807aa --- /dev/null +++ b/packages/base-modal/dist_side_poly/esm/utils.js @@ -0,0 +1,91 @@ +import { getModalStore } from '@alfalab/core-components-global-store/esm'; +import { browser } from '@alfalab/core-components-shared/esm'; + +function isScrolledToTop(target) { + return target.scrollTop <= 0; +} +function isScrolledToBottom(target) { + return target.scrollHeight - target.offsetHeight <= target.scrollTop; +} +function hasScrollbar(target) { + return target.scrollHeight > target.clientHeight; +} +var isOverflowing = function (container) { + if (document.body === container) { + return window.innerWidth > document.documentElement.clientWidth; + } + return container.scrollHeight > container.clientHeight; +}; +var getPaddingRight = function (node) { + return parseInt(window.getComputedStyle(node).paddingRight, 10) || 0; +}; +var restoreContainerStyles = function (container) { + var modalRestoreStyles = getModalStore().getRestoreStyles(); + var index = modalRestoreStyles.findIndex(function (s) { return s.container === container; }); + var existingStyles = modalRestoreStyles[index]; + if (!existingStyles) + return; + existingStyles.modals -= 1; + if (existingStyles.modals <= 0) { + modalRestoreStyles.splice(index, 1); + existingStyles.styles.forEach(function (_a) { + var value = _a.value, el = _a.el, key = _a.key; + if (value) { + el.style.setProperty(key, value); + } + else { + el.style.removeProperty(key); + } + }); + } +}; +var handleContainer = function (container, shouldIOSLock) { + if (shouldIOSLock === void 0) { shouldIOSLock = false; } + if (!container) + return; + var modalRestoreStyles = getModalStore().getRestoreStyles(); + var existingStyles = modalRestoreStyles.find(function (s) { return s.container === container; }); + if (existingStyles) { + existingStyles.modals += 1; + return; + } + var containerStyles = []; + if (isOverflowing(container)) { + // Вычисляет размер до применения `overflow hidden` для избежания скачков + var scrollbarSize = browser.getScrollbarSize(); + containerStyles.push({ + value: container.style.paddingRight, + key: 'padding-right', + el: container, + }); + // Вычисляем стили, чтобы получить реальный `padding` c шириной сколлбара + // eslint-disable-next-line no-param-reassign + container.style.paddingRight = "".concat(getPaddingRight(container) + scrollbarSize, "px"); + } + var parent = container.parentElement; + var scrollContainer = + // TODO: заменить на optional chaining + parent && + parent.nodeName === 'HTML' && + window.getComputedStyle(parent).overflowY === 'scroll' + ? parent + : container; + // Блокируем скролл даже если отсутствует скроллбар + if (scrollContainer.style.overflow !== 'hidden') { + containerStyles.push({ + value: scrollContainer.style.overflow, + key: 'overflow', + el: scrollContainer, + }); + } + if (!shouldIOSLock) { + scrollContainer.style.overflow = 'hidden'; + } + modalRestoreStyles.push({ + container: container, + modals: 1, + styles: containerStyles, + }); +}; + +export { handleContainer, hasScrollbar, isScrolledToBottom, isScrolledToTop, restoreContainerStyles }; diff --git a/packages/base-modal/dist_side_poly/helpers/lockScroll.d.ts b/packages/base-modal/dist_side_poly/helpers/lockScroll.d.ts new file mode 100644 index 0000000000..80e91475f8 --- /dev/null +++ b/packages/base-modal/dist_side_poly/helpers/lockScroll.d.ts @@ -0,0 +1,5 @@ +declare const isScrollLocked: () => boolean; +declare const lockScroll: () => void; +declare const unlockScroll: () => void; +declare const syncHeight: () => void; +export { isScrollLocked, lockScroll, unlockScroll, syncHeight }; diff --git a/packages/base-modal/dist_side_poly/helpers/lockScroll.js b/packages/base-modal/dist_side_poly/helpers/lockScroll.js new file mode 100644 index 0000000000..5eea467f5b --- /dev/null +++ b/packages/base-modal/dist_side_poly/helpers/lockScroll.js @@ -0,0 +1,28 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +/** + * Хелпер для блокирования скроллинга в iOS + * В проекте используется overflow: hidden для блокировки, но в некоторых случаях этого недостаточно. Данный хелпер призван решать эту проблему + */ +var scrollY; +var isScrollLocked = function () { return document.body.classList.contains('is-locked'); }; +var lockScroll = function () { + scrollY = window.scrollY; + document.body.classList.add('is-locked'); +}; +var unlockScroll = function () { + if (!isScrollLocked()) + return; + document.body.classList.remove('is-locked'); + window.scrollTo(0, scrollY); +}; +var syncHeight = function () { + document.body.style.setProperty('--window-inner-scrollY', "".concat(window.scrollY, "px")); +}; + +exports.isScrollLocked = isScrollLocked; +exports.lockScroll = lockScroll; +exports.syncHeight = syncHeight; +exports.unlockScroll = unlockScroll; diff --git a/packages/base-modal/dist_side_poly/index.css b/packages/base-modal/dist_side_poly/index.css new file mode 100644 index 0000000000..717db4385d --- /dev/null +++ b/packages/base-modal/dist_side_poly/index.css @@ -0,0 +1,71 @@ +/* hash: 5nduy */ +:root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ +} /* deprecated */ :root { + --color-light-modal-bg-primary: #fff; /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ +} :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ +} :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ +} :root { + + /* Hard */ + + /* Up */ + + /* Hard up */ +} :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ + + /* новые значения, используйте их */ +} :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ + + /* новые значения, используйте их */ + --gap-0: 0; +} :root { +} :root { +} /* сбрасывает синюю подсветку при нажатии */ :root { + --window-inner-scrollY: 10px; /* fallback value to prevent ci error */ +} body.is-locked { + margin-top: calc(var(--window-inner-scrollY) * -1); + position: fixed; + overflow: hidden; +} .base-modal__component_1y6m8 { + position: relative; + box-sizing: border-box; + background: var(--color-light-modal-bg-primary); + margin: auto; + flex-shrink: 0; +} .base-modal__wrapper_1y6m8 { + position: fixed; + top: var(--gap-0); + left: var(--gap-0); + right: var(--gap-0); + bottom: var(--gap-0); + + overflow: auto; + display: flex; + flex-direction: column; + align-items: center; + outline: 0; + overscroll-behavior: none; +} .base-modal__content_1y6m8 { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + flex: 1; +} .base-modal__hidden_1y6m8 { + display: none; +} .base-modal__backdrop_1y6m8 { + z-index: 0; +} .base-modal__appear_1y6m8, +.base-modal__enter_1y6m8 { + opacity: 0; +} .base-modal__appearActive_1y6m8, +.base-modal__enterActive_1y6m8 { + opacity: 1; + transition: opacity 200ms ease-in; +} .base-modal__exit_1y6m8 { + opacity: 1; +} .base-modal__exitActive_1y6m8, +.base-modal__exitDone_1y6m8 { + opacity: 0; + transition: opacity 200ms ease-out; +} diff --git a/packages/base-modal/dist_side_poly/index.d.ts b/packages/base-modal/dist_side_poly/index.d.ts new file mode 100644 index 0000000000..61ae91968a --- /dev/null +++ b/packages/base-modal/dist_side_poly/index.d.ts @@ -0,0 +1,3 @@ +export * from "./Component"; +export * from "./utils"; +export * from "./helpers/lockScroll"; diff --git a/packages/base-modal/dist_side_poly/index.js b/packages/base-modal/dist_side_poly/index.js new file mode 100644 index 0000000000..cf4a09932b --- /dev/null +++ b/packages/base-modal/dist_side_poly/index.js @@ -0,0 +1,21 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +var Component = require('./Component.js'); +var utils = require('./utils.js'); +var helpers_lockScroll = require('./helpers/lockScroll.js'); + + + +exports.BaseModal = Component.BaseModal; +exports.BaseModalContext = Component.BaseModalContext; +exports.handleContainer = utils.handleContainer; +exports.hasScrollbar = utils.hasScrollbar; +exports.isScrolledToBottom = utils.isScrolledToBottom; +exports.isScrolledToTop = utils.isScrolledToTop; +exports.restoreContainerStyles = utils.restoreContainerStyles; +exports.isScrollLocked = helpers_lockScroll.isScrollLocked; +exports.lockScroll = helpers_lockScroll.lockScroll; +exports.syncHeight = helpers_lockScroll.syncHeight; +exports.unlockScroll = helpers_lockScroll.unlockScroll; diff --git a/packages/base-modal/dist_side_poly/matches-polyfill.d.ts b/packages/base-modal/dist_side_poly/matches-polyfill.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/packages/base-modal/dist_side_poly/matches-polyfill.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/base-modal/dist_side_poly/matches-polyfill.js b/packages/base-modal/dist_side_poly/matches-polyfill.js new file mode 100644 index 0000000000..e36a0cd0b7 --- /dev/null +++ b/packages/base-modal/dist_side_poly/matches-polyfill.js @@ -0,0 +1,20 @@ +'use strict'; + +/* eslint-disable */ +// @ts-nocheck +if (typeof window !== 'undefined') { + if (Element && !Element.prototype.matches) { + Element.prototype.matches = + Element.prototype.matchesSelector || + Element.prototype.mozMatchesSelector || + Element.prototype.msMatchesSelector || + Element.prototype.oMatchesSelector || + Element.prototype.webkitMatchesSelector || + function (s) { + var matches = (this.document || this.ownerDocument).querySelectorAll(s); + var i = matches.length; + while (--i >= 0 && matches.item(i) !== this) { } + return i > -1; + }; + } +} diff --git a/packages/base-modal/dist_side_poly/modern/Component.d.ts b/packages/base-modal/dist_side_poly/modern/Component.d.ts new file mode 100644 index 0000000000..44533e4e97 --- /dev/null +++ b/packages/base-modal/dist_side_poly/modern/Component.d.ts @@ -0,0 +1,159 @@ +/// +/// +import React from 'react'; +import { ComponentType, KeyboardEvent, MouseEvent, MutableRefObject, ReactNode, Ref } from "react"; +import { TransitionProps } from 'react-transition-group/Transition'; +import { BackdropProps } from "@alfalab/core-components-backdrop"; +import { PortalProps } from "@alfalab/core-components-portal"; +type BaseModalProps = { + /** + * Контент + */ + children?: ReactNode; + /** + * Компонент бэкдропа + */ + Backdrop?: ComponentType; + /** + * Свойства для Бэкдропа + */ + backdropProps?: Partial & Record; + /** + * Нода, компонент или функция возвращающая их + * + * Контейнер к которому будут добавляться порталы + */ + container?: PortalProps['getPortalContainer']; + /** + * Отключает автоматический перевод фокуса на модалку при открытии + * @default false + */ + disableAutoFocus?: boolean; + /** + * Отключает ловушку фокуса + * @default false + */ + disableFocusLock?: boolean; + /** + * Отключает восстановление фокуса на предыдущем элементе после закрытия модалки + * @default false + */ + disableRestoreFocus?: boolean; + /** + * Отключает вызов `callback` при нажатии Escape + * @default false + */ + disableEscapeKeyDown?: boolean; + /** + * Отключает вызов `callback` при клике на бэкдроп + * @default false + */ + disableBackdropClick?: boolean; + /** + * Отключает блокировку скролла при открытии модального окна + * @default false + */ + disableBlockingScroll?: boolean; + /** + * Содержимое модалки всегда в DOM + * @default false + */ + keepMounted?: boolean; + /** + * Управление видимостью модалки + */ + open: boolean; + /** + * Дополнительный класс + */ + className?: string; + /** + * Дополнительный класс + */ + contentClassName?: string; + /** + * Дополнительные пропсы на dialog wrapper + */ + wrapperProps?: React.DetailedHTMLProps, HTMLDivElement>; + /** + * Дополнительные пропсы на обертку контента + */ + contentProps?: React.DetailedHTMLProps, HTMLDivElement>; + /** + * Дополнительные пропсы на компонентную обертку контента + */ + componentDivProps?: React.DetailedHTMLProps, HTMLDivElement>; + /** + * Дополнительный класс для обертки (Modal) + */ + wrapperClassName?: string; + /** + * Обработчик скролла контента + */ + scrollHandler?: 'wrapper' | 'content' | MutableRefObject; + /** + * Пропсы для анимации (CSSTransition) + */ + transitionProps?: Partial; + /** + * Рендерить ли в контейнер через портал. + * @default true + */ + usePortal?: boolean; + /** + * Обработчик события нажатия на бэкдроп + */ + onBackdropClick?: (event: MouseEvent) => void; + /** + * Обработчик события нажатия на Escape + * + * Если `disableEscapeKeyDown` - false и модальное окно в фокусе + */ + onEscapeKeyDown?: (event: KeyboardEvent) => void; + /** + * Обработчик закрытия + */ + onClose?: (event: MouseEvent | KeyboardEvent, reason?: 'backdropClick' | 'escapeKeyDown' | 'closerClick') => void; + /** + * Обработчик события onEntered компонента Transition + */ + onMount?: () => void; + /** + * Обработчик события onExited компонента Transition + */ + onUnmount?: () => void; + /** + * Идентификатор для систем автоматизированного тестирования + */ + dataTestId?: string; + /** + * z-index компонента + */ + zIndex?: number; + /** + * Реф, который должен быть установлен компонентной области + */ + componentRef?: MutableRefObject; + /** + * Блокирует скролл когда модальное окно открыто. Работает только на iOS. + */ + iOSLock?: boolean; +}; +type BaseModalContext = { + parentRef: React.RefObject; + componentRef: React.RefObject; + hasFooter?: boolean; + hasHeader?: boolean; + hasScroll?: boolean; + headerHighlighted?: boolean; + footerHighlighted?: boolean; + headerOffset?: number; + setHeaderOffset: (offset: number) => void; + contentRef: Ref; + setHasHeader: (exists: boolean) => void; + setHasFooter: (exists: boolean) => void; + onClose: Required['onClose']; +}; +declare const BaseModalContext: React.Context; +declare const BaseModal: React.ForwardRefExoticComponent>; +export { BaseModalProps, BaseModalContext, BaseModal }; diff --git a/packages/base-modal/dist_side_poly/modern/Component.js b/packages/base-modal/dist_side_poly/modern/Component.js new file mode 100644 index 0000000000..e09ffa65a8 --- /dev/null +++ b/packages/base-modal/dist_side_poly/modern/Component.js @@ -0,0 +1,269 @@ +import React, { forwardRef, useState, useRef, useCallback, useEffect, useMemo } from 'react'; +import FocusLock from 'react-focus-lock'; +import mergeRefs from 'react-merge-refs'; +import { CSSTransition } from 'react-transition-group'; +import { ResizeObserver } from '@juggle/resize-observer'; +import cn from 'classnames'; +import { Backdrop } from '@alfalab/core-components-backdrop/modern'; +import { Portal } from '@alfalab/core-components-portal/modern'; +import { os, browser } from '@alfalab/core-components-shared/modern'; +import { Stack } from '@alfalab/core-components-stack/modern'; +import { stackingOrder } from '@alfalab/stack-context'; +import { unlockScroll, syncHeight, lockScroll } from './helpers/lockScroll.js'; +import { isScrolledToTop, isScrolledToBottom, handleContainer, restoreContainerStyles, hasScrollbar } from './utils.js'; +import './matches-polyfill.js'; + +const styles = {"component":"base-modal__component_1y6m8","wrapper":"base-modal__wrapper_1y6m8","content":"base-modal__content_1y6m8","hidden":"base-modal__hidden_1y6m8","backdrop":"base-modal__backdrop_1y6m8","appear":"base-modal__appear_1y6m8","enter":"base-modal__enter_1y6m8","appearActive":"base-modal__appearActive_1y6m8","enterActive":"base-modal__enterActive_1y6m8","exit":"base-modal__exit_1y6m8","exitActive":"base-modal__exitActive_1y6m8","exitDone":"base-modal__exitDone_1y6m8"}; +require('./index.css') + +/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */ +// eslint-disable-next-line @typescript-eslint/no-redeclare +const BaseModalContext = React.createContext({ + parentRef: { current: null }, + componentRef: { current: null }, + hasFooter: false, + hasHeader: false, + hasScroll: false, + headerHighlighted: false, + footerHighlighted: false, + headerOffset: 0, + setHeaderOffset: () => null, + contentRef: () => null, + setHasHeader: () => null, + setHasFooter: () => null, + onClose: () => null, +}); +const BaseModal = forwardRef(({ open, container, children, scrollHandler = 'wrapper', Backdrop: Backdrop$1 = Backdrop, backdropProps = {}, transitionProps = {}, disableBackdropClick, disableAutoFocus = false, disableFocusLock = false, disableEscapeKeyDown = false, disableRestoreFocus = false, disableBlockingScroll = false, keepMounted = false, className, contentClassName, wrapperProps, contentProps, componentDivProps, wrapperClassName, onBackdropClick, onClose, onEscapeKeyDown, onMount, onUnmount, dataTestId, zIndex = stackingOrder.MODAL, componentRef = null, usePortal = true, iOSLock = false, }, ref) => { + const [exited, setExited] = useState(null); + const [hasScroll, setHasScroll] = useState(false); + const [hasHeader, setHasHeader] = useState(false); + const [hasFooter, setHasFooter] = useState(false); + const [headerHighlighted, setHeaderHighlighted] = useState(false); + const [footerHighlighted, setFooterHighlighted] = useState(false); + const [headerOffset, setHeaderOffset] = useState(0); + const componentNodeRef = useRef(null); + const wrapperRef = useRef(null); + const scrollableNodeRef = useRef(null); + const contentNodeRef = useRef(null); + const restoreContainerStylesRef = useRef(null); + const mouseDownTarget = useRef(); + const resizeObserverRef = useRef(); + const checkToHasScrollBar = () => { + if (scrollableNodeRef.current) { + const scrollExists = hasScrollbar(scrollableNodeRef.current); + setFooterHighlighted(scrollExists); + setHasScroll(scrollExists); + } + }; + const isExited = exited || exited === null; + const shouldRender = keepMounted || open || !isExited; + const getContainer = useCallback(() => (container ? container() : document.body), [container]); + const addResizeHandle = useCallback(() => { + if (!resizeObserverRef.current) + return; + if (scrollableNodeRef.current) { + resizeObserverRef.current.observe(scrollableNodeRef.current); + } + if (contentNodeRef.current) { + resizeObserverRef.current.observe(contentNodeRef.current); + } + }, []); + const removeResizeHandle = useCallback(() => resizeObserverRef.current?.disconnect(), []); + const contentRef = useCallback((node) => { + if (node !== null) { + contentNodeRef.current = node; + if (resizeObserverRef.current) { + resizeObserverRef.current.observe(node); + } + checkToHasScrollBar(); + } + }, []); + const handleScroll = useCallback(() => { + if (!scrollableNodeRef.current || !componentNodeRef.current) + return; + if (hasHeader) { + setHeaderHighlighted(!isScrolledToTop(scrollableNodeRef.current) && + componentNodeRef.current.getBoundingClientRect().top - headerOffset <= 1); + } + if (hasFooter) { + setFooterHighlighted(!isScrolledToBottom(scrollableNodeRef.current) && + componentNodeRef.current.getBoundingClientRect().bottom >= + window.innerHeight - 1); + } + }, [hasFooter, hasHeader, headerOffset]); + const handleClose = useCallback((event, reason) => { + if (iOSLock && os.isIOS()) { + unlockScroll(); + } + if (onClose) { + onClose(event, reason); + } + if (reason === 'backdropClick' && onBackdropClick) { + onBackdropClick(event); + } + if (reason === 'escapeKeyDown' && onEscapeKeyDown) { + onEscapeKeyDown(event); + } + return null; + }, [onBackdropClick, onClose, onEscapeKeyDown, iOSLock]); + const handleBackdropMouseDown = (event) => { + let clickedOnScrollbar = false; + const clientWidth = event.target?.clientWidth; + if (event.clientX && clientWidth) { + // Устанавливаем смещение для абсолютно спозиционированного скроллбара в OSX в 17px. + const offset = browser.getScrollbarSize() === 0 ? 17 : 0; + clickedOnScrollbar = event.clientX + offset > clientWidth; + } + if (!disableBackdropClick && !clickedOnScrollbar) { + mouseDownTarget.current = event.target; + } + }; + const handleBackdropMouseUp = (event) => { + if (!disableBackdropClick && + event.target === wrapperRef.current && + mouseDownTarget.current === wrapperRef.current) { + handleClose(event, 'backdropClick'); + } + mouseDownTarget.current = undefined; + }; + const handleKeyDown = useCallback((event) => { + /* + * Чтобы сохранить дефолтное поведение элементов и событий форм, + * обработчик не устанавливает event.preventDefault() + */ + if (event.key !== 'Escape') { + return; + } + // Если есть обработчик escape на body + event.stopPropagation(); + if (!disableEscapeKeyDown && handleClose) { + handleClose(event, 'escapeKeyDown'); + } + }, [disableEscapeKeyDown, handleClose]); + const getScrollHandler = useCallback(() => { + if (scrollHandler === 'wrapper') + return wrapperRef.current; + if (scrollHandler === 'content') + return componentNodeRef.current; + return scrollHandler.current || wrapperRef.current; + }, [scrollHandler]); + const handleEntered = useCallback((node, isAppearing) => { + scrollableNodeRef.current = getScrollHandler(); + addResizeHandle(); + if (scrollableNodeRef.current) { + scrollableNodeRef.current.addEventListener('scroll', handleScroll); + handleScroll(); + } + if (transitionProps.onEntered) { + transitionProps.onEntered(node, isAppearing); + } + if (onMount) + onMount(); + }, [addResizeHandle, getScrollHandler, handleScroll, onMount, transitionProps]); + const handleExited = useCallback((node) => { + removeResizeHandle(); + setExited(true); + if (scrollableNodeRef.current) { + scrollableNodeRef.current.removeEventListener('scroll', handleScroll); + } + if (transitionProps.onExited) { + transitionProps.onExited(node); + } + if (onUnmount) + onUnmount(); + if (restoreContainerStylesRef.current) { + restoreContainerStylesRef.current(); + } + }, [handleScroll, onUnmount, removeResizeHandle, transitionProps]); + useEffect(() => { + if (open && isExited) { + if (!disableBlockingScroll) { + const el = getContainer(); + const shouldIOSLock = iOSLock && os.isIOS(); + handleContainer(el, shouldIOSLock); + if (shouldIOSLock) { + syncHeight(); + lockScroll(); + } + restoreContainerStylesRef.current = () => { + restoreContainerStylesRef.current = null; + restoreContainerStyles(el); + }; + } + setExited(false); + } + if (!open) { + unlockScroll(); + } + }, [getContainer, open, disableBlockingScroll, isExited, iOSLock]); + useEffect(() => { + const ResizeObserver$1 = window.ResizeObserver || ResizeObserver; + resizeObserverRef.current = new ResizeObserver$1(checkToHasScrollBar); + return () => { + if (restoreContainerStylesRef.current) { + restoreContainerStylesRef.current(); + } + if (resizeObserverRef.current) { + resizeObserverRef.current.disconnect(); + } + }; + }, []); + useEffect(() => { + if (disableAutoFocus || !open) + return; + wrapperRef.current?.focus(); + }, [open, disableAutoFocus]); + const contextValue = useMemo(() => ({ + parentRef: wrapperRef, + componentRef: componentNodeRef, + hasHeader, + hasFooter, + hasScroll, + headerHighlighted, + footerHighlighted, + headerOffset, + setHeaderOffset, + contentRef, + setHasHeader, + setHasFooter, + onClose: handleClose, + }), [ + contentRef, + hasHeader, + hasFooter, + hasScroll, + headerHighlighted, + footerHighlighted, + headerOffset, + setHeaderOffset, + handleClose, + ]); + const renderContent = () => (React.createElement(Stack, { value: zIndex }, (computedZIndex) => (React.createElement(BaseModalContext.Provider, { value: contextValue }, + React.createElement(FocusLock, { disabled: disableFocusLock || !open, returnFocus: !disableRestoreFocus }, + Backdrop$1 && (React.createElement(Backdrop$1, { ...backdropProps, className: cn(backdropProps.className, styles.backdrop), open: open, style: { + zIndex: computedZIndex, + } })), + React.createElement("div", { ...wrapperProps, role: 'dialog', className: cn(styles.wrapper, wrapperClassName, wrapperProps?.className, { + [styles.hidden]: !open && isExited, + }), ref: mergeRefs([ + ref, + wrapperRef, + wrapperProps?.ref, + ]), onKeyDown: handleKeyDown, onMouseDown: handleBackdropMouseDown, onMouseUp: handleBackdropMouseUp, tabIndex: -1, "data-test-id": dataTestId, style: { + zIndex: computedZIndex, + } }, + React.createElement(CSSTransition, { appear: true, timeout: 200, classNames: styles, nodeRef: componentNodeRef, ...transitionProps, in: open, onEntered: handleEntered, onExited: handleExited }, + React.createElement("div", { ...componentDivProps, className: cn(styles.component, className, componentDivProps?.className), ref: mergeRefs([ + componentRef, + componentNodeRef, + componentDivProps?.ref || null, + ]) }, + React.createElement("div", { ...contentProps, className: cn(styles.content, contentClassName, contentProps?.className) }, children))))))))); + if (!shouldRender) + return null; + return usePortal ? (React.createElement(Portal, { getPortalContainer: container, immediateMount: true }, renderContent())) : (renderContent()); +}); +BaseModal.displayName = 'BaseModal'; +BaseModalContext.displayName = 'BaseModalContext'; + +export { BaseModal, BaseModalContext }; diff --git a/packages/base-modal/dist_side_poly/modern/helpers/lockScroll.d.ts b/packages/base-modal/dist_side_poly/modern/helpers/lockScroll.d.ts new file mode 100644 index 0000000000..80e91475f8 --- /dev/null +++ b/packages/base-modal/dist_side_poly/modern/helpers/lockScroll.d.ts @@ -0,0 +1,5 @@ +declare const isScrollLocked: () => boolean; +declare const lockScroll: () => void; +declare const unlockScroll: () => void; +declare const syncHeight: () => void; +export { isScrollLocked, lockScroll, unlockScroll, syncHeight }; diff --git a/packages/base-modal/dist_side_poly/modern/helpers/lockScroll.js b/packages/base-modal/dist_side_poly/modern/helpers/lockScroll.js new file mode 100644 index 0000000000..7d6a7f293e --- /dev/null +++ b/packages/base-modal/dist_side_poly/modern/helpers/lockScroll.js @@ -0,0 +1,21 @@ +/** + * Хелпер для блокирования скроллинга в iOS + * В проекте используется overflow: hidden для блокировки, но в некоторых случаях этого недостаточно. Данный хелпер призван решать эту проблему + */ +let scrollY; +const isScrollLocked = () => document.body.classList.contains('is-locked'); +const lockScroll = () => { + scrollY = window.scrollY; + document.body.classList.add('is-locked'); +}; +const unlockScroll = () => { + if (!isScrollLocked()) + return; + document.body.classList.remove('is-locked'); + window.scrollTo(0, scrollY); +}; +const syncHeight = () => { + document.body.style.setProperty('--window-inner-scrollY', `${window.scrollY}px`); +}; + +export { isScrollLocked, lockScroll, syncHeight, unlockScroll }; diff --git a/packages/base-modal/dist_side_poly/modern/index.css b/packages/base-modal/dist_side_poly/modern/index.css new file mode 100644 index 0000000000..717db4385d --- /dev/null +++ b/packages/base-modal/dist_side_poly/modern/index.css @@ -0,0 +1,71 @@ +/* hash: 5nduy */ +:root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ +} /* deprecated */ :root { + --color-light-modal-bg-primary: #fff; /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ +} :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ +} :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ +} :root { + + /* Hard */ + + /* Up */ + + /* Hard up */ +} :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ + + /* новые значения, используйте их */ +} :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ + + /* новые значения, используйте их */ + --gap-0: 0; +} :root { +} :root { +} /* сбрасывает синюю подсветку при нажатии */ :root { + --window-inner-scrollY: 10px; /* fallback value to prevent ci error */ +} body.is-locked { + margin-top: calc(var(--window-inner-scrollY) * -1); + position: fixed; + overflow: hidden; +} .base-modal__component_1y6m8 { + position: relative; + box-sizing: border-box; + background: var(--color-light-modal-bg-primary); + margin: auto; + flex-shrink: 0; +} .base-modal__wrapper_1y6m8 { + position: fixed; + top: var(--gap-0); + left: var(--gap-0); + right: var(--gap-0); + bottom: var(--gap-0); + + overflow: auto; + display: flex; + flex-direction: column; + align-items: center; + outline: 0; + overscroll-behavior: none; +} .base-modal__content_1y6m8 { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + flex: 1; +} .base-modal__hidden_1y6m8 { + display: none; +} .base-modal__backdrop_1y6m8 { + z-index: 0; +} .base-modal__appear_1y6m8, +.base-modal__enter_1y6m8 { + opacity: 0; +} .base-modal__appearActive_1y6m8, +.base-modal__enterActive_1y6m8 { + opacity: 1; + transition: opacity 200ms ease-in; +} .base-modal__exit_1y6m8 { + opacity: 1; +} .base-modal__exitActive_1y6m8, +.base-modal__exitDone_1y6m8 { + opacity: 0; + transition: opacity 200ms ease-out; +} diff --git a/packages/base-modal/dist_side_poly/modern/index.d.ts b/packages/base-modal/dist_side_poly/modern/index.d.ts new file mode 100644 index 0000000000..61ae91968a --- /dev/null +++ b/packages/base-modal/dist_side_poly/modern/index.d.ts @@ -0,0 +1,3 @@ +export * from "./Component"; +export * from "./utils"; +export * from "./helpers/lockScroll"; diff --git a/packages/base-modal/dist_side_poly/modern/index.js b/packages/base-modal/dist_side_poly/modern/index.js new file mode 100644 index 0000000000..ee07c7a608 --- /dev/null +++ b/packages/base-modal/dist_side_poly/modern/index.js @@ -0,0 +1,3 @@ +export { BaseModal, BaseModalContext } from './Component.js'; +export { handleContainer, hasScrollbar, isScrolledToBottom, isScrolledToTop, restoreContainerStyles } from './utils.js'; +export { isScrollLocked, lockScroll, syncHeight, unlockScroll } from './helpers/lockScroll.js'; diff --git a/packages/base-modal/dist_side_poly/modern/matches-polyfill.d.ts b/packages/base-modal/dist_side_poly/modern/matches-polyfill.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/packages/base-modal/dist_side_poly/modern/matches-polyfill.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/base-modal/dist_side_poly/modern/matches-polyfill.js b/packages/base-modal/dist_side_poly/modern/matches-polyfill.js new file mode 100644 index 0000000000..931ad2a8ea --- /dev/null +++ b/packages/base-modal/dist_side_poly/modern/matches-polyfill.js @@ -0,0 +1,18 @@ +/* eslint-disable */ +// @ts-nocheck +if (typeof window !== 'undefined') { + if (Element && !Element.prototype.matches) { + Element.prototype.matches = + Element.prototype.matchesSelector || + Element.prototype.mozMatchesSelector || + Element.prototype.msMatchesSelector || + Element.prototype.oMatchesSelector || + Element.prototype.webkitMatchesSelector || + function (s) { + const matches = (this.document || this.ownerDocument).querySelectorAll(s); + let i = matches.length; + while (--i >= 0 && matches.item(i) !== this) { } + return i > -1; + }; + } +} diff --git a/packages/base-modal/dist_side_poly/modern/utils.d.ts b/packages/base-modal/dist_side_poly/modern/utils.d.ts new file mode 100644 index 0000000000..75401779bb --- /dev/null +++ b/packages/base-modal/dist_side_poly/modern/utils.d.ts @@ -0,0 +1,6 @@ +declare function isScrolledToTop(target: HTMLElement): boolean; +declare function isScrolledToBottom(target: HTMLElement): boolean; +declare function hasScrollbar(target: HTMLElement): boolean; +declare const restoreContainerStyles: (container: HTMLElement) => void; +declare const handleContainer: (container?: HTMLElement, shouldIOSLock?: boolean) => void; +export { isScrolledToTop, isScrolledToBottom, hasScrollbar, restoreContainerStyles, handleContainer }; diff --git a/packages/base-modal/dist_side_poly/modern/utils.js b/packages/base-modal/dist_side_poly/modern/utils.js new file mode 100644 index 0000000000..6432752044 --- /dev/null +++ b/packages/base-modal/dist_side_poly/modern/utils.js @@ -0,0 +1,87 @@ +import { getModalStore } from '@alfalab/core-components-global-store/modern'; +import { browser } from '@alfalab/core-components-shared/modern'; + +function isScrolledToTop(target) { + return target.scrollTop <= 0; +} +function isScrolledToBottom(target) { + return target.scrollHeight - target.offsetHeight <= target.scrollTop; +} +function hasScrollbar(target) { + return target.scrollHeight > target.clientHeight; +} +const isOverflowing = (container) => { + if (document.body === container) { + return window.innerWidth > document.documentElement.clientWidth; + } + return container.scrollHeight > container.clientHeight; +}; +const getPaddingRight = (node) => parseInt(window.getComputedStyle(node).paddingRight, 10) || 0; +const restoreContainerStyles = (container) => { + const modalRestoreStyles = getModalStore().getRestoreStyles(); + const index = modalRestoreStyles.findIndex((s) => s.container === container); + const existingStyles = modalRestoreStyles[index]; + if (!existingStyles) + return; + existingStyles.modals -= 1; + if (existingStyles.modals <= 0) { + modalRestoreStyles.splice(index, 1); + existingStyles.styles.forEach(({ value, el, key }) => { + if (value) { + el.style.setProperty(key, value); + } + else { + el.style.removeProperty(key); + } + }); + } +}; +const handleContainer = (container, shouldIOSLock = false) => { + if (!container) + return; + const modalRestoreStyles = getModalStore().getRestoreStyles(); + const existingStyles = modalRestoreStyles.find((s) => s.container === container); + if (existingStyles) { + existingStyles.modals += 1; + return; + } + const containerStyles = []; + if (isOverflowing(container)) { + // Вычисляет размер до применения `overflow hidden` для избежания скачков + const scrollbarSize = browser.getScrollbarSize(); + containerStyles.push({ + value: container.style.paddingRight, + key: 'padding-right', + el: container, + }); + // Вычисляем стили, чтобы получить реальный `padding` c шириной сколлбара + // eslint-disable-next-line no-param-reassign + container.style.paddingRight = `${getPaddingRight(container) + scrollbarSize}px`; + } + const parent = container.parentElement; + const scrollContainer = + // TODO: заменить на optional chaining + parent && + parent.nodeName === 'HTML' && + window.getComputedStyle(parent).overflowY === 'scroll' + ? parent + : container; + // Блокируем скролл даже если отсутствует скроллбар + if (scrollContainer.style.overflow !== 'hidden') { + containerStyles.push({ + value: scrollContainer.style.overflow, + key: 'overflow', + el: scrollContainer, + }); + } + if (!shouldIOSLock) { + scrollContainer.style.overflow = 'hidden'; + } + modalRestoreStyles.push({ + container, + modals: 1, + styles: containerStyles, + }); +}; + +export { handleContainer, hasScrollbar, isScrolledToBottom, isScrolledToTop, restoreContainerStyles }; diff --git a/packages/base-modal/dist_side_poly/moderncssm/Component.d.ts b/packages/base-modal/dist_side_poly/moderncssm/Component.d.ts new file mode 100644 index 0000000000..44533e4e97 --- /dev/null +++ b/packages/base-modal/dist_side_poly/moderncssm/Component.d.ts @@ -0,0 +1,159 @@ +/// +/// +import React from 'react'; +import { ComponentType, KeyboardEvent, MouseEvent, MutableRefObject, ReactNode, Ref } from "react"; +import { TransitionProps } from 'react-transition-group/Transition'; +import { BackdropProps } from "@alfalab/core-components-backdrop"; +import { PortalProps } from "@alfalab/core-components-portal"; +type BaseModalProps = { + /** + * Контент + */ + children?: ReactNode; + /** + * Компонент бэкдропа + */ + Backdrop?: ComponentType; + /** + * Свойства для Бэкдропа + */ + backdropProps?: Partial & Record; + /** + * Нода, компонент или функция возвращающая их + * + * Контейнер к которому будут добавляться порталы + */ + container?: PortalProps['getPortalContainer']; + /** + * Отключает автоматический перевод фокуса на модалку при открытии + * @default false + */ + disableAutoFocus?: boolean; + /** + * Отключает ловушку фокуса + * @default false + */ + disableFocusLock?: boolean; + /** + * Отключает восстановление фокуса на предыдущем элементе после закрытия модалки + * @default false + */ + disableRestoreFocus?: boolean; + /** + * Отключает вызов `callback` при нажатии Escape + * @default false + */ + disableEscapeKeyDown?: boolean; + /** + * Отключает вызов `callback` при клике на бэкдроп + * @default false + */ + disableBackdropClick?: boolean; + /** + * Отключает блокировку скролла при открытии модального окна + * @default false + */ + disableBlockingScroll?: boolean; + /** + * Содержимое модалки всегда в DOM + * @default false + */ + keepMounted?: boolean; + /** + * Управление видимостью модалки + */ + open: boolean; + /** + * Дополнительный класс + */ + className?: string; + /** + * Дополнительный класс + */ + contentClassName?: string; + /** + * Дополнительные пропсы на dialog wrapper + */ + wrapperProps?: React.DetailedHTMLProps, HTMLDivElement>; + /** + * Дополнительные пропсы на обертку контента + */ + contentProps?: React.DetailedHTMLProps, HTMLDivElement>; + /** + * Дополнительные пропсы на компонентную обертку контента + */ + componentDivProps?: React.DetailedHTMLProps, HTMLDivElement>; + /** + * Дополнительный класс для обертки (Modal) + */ + wrapperClassName?: string; + /** + * Обработчик скролла контента + */ + scrollHandler?: 'wrapper' | 'content' | MutableRefObject; + /** + * Пропсы для анимации (CSSTransition) + */ + transitionProps?: Partial; + /** + * Рендерить ли в контейнер через портал. + * @default true + */ + usePortal?: boolean; + /** + * Обработчик события нажатия на бэкдроп + */ + onBackdropClick?: (event: MouseEvent) => void; + /** + * Обработчик события нажатия на Escape + * + * Если `disableEscapeKeyDown` - false и модальное окно в фокусе + */ + onEscapeKeyDown?: (event: KeyboardEvent) => void; + /** + * Обработчик закрытия + */ + onClose?: (event: MouseEvent | KeyboardEvent, reason?: 'backdropClick' | 'escapeKeyDown' | 'closerClick') => void; + /** + * Обработчик события onEntered компонента Transition + */ + onMount?: () => void; + /** + * Обработчик события onExited компонента Transition + */ + onUnmount?: () => void; + /** + * Идентификатор для систем автоматизированного тестирования + */ + dataTestId?: string; + /** + * z-index компонента + */ + zIndex?: number; + /** + * Реф, который должен быть установлен компонентной области + */ + componentRef?: MutableRefObject; + /** + * Блокирует скролл когда модальное окно открыто. Работает только на iOS. + */ + iOSLock?: boolean; +}; +type BaseModalContext = { + parentRef: React.RefObject; + componentRef: React.RefObject; + hasFooter?: boolean; + hasHeader?: boolean; + hasScroll?: boolean; + headerHighlighted?: boolean; + footerHighlighted?: boolean; + headerOffset?: number; + setHeaderOffset: (offset: number) => void; + contentRef: Ref; + setHasHeader: (exists: boolean) => void; + setHasFooter: (exists: boolean) => void; + onClose: Required['onClose']; +}; +declare const BaseModalContext: React.Context; +declare const BaseModal: React.ForwardRefExoticComponent>; +export { BaseModalProps, BaseModalContext, BaseModal }; diff --git a/packages/base-modal/dist_side_poly/moderncssm/Component.js b/packages/base-modal/dist_side_poly/moderncssm/Component.js new file mode 100644 index 0000000000..865b66f59b --- /dev/null +++ b/packages/base-modal/dist_side_poly/moderncssm/Component.js @@ -0,0 +1,267 @@ +import React, { forwardRef, useState, useRef, useCallback, useEffect, useMemo } from 'react'; +import FocusLock from 'react-focus-lock'; +import mergeRefs from 'react-merge-refs'; +import { CSSTransition } from 'react-transition-group'; +import { ResizeObserver } from '@juggle/resize-observer'; +import cn from 'classnames'; +import { Backdrop } from '@alfalab/core-components-backdrop/moderncssm'; +import { Portal } from '@alfalab/core-components-portal/moderncssm'; +import { os, browser } from '@alfalab/core-components-shared/moderncssm'; +import { Stack } from '@alfalab/core-components-stack/moderncssm'; +import { stackingOrder } from '@alfalab/stack-context'; +import { unlockScroll, syncHeight, lockScroll } from './helpers/lockScroll.js'; +import { isScrolledToTop, isScrolledToBottom, handleContainer, restoreContainerStyles, hasScrollbar } from './utils.js'; +import styles from './index.module.css'; +import './matches-polyfill.js'; + +/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */ +// eslint-disable-next-line @typescript-eslint/no-redeclare +const BaseModalContext = React.createContext({ + parentRef: { current: null }, + componentRef: { current: null }, + hasFooter: false, + hasHeader: false, + hasScroll: false, + headerHighlighted: false, + footerHighlighted: false, + headerOffset: 0, + setHeaderOffset: () => null, + contentRef: () => null, + setHasHeader: () => null, + setHasFooter: () => null, + onClose: () => null, +}); +const BaseModal = forwardRef(({ open, container, children, scrollHandler = 'wrapper', Backdrop: Backdrop$1 = Backdrop, backdropProps = {}, transitionProps = {}, disableBackdropClick, disableAutoFocus = false, disableFocusLock = false, disableEscapeKeyDown = false, disableRestoreFocus = false, disableBlockingScroll = false, keepMounted = false, className, contentClassName, wrapperProps, contentProps, componentDivProps, wrapperClassName, onBackdropClick, onClose, onEscapeKeyDown, onMount, onUnmount, dataTestId, zIndex = stackingOrder.MODAL, componentRef = null, usePortal = true, iOSLock = false, }, ref) => { + const [exited, setExited] = useState(null); + const [hasScroll, setHasScroll] = useState(false); + const [hasHeader, setHasHeader] = useState(false); + const [hasFooter, setHasFooter] = useState(false); + const [headerHighlighted, setHeaderHighlighted] = useState(false); + const [footerHighlighted, setFooterHighlighted] = useState(false); + const [headerOffset, setHeaderOffset] = useState(0); + const componentNodeRef = useRef(null); + const wrapperRef = useRef(null); + const scrollableNodeRef = useRef(null); + const contentNodeRef = useRef(null); + const restoreContainerStylesRef = useRef(null); + const mouseDownTarget = useRef(); + const resizeObserverRef = useRef(); + const checkToHasScrollBar = () => { + if (scrollableNodeRef.current) { + const scrollExists = hasScrollbar(scrollableNodeRef.current); + setFooterHighlighted(scrollExists); + setHasScroll(scrollExists); + } + }; + const isExited = exited || exited === null; + const shouldRender = keepMounted || open || !isExited; + const getContainer = useCallback(() => (container ? container() : document.body), [container]); + const addResizeHandle = useCallback(() => { + if (!resizeObserverRef.current) + return; + if (scrollableNodeRef.current) { + resizeObserverRef.current.observe(scrollableNodeRef.current); + } + if (contentNodeRef.current) { + resizeObserverRef.current.observe(contentNodeRef.current); + } + }, []); + const removeResizeHandle = useCallback(() => resizeObserverRef.current?.disconnect(), []); + const contentRef = useCallback((node) => { + if (node !== null) { + contentNodeRef.current = node; + if (resizeObserverRef.current) { + resizeObserverRef.current.observe(node); + } + checkToHasScrollBar(); + } + }, []); + const handleScroll = useCallback(() => { + if (!scrollableNodeRef.current || !componentNodeRef.current) + return; + if (hasHeader) { + setHeaderHighlighted(!isScrolledToTop(scrollableNodeRef.current) && + componentNodeRef.current.getBoundingClientRect().top - headerOffset <= 1); + } + if (hasFooter) { + setFooterHighlighted(!isScrolledToBottom(scrollableNodeRef.current) && + componentNodeRef.current.getBoundingClientRect().bottom >= + window.innerHeight - 1); + } + }, [hasFooter, hasHeader, headerOffset]); + const handleClose = useCallback((event, reason) => { + if (iOSLock && os.isIOS()) { + unlockScroll(); + } + if (onClose) { + onClose(event, reason); + } + if (reason === 'backdropClick' && onBackdropClick) { + onBackdropClick(event); + } + if (reason === 'escapeKeyDown' && onEscapeKeyDown) { + onEscapeKeyDown(event); + } + return null; + }, [onBackdropClick, onClose, onEscapeKeyDown, iOSLock]); + const handleBackdropMouseDown = (event) => { + let clickedOnScrollbar = false; + const clientWidth = event.target?.clientWidth; + if (event.clientX && clientWidth) { + // Устанавливаем смещение для абсолютно спозиционированного скроллбара в OSX в 17px. + const offset = browser.getScrollbarSize() === 0 ? 17 : 0; + clickedOnScrollbar = event.clientX + offset > clientWidth; + } + if (!disableBackdropClick && !clickedOnScrollbar) { + mouseDownTarget.current = event.target; + } + }; + const handleBackdropMouseUp = (event) => { + if (!disableBackdropClick && + event.target === wrapperRef.current && + mouseDownTarget.current === wrapperRef.current) { + handleClose(event, 'backdropClick'); + } + mouseDownTarget.current = undefined; + }; + const handleKeyDown = useCallback((event) => { + /* + * Чтобы сохранить дефолтное поведение элементов и событий форм, + * обработчик не устанавливает event.preventDefault() + */ + if (event.key !== 'Escape') { + return; + } + // Если есть обработчик escape на body + event.stopPropagation(); + if (!disableEscapeKeyDown && handleClose) { + handleClose(event, 'escapeKeyDown'); + } + }, [disableEscapeKeyDown, handleClose]); + const getScrollHandler = useCallback(() => { + if (scrollHandler === 'wrapper') + return wrapperRef.current; + if (scrollHandler === 'content') + return componentNodeRef.current; + return scrollHandler.current || wrapperRef.current; + }, [scrollHandler]); + const handleEntered = useCallback((node, isAppearing) => { + scrollableNodeRef.current = getScrollHandler(); + addResizeHandle(); + if (scrollableNodeRef.current) { + scrollableNodeRef.current.addEventListener('scroll', handleScroll); + handleScroll(); + } + if (transitionProps.onEntered) { + transitionProps.onEntered(node, isAppearing); + } + if (onMount) + onMount(); + }, [addResizeHandle, getScrollHandler, handleScroll, onMount, transitionProps]); + const handleExited = useCallback((node) => { + removeResizeHandle(); + setExited(true); + if (scrollableNodeRef.current) { + scrollableNodeRef.current.removeEventListener('scroll', handleScroll); + } + if (transitionProps.onExited) { + transitionProps.onExited(node); + } + if (onUnmount) + onUnmount(); + if (restoreContainerStylesRef.current) { + restoreContainerStylesRef.current(); + } + }, [handleScroll, onUnmount, removeResizeHandle, transitionProps]); + useEffect(() => { + if (open && isExited) { + if (!disableBlockingScroll) { + const el = getContainer(); + const shouldIOSLock = iOSLock && os.isIOS(); + handleContainer(el, shouldIOSLock); + if (shouldIOSLock) { + syncHeight(); + lockScroll(); + } + restoreContainerStylesRef.current = () => { + restoreContainerStylesRef.current = null; + restoreContainerStyles(el); + }; + } + setExited(false); + } + if (!open) { + unlockScroll(); + } + }, [getContainer, open, disableBlockingScroll, isExited, iOSLock]); + useEffect(() => { + const ResizeObserver$1 = window.ResizeObserver || ResizeObserver; + resizeObserverRef.current = new ResizeObserver$1(checkToHasScrollBar); + return () => { + if (restoreContainerStylesRef.current) { + restoreContainerStylesRef.current(); + } + if (resizeObserverRef.current) { + resizeObserverRef.current.disconnect(); + } + }; + }, []); + useEffect(() => { + if (disableAutoFocus || !open) + return; + wrapperRef.current?.focus(); + }, [open, disableAutoFocus]); + const contextValue = useMemo(() => ({ + parentRef: wrapperRef, + componentRef: componentNodeRef, + hasHeader, + hasFooter, + hasScroll, + headerHighlighted, + footerHighlighted, + headerOffset, + setHeaderOffset, + contentRef, + setHasHeader, + setHasFooter, + onClose: handleClose, + }), [ + contentRef, + hasHeader, + hasFooter, + hasScroll, + headerHighlighted, + footerHighlighted, + headerOffset, + setHeaderOffset, + handleClose, + ]); + const renderContent = () => (React.createElement(Stack, { value: zIndex }, (computedZIndex) => (React.createElement(BaseModalContext.Provider, { value: contextValue }, + React.createElement(FocusLock, { disabled: disableFocusLock || !open, returnFocus: !disableRestoreFocus }, + Backdrop$1 && (React.createElement(Backdrop$1, { ...backdropProps, className: cn(backdropProps.className, styles.backdrop), open: open, style: { + zIndex: computedZIndex, + } })), + React.createElement("div", { ...wrapperProps, role: 'dialog', className: cn(styles.wrapper, wrapperClassName, wrapperProps?.className, { + [styles.hidden]: !open && isExited, + }), ref: mergeRefs([ + ref, + wrapperRef, + wrapperProps?.ref, + ]), onKeyDown: handleKeyDown, onMouseDown: handleBackdropMouseDown, onMouseUp: handleBackdropMouseUp, tabIndex: -1, "data-test-id": dataTestId, style: { + zIndex: computedZIndex, + } }, + React.createElement(CSSTransition, { appear: true, timeout: 200, classNames: styles, nodeRef: componentNodeRef, ...transitionProps, in: open, onEntered: handleEntered, onExited: handleExited }, + React.createElement("div", { ...componentDivProps, className: cn(styles.component, className, componentDivProps?.className), ref: mergeRefs([ + componentRef, + componentNodeRef, + componentDivProps?.ref || null, + ]) }, + React.createElement("div", { ...contentProps, className: cn(styles.content, contentClassName, contentProps?.className) }, children))))))))); + if (!shouldRender) + return null; + return usePortal ? (React.createElement(Portal, { getPortalContainer: container, immediateMount: true }, renderContent())) : (renderContent()); +}); +BaseModal.displayName = 'BaseModal'; +BaseModalContext.displayName = 'BaseModalContext'; + +export { BaseModal, BaseModalContext }; diff --git a/packages/base-modal/dist_side_poly/moderncssm/helpers/lockScroll.d.ts b/packages/base-modal/dist_side_poly/moderncssm/helpers/lockScroll.d.ts new file mode 100644 index 0000000000..80e91475f8 --- /dev/null +++ b/packages/base-modal/dist_side_poly/moderncssm/helpers/lockScroll.d.ts @@ -0,0 +1,5 @@ +declare const isScrollLocked: () => boolean; +declare const lockScroll: () => void; +declare const unlockScroll: () => void; +declare const syncHeight: () => void; +export { isScrollLocked, lockScroll, unlockScroll, syncHeight }; diff --git a/packages/base-modal/dist_side_poly/moderncssm/helpers/lockScroll.js b/packages/base-modal/dist_side_poly/moderncssm/helpers/lockScroll.js new file mode 100644 index 0000000000..7d6a7f293e --- /dev/null +++ b/packages/base-modal/dist_side_poly/moderncssm/helpers/lockScroll.js @@ -0,0 +1,21 @@ +/** + * Хелпер для блокирования скроллинга в iOS + * В проекте используется overflow: hidden для блокировки, но в некоторых случаях этого недостаточно. Данный хелпер призван решать эту проблему + */ +let scrollY; +const isScrollLocked = () => document.body.classList.contains('is-locked'); +const lockScroll = () => { + scrollY = window.scrollY; + document.body.classList.add('is-locked'); +}; +const unlockScroll = () => { + if (!isScrollLocked()) + return; + document.body.classList.remove('is-locked'); + window.scrollTo(0, scrollY); +}; +const syncHeight = () => { + document.body.style.setProperty('--window-inner-scrollY', `${window.scrollY}px`); +}; + +export { isScrollLocked, lockScroll, syncHeight, unlockScroll }; diff --git a/packages/base-modal/dist_side_poly/moderncssm/index.d.ts b/packages/base-modal/dist_side_poly/moderncssm/index.d.ts new file mode 100644 index 0000000000..61ae91968a --- /dev/null +++ b/packages/base-modal/dist_side_poly/moderncssm/index.d.ts @@ -0,0 +1,3 @@ +export * from "./Component"; +export * from "./utils"; +export * from "./helpers/lockScroll"; diff --git a/packages/base-modal/dist_side_poly/moderncssm/index.js b/packages/base-modal/dist_side_poly/moderncssm/index.js new file mode 100644 index 0000000000..ee07c7a608 --- /dev/null +++ b/packages/base-modal/dist_side_poly/moderncssm/index.js @@ -0,0 +1,3 @@ +export { BaseModal, BaseModalContext } from './Component.js'; +export { handleContainer, hasScrollbar, isScrolledToBottom, isScrolledToTop, restoreContainerStyles } from './utils.js'; +export { isScrollLocked, lockScroll, syncHeight, unlockScroll } from './helpers/lockScroll.js'; diff --git a/packages/base-modal/dist_side_poly/moderncssm/index.module.css b/packages/base-modal/dist_side_poly/moderncssm/index.module.css new file mode 100644 index 0000000000..3454492221 --- /dev/null +++ b/packages/base-modal/dist_side_poly/moderncssm/index.module.css @@ -0,0 +1,71 @@ +/* */ + +:root { + --window-inner-scrollY: 10px; /* fallback value to prevent ci error */ +} + +body:global(.is-locked) { + margin-top: calc(var(--window-inner-scrollY) * -1); + position: fixed; + overflow: hidden; +} + +.component { + position: relative; + box-sizing: border-box; + background: var(--color-light-modal-bg-primary); + margin: auto; + flex-shrink: 0; +} + +.wrapper { + position: fixed; + top: var(--gap-0); + left: var(--gap-0); + right: var(--gap-0); + bottom: var(--gap-0); + + overflow: auto; + display: flex; + flex-direction: column; + align-items: center; + outline: 0; + overscroll-behavior: none; +} + +.content { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + flex: 1; +} + +.hidden { + display: none; +} + +.backdrop { + z-index: 0; +} + +.appear, +.enter { + opacity: 0; +} + +.appearActive, +.enterActive { + opacity: 1; + transition: opacity 200ms ease-in; +} + +.exit { + opacity: 1; +} + +.exitActive, +.exitDone { + opacity: 0; + transition: opacity 200ms ease-out; +} diff --git a/packages/base-modal/dist_side_poly/moderncssm/matches-polyfill.d.ts b/packages/base-modal/dist_side_poly/moderncssm/matches-polyfill.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/packages/base-modal/dist_side_poly/moderncssm/matches-polyfill.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/base-modal/dist_side_poly/moderncssm/matches-polyfill.js b/packages/base-modal/dist_side_poly/moderncssm/matches-polyfill.js new file mode 100644 index 0000000000..931ad2a8ea --- /dev/null +++ b/packages/base-modal/dist_side_poly/moderncssm/matches-polyfill.js @@ -0,0 +1,18 @@ +/* eslint-disable */ +// @ts-nocheck +if (typeof window !== 'undefined') { + if (Element && !Element.prototype.matches) { + Element.prototype.matches = + Element.prototype.matchesSelector || + Element.prototype.mozMatchesSelector || + Element.prototype.msMatchesSelector || + Element.prototype.oMatchesSelector || + Element.prototype.webkitMatchesSelector || + function (s) { + const matches = (this.document || this.ownerDocument).querySelectorAll(s); + let i = matches.length; + while (--i >= 0 && matches.item(i) !== this) { } + return i > -1; + }; + } +} diff --git a/packages/base-modal/dist_side_poly/moderncssm/utils.d.ts b/packages/base-modal/dist_side_poly/moderncssm/utils.d.ts new file mode 100644 index 0000000000..75401779bb --- /dev/null +++ b/packages/base-modal/dist_side_poly/moderncssm/utils.d.ts @@ -0,0 +1,6 @@ +declare function isScrolledToTop(target: HTMLElement): boolean; +declare function isScrolledToBottom(target: HTMLElement): boolean; +declare function hasScrollbar(target: HTMLElement): boolean; +declare const restoreContainerStyles: (container: HTMLElement) => void; +declare const handleContainer: (container?: HTMLElement, shouldIOSLock?: boolean) => void; +export { isScrolledToTop, isScrolledToBottom, hasScrollbar, restoreContainerStyles, handleContainer }; diff --git a/packages/base-modal/dist_side_poly/moderncssm/utils.js b/packages/base-modal/dist_side_poly/moderncssm/utils.js new file mode 100644 index 0000000000..a42cedaa29 --- /dev/null +++ b/packages/base-modal/dist_side_poly/moderncssm/utils.js @@ -0,0 +1,87 @@ +import { getModalStore } from '@alfalab/core-components-global-store/moderncssm'; +import { browser } from '@alfalab/core-components-shared/moderncssm'; + +function isScrolledToTop(target) { + return target.scrollTop <= 0; +} +function isScrolledToBottom(target) { + return target.scrollHeight - target.offsetHeight <= target.scrollTop; +} +function hasScrollbar(target) { + return target.scrollHeight > target.clientHeight; +} +const isOverflowing = (container) => { + if (document.body === container) { + return window.innerWidth > document.documentElement.clientWidth; + } + return container.scrollHeight > container.clientHeight; +}; +const getPaddingRight = (node) => parseInt(window.getComputedStyle(node).paddingRight, 10) || 0; +const restoreContainerStyles = (container) => { + const modalRestoreStyles = getModalStore().getRestoreStyles(); + const index = modalRestoreStyles.findIndex((s) => s.container === container); + const existingStyles = modalRestoreStyles[index]; + if (!existingStyles) + return; + existingStyles.modals -= 1; + if (existingStyles.modals <= 0) { + modalRestoreStyles.splice(index, 1); + existingStyles.styles.forEach(({ value, el, key }) => { + if (value) { + el.style.setProperty(key, value); + } + else { + el.style.removeProperty(key); + } + }); + } +}; +const handleContainer = (container, shouldIOSLock = false) => { + if (!container) + return; + const modalRestoreStyles = getModalStore().getRestoreStyles(); + const existingStyles = modalRestoreStyles.find((s) => s.container === container); + if (existingStyles) { + existingStyles.modals += 1; + return; + } + const containerStyles = []; + if (isOverflowing(container)) { + // Вычисляет размер до применения `overflow hidden` для избежания скачков + const scrollbarSize = browser.getScrollbarSize(); + containerStyles.push({ + value: container.style.paddingRight, + key: 'padding-right', + el: container, + }); + // Вычисляем стили, чтобы получить реальный `padding` c шириной сколлбара + // eslint-disable-next-line no-param-reassign + container.style.paddingRight = `${getPaddingRight(container) + scrollbarSize}px`; + } + const parent = container.parentElement; + const scrollContainer = + // TODO: заменить на optional chaining + parent && + parent.nodeName === 'HTML' && + window.getComputedStyle(parent).overflowY === 'scroll' + ? parent + : container; + // Блокируем скролл даже если отсутствует скроллбар + if (scrollContainer.style.overflow !== 'hidden') { + containerStyles.push({ + value: scrollContainer.style.overflow, + key: 'overflow', + el: scrollContainer, + }); + } + if (!shouldIOSLock) { + scrollContainer.style.overflow = 'hidden'; + } + modalRestoreStyles.push({ + container, + modals: 1, + styles: containerStyles, + }); +}; + +export { handleContainer, hasScrollbar, isScrolledToBottom, isScrolledToTop, restoreContainerStyles }; diff --git a/packages/base-modal/dist_side_poly/package.json b/packages/base-modal/dist_side_poly/package.json new file mode 100644 index 0000000000..6f0d2d4e13 --- /dev/null +++ b/packages/base-modal/dist_side_poly/package.json @@ -0,0 +1,37 @@ +{ + "name": "@alfalab/core-components-base-modal", + "version": "5.8.6", + "description": "BaseModal component", + "keywords": [], + "license": "MIT", + "main": "index.js", + "module": "./esm/index.js", + "publishConfig": { + "access": "public", + "directory": "dist" + }, + "sideEffects": [ + "./matches-polyfill" + ], + "dependencies": { + "@alfalab/core-components-backdrop": "^3.4.3", + "@alfalab/core-components-global-store": "^2.1.0", + "@alfalab/core-components-portal": "^3.3.4", + "@alfalab/core-components-stack": "^5.0.1", + "@alfalab/core-components-shared": "^0.14.0", + "@juggle/resize-observer": "^3.3.1", + "classnames": "^2.5.1", + "react-focus-lock": "^2.12.1", + "react-merge-refs": "^1.1.0", + "react-transition-group": "^4.4.5", + "tslib": "^2.4.0" + }, + "devDependencies": { + "@types/react-transition-group": "^4.4.5" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.1 || ^18.0.0" + }, + "themesVersion": "13.6.0", + "varsVersion": "9.16.0" +} diff --git a/packages/base-modal/dist_side_poly/src/Component.tsx b/packages/base-modal/dist_side_poly/src/Component.tsx new file mode 100644 index 0000000000..bcd9d7e773 --- /dev/null +++ b/packages/base-modal/dist_side_poly/src/Component.tsx @@ -0,0 +1,654 @@ +/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */ +import React, { + ComponentType, + forwardRef, + KeyboardEvent, + MouseEvent, + MutableRefObject, + ReactNode, + Ref, + useCallback, + useEffect, + useMemo, + useRef, + useState, +} from 'react'; +import FocusLock from 'react-focus-lock'; +import mergeRefs from 'react-merge-refs'; +import { CSSTransition } from 'react-transition-group'; +import { TransitionProps } from 'react-transition-group/Transition'; +import { ResizeObserver as ResizeObserverPolyfill } from '@juggle/resize-observer'; +import cn from 'classnames'; + +import { Backdrop as DefaultBackdrop, BackdropProps } from '@alfalab/core-components-backdrop'; +import { Portal, PortalProps } from '@alfalab/core-components-portal'; +import { browser, os } from '@alfalab/core-components-shared'; +import { Stack } from '@alfalab/core-components-stack'; +import { stackingOrder } from '@alfalab/stack-context'; + +import { lockScroll, syncHeight, unlockScroll } from './helpers/lockScroll'; +import { + handleContainer, + hasScrollbar, + isScrolledToBottom, + isScrolledToTop, + restoreContainerStyles, +} from './utils'; + +import styles from './index.module.css'; + +// TODO Без полифила крашится FocusLock в IE11. Выпилить в будущем!!!. +import './matches-polyfill'; + +export type BaseModalProps = { + /** + * Контент + */ + children?: ReactNode; + + /** + * Компонент бэкдропа + */ + Backdrop?: ComponentType; + + /** + * Свойства для Бэкдропа + */ + backdropProps?: Partial & Record; + + /** + * Нода, компонент или функция возвращающая их + * + * Контейнер к которому будут добавляться порталы + */ + container?: PortalProps['getPortalContainer']; + + /** + * Отключает автоматический перевод фокуса на модалку при открытии + * @default false + */ + disableAutoFocus?: boolean; + + /** + * Отключает ловушку фокуса + * @default false + */ + disableFocusLock?: boolean; + + /** + * Отключает восстановление фокуса на предыдущем элементе после закрытия модалки + * @default false + */ + disableRestoreFocus?: boolean; + + /** + * Отключает вызов `callback` при нажатии Escape + * @default false + */ + disableEscapeKeyDown?: boolean; + + /** + * Отключает вызов `callback` при клике на бэкдроп + * @default false + */ + disableBackdropClick?: boolean; + + /** + * Отключает блокировку скролла при открытии модального окна + * @default false + */ + disableBlockingScroll?: boolean; + + /** + * Содержимое модалки всегда в DOM + * @default false + */ + keepMounted?: boolean; + + /** + * Управление видимостью модалки + */ + open: boolean; + + /** + * Дополнительный класс + */ + className?: string; + + /** + * Дополнительный класс + */ + contentClassName?: string; + + /** + * Дополнительные пропсы на dialog wrapper + */ + wrapperProps?: React.DetailedHTMLProps, HTMLDivElement>; + + /** + * Дополнительные пропсы на обертку контента + */ + contentProps?: React.DetailedHTMLProps, HTMLDivElement>; + + /** + * Дополнительные пропсы на компонентную обертку контента + */ + componentDivProps?: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLDivElement + >; + + /** + * Дополнительный класс для обертки (Modal) + */ + wrapperClassName?: string; + + /** + * Обработчик скролла контента + */ + scrollHandler?: 'wrapper' | 'content' | MutableRefObject; + + /** + * Пропсы для анимации (CSSTransition) + */ + transitionProps?: Partial; + + /** + * Рендерить ли в контейнер через портал. + * @default true + */ + usePortal?: boolean; + + /** + * Обработчик события нажатия на бэкдроп + */ + onBackdropClick?: (event: MouseEvent) => void; + + /** + * Обработчик события нажатия на Escape + * + * Если `disableEscapeKeyDown` - false и модальное окно в фокусе + */ + onEscapeKeyDown?: (event: KeyboardEvent) => void; + + /** + * Обработчик закрытия + */ + onClose?: ( + event: MouseEvent | KeyboardEvent, + reason?: 'backdropClick' | 'escapeKeyDown' | 'closerClick', + ) => void; + + /** + * Обработчик события onEntered компонента Transition + */ + onMount?: () => void; + + /** + * Обработчик события onExited компонента Transition + */ + onUnmount?: () => void; + + /** + * Идентификатор для систем автоматизированного тестирования + */ + dataTestId?: string; + + /** + * z-index компонента + */ + zIndex?: number; + + /** + * Реф, который должен быть установлен компонентной области + */ + componentRef?: MutableRefObject; + + /** + * Блокирует скролл когда модальное окно открыто. Работает только на iOS. + */ + iOSLock?: boolean; +}; + +export type BaseModalContext = { + parentRef: React.RefObject; + componentRef: React.RefObject; + hasFooter?: boolean; + hasHeader?: boolean; + hasScroll?: boolean; + headerHighlighted?: boolean; + footerHighlighted?: boolean; + headerOffset?: number; + setHeaderOffset: (offset: number) => void; + contentRef: Ref; + setHasHeader: (exists: boolean) => void; + setHasFooter: (exists: boolean) => void; + onClose: Required['onClose']; +}; + +// eslint-disable-next-line @typescript-eslint/no-redeclare +export const BaseModalContext = React.createContext({ + parentRef: { current: null }, + componentRef: { current: null }, + hasFooter: false, + hasHeader: false, + hasScroll: false, + headerHighlighted: false, + footerHighlighted: false, + headerOffset: 0, + setHeaderOffset: () => null, + contentRef: () => null, + setHasHeader: () => null, + setHasFooter: () => null, + onClose: () => null, +}); + +export const BaseModal = forwardRef( + ( + { + open, + container, + children, + scrollHandler = 'wrapper', + Backdrop = DefaultBackdrop, + backdropProps = {}, + transitionProps = {}, + disableBackdropClick, + disableAutoFocus = false, + disableFocusLock = false, + disableEscapeKeyDown = false, + disableRestoreFocus = false, + disableBlockingScroll = false, + keepMounted = false, + className, + contentClassName, + wrapperProps, + contentProps, + componentDivProps, + wrapperClassName, + onBackdropClick, + onClose, + onEscapeKeyDown, + onMount, + onUnmount, + dataTestId, + zIndex = stackingOrder.MODAL, + componentRef = null, + usePortal = true, + iOSLock = false, + }, + ref, + ) => { + const [exited, setExited] = useState(null); + const [hasScroll, setHasScroll] = useState(false); + const [hasHeader, setHasHeader] = useState(false); + const [hasFooter, setHasFooter] = useState(false); + const [headerHighlighted, setHeaderHighlighted] = useState(false); + const [footerHighlighted, setFooterHighlighted] = useState(false); + const [headerOffset, setHeaderOffset] = useState(0); + + const componentNodeRef = useRef(null); + const wrapperRef = useRef(null); + const scrollableNodeRef = useRef(null); + const contentNodeRef = useRef(null); + const restoreContainerStylesRef = useRef void)>(null); + const mouseDownTarget = useRef(); + const resizeObserverRef = useRef(); + + const checkToHasScrollBar = () => { + if (scrollableNodeRef.current) { + const scrollExists = hasScrollbar(scrollableNodeRef.current); + + setFooterHighlighted(scrollExists); + setHasScroll(scrollExists); + } + }; + + const isExited = exited || exited === null; + const shouldRender = keepMounted || open || !isExited; + + const getContainer = useCallback( + () => (container ? container() : document.body) as HTMLElement, + [container], + ); + + const addResizeHandle = useCallback(() => { + if (!resizeObserverRef.current) return; + + if (scrollableNodeRef.current) { + resizeObserverRef.current.observe(scrollableNodeRef.current); + } + if (contentNodeRef.current) { + resizeObserverRef.current.observe(contentNodeRef.current); + } + }, []); + + const removeResizeHandle = useCallback(() => resizeObserverRef.current?.disconnect(), []); + + const contentRef = useCallback((node: HTMLDivElement) => { + if (node !== null) { + contentNodeRef.current = node; + if (resizeObserverRef.current) { + resizeObserverRef.current.observe(node); + } + checkToHasScrollBar(); + } + }, []); + + const handleScroll = useCallback(() => { + if (!scrollableNodeRef.current || !componentNodeRef.current) return; + + if (hasHeader) { + setHeaderHighlighted( + !isScrolledToTop(scrollableNodeRef.current) && + componentNodeRef.current.getBoundingClientRect().top - headerOffset <= 1, + ); + } + + if (hasFooter) { + setFooterHighlighted( + !isScrolledToBottom(scrollableNodeRef.current) && + componentNodeRef.current.getBoundingClientRect().bottom >= + window.innerHeight - 1, + ); + } + }, [hasFooter, hasHeader, headerOffset]); + + const handleClose = useCallback['onClose']>( + (event, reason) => { + if (iOSLock && os.isIOS()) { + unlockScroll(); + } + + if (onClose) { + onClose(event, reason); + } + + if (reason === 'backdropClick' && onBackdropClick) { + onBackdropClick(event as MouseEvent); + } + + if (reason === 'escapeKeyDown' && onEscapeKeyDown) { + onEscapeKeyDown(event as KeyboardEvent); + } + + return null; + }, + [onBackdropClick, onClose, onEscapeKeyDown, iOSLock], + ); + + const handleBackdropMouseDown = (event: MouseEvent) => { + let clickedOnScrollbar = false; + const clientWidth = (event.target as HTMLElement)?.clientWidth; + + if (event.clientX && clientWidth) { + // Устанавливаем смещение для абсолютно спозиционированного скроллбара в OSX в 17px. + const offset = browser.getScrollbarSize() === 0 ? 17 : 0; + + clickedOnScrollbar = event.clientX + offset > clientWidth; + } + + if (!disableBackdropClick && !clickedOnScrollbar) { + mouseDownTarget.current = event.target as HTMLElement; + } + }; + + const handleBackdropMouseUp = (event: MouseEvent) => { + if ( + !disableBackdropClick && + event.target === wrapperRef.current && + mouseDownTarget.current === wrapperRef.current + ) { + handleClose(event, 'backdropClick'); + } + + mouseDownTarget.current = undefined; + }; + + const handleKeyDown = useCallback( + (event: KeyboardEvent) => { + /* + * Чтобы сохранить дефолтное поведение элементов и событий форм, + * обработчик не устанавливает event.preventDefault() + */ + if (event.key !== 'Escape') { + return; + } + + // Если есть обработчик escape на body + event.stopPropagation(); + + if (!disableEscapeKeyDown && handleClose) { + handleClose(event, 'escapeKeyDown'); + } + }, + [disableEscapeKeyDown, handleClose], + ); + + const getScrollHandler = useCallback(() => { + if (scrollHandler === 'wrapper') return wrapperRef.current; + if (scrollHandler === 'content') return componentNodeRef.current; + + return scrollHandler.current || wrapperRef.current; + }, [scrollHandler]); + + const handleEntered: Required['onEntered'] = useCallback( + (node, isAppearing) => { + scrollableNodeRef.current = getScrollHandler(); + + addResizeHandle(); + + if (scrollableNodeRef.current) { + scrollableNodeRef.current.addEventListener('scroll', handleScroll); + handleScroll(); + } + + if (transitionProps.onEntered) { + transitionProps.onEntered(node, isAppearing); + } + + if (onMount) onMount(); + }, + [addResizeHandle, getScrollHandler, handleScroll, onMount, transitionProps], + ); + + const handleExited: Required['onExited'] = useCallback( + (node) => { + removeResizeHandle(); + + setExited(true); + + if (scrollableNodeRef.current) { + scrollableNodeRef.current.removeEventListener('scroll', handleScroll); + } + + if (transitionProps.onExited) { + transitionProps.onExited(node); + } + + if (onUnmount) onUnmount(); + + if (restoreContainerStylesRef.current) { + restoreContainerStylesRef.current(); + } + }, + [handleScroll, onUnmount, removeResizeHandle, transitionProps], + ); + + useEffect(() => { + if (open && isExited) { + if (!disableBlockingScroll) { + const el = getContainer(); + + const shouldIOSLock = iOSLock && os.isIOS(); + + handleContainer(el, shouldIOSLock); + if (shouldIOSLock) { + syncHeight(); + lockScroll(); + } + + restoreContainerStylesRef.current = () => { + restoreContainerStylesRef.current = null; + restoreContainerStyles(el); + }; + } + + setExited(false); + } + + if (!open) { + unlockScroll(); + } + }, [getContainer, open, disableBlockingScroll, isExited, iOSLock]); + + useEffect(() => { + const ResizeObserver = window.ResizeObserver || ResizeObserverPolyfill; + + resizeObserverRef.current = new ResizeObserver(checkToHasScrollBar); + + return () => { + if (restoreContainerStylesRef.current) { + restoreContainerStylesRef.current(); + } + + if (resizeObserverRef.current) { + resizeObserverRef.current.disconnect(); + } + }; + }, []); + + useEffect(() => { + if (disableAutoFocus || !open) return; + + wrapperRef.current?.focus(); + }, [open, disableAutoFocus]); + + const contextValue = useMemo( + () => ({ + parentRef: wrapperRef, + componentRef: componentNodeRef, + hasHeader, + hasFooter, + hasScroll, + headerHighlighted, + footerHighlighted, + headerOffset, + setHeaderOffset, + contentRef, + setHasHeader, + setHasFooter, + onClose: handleClose, + }), + [ + contentRef, + hasHeader, + hasFooter, + hasScroll, + headerHighlighted, + footerHighlighted, + headerOffset, + setHeaderOffset, + handleClose, + ], + ); + + const renderContent = () => ( + + {(computedZIndex) => ( + + + {Backdrop && ( + + )} +
, + ])} + onKeyDown={handleKeyDown} + onMouseDown={handleBackdropMouseDown} + onMouseUp={handleBackdropMouseUp} + tabIndex={-1} + data-test-id={dataTestId} + style={{ + zIndex: computedZIndex, + }} + > + +
+
+ {children} +
+
+
+
+
+
+ )} +
+ ); + + if (!shouldRender) return null; + + return usePortal ? ( + + {renderContent()} + + ) : ( + renderContent() + ); + }, +); + +BaseModal.displayName = 'BaseModal'; +BaseModalContext.displayName = 'BaseModalContext'; diff --git a/packages/base-modal/dist_side_poly/src/helpers/lockScroll.ts b/packages/base-modal/dist_side_poly/src/helpers/lockScroll.ts new file mode 100644 index 0000000000..f2aedc0e6e --- /dev/null +++ b/packages/base-modal/dist_side_poly/src/helpers/lockScroll.ts @@ -0,0 +1,24 @@ +/** + * Хелпер для блокирования скроллинга в iOS + * В проекте используется overflow: hidden для блокировки, но в некоторых случаях этого недостаточно. Данный хелпер призван решать эту проблему + */ + +let scrollY: number; + +export const isScrollLocked = () => document.body.classList.contains('is-locked'); + +export const lockScroll = () => { + scrollY = window.scrollY; + document.body.classList.add('is-locked'); +}; + +export const unlockScroll = () => { + if (!isScrollLocked()) return; + + document.body.classList.remove('is-locked'); + window.scrollTo(0, scrollY); +}; + +export const syncHeight = () => { + document.body.style.setProperty('--window-inner-scrollY', `${window.scrollY}px`); +}; diff --git a/packages/base-modal/dist_side_poly/src/index.module.css b/packages/base-modal/dist_side_poly/src/index.module.css new file mode 100644 index 0000000000..4aa602362c --- /dev/null +++ b/packages/base-modal/dist_side_poly/src/index.module.css @@ -0,0 +1,71 @@ +@import '@alfalab/core-components-vars/src/index.css'; + +:root { + --window-inner-scrollY: 10px; /* fallback value to prevent ci error */ +} + +body:global(.is-locked) { + margin-top: calc(var(--window-inner-scrollY) * -1); + position: fixed; + overflow: hidden; +} + +.component { + position: relative; + box-sizing: border-box; + background: var(--color-light-modal-bg-primary); + margin: auto; + flex-shrink: 0; +} + +.wrapper { + position: fixed; + top: var(--gap-0); + left: var(--gap-0); + right: var(--gap-0); + bottom: var(--gap-0); + + overflow: auto; + display: flex; + flex-direction: column; + align-items: center; + outline: 0; + overscroll-behavior: none; +} + +.content { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + flex: 1; +} + +.hidden { + display: none; +} + +.backdrop { + z-index: 0; +} + +.appear, +.enter { + opacity: 0; +} + +.appearActive, +.enterActive { + opacity: 1; + transition: opacity 200ms ease-in; +} + +.exit { + opacity: 1; +} + +.exitActive, +.exitDone { + opacity: 0; + transition: opacity 200ms ease-out; +} diff --git a/packages/base-modal/dist_side_poly/src/index.ts b/packages/base-modal/dist_side_poly/src/index.ts new file mode 100644 index 0000000000..b48bf6698e --- /dev/null +++ b/packages/base-modal/dist_side_poly/src/index.ts @@ -0,0 +1,3 @@ +export * from './Component'; +export * from './utils'; +export * from './helpers/lockScroll'; diff --git a/packages/base-modal/dist_side_poly/src/matches-polyfill.ts b/packages/base-modal/dist_side_poly/src/matches-polyfill.ts new file mode 100644 index 0000000000..a0c7e8a9f4 --- /dev/null +++ b/packages/base-modal/dist_side_poly/src/matches-polyfill.ts @@ -0,0 +1,19 @@ +/* eslint-disable */ +// @ts-nocheck + +if (typeof window !== 'undefined') { + if (Element && !Element.prototype.matches) { + Element.prototype.matches = + Element.prototype.matchesSelector || + Element.prototype.mozMatchesSelector || + Element.prototype.msMatchesSelector || + Element.prototype.oMatchesSelector || + Element.prototype.webkitMatchesSelector || + function (s) { + const matches = (this.document || this.ownerDocument).querySelectorAll(s); + let i = matches.length; + while (--i >= 0 && matches.item(i) !== this) {} + return i > -1; + }; + } +} diff --git a/packages/base-modal/dist_side_poly/src/utils.ts b/packages/base-modal/dist_side_poly/src/utils.ts new file mode 100644 index 0000000000..0958516019 --- /dev/null +++ b/packages/base-modal/dist_side_poly/src/utils.ts @@ -0,0 +1,106 @@ +import { getModalStore, SavedStyle } from '@alfalab/core-components-global-store'; +import { browser } from '@alfalab/core-components-shared'; + +export function isScrolledToTop(target: HTMLElement) { + return target.scrollTop <= 0; +} + +export function isScrolledToBottom(target: HTMLElement) { + return target.scrollHeight - target.offsetHeight <= target.scrollTop; +} + +export function hasScrollbar(target: HTMLElement) { + return target.scrollHeight > target.clientHeight; +} + +const isOverflowing = (container: Element) => { + if (document.body === container) { + return window.innerWidth > document.documentElement.clientWidth; + } + + return container.scrollHeight > container.clientHeight; +}; + +const getPaddingRight = (node: Element) => + parseInt(window.getComputedStyle(node).paddingRight, 10) || 0; + +export const restoreContainerStyles = (container: HTMLElement) => { + const modalRestoreStyles = getModalStore().getRestoreStyles(); + + const index = modalRestoreStyles.findIndex((s) => s.container === container); + const existingStyles = modalRestoreStyles[index]; + + if (!existingStyles) return; + + existingStyles.modals -= 1; + + if (existingStyles.modals <= 0) { + modalRestoreStyles.splice(index, 1); + + existingStyles.styles.forEach(({ value, el, key }) => { + if (value) { + el.style.setProperty(key, value); + } else { + el.style.removeProperty(key); + } + }); + } +}; + +export const handleContainer = (container?: HTMLElement, shouldIOSLock = false) => { + if (!container) return; + + const modalRestoreStyles = getModalStore().getRestoreStyles(); + + const existingStyles = modalRestoreStyles.find((s) => s.container === container); + + if (existingStyles) { + existingStyles.modals += 1; + + return; + } + + const containerStyles: SavedStyle[] = []; + + if (isOverflowing(container)) { + // Вычисляет размер до применения `overflow hidden` для избежания скачков + const scrollbarSize = browser.getScrollbarSize(); + + containerStyles.push({ + value: container.style.paddingRight, + key: 'padding-right', + el: container, + }); + // Вычисляем стили, чтобы получить реальный `padding` c шириной сколлбара + // eslint-disable-next-line no-param-reassign + container.style.paddingRight = `${getPaddingRight(container) + scrollbarSize}px`; + } + + const parent = container.parentElement; + const scrollContainer = + // TODO: заменить на optional chaining + parent && + parent.nodeName === 'HTML' && + window.getComputedStyle(parent).overflowY === 'scroll' + ? parent + : container; + + // Блокируем скролл даже если отсутствует скроллбар + if (scrollContainer.style.overflow !== 'hidden') { + containerStyles.push({ + value: scrollContainer.style.overflow, + key: 'overflow', + el: scrollContainer, + }); + } + + if (!shouldIOSLock) { + scrollContainer.style.overflow = 'hidden'; + } + + modalRestoreStyles.push({ + container, + modals: 1, + styles: containerStyles, + }); +}; diff --git a/packages/base-modal/dist_side_poly/utils.d.ts b/packages/base-modal/dist_side_poly/utils.d.ts new file mode 100644 index 0000000000..75401779bb --- /dev/null +++ b/packages/base-modal/dist_side_poly/utils.d.ts @@ -0,0 +1,6 @@ +declare function isScrolledToTop(target: HTMLElement): boolean; +declare function isScrolledToBottom(target: HTMLElement): boolean; +declare function hasScrollbar(target: HTMLElement): boolean; +declare const restoreContainerStyles: (container: HTMLElement) => void; +declare const handleContainer: (container?: HTMLElement, shouldIOSLock?: boolean) => void; +export { isScrolledToTop, isScrolledToBottom, hasScrollbar, restoreContainerStyles, handleContainer }; diff --git a/packages/base-modal/dist_side_poly/utils.js b/packages/base-modal/dist_side_poly/utils.js new file mode 100644 index 0000000000..02953e4ae2 --- /dev/null +++ b/packages/base-modal/dist_side_poly/utils.js @@ -0,0 +1,99 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +var coreComponentsGlobalStore = require('@alfalab/core-components-global-store'); +var coreComponentsShared = require('@alfalab/core-components-shared'); + +function isScrolledToTop(target) { + return target.scrollTop <= 0; +} +function isScrolledToBottom(target) { + return target.scrollHeight - target.offsetHeight <= target.scrollTop; +} +function hasScrollbar(target) { + return target.scrollHeight > target.clientHeight; +} +var isOverflowing = function (container) { + if (document.body === container) { + return window.innerWidth > document.documentElement.clientWidth; + } + return container.scrollHeight > container.clientHeight; +}; +var getPaddingRight = function (node) { + return parseInt(window.getComputedStyle(node).paddingRight, 10) || 0; +}; +var restoreContainerStyles = function (container) { + var modalRestoreStyles = coreComponentsGlobalStore.getModalStore().getRestoreStyles(); + var index = modalRestoreStyles.findIndex(function (s) { return s.container === container; }); + var existingStyles = modalRestoreStyles[index]; + if (!existingStyles) + return; + existingStyles.modals -= 1; + if (existingStyles.modals <= 0) { + modalRestoreStyles.splice(index, 1); + existingStyles.styles.forEach(function (_a) { + var value = _a.value, el = _a.el, key = _a.key; + if (value) { + el.style.setProperty(key, value); + } + else { + el.style.removeProperty(key); + } + }); + } +}; +var handleContainer = function (container, shouldIOSLock) { + if (shouldIOSLock === void 0) { shouldIOSLock = false; } + if (!container) + return; + var modalRestoreStyles = coreComponentsGlobalStore.getModalStore().getRestoreStyles(); + var existingStyles = modalRestoreStyles.find(function (s) { return s.container === container; }); + if (existingStyles) { + existingStyles.modals += 1; + return; + } + var containerStyles = []; + if (isOverflowing(container)) { + // Вычисляет размер до применения `overflow hidden` для избежания скачков + var scrollbarSize = coreComponentsShared.browser.getScrollbarSize(); + containerStyles.push({ + value: container.style.paddingRight, + key: 'padding-right', + el: container, + }); + // Вычисляем стили, чтобы получить реальный `padding` c шириной сколлбара + // eslint-disable-next-line no-param-reassign + container.style.paddingRight = "".concat(getPaddingRight(container) + scrollbarSize, "px"); + } + var parent = container.parentElement; + var scrollContainer = + // TODO: заменить на optional chaining + parent && + parent.nodeName === 'HTML' && + window.getComputedStyle(parent).overflowY === 'scroll' + ? parent + : container; + // Блокируем скролл даже если отсутствует скроллбар + if (scrollContainer.style.overflow !== 'hidden') { + containerStyles.push({ + value: scrollContainer.style.overflow, + key: 'overflow', + el: scrollContainer, + }); + } + if (!shouldIOSLock) { + scrollContainer.style.overflow = 'hidden'; + } + modalRestoreStyles.push({ + container: container, + modals: 1, + styles: containerStyles, + }); +}; + +exports.handleContainer = handleContainer; +exports.hasScrollbar = hasScrollbar; +exports.isScrolledToBottom = isScrolledToBottom; +exports.isScrolledToTop = isScrolledToTop; +exports.restoreContainerStyles = restoreContainerStyles; diff --git a/packages/base-modal/package.json b/packages/base-modal/package.json index 634e2e12d3..b1c6d7c9bf 100644 --- a/packages/base-modal/package.json +++ b/packages/base-modal/package.json @@ -10,9 +10,7 @@ "access": "public", "directory": "dist" }, - "sideEffects": [ - "matches-polyfill.*" - ], + "sideEffects": false, "dependencies": { "@alfalab/core-components-backdrop": "^3.4.3", "@alfalab/core-components-global-store": "^2.1.0", diff --git a/packages/form-control/package.json b/packages/form-control/package.json index 0f8c289b7a..14de9999fd 100644 --- a/packages/form-control/package.json +++ b/packages/form-control/package.json @@ -10,7 +10,6 @@ "access": "public", "directory": "dist" }, - "sideEffects": false, "peerDependencies": { "react": "^16.9.0 || ^17.0.1 || ^18.0.0", "react-dom": "^16.9.0 || ^17.0.1 || ^18.0.0" diff --git a/packages/gap/package.json b/packages/gap/package.json index 19939751a9..0c9804f8e5 100644 --- a/packages/gap/package.json +++ b/packages/gap/package.json @@ -10,7 +10,6 @@ "access": "public", "directory": "dist" }, - "sideEffects": false, "peerDependencies": { "react": "^16.9.0 || ^17.0.1 || ^18.0.0" }, From e59f3d81a31aeeb7f31c611d090be16055cb18ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Denis=20=F0=9F=8E=83=20Khripkov?= Date: Fri, 20 Dec 2024 00:21:47 +0300 Subject: [PATCH 4/6] fix: rm; --- .../base-modal/dist_side_poly/Component.d.ts | 159 ----- .../base-modal/dist_side_poly/Component.js | 287 -------- .../dist_side_poly/cssm/Component.d.ts | 159 ----- .../dist_side_poly/cssm/Component.js | 286 -------- .../cssm/helpers/lockScroll.d.ts | 5 - .../dist_side_poly/cssm/helpers/lockScroll.js | 28 - .../base-modal/dist_side_poly/cssm/index.d.ts | 3 - .../base-modal/dist_side_poly/cssm/index.js | 21 - .../dist_side_poly/cssm/index.module.css | 70 -- .../dist_side_poly/cssm/matches-polyfill.d.ts | 1 - .../dist_side_poly/cssm/matches-polyfill.js | 20 - .../base-modal/dist_side_poly/cssm/utils.d.ts | 6 - .../base-modal/dist_side_poly/cssm/utils.js | 99 --- .../dist_side_poly/esm/Component.d.ts | 159 ----- .../dist_side_poly/esm/Component.js | 275 -------- .../esm/helpers/lockScroll.d.ts | 5 - .../dist_side_poly/esm/helpers/lockScroll.js | 21 - .../base-modal/dist_side_poly/esm/index.css | 71 -- .../base-modal/dist_side_poly/esm/index.d.ts | 3 - .../base-modal/dist_side_poly/esm/index.js | 3 - .../dist_side_poly/esm/matches-polyfill.d.ts | 1 - .../dist_side_poly/esm/matches-polyfill.js | 18 - .../base-modal/dist_side_poly/esm/utils.d.ts | 6 - .../base-modal/dist_side_poly/esm/utils.js | 91 --- .../dist_side_poly/helpers/lockScroll.d.ts | 5 - .../dist_side_poly/helpers/lockScroll.js | 28 - packages/base-modal/dist_side_poly/index.css | 71 -- packages/base-modal/dist_side_poly/index.d.ts | 3 - packages/base-modal/dist_side_poly/index.js | 21 - .../dist_side_poly/matches-polyfill.d.ts | 1 - .../dist_side_poly/matches-polyfill.js | 20 - .../dist_side_poly/modern/Component.d.ts | 159 ----- .../dist_side_poly/modern/Component.js | 269 ------- .../modern/helpers/lockScroll.d.ts | 5 - .../modern/helpers/lockScroll.js | 21 - .../dist_side_poly/modern/index.css | 71 -- .../dist_side_poly/modern/index.d.ts | 3 - .../base-modal/dist_side_poly/modern/index.js | 3 - .../modern/matches-polyfill.d.ts | 1 - .../dist_side_poly/modern/matches-polyfill.js | 18 - .../dist_side_poly/modern/utils.d.ts | 6 - .../base-modal/dist_side_poly/modern/utils.js | 87 --- .../dist_side_poly/moderncssm/Component.d.ts | 159 ----- .../dist_side_poly/moderncssm/Component.js | 267 ------- .../moderncssm/helpers/lockScroll.d.ts | 5 - .../moderncssm/helpers/lockScroll.js | 21 - .../dist_side_poly/moderncssm/index.d.ts | 3 - .../dist_side_poly/moderncssm/index.js | 3 - .../moderncssm/index.module.css | 71 -- .../moderncssm/matches-polyfill.d.ts | 1 - .../moderncssm/matches-polyfill.js | 18 - .../dist_side_poly/moderncssm/utils.d.ts | 6 - .../dist_side_poly/moderncssm/utils.js | 87 --- .../base-modal/dist_side_poly/package.json | 37 - .../dist_side_poly/src/Component.tsx | 654 ------------------ .../dist_side_poly/src/helpers/lockScroll.ts | 24 - .../dist_side_poly/src/index.module.css | 71 -- .../base-modal/dist_side_poly/src/index.ts | 3 - .../dist_side_poly/src/matches-polyfill.ts | 19 - .../base-modal/dist_side_poly/src/utils.ts | 106 --- packages/base-modal/dist_side_poly/utils.d.ts | 6 - packages/base-modal/dist_side_poly/utils.js | 99 --- 62 files changed, 4249 deletions(-) delete mode 100644 packages/base-modal/dist_side_poly/Component.d.ts delete mode 100644 packages/base-modal/dist_side_poly/Component.js delete mode 100644 packages/base-modal/dist_side_poly/cssm/Component.d.ts delete mode 100644 packages/base-modal/dist_side_poly/cssm/Component.js delete mode 100644 packages/base-modal/dist_side_poly/cssm/helpers/lockScroll.d.ts delete mode 100644 packages/base-modal/dist_side_poly/cssm/helpers/lockScroll.js delete mode 100644 packages/base-modal/dist_side_poly/cssm/index.d.ts delete mode 100644 packages/base-modal/dist_side_poly/cssm/index.js delete mode 100644 packages/base-modal/dist_side_poly/cssm/index.module.css delete mode 100644 packages/base-modal/dist_side_poly/cssm/matches-polyfill.d.ts delete mode 100644 packages/base-modal/dist_side_poly/cssm/matches-polyfill.js delete mode 100644 packages/base-modal/dist_side_poly/cssm/utils.d.ts delete mode 100644 packages/base-modal/dist_side_poly/cssm/utils.js delete mode 100644 packages/base-modal/dist_side_poly/esm/Component.d.ts delete mode 100644 packages/base-modal/dist_side_poly/esm/Component.js delete mode 100644 packages/base-modal/dist_side_poly/esm/helpers/lockScroll.d.ts delete mode 100644 packages/base-modal/dist_side_poly/esm/helpers/lockScroll.js delete mode 100644 packages/base-modal/dist_side_poly/esm/index.css delete mode 100644 packages/base-modal/dist_side_poly/esm/index.d.ts delete mode 100644 packages/base-modal/dist_side_poly/esm/index.js delete mode 100644 packages/base-modal/dist_side_poly/esm/matches-polyfill.d.ts delete mode 100644 packages/base-modal/dist_side_poly/esm/matches-polyfill.js delete mode 100644 packages/base-modal/dist_side_poly/esm/utils.d.ts delete mode 100644 packages/base-modal/dist_side_poly/esm/utils.js delete mode 100644 packages/base-modal/dist_side_poly/helpers/lockScroll.d.ts delete mode 100644 packages/base-modal/dist_side_poly/helpers/lockScroll.js delete mode 100644 packages/base-modal/dist_side_poly/index.css delete mode 100644 packages/base-modal/dist_side_poly/index.d.ts delete mode 100644 packages/base-modal/dist_side_poly/index.js delete mode 100644 packages/base-modal/dist_side_poly/matches-polyfill.d.ts delete mode 100644 packages/base-modal/dist_side_poly/matches-polyfill.js delete mode 100644 packages/base-modal/dist_side_poly/modern/Component.d.ts delete mode 100644 packages/base-modal/dist_side_poly/modern/Component.js delete mode 100644 packages/base-modal/dist_side_poly/modern/helpers/lockScroll.d.ts delete mode 100644 packages/base-modal/dist_side_poly/modern/helpers/lockScroll.js delete mode 100644 packages/base-modal/dist_side_poly/modern/index.css delete mode 100644 packages/base-modal/dist_side_poly/modern/index.d.ts delete mode 100644 packages/base-modal/dist_side_poly/modern/index.js delete mode 100644 packages/base-modal/dist_side_poly/modern/matches-polyfill.d.ts delete mode 100644 packages/base-modal/dist_side_poly/modern/matches-polyfill.js delete mode 100644 packages/base-modal/dist_side_poly/modern/utils.d.ts delete mode 100644 packages/base-modal/dist_side_poly/modern/utils.js delete mode 100644 packages/base-modal/dist_side_poly/moderncssm/Component.d.ts delete mode 100644 packages/base-modal/dist_side_poly/moderncssm/Component.js delete mode 100644 packages/base-modal/dist_side_poly/moderncssm/helpers/lockScroll.d.ts delete mode 100644 packages/base-modal/dist_side_poly/moderncssm/helpers/lockScroll.js delete mode 100644 packages/base-modal/dist_side_poly/moderncssm/index.d.ts delete mode 100644 packages/base-modal/dist_side_poly/moderncssm/index.js delete mode 100644 packages/base-modal/dist_side_poly/moderncssm/index.module.css delete mode 100644 packages/base-modal/dist_side_poly/moderncssm/matches-polyfill.d.ts delete mode 100644 packages/base-modal/dist_side_poly/moderncssm/matches-polyfill.js delete mode 100644 packages/base-modal/dist_side_poly/moderncssm/utils.d.ts delete mode 100644 packages/base-modal/dist_side_poly/moderncssm/utils.js delete mode 100644 packages/base-modal/dist_side_poly/package.json delete mode 100644 packages/base-modal/dist_side_poly/src/Component.tsx delete mode 100644 packages/base-modal/dist_side_poly/src/helpers/lockScroll.ts delete mode 100644 packages/base-modal/dist_side_poly/src/index.module.css delete mode 100644 packages/base-modal/dist_side_poly/src/index.ts delete mode 100644 packages/base-modal/dist_side_poly/src/matches-polyfill.ts delete mode 100644 packages/base-modal/dist_side_poly/src/utils.ts delete mode 100644 packages/base-modal/dist_side_poly/utils.d.ts delete mode 100644 packages/base-modal/dist_side_poly/utils.js diff --git a/packages/base-modal/dist_side_poly/Component.d.ts b/packages/base-modal/dist_side_poly/Component.d.ts deleted file mode 100644 index 44533e4e97..0000000000 --- a/packages/base-modal/dist_side_poly/Component.d.ts +++ /dev/null @@ -1,159 +0,0 @@ -/// -/// -import React from 'react'; -import { ComponentType, KeyboardEvent, MouseEvent, MutableRefObject, ReactNode, Ref } from "react"; -import { TransitionProps } from 'react-transition-group/Transition'; -import { BackdropProps } from "@alfalab/core-components-backdrop"; -import { PortalProps } from "@alfalab/core-components-portal"; -type BaseModalProps = { - /** - * Контент - */ - children?: ReactNode; - /** - * Компонент бэкдропа - */ - Backdrop?: ComponentType; - /** - * Свойства для Бэкдропа - */ - backdropProps?: Partial & Record; - /** - * Нода, компонент или функция возвращающая их - * - * Контейнер к которому будут добавляться порталы - */ - container?: PortalProps['getPortalContainer']; - /** - * Отключает автоматический перевод фокуса на модалку при открытии - * @default false - */ - disableAutoFocus?: boolean; - /** - * Отключает ловушку фокуса - * @default false - */ - disableFocusLock?: boolean; - /** - * Отключает восстановление фокуса на предыдущем элементе после закрытия модалки - * @default false - */ - disableRestoreFocus?: boolean; - /** - * Отключает вызов `callback` при нажатии Escape - * @default false - */ - disableEscapeKeyDown?: boolean; - /** - * Отключает вызов `callback` при клике на бэкдроп - * @default false - */ - disableBackdropClick?: boolean; - /** - * Отключает блокировку скролла при открытии модального окна - * @default false - */ - disableBlockingScroll?: boolean; - /** - * Содержимое модалки всегда в DOM - * @default false - */ - keepMounted?: boolean; - /** - * Управление видимостью модалки - */ - open: boolean; - /** - * Дополнительный класс - */ - className?: string; - /** - * Дополнительный класс - */ - contentClassName?: string; - /** - * Дополнительные пропсы на dialog wrapper - */ - wrapperProps?: React.DetailedHTMLProps, HTMLDivElement>; - /** - * Дополнительные пропсы на обертку контента - */ - contentProps?: React.DetailedHTMLProps, HTMLDivElement>; - /** - * Дополнительные пропсы на компонентную обертку контента - */ - componentDivProps?: React.DetailedHTMLProps, HTMLDivElement>; - /** - * Дополнительный класс для обертки (Modal) - */ - wrapperClassName?: string; - /** - * Обработчик скролла контента - */ - scrollHandler?: 'wrapper' | 'content' | MutableRefObject; - /** - * Пропсы для анимации (CSSTransition) - */ - transitionProps?: Partial; - /** - * Рендерить ли в контейнер через портал. - * @default true - */ - usePortal?: boolean; - /** - * Обработчик события нажатия на бэкдроп - */ - onBackdropClick?: (event: MouseEvent) => void; - /** - * Обработчик события нажатия на Escape - * - * Если `disableEscapeKeyDown` - false и модальное окно в фокусе - */ - onEscapeKeyDown?: (event: KeyboardEvent) => void; - /** - * Обработчик закрытия - */ - onClose?: (event: MouseEvent | KeyboardEvent, reason?: 'backdropClick' | 'escapeKeyDown' | 'closerClick') => void; - /** - * Обработчик события onEntered компонента Transition - */ - onMount?: () => void; - /** - * Обработчик события onExited компонента Transition - */ - onUnmount?: () => void; - /** - * Идентификатор для систем автоматизированного тестирования - */ - dataTestId?: string; - /** - * z-index компонента - */ - zIndex?: number; - /** - * Реф, который должен быть установлен компонентной области - */ - componentRef?: MutableRefObject; - /** - * Блокирует скролл когда модальное окно открыто. Работает только на iOS. - */ - iOSLock?: boolean; -}; -type BaseModalContext = { - parentRef: React.RefObject; - componentRef: React.RefObject; - hasFooter?: boolean; - hasHeader?: boolean; - hasScroll?: boolean; - headerHighlighted?: boolean; - footerHighlighted?: boolean; - headerOffset?: number; - setHeaderOffset: (offset: number) => void; - contentRef: Ref; - setHasHeader: (exists: boolean) => void; - setHasFooter: (exists: boolean) => void; - onClose: Required['onClose']; -}; -declare const BaseModalContext: React.Context; -declare const BaseModal: React.ForwardRefExoticComponent>; -export { BaseModalProps, BaseModalContext, BaseModal }; diff --git a/packages/base-modal/dist_side_poly/Component.js b/packages/base-modal/dist_side_poly/Component.js deleted file mode 100644 index 6f368d202f..0000000000 --- a/packages/base-modal/dist_side_poly/Component.js +++ /dev/null @@ -1,287 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, '__esModule', { value: true }); - -var tslib = require('tslib'); -var React = require('react'); -var FocusLock = require('react-focus-lock'); -var mergeRefs = require('react-merge-refs'); -var reactTransitionGroup = require('react-transition-group'); -var resizeObserver = require('@juggle/resize-observer'); -var cn = require('classnames'); -var coreComponentsBackdrop = require('@alfalab/core-components-backdrop'); -var coreComponentsPortal = require('@alfalab/core-components-portal'); -var coreComponentsShared = require('@alfalab/core-components-shared'); -var coreComponentsStack = require('@alfalab/core-components-stack'); -var stackContext = require('@alfalab/stack-context'); -var helpers_lockScroll = require('./helpers/lockScroll.js'); -var utils = require('./utils.js'); -require('./matches-polyfill.js'); - -function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; } - -var React__default = /*#__PURE__*/_interopDefaultCompat(React); -var FocusLock__default = /*#__PURE__*/_interopDefaultCompat(FocusLock); -var mergeRefs__default = /*#__PURE__*/_interopDefaultCompat(mergeRefs); -var cn__default = /*#__PURE__*/_interopDefaultCompat(cn); - -var styles = {"component":"base-modal__component_1y6m8","wrapper":"base-modal__wrapper_1y6m8","content":"base-modal__content_1y6m8","hidden":"base-modal__hidden_1y6m8","backdrop":"base-modal__backdrop_1y6m8","appear":"base-modal__appear_1y6m8","enter":"base-modal__enter_1y6m8","appearActive":"base-modal__appearActive_1y6m8","enterActive":"base-modal__enterActive_1y6m8","exit":"base-modal__exit_1y6m8","exitActive":"base-modal__exitActive_1y6m8","exitDone":"base-modal__exitDone_1y6m8"}; -require('./index.css') - -// eslint-disable-next-line @typescript-eslint/no-redeclare -var BaseModalContext = React__default.default.createContext({ - parentRef: { current: null }, - componentRef: { current: null }, - hasFooter: false, - hasHeader: false, - hasScroll: false, - headerHighlighted: false, - footerHighlighted: false, - headerOffset: 0, - setHeaderOffset: function () { return null; }, - contentRef: function () { return null; }, - setHasHeader: function () { return null; }, - setHasFooter: function () { return null; }, - onClose: function () { return null; }, -}); -var BaseModal = React.forwardRef(function (_a, ref) { - var open = _a.open, container = _a.container, children = _a.children, _b = _a.scrollHandler, scrollHandler = _b === void 0 ? 'wrapper' : _b, _c = _a.Backdrop, Backdrop = _c === void 0 ? coreComponentsBackdrop.Backdrop : _c, _d = _a.backdropProps, backdropProps = _d === void 0 ? {} : _d, _e = _a.transitionProps, transitionProps = _e === void 0 ? {} : _e, disableBackdropClick = _a.disableBackdropClick, _f = _a.disableAutoFocus, disableAutoFocus = _f === void 0 ? false : _f, _g = _a.disableFocusLock, disableFocusLock = _g === void 0 ? false : _g, _h = _a.disableEscapeKeyDown, disableEscapeKeyDown = _h === void 0 ? false : _h, _j = _a.disableRestoreFocus, disableRestoreFocus = _j === void 0 ? false : _j, _k = _a.disableBlockingScroll, disableBlockingScroll = _k === void 0 ? false : _k, _l = _a.keepMounted, keepMounted = _l === void 0 ? false : _l, className = _a.className, contentClassName = _a.contentClassName, wrapperProps = _a.wrapperProps, contentProps = _a.contentProps, componentDivProps = _a.componentDivProps, wrapperClassName = _a.wrapperClassName, onBackdropClick = _a.onBackdropClick, onClose = _a.onClose, onEscapeKeyDown = _a.onEscapeKeyDown, onMount = _a.onMount, onUnmount = _a.onUnmount, dataTestId = _a.dataTestId, _m = _a.zIndex, zIndex = _m === void 0 ? stackContext.stackingOrder.MODAL : _m, _o = _a.componentRef, componentRef = _o === void 0 ? null : _o, _p = _a.usePortal, usePortal = _p === void 0 ? true : _p, _q = _a.iOSLock, iOSLock = _q === void 0 ? false : _q; - var _r = React.useState(null), exited = _r[0], setExited = _r[1]; - var _s = React.useState(false), hasScroll = _s[0], setHasScroll = _s[1]; - var _t = React.useState(false), hasHeader = _t[0], setHasHeader = _t[1]; - var _u = React.useState(false), hasFooter = _u[0], setHasFooter = _u[1]; - var _v = React.useState(false), headerHighlighted = _v[0], setHeaderHighlighted = _v[1]; - var _w = React.useState(false), footerHighlighted = _w[0], setFooterHighlighted = _w[1]; - var _x = React.useState(0), headerOffset = _x[0], setHeaderOffset = _x[1]; - var componentNodeRef = React.useRef(null); - var wrapperRef = React.useRef(null); - var scrollableNodeRef = React.useRef(null); - var contentNodeRef = React.useRef(null); - var restoreContainerStylesRef = React.useRef(null); - var mouseDownTarget = React.useRef(); - var resizeObserverRef = React.useRef(); - var checkToHasScrollBar = function () { - if (scrollableNodeRef.current) { - var scrollExists = utils.hasScrollbar(scrollableNodeRef.current); - setFooterHighlighted(scrollExists); - setHasScroll(scrollExists); - } - }; - var isExited = exited || exited === null; - var shouldRender = keepMounted || open || !isExited; - var getContainer = React.useCallback(function () { return (container ? container() : document.body); }, [container]); - var addResizeHandle = React.useCallback(function () { - if (!resizeObserverRef.current) - return; - if (scrollableNodeRef.current) { - resizeObserverRef.current.observe(scrollableNodeRef.current); - } - if (contentNodeRef.current) { - resizeObserverRef.current.observe(contentNodeRef.current); - } - }, []); - var removeResizeHandle = React.useCallback(function () { var _a; return (_a = resizeObserverRef.current) === null || _a === void 0 ? void 0 : _a.disconnect(); }, []); - var contentRef = React.useCallback(function (node) { - if (node !== null) { - contentNodeRef.current = node; - if (resizeObserverRef.current) { - resizeObserverRef.current.observe(node); - } - checkToHasScrollBar(); - } - }, []); - var handleScroll = React.useCallback(function () { - if (!scrollableNodeRef.current || !componentNodeRef.current) - return; - if (hasHeader) { - setHeaderHighlighted(!utils.isScrolledToTop(scrollableNodeRef.current) && - componentNodeRef.current.getBoundingClientRect().top - headerOffset <= 1); - } - if (hasFooter) { - setFooterHighlighted(!utils.isScrolledToBottom(scrollableNodeRef.current) && - componentNodeRef.current.getBoundingClientRect().bottom >= - window.innerHeight - 1); - } - }, [hasFooter, hasHeader, headerOffset]); - var handleClose = React.useCallback(function (event, reason) { - if (iOSLock && coreComponentsShared.os.isIOS()) { - helpers_lockScroll.unlockScroll(); - } - if (onClose) { - onClose(event, reason); - } - if (reason === 'backdropClick' && onBackdropClick) { - onBackdropClick(event); - } - if (reason === 'escapeKeyDown' && onEscapeKeyDown) { - onEscapeKeyDown(event); - } - return null; - }, [onBackdropClick, onClose, onEscapeKeyDown, iOSLock]); - var handleBackdropMouseDown = function (event) { - var _a; - var clickedOnScrollbar = false; - var clientWidth = (_a = event.target) === null || _a === void 0 ? void 0 : _a.clientWidth; - if (event.clientX && clientWidth) { - // Устанавливаем смещение для абсолютно спозиционированного скроллбара в OSX в 17px. - var offset = coreComponentsShared.browser.getScrollbarSize() === 0 ? 17 : 0; - clickedOnScrollbar = event.clientX + offset > clientWidth; - } - if (!disableBackdropClick && !clickedOnScrollbar) { - mouseDownTarget.current = event.target; - } - }; - var handleBackdropMouseUp = function (event) { - if (!disableBackdropClick && - event.target === wrapperRef.current && - mouseDownTarget.current === wrapperRef.current) { - handleClose(event, 'backdropClick'); - } - mouseDownTarget.current = undefined; - }; - var handleKeyDown = React.useCallback(function (event) { - /* - * Чтобы сохранить дефолтное поведение элементов и событий форм, - * обработчик не устанавливает event.preventDefault() - */ - if (event.key !== 'Escape') { - return; - } - // Если есть обработчик escape на body - event.stopPropagation(); - if (!disableEscapeKeyDown && handleClose) { - handleClose(event, 'escapeKeyDown'); - } - }, [disableEscapeKeyDown, handleClose]); - var getScrollHandler = React.useCallback(function () { - if (scrollHandler === 'wrapper') - return wrapperRef.current; - if (scrollHandler === 'content') - return componentNodeRef.current; - return scrollHandler.current || wrapperRef.current; - }, [scrollHandler]); - var handleEntered = React.useCallback(function (node, isAppearing) { - scrollableNodeRef.current = getScrollHandler(); - addResizeHandle(); - if (scrollableNodeRef.current) { - scrollableNodeRef.current.addEventListener('scroll', handleScroll); - handleScroll(); - } - if (transitionProps.onEntered) { - transitionProps.onEntered(node, isAppearing); - } - if (onMount) - onMount(); - }, [addResizeHandle, getScrollHandler, handleScroll, onMount, transitionProps]); - var handleExited = React.useCallback(function (node) { - removeResizeHandle(); - setExited(true); - if (scrollableNodeRef.current) { - scrollableNodeRef.current.removeEventListener('scroll', handleScroll); - } - if (transitionProps.onExited) { - transitionProps.onExited(node); - } - if (onUnmount) - onUnmount(); - if (restoreContainerStylesRef.current) { - restoreContainerStylesRef.current(); - } - }, [handleScroll, onUnmount, removeResizeHandle, transitionProps]); - React.useEffect(function () { - if (open && isExited) { - if (!disableBlockingScroll) { - var el_1 = getContainer(); - var shouldIOSLock = iOSLock && coreComponentsShared.os.isIOS(); - utils.handleContainer(el_1, shouldIOSLock); - if (shouldIOSLock) { - helpers_lockScroll.syncHeight(); - helpers_lockScroll.lockScroll(); - } - restoreContainerStylesRef.current = function () { - restoreContainerStylesRef.current = null; - utils.restoreContainerStyles(el_1); - }; - } - setExited(false); - } - if (!open) { - helpers_lockScroll.unlockScroll(); - } - }, [getContainer, open, disableBlockingScroll, isExited, iOSLock]); - React.useEffect(function () { - var ResizeObserver = window.ResizeObserver || resizeObserver.ResizeObserver; - resizeObserverRef.current = new ResizeObserver(checkToHasScrollBar); - return function () { - if (restoreContainerStylesRef.current) { - restoreContainerStylesRef.current(); - } - if (resizeObserverRef.current) { - resizeObserverRef.current.disconnect(); - } - }; - }, []); - React.useEffect(function () { - var _a; - if (disableAutoFocus || !open) - return; - (_a = wrapperRef.current) === null || _a === void 0 ? void 0 : _a.focus(); - }, [open, disableAutoFocus]); - var contextValue = React.useMemo(function () { return ({ - parentRef: wrapperRef, - componentRef: componentNodeRef, - hasHeader: hasHeader, - hasFooter: hasFooter, - hasScroll: hasScroll, - headerHighlighted: headerHighlighted, - footerHighlighted: footerHighlighted, - headerOffset: headerOffset, - setHeaderOffset: setHeaderOffset, - contentRef: contentRef, - setHasHeader: setHasHeader, - setHasFooter: setHasFooter, - onClose: handleClose, - }); }, [ - contentRef, - hasHeader, - hasFooter, - hasScroll, - headerHighlighted, - footerHighlighted, - headerOffset, - setHeaderOffset, - handleClose, - ]); - var renderContent = function () { return (React__default.default.createElement(coreComponentsStack.Stack, { value: zIndex }, function (computedZIndex) { - var _a; - return (React__default.default.createElement(BaseModalContext.Provider, { value: contextValue }, - React__default.default.createElement(FocusLock__default.default, { disabled: disableFocusLock || !open, returnFocus: !disableRestoreFocus }, - Backdrop && (React__default.default.createElement(Backdrop, tslib.__assign({}, backdropProps, { className: cn__default.default(backdropProps.className, styles.backdrop), open: open, style: { - zIndex: computedZIndex, - } }))), - React__default.default.createElement("div", tslib.__assign({}, wrapperProps, { role: 'dialog', className: cn__default.default(styles.wrapper, wrapperClassName, wrapperProps === null || wrapperProps === void 0 ? void 0 : wrapperProps.className, (_a = {}, - _a[styles.hidden] = !open && isExited, - _a)), ref: mergeRefs__default.default([ - ref, - wrapperRef, - wrapperProps === null || wrapperProps === void 0 ? void 0 : wrapperProps.ref, - ]), onKeyDown: handleKeyDown, onMouseDown: handleBackdropMouseDown, onMouseUp: handleBackdropMouseUp, tabIndex: -1, "data-test-id": dataTestId, style: { - zIndex: computedZIndex, - } }), - React__default.default.createElement(reactTransitionGroup.CSSTransition, tslib.__assign({ appear: true, timeout: 200, classNames: styles, nodeRef: componentNodeRef }, transitionProps, { in: open, onEntered: handleEntered, onExited: handleExited }), - React__default.default.createElement("div", tslib.__assign({}, componentDivProps, { className: cn__default.default(styles.component, className, componentDivProps === null || componentDivProps === void 0 ? void 0 : componentDivProps.className), ref: mergeRefs__default.default([ - componentRef, - componentNodeRef, - (componentDivProps === null || componentDivProps === void 0 ? void 0 : componentDivProps.ref) || null, - ]) }), - React__default.default.createElement("div", tslib.__assign({}, contentProps, { className: cn__default.default(styles.content, contentClassName, contentProps === null || contentProps === void 0 ? void 0 : contentProps.className) }), children))))))); - })); }; - if (!shouldRender) - return null; - return usePortal ? (React__default.default.createElement(coreComponentsPortal.Portal, { getPortalContainer: container, immediateMount: true }, renderContent())) : (renderContent()); -}); -BaseModal.displayName = 'BaseModal'; -BaseModalContext.displayName = 'BaseModalContext'; - -exports.BaseModal = BaseModal; -exports.BaseModalContext = BaseModalContext; diff --git a/packages/base-modal/dist_side_poly/cssm/Component.d.ts b/packages/base-modal/dist_side_poly/cssm/Component.d.ts deleted file mode 100644 index 44533e4e97..0000000000 --- a/packages/base-modal/dist_side_poly/cssm/Component.d.ts +++ /dev/null @@ -1,159 +0,0 @@ -/// -/// -import React from 'react'; -import { ComponentType, KeyboardEvent, MouseEvent, MutableRefObject, ReactNode, Ref } from "react"; -import { TransitionProps } from 'react-transition-group/Transition'; -import { BackdropProps } from "@alfalab/core-components-backdrop"; -import { PortalProps } from "@alfalab/core-components-portal"; -type BaseModalProps = { - /** - * Контент - */ - children?: ReactNode; - /** - * Компонент бэкдропа - */ - Backdrop?: ComponentType; - /** - * Свойства для Бэкдропа - */ - backdropProps?: Partial & Record; - /** - * Нода, компонент или функция возвращающая их - * - * Контейнер к которому будут добавляться порталы - */ - container?: PortalProps['getPortalContainer']; - /** - * Отключает автоматический перевод фокуса на модалку при открытии - * @default false - */ - disableAutoFocus?: boolean; - /** - * Отключает ловушку фокуса - * @default false - */ - disableFocusLock?: boolean; - /** - * Отключает восстановление фокуса на предыдущем элементе после закрытия модалки - * @default false - */ - disableRestoreFocus?: boolean; - /** - * Отключает вызов `callback` при нажатии Escape - * @default false - */ - disableEscapeKeyDown?: boolean; - /** - * Отключает вызов `callback` при клике на бэкдроп - * @default false - */ - disableBackdropClick?: boolean; - /** - * Отключает блокировку скролла при открытии модального окна - * @default false - */ - disableBlockingScroll?: boolean; - /** - * Содержимое модалки всегда в DOM - * @default false - */ - keepMounted?: boolean; - /** - * Управление видимостью модалки - */ - open: boolean; - /** - * Дополнительный класс - */ - className?: string; - /** - * Дополнительный класс - */ - contentClassName?: string; - /** - * Дополнительные пропсы на dialog wrapper - */ - wrapperProps?: React.DetailedHTMLProps, HTMLDivElement>; - /** - * Дополнительные пропсы на обертку контента - */ - contentProps?: React.DetailedHTMLProps, HTMLDivElement>; - /** - * Дополнительные пропсы на компонентную обертку контента - */ - componentDivProps?: React.DetailedHTMLProps, HTMLDivElement>; - /** - * Дополнительный класс для обертки (Modal) - */ - wrapperClassName?: string; - /** - * Обработчик скролла контента - */ - scrollHandler?: 'wrapper' | 'content' | MutableRefObject; - /** - * Пропсы для анимации (CSSTransition) - */ - transitionProps?: Partial; - /** - * Рендерить ли в контейнер через портал. - * @default true - */ - usePortal?: boolean; - /** - * Обработчик события нажатия на бэкдроп - */ - onBackdropClick?: (event: MouseEvent) => void; - /** - * Обработчик события нажатия на Escape - * - * Если `disableEscapeKeyDown` - false и модальное окно в фокусе - */ - onEscapeKeyDown?: (event: KeyboardEvent) => void; - /** - * Обработчик закрытия - */ - onClose?: (event: MouseEvent | KeyboardEvent, reason?: 'backdropClick' | 'escapeKeyDown' | 'closerClick') => void; - /** - * Обработчик события onEntered компонента Transition - */ - onMount?: () => void; - /** - * Обработчик события onExited компонента Transition - */ - onUnmount?: () => void; - /** - * Идентификатор для систем автоматизированного тестирования - */ - dataTestId?: string; - /** - * z-index компонента - */ - zIndex?: number; - /** - * Реф, который должен быть установлен компонентной области - */ - componentRef?: MutableRefObject; - /** - * Блокирует скролл когда модальное окно открыто. Работает только на iOS. - */ - iOSLock?: boolean; -}; -type BaseModalContext = { - parentRef: React.RefObject; - componentRef: React.RefObject; - hasFooter?: boolean; - hasHeader?: boolean; - hasScroll?: boolean; - headerHighlighted?: boolean; - footerHighlighted?: boolean; - headerOffset?: number; - setHeaderOffset: (offset: number) => void; - contentRef: Ref; - setHasHeader: (exists: boolean) => void; - setHasFooter: (exists: boolean) => void; - onClose: Required['onClose']; -}; -declare const BaseModalContext: React.Context; -declare const BaseModal: React.ForwardRefExoticComponent>; -export { BaseModalProps, BaseModalContext, BaseModal }; diff --git a/packages/base-modal/dist_side_poly/cssm/Component.js b/packages/base-modal/dist_side_poly/cssm/Component.js deleted file mode 100644 index 924c025d3d..0000000000 --- a/packages/base-modal/dist_side_poly/cssm/Component.js +++ /dev/null @@ -1,286 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, '__esModule', { value: true }); - -var tslib = require('tslib'); -var React = require('react'); -var FocusLock = require('react-focus-lock'); -var mergeRefs = require('react-merge-refs'); -var reactTransitionGroup = require('react-transition-group'); -var resizeObserver = require('@juggle/resize-observer'); -var cn = require('classnames'); -var coreComponentsBackdrop = require('@alfalab/core-components-backdrop/cssm'); -var coreComponentsPortal = require('@alfalab/core-components-portal/cssm'); -var coreComponentsShared = require('@alfalab/core-components-shared/cssm'); -var coreComponentsStack = require('@alfalab/core-components-stack/cssm'); -var stackContext = require('@alfalab/stack-context'); -var helpers_lockScroll = require('./helpers/lockScroll.js'); -var utils = require('./utils.js'); -var styles = require('./index.module.css'); -require('./matches-polyfill.js'); - -function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; } - -var React__default = /*#__PURE__*/_interopDefaultCompat(React); -var FocusLock__default = /*#__PURE__*/_interopDefaultCompat(FocusLock); -var mergeRefs__default = /*#__PURE__*/_interopDefaultCompat(mergeRefs); -var cn__default = /*#__PURE__*/_interopDefaultCompat(cn); -var styles__default = /*#__PURE__*/_interopDefaultCompat(styles); - -// eslint-disable-next-line @typescript-eslint/no-redeclare -var BaseModalContext = React__default.default.createContext({ - parentRef: { current: null }, - componentRef: { current: null }, - hasFooter: false, - hasHeader: false, - hasScroll: false, - headerHighlighted: false, - footerHighlighted: false, - headerOffset: 0, - setHeaderOffset: function () { return null; }, - contentRef: function () { return null; }, - setHasHeader: function () { return null; }, - setHasFooter: function () { return null; }, - onClose: function () { return null; }, -}); -var BaseModal = React.forwardRef(function (_a, ref) { - var open = _a.open, container = _a.container, children = _a.children, _b = _a.scrollHandler, scrollHandler = _b === void 0 ? 'wrapper' : _b, _c = _a.Backdrop, Backdrop = _c === void 0 ? coreComponentsBackdrop.Backdrop : _c, _d = _a.backdropProps, backdropProps = _d === void 0 ? {} : _d, _e = _a.transitionProps, transitionProps = _e === void 0 ? {} : _e, disableBackdropClick = _a.disableBackdropClick, _f = _a.disableAutoFocus, disableAutoFocus = _f === void 0 ? false : _f, _g = _a.disableFocusLock, disableFocusLock = _g === void 0 ? false : _g, _h = _a.disableEscapeKeyDown, disableEscapeKeyDown = _h === void 0 ? false : _h, _j = _a.disableRestoreFocus, disableRestoreFocus = _j === void 0 ? false : _j, _k = _a.disableBlockingScroll, disableBlockingScroll = _k === void 0 ? false : _k, _l = _a.keepMounted, keepMounted = _l === void 0 ? false : _l, className = _a.className, contentClassName = _a.contentClassName, wrapperProps = _a.wrapperProps, contentProps = _a.contentProps, componentDivProps = _a.componentDivProps, wrapperClassName = _a.wrapperClassName, onBackdropClick = _a.onBackdropClick, onClose = _a.onClose, onEscapeKeyDown = _a.onEscapeKeyDown, onMount = _a.onMount, onUnmount = _a.onUnmount, dataTestId = _a.dataTestId, _m = _a.zIndex, zIndex = _m === void 0 ? stackContext.stackingOrder.MODAL : _m, _o = _a.componentRef, componentRef = _o === void 0 ? null : _o, _p = _a.usePortal, usePortal = _p === void 0 ? true : _p, _q = _a.iOSLock, iOSLock = _q === void 0 ? false : _q; - var _r = React.useState(null), exited = _r[0], setExited = _r[1]; - var _s = React.useState(false), hasScroll = _s[0], setHasScroll = _s[1]; - var _t = React.useState(false), hasHeader = _t[0], setHasHeader = _t[1]; - var _u = React.useState(false), hasFooter = _u[0], setHasFooter = _u[1]; - var _v = React.useState(false), headerHighlighted = _v[0], setHeaderHighlighted = _v[1]; - var _w = React.useState(false), footerHighlighted = _w[0], setFooterHighlighted = _w[1]; - var _x = React.useState(0), headerOffset = _x[0], setHeaderOffset = _x[1]; - var componentNodeRef = React.useRef(null); - var wrapperRef = React.useRef(null); - var scrollableNodeRef = React.useRef(null); - var contentNodeRef = React.useRef(null); - var restoreContainerStylesRef = React.useRef(null); - var mouseDownTarget = React.useRef(); - var resizeObserverRef = React.useRef(); - var checkToHasScrollBar = function () { - if (scrollableNodeRef.current) { - var scrollExists = utils.hasScrollbar(scrollableNodeRef.current); - setFooterHighlighted(scrollExists); - setHasScroll(scrollExists); - } - }; - var isExited = exited || exited === null; - var shouldRender = keepMounted || open || !isExited; - var getContainer = React.useCallback(function () { return (container ? container() : document.body); }, [container]); - var addResizeHandle = React.useCallback(function () { - if (!resizeObserverRef.current) - return; - if (scrollableNodeRef.current) { - resizeObserverRef.current.observe(scrollableNodeRef.current); - } - if (contentNodeRef.current) { - resizeObserverRef.current.observe(contentNodeRef.current); - } - }, []); - var removeResizeHandle = React.useCallback(function () { var _a; return (_a = resizeObserverRef.current) === null || _a === void 0 ? void 0 : _a.disconnect(); }, []); - var contentRef = React.useCallback(function (node) { - if (node !== null) { - contentNodeRef.current = node; - if (resizeObserverRef.current) { - resizeObserverRef.current.observe(node); - } - checkToHasScrollBar(); - } - }, []); - var handleScroll = React.useCallback(function () { - if (!scrollableNodeRef.current || !componentNodeRef.current) - return; - if (hasHeader) { - setHeaderHighlighted(!utils.isScrolledToTop(scrollableNodeRef.current) && - componentNodeRef.current.getBoundingClientRect().top - headerOffset <= 1); - } - if (hasFooter) { - setFooterHighlighted(!utils.isScrolledToBottom(scrollableNodeRef.current) && - componentNodeRef.current.getBoundingClientRect().bottom >= - window.innerHeight - 1); - } - }, [hasFooter, hasHeader, headerOffset]); - var handleClose = React.useCallback(function (event, reason) { - if (iOSLock && coreComponentsShared.os.isIOS()) { - helpers_lockScroll.unlockScroll(); - } - if (onClose) { - onClose(event, reason); - } - if (reason === 'backdropClick' && onBackdropClick) { - onBackdropClick(event); - } - if (reason === 'escapeKeyDown' && onEscapeKeyDown) { - onEscapeKeyDown(event); - } - return null; - }, [onBackdropClick, onClose, onEscapeKeyDown, iOSLock]); - var handleBackdropMouseDown = function (event) { - var _a; - var clickedOnScrollbar = false; - var clientWidth = (_a = event.target) === null || _a === void 0 ? void 0 : _a.clientWidth; - if (event.clientX && clientWidth) { - // Устанавливаем смещение для абсолютно спозиционированного скроллбара в OSX в 17px. - var offset = coreComponentsShared.browser.getScrollbarSize() === 0 ? 17 : 0; - clickedOnScrollbar = event.clientX + offset > clientWidth; - } - if (!disableBackdropClick && !clickedOnScrollbar) { - mouseDownTarget.current = event.target; - } - }; - var handleBackdropMouseUp = function (event) { - if (!disableBackdropClick && - event.target === wrapperRef.current && - mouseDownTarget.current === wrapperRef.current) { - handleClose(event, 'backdropClick'); - } - mouseDownTarget.current = undefined; - }; - var handleKeyDown = React.useCallback(function (event) { - /* - * Чтобы сохранить дефолтное поведение элементов и событий форм, - * обработчик не устанавливает event.preventDefault() - */ - if (event.key !== 'Escape') { - return; - } - // Если есть обработчик escape на body - event.stopPropagation(); - if (!disableEscapeKeyDown && handleClose) { - handleClose(event, 'escapeKeyDown'); - } - }, [disableEscapeKeyDown, handleClose]); - var getScrollHandler = React.useCallback(function () { - if (scrollHandler === 'wrapper') - return wrapperRef.current; - if (scrollHandler === 'content') - return componentNodeRef.current; - return scrollHandler.current || wrapperRef.current; - }, [scrollHandler]); - var handleEntered = React.useCallback(function (node, isAppearing) { - scrollableNodeRef.current = getScrollHandler(); - addResizeHandle(); - if (scrollableNodeRef.current) { - scrollableNodeRef.current.addEventListener('scroll', handleScroll); - handleScroll(); - } - if (transitionProps.onEntered) { - transitionProps.onEntered(node, isAppearing); - } - if (onMount) - onMount(); - }, [addResizeHandle, getScrollHandler, handleScroll, onMount, transitionProps]); - var handleExited = React.useCallback(function (node) { - removeResizeHandle(); - setExited(true); - if (scrollableNodeRef.current) { - scrollableNodeRef.current.removeEventListener('scroll', handleScroll); - } - if (transitionProps.onExited) { - transitionProps.onExited(node); - } - if (onUnmount) - onUnmount(); - if (restoreContainerStylesRef.current) { - restoreContainerStylesRef.current(); - } - }, [handleScroll, onUnmount, removeResizeHandle, transitionProps]); - React.useEffect(function () { - if (open && isExited) { - if (!disableBlockingScroll) { - var el_1 = getContainer(); - var shouldIOSLock = iOSLock && coreComponentsShared.os.isIOS(); - utils.handleContainer(el_1, shouldIOSLock); - if (shouldIOSLock) { - helpers_lockScroll.syncHeight(); - helpers_lockScroll.lockScroll(); - } - restoreContainerStylesRef.current = function () { - restoreContainerStylesRef.current = null; - utils.restoreContainerStyles(el_1); - }; - } - setExited(false); - } - if (!open) { - helpers_lockScroll.unlockScroll(); - } - }, [getContainer, open, disableBlockingScroll, isExited, iOSLock]); - React.useEffect(function () { - var ResizeObserver = window.ResizeObserver || resizeObserver.ResizeObserver; - resizeObserverRef.current = new ResizeObserver(checkToHasScrollBar); - return function () { - if (restoreContainerStylesRef.current) { - restoreContainerStylesRef.current(); - } - if (resizeObserverRef.current) { - resizeObserverRef.current.disconnect(); - } - }; - }, []); - React.useEffect(function () { - var _a; - if (disableAutoFocus || !open) - return; - (_a = wrapperRef.current) === null || _a === void 0 ? void 0 : _a.focus(); - }, [open, disableAutoFocus]); - var contextValue = React.useMemo(function () { return ({ - parentRef: wrapperRef, - componentRef: componentNodeRef, - hasHeader: hasHeader, - hasFooter: hasFooter, - hasScroll: hasScroll, - headerHighlighted: headerHighlighted, - footerHighlighted: footerHighlighted, - headerOffset: headerOffset, - setHeaderOffset: setHeaderOffset, - contentRef: contentRef, - setHasHeader: setHasHeader, - setHasFooter: setHasFooter, - onClose: handleClose, - }); }, [ - contentRef, - hasHeader, - hasFooter, - hasScroll, - headerHighlighted, - footerHighlighted, - headerOffset, - setHeaderOffset, - handleClose, - ]); - var renderContent = function () { return (React__default.default.createElement(coreComponentsStack.Stack, { value: zIndex }, function (computedZIndex) { - var _a; - return (React__default.default.createElement(BaseModalContext.Provider, { value: contextValue }, - React__default.default.createElement(FocusLock__default.default, { disabled: disableFocusLock || !open, returnFocus: !disableRestoreFocus }, - Backdrop && (React__default.default.createElement(Backdrop, tslib.__assign({}, backdropProps, { className: cn__default.default(backdropProps.className, styles__default.default.backdrop), open: open, style: { - zIndex: computedZIndex, - } }))), - React__default.default.createElement("div", tslib.__assign({}, wrapperProps, { role: 'dialog', className: cn__default.default(styles__default.default.wrapper, wrapperClassName, wrapperProps === null || wrapperProps === void 0 ? void 0 : wrapperProps.className, (_a = {}, - _a[styles__default.default.hidden] = !open && isExited, - _a)), ref: mergeRefs__default.default([ - ref, - wrapperRef, - wrapperProps === null || wrapperProps === void 0 ? void 0 : wrapperProps.ref, - ]), onKeyDown: handleKeyDown, onMouseDown: handleBackdropMouseDown, onMouseUp: handleBackdropMouseUp, tabIndex: -1, "data-test-id": dataTestId, style: { - zIndex: computedZIndex, - } }), - React__default.default.createElement(reactTransitionGroup.CSSTransition, tslib.__assign({ appear: true, timeout: 200, classNames: styles__default.default, nodeRef: componentNodeRef }, transitionProps, { in: open, onEntered: handleEntered, onExited: handleExited }), - React__default.default.createElement("div", tslib.__assign({}, componentDivProps, { className: cn__default.default(styles__default.default.component, className, componentDivProps === null || componentDivProps === void 0 ? void 0 : componentDivProps.className), ref: mergeRefs__default.default([ - componentRef, - componentNodeRef, - (componentDivProps === null || componentDivProps === void 0 ? void 0 : componentDivProps.ref) || null, - ]) }), - React__default.default.createElement("div", tslib.__assign({}, contentProps, { className: cn__default.default(styles__default.default.content, contentClassName, contentProps === null || contentProps === void 0 ? void 0 : contentProps.className) }), children))))))); - })); }; - if (!shouldRender) - return null; - return usePortal ? (React__default.default.createElement(coreComponentsPortal.Portal, { getPortalContainer: container, immediateMount: true }, renderContent())) : (renderContent()); -}); -BaseModal.displayName = 'BaseModal'; -BaseModalContext.displayName = 'BaseModalContext'; - -exports.BaseModal = BaseModal; -exports.BaseModalContext = BaseModalContext; diff --git a/packages/base-modal/dist_side_poly/cssm/helpers/lockScroll.d.ts b/packages/base-modal/dist_side_poly/cssm/helpers/lockScroll.d.ts deleted file mode 100644 index 80e91475f8..0000000000 --- a/packages/base-modal/dist_side_poly/cssm/helpers/lockScroll.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -declare const isScrollLocked: () => boolean; -declare const lockScroll: () => void; -declare const unlockScroll: () => void; -declare const syncHeight: () => void; -export { isScrollLocked, lockScroll, unlockScroll, syncHeight }; diff --git a/packages/base-modal/dist_side_poly/cssm/helpers/lockScroll.js b/packages/base-modal/dist_side_poly/cssm/helpers/lockScroll.js deleted file mode 100644 index 5eea467f5b..0000000000 --- a/packages/base-modal/dist_side_poly/cssm/helpers/lockScroll.js +++ /dev/null @@ -1,28 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, '__esModule', { value: true }); - -/** - * Хелпер для блокирования скроллинга в iOS - * В проекте используется overflow: hidden для блокировки, но в некоторых случаях этого недостаточно. Данный хелпер призван решать эту проблему - */ -var scrollY; -var isScrollLocked = function () { return document.body.classList.contains('is-locked'); }; -var lockScroll = function () { - scrollY = window.scrollY; - document.body.classList.add('is-locked'); -}; -var unlockScroll = function () { - if (!isScrollLocked()) - return; - document.body.classList.remove('is-locked'); - window.scrollTo(0, scrollY); -}; -var syncHeight = function () { - document.body.style.setProperty('--window-inner-scrollY', "".concat(window.scrollY, "px")); -}; - -exports.isScrollLocked = isScrollLocked; -exports.lockScroll = lockScroll; -exports.syncHeight = syncHeight; -exports.unlockScroll = unlockScroll; diff --git a/packages/base-modal/dist_side_poly/cssm/index.d.ts b/packages/base-modal/dist_side_poly/cssm/index.d.ts deleted file mode 100644 index 61ae91968a..0000000000 --- a/packages/base-modal/dist_side_poly/cssm/index.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from "./Component"; -export * from "./utils"; -export * from "./helpers/lockScroll"; diff --git a/packages/base-modal/dist_side_poly/cssm/index.js b/packages/base-modal/dist_side_poly/cssm/index.js deleted file mode 100644 index cf4a09932b..0000000000 --- a/packages/base-modal/dist_side_poly/cssm/index.js +++ /dev/null @@ -1,21 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, '__esModule', { value: true }); - -var Component = require('./Component.js'); -var utils = require('./utils.js'); -var helpers_lockScroll = require('./helpers/lockScroll.js'); - - - -exports.BaseModal = Component.BaseModal; -exports.BaseModalContext = Component.BaseModalContext; -exports.handleContainer = utils.handleContainer; -exports.hasScrollbar = utils.hasScrollbar; -exports.isScrolledToBottom = utils.isScrolledToBottom; -exports.isScrolledToTop = utils.isScrolledToTop; -exports.restoreContainerStyles = utils.restoreContainerStyles; -exports.isScrollLocked = helpers_lockScroll.isScrollLocked; -exports.lockScroll = helpers_lockScroll.lockScroll; -exports.syncHeight = helpers_lockScroll.syncHeight; -exports.unlockScroll = helpers_lockScroll.unlockScroll; diff --git a/packages/base-modal/dist_side_poly/cssm/index.module.css b/packages/base-modal/dist_side_poly/cssm/index.module.css deleted file mode 100644 index 0723c8d479..0000000000 --- a/packages/base-modal/dist_side_poly/cssm/index.module.css +++ /dev/null @@ -1,70 +0,0 @@ -:root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ -} /* deprecated */ :root { - --color-light-modal-bg-primary: #fff; /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ -} :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ -} :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ -} :root { - - /* Hard */ - - /* Up */ - - /* Hard up */ -} :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ - - /* новые значения, используйте их */ -} :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ - - /* новые значения, используйте их */ - --gap-0: 0; -} :root { -} :root { -} /* сбрасывает синюю подсветку при нажатии */ :root { - --window-inner-scrollY: 10px; /* fallback value to prevent ci error */ -} body:global(.is-locked) { - margin-top: calc(var(--window-inner-scrollY) * -1); - position: fixed; - overflow: hidden; -} .component { - position: relative; - box-sizing: border-box; - background: var(--color-light-modal-bg-primary); - margin: auto; - flex-shrink: 0; -} .wrapper { - position: fixed; - top: var(--gap-0); - left: var(--gap-0); - right: var(--gap-0); - bottom: var(--gap-0); - - overflow: auto; - display: flex; - flex-direction: column; - align-items: center; - outline: 0; - overscroll-behavior: none; -} .content { - width: 100%; - height: 100%; - display: flex; - flex-direction: column; - flex: 1; -} .hidden { - display: none; -} .backdrop { - z-index: 0; -} .appear, -.enter { - opacity: 0; -} .appearActive, -.enterActive { - opacity: 1; - transition: opacity 200ms ease-in; -} .exit { - opacity: 1; -} .exitActive, -.exitDone { - opacity: 0; - transition: opacity 200ms ease-out; -} diff --git a/packages/base-modal/dist_side_poly/cssm/matches-polyfill.d.ts b/packages/base-modal/dist_side_poly/cssm/matches-polyfill.d.ts deleted file mode 100644 index cb0ff5c3b5..0000000000 --- a/packages/base-modal/dist_side_poly/cssm/matches-polyfill.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/packages/base-modal/dist_side_poly/cssm/matches-polyfill.js b/packages/base-modal/dist_side_poly/cssm/matches-polyfill.js deleted file mode 100644 index e36a0cd0b7..0000000000 --- a/packages/base-modal/dist_side_poly/cssm/matches-polyfill.js +++ /dev/null @@ -1,20 +0,0 @@ -'use strict'; - -/* eslint-disable */ -// @ts-nocheck -if (typeof window !== 'undefined') { - if (Element && !Element.prototype.matches) { - Element.prototype.matches = - Element.prototype.matchesSelector || - Element.prototype.mozMatchesSelector || - Element.prototype.msMatchesSelector || - Element.prototype.oMatchesSelector || - Element.prototype.webkitMatchesSelector || - function (s) { - var matches = (this.document || this.ownerDocument).querySelectorAll(s); - var i = matches.length; - while (--i >= 0 && matches.item(i) !== this) { } - return i > -1; - }; - } -} diff --git a/packages/base-modal/dist_side_poly/cssm/utils.d.ts b/packages/base-modal/dist_side_poly/cssm/utils.d.ts deleted file mode 100644 index 75401779bb..0000000000 --- a/packages/base-modal/dist_side_poly/cssm/utils.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -declare function isScrolledToTop(target: HTMLElement): boolean; -declare function isScrolledToBottom(target: HTMLElement): boolean; -declare function hasScrollbar(target: HTMLElement): boolean; -declare const restoreContainerStyles: (container: HTMLElement) => void; -declare const handleContainer: (container?: HTMLElement, shouldIOSLock?: boolean) => void; -export { isScrolledToTop, isScrolledToBottom, hasScrollbar, restoreContainerStyles, handleContainer }; diff --git a/packages/base-modal/dist_side_poly/cssm/utils.js b/packages/base-modal/dist_side_poly/cssm/utils.js deleted file mode 100644 index 0754e95b42..0000000000 --- a/packages/base-modal/dist_side_poly/cssm/utils.js +++ /dev/null @@ -1,99 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, '__esModule', { value: true }); - -var coreComponentsGlobalStore = require('@alfalab/core-components-global-store/cssm'); -var coreComponentsShared = require('@alfalab/core-components-shared/cssm'); - -function isScrolledToTop(target) { - return target.scrollTop <= 0; -} -function isScrolledToBottom(target) { - return target.scrollHeight - target.offsetHeight <= target.scrollTop; -} -function hasScrollbar(target) { - return target.scrollHeight > target.clientHeight; -} -var isOverflowing = function (container) { - if (document.body === container) { - return window.innerWidth > document.documentElement.clientWidth; - } - return container.scrollHeight > container.clientHeight; -}; -var getPaddingRight = function (node) { - return parseInt(window.getComputedStyle(node).paddingRight, 10) || 0; -}; -var restoreContainerStyles = function (container) { - var modalRestoreStyles = coreComponentsGlobalStore.getModalStore().getRestoreStyles(); - var index = modalRestoreStyles.findIndex(function (s) { return s.container === container; }); - var existingStyles = modalRestoreStyles[index]; - if (!existingStyles) - return; - existingStyles.modals -= 1; - if (existingStyles.modals <= 0) { - modalRestoreStyles.splice(index, 1); - existingStyles.styles.forEach(function (_a) { - var value = _a.value, el = _a.el, key = _a.key; - if (value) { - el.style.setProperty(key, value); - } - else { - el.style.removeProperty(key); - } - }); - } -}; -var handleContainer = function (container, shouldIOSLock) { - if (shouldIOSLock === void 0) { shouldIOSLock = false; } - if (!container) - return; - var modalRestoreStyles = coreComponentsGlobalStore.getModalStore().getRestoreStyles(); - var existingStyles = modalRestoreStyles.find(function (s) { return s.container === container; }); - if (existingStyles) { - existingStyles.modals += 1; - return; - } - var containerStyles = []; - if (isOverflowing(container)) { - // Вычисляет размер до применения `overflow hidden` для избежания скачков - var scrollbarSize = coreComponentsShared.browser.getScrollbarSize(); - containerStyles.push({ - value: container.style.paddingRight, - key: 'padding-right', - el: container, - }); - // Вычисляем стили, чтобы получить реальный `padding` c шириной сколлбара - // eslint-disable-next-line no-param-reassign - container.style.paddingRight = "".concat(getPaddingRight(container) + scrollbarSize, "px"); - } - var parent = container.parentElement; - var scrollContainer = - // TODO: заменить на optional chaining - parent && - parent.nodeName === 'HTML' && - window.getComputedStyle(parent).overflowY === 'scroll' - ? parent - : container; - // Блокируем скролл даже если отсутствует скроллбар - if (scrollContainer.style.overflow !== 'hidden') { - containerStyles.push({ - value: scrollContainer.style.overflow, - key: 'overflow', - el: scrollContainer, - }); - } - if (!shouldIOSLock) { - scrollContainer.style.overflow = 'hidden'; - } - modalRestoreStyles.push({ - container: container, - modals: 1, - styles: containerStyles, - }); -}; - -exports.handleContainer = handleContainer; -exports.hasScrollbar = hasScrollbar; -exports.isScrolledToBottom = isScrolledToBottom; -exports.isScrolledToTop = isScrolledToTop; -exports.restoreContainerStyles = restoreContainerStyles; diff --git a/packages/base-modal/dist_side_poly/esm/Component.d.ts b/packages/base-modal/dist_side_poly/esm/Component.d.ts deleted file mode 100644 index 44533e4e97..0000000000 --- a/packages/base-modal/dist_side_poly/esm/Component.d.ts +++ /dev/null @@ -1,159 +0,0 @@ -/// -/// -import React from 'react'; -import { ComponentType, KeyboardEvent, MouseEvent, MutableRefObject, ReactNode, Ref } from "react"; -import { TransitionProps } from 'react-transition-group/Transition'; -import { BackdropProps } from "@alfalab/core-components-backdrop"; -import { PortalProps } from "@alfalab/core-components-portal"; -type BaseModalProps = { - /** - * Контент - */ - children?: ReactNode; - /** - * Компонент бэкдропа - */ - Backdrop?: ComponentType; - /** - * Свойства для Бэкдропа - */ - backdropProps?: Partial & Record; - /** - * Нода, компонент или функция возвращающая их - * - * Контейнер к которому будут добавляться порталы - */ - container?: PortalProps['getPortalContainer']; - /** - * Отключает автоматический перевод фокуса на модалку при открытии - * @default false - */ - disableAutoFocus?: boolean; - /** - * Отключает ловушку фокуса - * @default false - */ - disableFocusLock?: boolean; - /** - * Отключает восстановление фокуса на предыдущем элементе после закрытия модалки - * @default false - */ - disableRestoreFocus?: boolean; - /** - * Отключает вызов `callback` при нажатии Escape - * @default false - */ - disableEscapeKeyDown?: boolean; - /** - * Отключает вызов `callback` при клике на бэкдроп - * @default false - */ - disableBackdropClick?: boolean; - /** - * Отключает блокировку скролла при открытии модального окна - * @default false - */ - disableBlockingScroll?: boolean; - /** - * Содержимое модалки всегда в DOM - * @default false - */ - keepMounted?: boolean; - /** - * Управление видимостью модалки - */ - open: boolean; - /** - * Дополнительный класс - */ - className?: string; - /** - * Дополнительный класс - */ - contentClassName?: string; - /** - * Дополнительные пропсы на dialog wrapper - */ - wrapperProps?: React.DetailedHTMLProps, HTMLDivElement>; - /** - * Дополнительные пропсы на обертку контента - */ - contentProps?: React.DetailedHTMLProps, HTMLDivElement>; - /** - * Дополнительные пропсы на компонентную обертку контента - */ - componentDivProps?: React.DetailedHTMLProps, HTMLDivElement>; - /** - * Дополнительный класс для обертки (Modal) - */ - wrapperClassName?: string; - /** - * Обработчик скролла контента - */ - scrollHandler?: 'wrapper' | 'content' | MutableRefObject; - /** - * Пропсы для анимации (CSSTransition) - */ - transitionProps?: Partial; - /** - * Рендерить ли в контейнер через портал. - * @default true - */ - usePortal?: boolean; - /** - * Обработчик события нажатия на бэкдроп - */ - onBackdropClick?: (event: MouseEvent) => void; - /** - * Обработчик события нажатия на Escape - * - * Если `disableEscapeKeyDown` - false и модальное окно в фокусе - */ - onEscapeKeyDown?: (event: KeyboardEvent) => void; - /** - * Обработчик закрытия - */ - onClose?: (event: MouseEvent | KeyboardEvent, reason?: 'backdropClick' | 'escapeKeyDown' | 'closerClick') => void; - /** - * Обработчик события onEntered компонента Transition - */ - onMount?: () => void; - /** - * Обработчик события onExited компонента Transition - */ - onUnmount?: () => void; - /** - * Идентификатор для систем автоматизированного тестирования - */ - dataTestId?: string; - /** - * z-index компонента - */ - zIndex?: number; - /** - * Реф, который должен быть установлен компонентной области - */ - componentRef?: MutableRefObject; - /** - * Блокирует скролл когда модальное окно открыто. Работает только на iOS. - */ - iOSLock?: boolean; -}; -type BaseModalContext = { - parentRef: React.RefObject; - componentRef: React.RefObject; - hasFooter?: boolean; - hasHeader?: boolean; - hasScroll?: boolean; - headerHighlighted?: boolean; - footerHighlighted?: boolean; - headerOffset?: number; - setHeaderOffset: (offset: number) => void; - contentRef: Ref; - setHasHeader: (exists: boolean) => void; - setHasFooter: (exists: boolean) => void; - onClose: Required['onClose']; -}; -declare const BaseModalContext: React.Context; -declare const BaseModal: React.ForwardRefExoticComponent>; -export { BaseModalProps, BaseModalContext, BaseModal }; diff --git a/packages/base-modal/dist_side_poly/esm/Component.js b/packages/base-modal/dist_side_poly/esm/Component.js deleted file mode 100644 index c608f5fc5c..0000000000 --- a/packages/base-modal/dist_side_poly/esm/Component.js +++ /dev/null @@ -1,275 +0,0 @@ -import { __assign } from 'tslib'; -import React, { forwardRef, useState, useRef, useCallback, useEffect, useMemo } from 'react'; -import FocusLock from 'react-focus-lock'; -import mergeRefs from 'react-merge-refs'; -import { CSSTransition } from 'react-transition-group'; -import { ResizeObserver } from '@juggle/resize-observer'; -import cn from 'classnames'; -import { Backdrop } from '@alfalab/core-components-backdrop/esm'; -import { Portal } from '@alfalab/core-components-portal/esm'; -import { os, browser } from '@alfalab/core-components-shared/esm'; -import { Stack } from '@alfalab/core-components-stack/esm'; -import { stackingOrder } from '@alfalab/stack-context'; -import { unlockScroll, syncHeight, lockScroll } from './helpers/lockScroll.js'; -import { isScrolledToTop, isScrolledToBottom, handleContainer, restoreContainerStyles, hasScrollbar } from './utils.js'; -import './matches-polyfill.js'; - -var styles = {"component":"base-modal__component_1y6m8","wrapper":"base-modal__wrapper_1y6m8","content":"base-modal__content_1y6m8","hidden":"base-modal__hidden_1y6m8","backdrop":"base-modal__backdrop_1y6m8","appear":"base-modal__appear_1y6m8","enter":"base-modal__enter_1y6m8","appearActive":"base-modal__appearActive_1y6m8","enterActive":"base-modal__enterActive_1y6m8","exit":"base-modal__exit_1y6m8","exitActive":"base-modal__exitActive_1y6m8","exitDone":"base-modal__exitDone_1y6m8"}; -require('./index.css') - -// eslint-disable-next-line @typescript-eslint/no-redeclare -var BaseModalContext = React.createContext({ - parentRef: { current: null }, - componentRef: { current: null }, - hasFooter: false, - hasHeader: false, - hasScroll: false, - headerHighlighted: false, - footerHighlighted: false, - headerOffset: 0, - setHeaderOffset: function () { return null; }, - contentRef: function () { return null; }, - setHasHeader: function () { return null; }, - setHasFooter: function () { return null; }, - onClose: function () { return null; }, -}); -var BaseModal = forwardRef(function (_a, ref) { - var open = _a.open, container = _a.container, children = _a.children, _b = _a.scrollHandler, scrollHandler = _b === void 0 ? 'wrapper' : _b, _c = _a.Backdrop, Backdrop$1 = _c === void 0 ? Backdrop : _c, _d = _a.backdropProps, backdropProps = _d === void 0 ? {} : _d, _e = _a.transitionProps, transitionProps = _e === void 0 ? {} : _e, disableBackdropClick = _a.disableBackdropClick, _f = _a.disableAutoFocus, disableAutoFocus = _f === void 0 ? false : _f, _g = _a.disableFocusLock, disableFocusLock = _g === void 0 ? false : _g, _h = _a.disableEscapeKeyDown, disableEscapeKeyDown = _h === void 0 ? false : _h, _j = _a.disableRestoreFocus, disableRestoreFocus = _j === void 0 ? false : _j, _k = _a.disableBlockingScroll, disableBlockingScroll = _k === void 0 ? false : _k, _l = _a.keepMounted, keepMounted = _l === void 0 ? false : _l, className = _a.className, contentClassName = _a.contentClassName, wrapperProps = _a.wrapperProps, contentProps = _a.contentProps, componentDivProps = _a.componentDivProps, wrapperClassName = _a.wrapperClassName, onBackdropClick = _a.onBackdropClick, onClose = _a.onClose, onEscapeKeyDown = _a.onEscapeKeyDown, onMount = _a.onMount, onUnmount = _a.onUnmount, dataTestId = _a.dataTestId, _m = _a.zIndex, zIndex = _m === void 0 ? stackingOrder.MODAL : _m, _o = _a.componentRef, componentRef = _o === void 0 ? null : _o, _p = _a.usePortal, usePortal = _p === void 0 ? true : _p, _q = _a.iOSLock, iOSLock = _q === void 0 ? false : _q; - var _r = useState(null), exited = _r[0], setExited = _r[1]; - var _s = useState(false), hasScroll = _s[0], setHasScroll = _s[1]; - var _t = useState(false), hasHeader = _t[0], setHasHeader = _t[1]; - var _u = useState(false), hasFooter = _u[0], setHasFooter = _u[1]; - var _v = useState(false), headerHighlighted = _v[0], setHeaderHighlighted = _v[1]; - var _w = useState(false), footerHighlighted = _w[0], setFooterHighlighted = _w[1]; - var _x = useState(0), headerOffset = _x[0], setHeaderOffset = _x[1]; - var componentNodeRef = useRef(null); - var wrapperRef = useRef(null); - var scrollableNodeRef = useRef(null); - var contentNodeRef = useRef(null); - var restoreContainerStylesRef = useRef(null); - var mouseDownTarget = useRef(); - var resizeObserverRef = useRef(); - var checkToHasScrollBar = function () { - if (scrollableNodeRef.current) { - var scrollExists = hasScrollbar(scrollableNodeRef.current); - setFooterHighlighted(scrollExists); - setHasScroll(scrollExists); - } - }; - var isExited = exited || exited === null; - var shouldRender = keepMounted || open || !isExited; - var getContainer = useCallback(function () { return (container ? container() : document.body); }, [container]); - var addResizeHandle = useCallback(function () { - if (!resizeObserverRef.current) - return; - if (scrollableNodeRef.current) { - resizeObserverRef.current.observe(scrollableNodeRef.current); - } - if (contentNodeRef.current) { - resizeObserverRef.current.observe(contentNodeRef.current); - } - }, []); - var removeResizeHandle = useCallback(function () { var _a; return (_a = resizeObserverRef.current) === null || _a === void 0 ? void 0 : _a.disconnect(); }, []); - var contentRef = useCallback(function (node) { - if (node !== null) { - contentNodeRef.current = node; - if (resizeObserverRef.current) { - resizeObserverRef.current.observe(node); - } - checkToHasScrollBar(); - } - }, []); - var handleScroll = useCallback(function () { - if (!scrollableNodeRef.current || !componentNodeRef.current) - return; - if (hasHeader) { - setHeaderHighlighted(!isScrolledToTop(scrollableNodeRef.current) && - componentNodeRef.current.getBoundingClientRect().top - headerOffset <= 1); - } - if (hasFooter) { - setFooterHighlighted(!isScrolledToBottom(scrollableNodeRef.current) && - componentNodeRef.current.getBoundingClientRect().bottom >= - window.innerHeight - 1); - } - }, [hasFooter, hasHeader, headerOffset]); - var handleClose = useCallback(function (event, reason) { - if (iOSLock && os.isIOS()) { - unlockScroll(); - } - if (onClose) { - onClose(event, reason); - } - if (reason === 'backdropClick' && onBackdropClick) { - onBackdropClick(event); - } - if (reason === 'escapeKeyDown' && onEscapeKeyDown) { - onEscapeKeyDown(event); - } - return null; - }, [onBackdropClick, onClose, onEscapeKeyDown, iOSLock]); - var handleBackdropMouseDown = function (event) { - var _a; - var clickedOnScrollbar = false; - var clientWidth = (_a = event.target) === null || _a === void 0 ? void 0 : _a.clientWidth; - if (event.clientX && clientWidth) { - // Устанавливаем смещение для абсолютно спозиционированного скроллбара в OSX в 17px. - var offset = browser.getScrollbarSize() === 0 ? 17 : 0; - clickedOnScrollbar = event.clientX + offset > clientWidth; - } - if (!disableBackdropClick && !clickedOnScrollbar) { - mouseDownTarget.current = event.target; - } - }; - var handleBackdropMouseUp = function (event) { - if (!disableBackdropClick && - event.target === wrapperRef.current && - mouseDownTarget.current === wrapperRef.current) { - handleClose(event, 'backdropClick'); - } - mouseDownTarget.current = undefined; - }; - var handleKeyDown = useCallback(function (event) { - /* - * Чтобы сохранить дефолтное поведение элементов и событий форм, - * обработчик не устанавливает event.preventDefault() - */ - if (event.key !== 'Escape') { - return; - } - // Если есть обработчик escape на body - event.stopPropagation(); - if (!disableEscapeKeyDown && handleClose) { - handleClose(event, 'escapeKeyDown'); - } - }, [disableEscapeKeyDown, handleClose]); - var getScrollHandler = useCallback(function () { - if (scrollHandler === 'wrapper') - return wrapperRef.current; - if (scrollHandler === 'content') - return componentNodeRef.current; - return scrollHandler.current || wrapperRef.current; - }, [scrollHandler]); - var handleEntered = useCallback(function (node, isAppearing) { - scrollableNodeRef.current = getScrollHandler(); - addResizeHandle(); - if (scrollableNodeRef.current) { - scrollableNodeRef.current.addEventListener('scroll', handleScroll); - handleScroll(); - } - if (transitionProps.onEntered) { - transitionProps.onEntered(node, isAppearing); - } - if (onMount) - onMount(); - }, [addResizeHandle, getScrollHandler, handleScroll, onMount, transitionProps]); - var handleExited = useCallback(function (node) { - removeResizeHandle(); - setExited(true); - if (scrollableNodeRef.current) { - scrollableNodeRef.current.removeEventListener('scroll', handleScroll); - } - if (transitionProps.onExited) { - transitionProps.onExited(node); - } - if (onUnmount) - onUnmount(); - if (restoreContainerStylesRef.current) { - restoreContainerStylesRef.current(); - } - }, [handleScroll, onUnmount, removeResizeHandle, transitionProps]); - useEffect(function () { - if (open && isExited) { - if (!disableBlockingScroll) { - var el_1 = getContainer(); - var shouldIOSLock = iOSLock && os.isIOS(); - handleContainer(el_1, shouldIOSLock); - if (shouldIOSLock) { - syncHeight(); - lockScroll(); - } - restoreContainerStylesRef.current = function () { - restoreContainerStylesRef.current = null; - restoreContainerStyles(el_1); - }; - } - setExited(false); - } - if (!open) { - unlockScroll(); - } - }, [getContainer, open, disableBlockingScroll, isExited, iOSLock]); - useEffect(function () { - var ResizeObserver$1 = window.ResizeObserver || ResizeObserver; - resizeObserverRef.current = new ResizeObserver$1(checkToHasScrollBar); - return function () { - if (restoreContainerStylesRef.current) { - restoreContainerStylesRef.current(); - } - if (resizeObserverRef.current) { - resizeObserverRef.current.disconnect(); - } - }; - }, []); - useEffect(function () { - var _a; - if (disableAutoFocus || !open) - return; - (_a = wrapperRef.current) === null || _a === void 0 ? void 0 : _a.focus(); - }, [open, disableAutoFocus]); - var contextValue = useMemo(function () { return ({ - parentRef: wrapperRef, - componentRef: componentNodeRef, - hasHeader: hasHeader, - hasFooter: hasFooter, - hasScroll: hasScroll, - headerHighlighted: headerHighlighted, - footerHighlighted: footerHighlighted, - headerOffset: headerOffset, - setHeaderOffset: setHeaderOffset, - contentRef: contentRef, - setHasHeader: setHasHeader, - setHasFooter: setHasFooter, - onClose: handleClose, - }); }, [ - contentRef, - hasHeader, - hasFooter, - hasScroll, - headerHighlighted, - footerHighlighted, - headerOffset, - setHeaderOffset, - handleClose, - ]); - var renderContent = function () { return (React.createElement(Stack, { value: zIndex }, function (computedZIndex) { - var _a; - return (React.createElement(BaseModalContext.Provider, { value: contextValue }, - React.createElement(FocusLock, { disabled: disableFocusLock || !open, returnFocus: !disableRestoreFocus }, - Backdrop$1 && (React.createElement(Backdrop$1, __assign({}, backdropProps, { className: cn(backdropProps.className, styles.backdrop), open: open, style: { - zIndex: computedZIndex, - } }))), - React.createElement("div", __assign({}, wrapperProps, { role: 'dialog', className: cn(styles.wrapper, wrapperClassName, wrapperProps === null || wrapperProps === void 0 ? void 0 : wrapperProps.className, (_a = {}, - _a[styles.hidden] = !open && isExited, - _a)), ref: mergeRefs([ - ref, - wrapperRef, - wrapperProps === null || wrapperProps === void 0 ? void 0 : wrapperProps.ref, - ]), onKeyDown: handleKeyDown, onMouseDown: handleBackdropMouseDown, onMouseUp: handleBackdropMouseUp, tabIndex: -1, "data-test-id": dataTestId, style: { - zIndex: computedZIndex, - } }), - React.createElement(CSSTransition, __assign({ appear: true, timeout: 200, classNames: styles, nodeRef: componentNodeRef }, transitionProps, { in: open, onEntered: handleEntered, onExited: handleExited }), - React.createElement("div", __assign({}, componentDivProps, { className: cn(styles.component, className, componentDivProps === null || componentDivProps === void 0 ? void 0 : componentDivProps.className), ref: mergeRefs([ - componentRef, - componentNodeRef, - (componentDivProps === null || componentDivProps === void 0 ? void 0 : componentDivProps.ref) || null, - ]) }), - React.createElement("div", __assign({}, contentProps, { className: cn(styles.content, contentClassName, contentProps === null || contentProps === void 0 ? void 0 : contentProps.className) }), children))))))); - })); }; - if (!shouldRender) - return null; - return usePortal ? (React.createElement(Portal, { getPortalContainer: container, immediateMount: true }, renderContent())) : (renderContent()); -}); -BaseModal.displayName = 'BaseModal'; -BaseModalContext.displayName = 'BaseModalContext'; - -export { BaseModal, BaseModalContext }; diff --git a/packages/base-modal/dist_side_poly/esm/helpers/lockScroll.d.ts b/packages/base-modal/dist_side_poly/esm/helpers/lockScroll.d.ts deleted file mode 100644 index 80e91475f8..0000000000 --- a/packages/base-modal/dist_side_poly/esm/helpers/lockScroll.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -declare const isScrollLocked: () => boolean; -declare const lockScroll: () => void; -declare const unlockScroll: () => void; -declare const syncHeight: () => void; -export { isScrollLocked, lockScroll, unlockScroll, syncHeight }; diff --git a/packages/base-modal/dist_side_poly/esm/helpers/lockScroll.js b/packages/base-modal/dist_side_poly/esm/helpers/lockScroll.js deleted file mode 100644 index dfab01bb42..0000000000 --- a/packages/base-modal/dist_side_poly/esm/helpers/lockScroll.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Хелпер для блокирования скроллинга в iOS - * В проекте используется overflow: hidden для блокировки, но в некоторых случаях этого недостаточно. Данный хелпер призван решать эту проблему - */ -var scrollY; -var isScrollLocked = function () { return document.body.classList.contains('is-locked'); }; -var lockScroll = function () { - scrollY = window.scrollY; - document.body.classList.add('is-locked'); -}; -var unlockScroll = function () { - if (!isScrollLocked()) - return; - document.body.classList.remove('is-locked'); - window.scrollTo(0, scrollY); -}; -var syncHeight = function () { - document.body.style.setProperty('--window-inner-scrollY', "".concat(window.scrollY, "px")); -}; - -export { isScrollLocked, lockScroll, syncHeight, unlockScroll }; diff --git a/packages/base-modal/dist_side_poly/esm/index.css b/packages/base-modal/dist_side_poly/esm/index.css deleted file mode 100644 index 717db4385d..0000000000 --- a/packages/base-modal/dist_side_poly/esm/index.css +++ /dev/null @@ -1,71 +0,0 @@ -/* hash: 5nduy */ -:root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ -} /* deprecated */ :root { - --color-light-modal-bg-primary: #fff; /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ -} :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ -} :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ -} :root { - - /* Hard */ - - /* Up */ - - /* Hard up */ -} :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ - - /* новые значения, используйте их */ -} :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ - - /* новые значения, используйте их */ - --gap-0: 0; -} :root { -} :root { -} /* сбрасывает синюю подсветку при нажатии */ :root { - --window-inner-scrollY: 10px; /* fallback value to prevent ci error */ -} body.is-locked { - margin-top: calc(var(--window-inner-scrollY) * -1); - position: fixed; - overflow: hidden; -} .base-modal__component_1y6m8 { - position: relative; - box-sizing: border-box; - background: var(--color-light-modal-bg-primary); - margin: auto; - flex-shrink: 0; -} .base-modal__wrapper_1y6m8 { - position: fixed; - top: var(--gap-0); - left: var(--gap-0); - right: var(--gap-0); - bottom: var(--gap-0); - - overflow: auto; - display: flex; - flex-direction: column; - align-items: center; - outline: 0; - overscroll-behavior: none; -} .base-modal__content_1y6m8 { - width: 100%; - height: 100%; - display: flex; - flex-direction: column; - flex: 1; -} .base-modal__hidden_1y6m8 { - display: none; -} .base-modal__backdrop_1y6m8 { - z-index: 0; -} .base-modal__appear_1y6m8, -.base-modal__enter_1y6m8 { - opacity: 0; -} .base-modal__appearActive_1y6m8, -.base-modal__enterActive_1y6m8 { - opacity: 1; - transition: opacity 200ms ease-in; -} .base-modal__exit_1y6m8 { - opacity: 1; -} .base-modal__exitActive_1y6m8, -.base-modal__exitDone_1y6m8 { - opacity: 0; - transition: opacity 200ms ease-out; -} diff --git a/packages/base-modal/dist_side_poly/esm/index.d.ts b/packages/base-modal/dist_side_poly/esm/index.d.ts deleted file mode 100644 index 61ae91968a..0000000000 --- a/packages/base-modal/dist_side_poly/esm/index.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from "./Component"; -export * from "./utils"; -export * from "./helpers/lockScroll"; diff --git a/packages/base-modal/dist_side_poly/esm/index.js b/packages/base-modal/dist_side_poly/esm/index.js deleted file mode 100644 index ee07c7a608..0000000000 --- a/packages/base-modal/dist_side_poly/esm/index.js +++ /dev/null @@ -1,3 +0,0 @@ -export { BaseModal, BaseModalContext } from './Component.js'; -export { handleContainer, hasScrollbar, isScrolledToBottom, isScrolledToTop, restoreContainerStyles } from './utils.js'; -export { isScrollLocked, lockScroll, syncHeight, unlockScroll } from './helpers/lockScroll.js'; diff --git a/packages/base-modal/dist_side_poly/esm/matches-polyfill.d.ts b/packages/base-modal/dist_side_poly/esm/matches-polyfill.d.ts deleted file mode 100644 index cb0ff5c3b5..0000000000 --- a/packages/base-modal/dist_side_poly/esm/matches-polyfill.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/packages/base-modal/dist_side_poly/esm/matches-polyfill.js b/packages/base-modal/dist_side_poly/esm/matches-polyfill.js deleted file mode 100644 index 46744867fc..0000000000 --- a/packages/base-modal/dist_side_poly/esm/matches-polyfill.js +++ /dev/null @@ -1,18 +0,0 @@ -/* eslint-disable */ -// @ts-nocheck -if (typeof window !== 'undefined') { - if (Element && !Element.prototype.matches) { - Element.prototype.matches = - Element.prototype.matchesSelector || - Element.prototype.mozMatchesSelector || - Element.prototype.msMatchesSelector || - Element.prototype.oMatchesSelector || - Element.prototype.webkitMatchesSelector || - function (s) { - var matches = (this.document || this.ownerDocument).querySelectorAll(s); - var i = matches.length; - while (--i >= 0 && matches.item(i) !== this) { } - return i > -1; - }; - } -} diff --git a/packages/base-modal/dist_side_poly/esm/utils.d.ts b/packages/base-modal/dist_side_poly/esm/utils.d.ts deleted file mode 100644 index 75401779bb..0000000000 --- a/packages/base-modal/dist_side_poly/esm/utils.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -declare function isScrolledToTop(target: HTMLElement): boolean; -declare function isScrolledToBottom(target: HTMLElement): boolean; -declare function hasScrollbar(target: HTMLElement): boolean; -declare const restoreContainerStyles: (container: HTMLElement) => void; -declare const handleContainer: (container?: HTMLElement, shouldIOSLock?: boolean) => void; -export { isScrolledToTop, isScrolledToBottom, hasScrollbar, restoreContainerStyles, handleContainer }; diff --git a/packages/base-modal/dist_side_poly/esm/utils.js b/packages/base-modal/dist_side_poly/esm/utils.js deleted file mode 100644 index 248cf807aa..0000000000 --- a/packages/base-modal/dist_side_poly/esm/utils.js +++ /dev/null @@ -1,91 +0,0 @@ -import { getModalStore } from '@alfalab/core-components-global-store/esm'; -import { browser } from '@alfalab/core-components-shared/esm'; - -function isScrolledToTop(target) { - return target.scrollTop <= 0; -} -function isScrolledToBottom(target) { - return target.scrollHeight - target.offsetHeight <= target.scrollTop; -} -function hasScrollbar(target) { - return target.scrollHeight > target.clientHeight; -} -var isOverflowing = function (container) { - if (document.body === container) { - return window.innerWidth > document.documentElement.clientWidth; - } - return container.scrollHeight > container.clientHeight; -}; -var getPaddingRight = function (node) { - return parseInt(window.getComputedStyle(node).paddingRight, 10) || 0; -}; -var restoreContainerStyles = function (container) { - var modalRestoreStyles = getModalStore().getRestoreStyles(); - var index = modalRestoreStyles.findIndex(function (s) { return s.container === container; }); - var existingStyles = modalRestoreStyles[index]; - if (!existingStyles) - return; - existingStyles.modals -= 1; - if (existingStyles.modals <= 0) { - modalRestoreStyles.splice(index, 1); - existingStyles.styles.forEach(function (_a) { - var value = _a.value, el = _a.el, key = _a.key; - if (value) { - el.style.setProperty(key, value); - } - else { - el.style.removeProperty(key); - } - }); - } -}; -var handleContainer = function (container, shouldIOSLock) { - if (shouldIOSLock === void 0) { shouldIOSLock = false; } - if (!container) - return; - var modalRestoreStyles = getModalStore().getRestoreStyles(); - var existingStyles = modalRestoreStyles.find(function (s) { return s.container === container; }); - if (existingStyles) { - existingStyles.modals += 1; - return; - } - var containerStyles = []; - if (isOverflowing(container)) { - // Вычисляет размер до применения `overflow hidden` для избежания скачков - var scrollbarSize = browser.getScrollbarSize(); - containerStyles.push({ - value: container.style.paddingRight, - key: 'padding-right', - el: container, - }); - // Вычисляем стили, чтобы получить реальный `padding` c шириной сколлбара - // eslint-disable-next-line no-param-reassign - container.style.paddingRight = "".concat(getPaddingRight(container) + scrollbarSize, "px"); - } - var parent = container.parentElement; - var scrollContainer = - // TODO: заменить на optional chaining - parent && - parent.nodeName === 'HTML' && - window.getComputedStyle(parent).overflowY === 'scroll' - ? parent - : container; - // Блокируем скролл даже если отсутствует скроллбар - if (scrollContainer.style.overflow !== 'hidden') { - containerStyles.push({ - value: scrollContainer.style.overflow, - key: 'overflow', - el: scrollContainer, - }); - } - if (!shouldIOSLock) { - scrollContainer.style.overflow = 'hidden'; - } - modalRestoreStyles.push({ - container: container, - modals: 1, - styles: containerStyles, - }); -}; - -export { handleContainer, hasScrollbar, isScrolledToBottom, isScrolledToTop, restoreContainerStyles }; diff --git a/packages/base-modal/dist_side_poly/helpers/lockScroll.d.ts b/packages/base-modal/dist_side_poly/helpers/lockScroll.d.ts deleted file mode 100644 index 80e91475f8..0000000000 --- a/packages/base-modal/dist_side_poly/helpers/lockScroll.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -declare const isScrollLocked: () => boolean; -declare const lockScroll: () => void; -declare const unlockScroll: () => void; -declare const syncHeight: () => void; -export { isScrollLocked, lockScroll, unlockScroll, syncHeight }; diff --git a/packages/base-modal/dist_side_poly/helpers/lockScroll.js b/packages/base-modal/dist_side_poly/helpers/lockScroll.js deleted file mode 100644 index 5eea467f5b..0000000000 --- a/packages/base-modal/dist_side_poly/helpers/lockScroll.js +++ /dev/null @@ -1,28 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, '__esModule', { value: true }); - -/** - * Хелпер для блокирования скроллинга в iOS - * В проекте используется overflow: hidden для блокировки, но в некоторых случаях этого недостаточно. Данный хелпер призван решать эту проблему - */ -var scrollY; -var isScrollLocked = function () { return document.body.classList.contains('is-locked'); }; -var lockScroll = function () { - scrollY = window.scrollY; - document.body.classList.add('is-locked'); -}; -var unlockScroll = function () { - if (!isScrollLocked()) - return; - document.body.classList.remove('is-locked'); - window.scrollTo(0, scrollY); -}; -var syncHeight = function () { - document.body.style.setProperty('--window-inner-scrollY', "".concat(window.scrollY, "px")); -}; - -exports.isScrollLocked = isScrollLocked; -exports.lockScroll = lockScroll; -exports.syncHeight = syncHeight; -exports.unlockScroll = unlockScroll; diff --git a/packages/base-modal/dist_side_poly/index.css b/packages/base-modal/dist_side_poly/index.css deleted file mode 100644 index 717db4385d..0000000000 --- a/packages/base-modal/dist_side_poly/index.css +++ /dev/null @@ -1,71 +0,0 @@ -/* hash: 5nduy */ -:root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ -} /* deprecated */ :root { - --color-light-modal-bg-primary: #fff; /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ -} :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ -} :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ -} :root { - - /* Hard */ - - /* Up */ - - /* Hard up */ -} :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ - - /* новые значения, используйте их */ -} :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ - - /* новые значения, используйте их */ - --gap-0: 0; -} :root { -} :root { -} /* сбрасывает синюю подсветку при нажатии */ :root { - --window-inner-scrollY: 10px; /* fallback value to prevent ci error */ -} body.is-locked { - margin-top: calc(var(--window-inner-scrollY) * -1); - position: fixed; - overflow: hidden; -} .base-modal__component_1y6m8 { - position: relative; - box-sizing: border-box; - background: var(--color-light-modal-bg-primary); - margin: auto; - flex-shrink: 0; -} .base-modal__wrapper_1y6m8 { - position: fixed; - top: var(--gap-0); - left: var(--gap-0); - right: var(--gap-0); - bottom: var(--gap-0); - - overflow: auto; - display: flex; - flex-direction: column; - align-items: center; - outline: 0; - overscroll-behavior: none; -} .base-modal__content_1y6m8 { - width: 100%; - height: 100%; - display: flex; - flex-direction: column; - flex: 1; -} .base-modal__hidden_1y6m8 { - display: none; -} .base-modal__backdrop_1y6m8 { - z-index: 0; -} .base-modal__appear_1y6m8, -.base-modal__enter_1y6m8 { - opacity: 0; -} .base-modal__appearActive_1y6m8, -.base-modal__enterActive_1y6m8 { - opacity: 1; - transition: opacity 200ms ease-in; -} .base-modal__exit_1y6m8 { - opacity: 1; -} .base-modal__exitActive_1y6m8, -.base-modal__exitDone_1y6m8 { - opacity: 0; - transition: opacity 200ms ease-out; -} diff --git a/packages/base-modal/dist_side_poly/index.d.ts b/packages/base-modal/dist_side_poly/index.d.ts deleted file mode 100644 index 61ae91968a..0000000000 --- a/packages/base-modal/dist_side_poly/index.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from "./Component"; -export * from "./utils"; -export * from "./helpers/lockScroll"; diff --git a/packages/base-modal/dist_side_poly/index.js b/packages/base-modal/dist_side_poly/index.js deleted file mode 100644 index cf4a09932b..0000000000 --- a/packages/base-modal/dist_side_poly/index.js +++ /dev/null @@ -1,21 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, '__esModule', { value: true }); - -var Component = require('./Component.js'); -var utils = require('./utils.js'); -var helpers_lockScroll = require('./helpers/lockScroll.js'); - - - -exports.BaseModal = Component.BaseModal; -exports.BaseModalContext = Component.BaseModalContext; -exports.handleContainer = utils.handleContainer; -exports.hasScrollbar = utils.hasScrollbar; -exports.isScrolledToBottom = utils.isScrolledToBottom; -exports.isScrolledToTop = utils.isScrolledToTop; -exports.restoreContainerStyles = utils.restoreContainerStyles; -exports.isScrollLocked = helpers_lockScroll.isScrollLocked; -exports.lockScroll = helpers_lockScroll.lockScroll; -exports.syncHeight = helpers_lockScroll.syncHeight; -exports.unlockScroll = helpers_lockScroll.unlockScroll; diff --git a/packages/base-modal/dist_side_poly/matches-polyfill.d.ts b/packages/base-modal/dist_side_poly/matches-polyfill.d.ts deleted file mode 100644 index cb0ff5c3b5..0000000000 --- a/packages/base-modal/dist_side_poly/matches-polyfill.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/packages/base-modal/dist_side_poly/matches-polyfill.js b/packages/base-modal/dist_side_poly/matches-polyfill.js deleted file mode 100644 index e36a0cd0b7..0000000000 --- a/packages/base-modal/dist_side_poly/matches-polyfill.js +++ /dev/null @@ -1,20 +0,0 @@ -'use strict'; - -/* eslint-disable */ -// @ts-nocheck -if (typeof window !== 'undefined') { - if (Element && !Element.prototype.matches) { - Element.prototype.matches = - Element.prototype.matchesSelector || - Element.prototype.mozMatchesSelector || - Element.prototype.msMatchesSelector || - Element.prototype.oMatchesSelector || - Element.prototype.webkitMatchesSelector || - function (s) { - var matches = (this.document || this.ownerDocument).querySelectorAll(s); - var i = matches.length; - while (--i >= 0 && matches.item(i) !== this) { } - return i > -1; - }; - } -} diff --git a/packages/base-modal/dist_side_poly/modern/Component.d.ts b/packages/base-modal/dist_side_poly/modern/Component.d.ts deleted file mode 100644 index 44533e4e97..0000000000 --- a/packages/base-modal/dist_side_poly/modern/Component.d.ts +++ /dev/null @@ -1,159 +0,0 @@ -/// -/// -import React from 'react'; -import { ComponentType, KeyboardEvent, MouseEvent, MutableRefObject, ReactNode, Ref } from "react"; -import { TransitionProps } from 'react-transition-group/Transition'; -import { BackdropProps } from "@alfalab/core-components-backdrop"; -import { PortalProps } from "@alfalab/core-components-portal"; -type BaseModalProps = { - /** - * Контент - */ - children?: ReactNode; - /** - * Компонент бэкдропа - */ - Backdrop?: ComponentType; - /** - * Свойства для Бэкдропа - */ - backdropProps?: Partial & Record; - /** - * Нода, компонент или функция возвращающая их - * - * Контейнер к которому будут добавляться порталы - */ - container?: PortalProps['getPortalContainer']; - /** - * Отключает автоматический перевод фокуса на модалку при открытии - * @default false - */ - disableAutoFocus?: boolean; - /** - * Отключает ловушку фокуса - * @default false - */ - disableFocusLock?: boolean; - /** - * Отключает восстановление фокуса на предыдущем элементе после закрытия модалки - * @default false - */ - disableRestoreFocus?: boolean; - /** - * Отключает вызов `callback` при нажатии Escape - * @default false - */ - disableEscapeKeyDown?: boolean; - /** - * Отключает вызов `callback` при клике на бэкдроп - * @default false - */ - disableBackdropClick?: boolean; - /** - * Отключает блокировку скролла при открытии модального окна - * @default false - */ - disableBlockingScroll?: boolean; - /** - * Содержимое модалки всегда в DOM - * @default false - */ - keepMounted?: boolean; - /** - * Управление видимостью модалки - */ - open: boolean; - /** - * Дополнительный класс - */ - className?: string; - /** - * Дополнительный класс - */ - contentClassName?: string; - /** - * Дополнительные пропсы на dialog wrapper - */ - wrapperProps?: React.DetailedHTMLProps, HTMLDivElement>; - /** - * Дополнительные пропсы на обертку контента - */ - contentProps?: React.DetailedHTMLProps, HTMLDivElement>; - /** - * Дополнительные пропсы на компонентную обертку контента - */ - componentDivProps?: React.DetailedHTMLProps, HTMLDivElement>; - /** - * Дополнительный класс для обертки (Modal) - */ - wrapperClassName?: string; - /** - * Обработчик скролла контента - */ - scrollHandler?: 'wrapper' | 'content' | MutableRefObject; - /** - * Пропсы для анимации (CSSTransition) - */ - transitionProps?: Partial; - /** - * Рендерить ли в контейнер через портал. - * @default true - */ - usePortal?: boolean; - /** - * Обработчик события нажатия на бэкдроп - */ - onBackdropClick?: (event: MouseEvent) => void; - /** - * Обработчик события нажатия на Escape - * - * Если `disableEscapeKeyDown` - false и модальное окно в фокусе - */ - onEscapeKeyDown?: (event: KeyboardEvent) => void; - /** - * Обработчик закрытия - */ - onClose?: (event: MouseEvent | KeyboardEvent, reason?: 'backdropClick' | 'escapeKeyDown' | 'closerClick') => void; - /** - * Обработчик события onEntered компонента Transition - */ - onMount?: () => void; - /** - * Обработчик события onExited компонента Transition - */ - onUnmount?: () => void; - /** - * Идентификатор для систем автоматизированного тестирования - */ - dataTestId?: string; - /** - * z-index компонента - */ - zIndex?: number; - /** - * Реф, который должен быть установлен компонентной области - */ - componentRef?: MutableRefObject; - /** - * Блокирует скролл когда модальное окно открыто. Работает только на iOS. - */ - iOSLock?: boolean; -}; -type BaseModalContext = { - parentRef: React.RefObject; - componentRef: React.RefObject; - hasFooter?: boolean; - hasHeader?: boolean; - hasScroll?: boolean; - headerHighlighted?: boolean; - footerHighlighted?: boolean; - headerOffset?: number; - setHeaderOffset: (offset: number) => void; - contentRef: Ref; - setHasHeader: (exists: boolean) => void; - setHasFooter: (exists: boolean) => void; - onClose: Required['onClose']; -}; -declare const BaseModalContext: React.Context; -declare const BaseModal: React.ForwardRefExoticComponent>; -export { BaseModalProps, BaseModalContext, BaseModal }; diff --git a/packages/base-modal/dist_side_poly/modern/Component.js b/packages/base-modal/dist_side_poly/modern/Component.js deleted file mode 100644 index e09ffa65a8..0000000000 --- a/packages/base-modal/dist_side_poly/modern/Component.js +++ /dev/null @@ -1,269 +0,0 @@ -import React, { forwardRef, useState, useRef, useCallback, useEffect, useMemo } from 'react'; -import FocusLock from 'react-focus-lock'; -import mergeRefs from 'react-merge-refs'; -import { CSSTransition } from 'react-transition-group'; -import { ResizeObserver } from '@juggle/resize-observer'; -import cn from 'classnames'; -import { Backdrop } from '@alfalab/core-components-backdrop/modern'; -import { Portal } from '@alfalab/core-components-portal/modern'; -import { os, browser } from '@alfalab/core-components-shared/modern'; -import { Stack } from '@alfalab/core-components-stack/modern'; -import { stackingOrder } from '@alfalab/stack-context'; -import { unlockScroll, syncHeight, lockScroll } from './helpers/lockScroll.js'; -import { isScrolledToTop, isScrolledToBottom, handleContainer, restoreContainerStyles, hasScrollbar } from './utils.js'; -import './matches-polyfill.js'; - -const styles = {"component":"base-modal__component_1y6m8","wrapper":"base-modal__wrapper_1y6m8","content":"base-modal__content_1y6m8","hidden":"base-modal__hidden_1y6m8","backdrop":"base-modal__backdrop_1y6m8","appear":"base-modal__appear_1y6m8","enter":"base-modal__enter_1y6m8","appearActive":"base-modal__appearActive_1y6m8","enterActive":"base-modal__enterActive_1y6m8","exit":"base-modal__exit_1y6m8","exitActive":"base-modal__exitActive_1y6m8","exitDone":"base-modal__exitDone_1y6m8"}; -require('./index.css') - -/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */ -// eslint-disable-next-line @typescript-eslint/no-redeclare -const BaseModalContext = React.createContext({ - parentRef: { current: null }, - componentRef: { current: null }, - hasFooter: false, - hasHeader: false, - hasScroll: false, - headerHighlighted: false, - footerHighlighted: false, - headerOffset: 0, - setHeaderOffset: () => null, - contentRef: () => null, - setHasHeader: () => null, - setHasFooter: () => null, - onClose: () => null, -}); -const BaseModal = forwardRef(({ open, container, children, scrollHandler = 'wrapper', Backdrop: Backdrop$1 = Backdrop, backdropProps = {}, transitionProps = {}, disableBackdropClick, disableAutoFocus = false, disableFocusLock = false, disableEscapeKeyDown = false, disableRestoreFocus = false, disableBlockingScroll = false, keepMounted = false, className, contentClassName, wrapperProps, contentProps, componentDivProps, wrapperClassName, onBackdropClick, onClose, onEscapeKeyDown, onMount, onUnmount, dataTestId, zIndex = stackingOrder.MODAL, componentRef = null, usePortal = true, iOSLock = false, }, ref) => { - const [exited, setExited] = useState(null); - const [hasScroll, setHasScroll] = useState(false); - const [hasHeader, setHasHeader] = useState(false); - const [hasFooter, setHasFooter] = useState(false); - const [headerHighlighted, setHeaderHighlighted] = useState(false); - const [footerHighlighted, setFooterHighlighted] = useState(false); - const [headerOffset, setHeaderOffset] = useState(0); - const componentNodeRef = useRef(null); - const wrapperRef = useRef(null); - const scrollableNodeRef = useRef(null); - const contentNodeRef = useRef(null); - const restoreContainerStylesRef = useRef(null); - const mouseDownTarget = useRef(); - const resizeObserverRef = useRef(); - const checkToHasScrollBar = () => { - if (scrollableNodeRef.current) { - const scrollExists = hasScrollbar(scrollableNodeRef.current); - setFooterHighlighted(scrollExists); - setHasScroll(scrollExists); - } - }; - const isExited = exited || exited === null; - const shouldRender = keepMounted || open || !isExited; - const getContainer = useCallback(() => (container ? container() : document.body), [container]); - const addResizeHandle = useCallback(() => { - if (!resizeObserverRef.current) - return; - if (scrollableNodeRef.current) { - resizeObserverRef.current.observe(scrollableNodeRef.current); - } - if (contentNodeRef.current) { - resizeObserverRef.current.observe(contentNodeRef.current); - } - }, []); - const removeResizeHandle = useCallback(() => resizeObserverRef.current?.disconnect(), []); - const contentRef = useCallback((node) => { - if (node !== null) { - contentNodeRef.current = node; - if (resizeObserverRef.current) { - resizeObserverRef.current.observe(node); - } - checkToHasScrollBar(); - } - }, []); - const handleScroll = useCallback(() => { - if (!scrollableNodeRef.current || !componentNodeRef.current) - return; - if (hasHeader) { - setHeaderHighlighted(!isScrolledToTop(scrollableNodeRef.current) && - componentNodeRef.current.getBoundingClientRect().top - headerOffset <= 1); - } - if (hasFooter) { - setFooterHighlighted(!isScrolledToBottom(scrollableNodeRef.current) && - componentNodeRef.current.getBoundingClientRect().bottom >= - window.innerHeight - 1); - } - }, [hasFooter, hasHeader, headerOffset]); - const handleClose = useCallback((event, reason) => { - if (iOSLock && os.isIOS()) { - unlockScroll(); - } - if (onClose) { - onClose(event, reason); - } - if (reason === 'backdropClick' && onBackdropClick) { - onBackdropClick(event); - } - if (reason === 'escapeKeyDown' && onEscapeKeyDown) { - onEscapeKeyDown(event); - } - return null; - }, [onBackdropClick, onClose, onEscapeKeyDown, iOSLock]); - const handleBackdropMouseDown = (event) => { - let clickedOnScrollbar = false; - const clientWidth = event.target?.clientWidth; - if (event.clientX && clientWidth) { - // Устанавливаем смещение для абсолютно спозиционированного скроллбара в OSX в 17px. - const offset = browser.getScrollbarSize() === 0 ? 17 : 0; - clickedOnScrollbar = event.clientX + offset > clientWidth; - } - if (!disableBackdropClick && !clickedOnScrollbar) { - mouseDownTarget.current = event.target; - } - }; - const handleBackdropMouseUp = (event) => { - if (!disableBackdropClick && - event.target === wrapperRef.current && - mouseDownTarget.current === wrapperRef.current) { - handleClose(event, 'backdropClick'); - } - mouseDownTarget.current = undefined; - }; - const handleKeyDown = useCallback((event) => { - /* - * Чтобы сохранить дефолтное поведение элементов и событий форм, - * обработчик не устанавливает event.preventDefault() - */ - if (event.key !== 'Escape') { - return; - } - // Если есть обработчик escape на body - event.stopPropagation(); - if (!disableEscapeKeyDown && handleClose) { - handleClose(event, 'escapeKeyDown'); - } - }, [disableEscapeKeyDown, handleClose]); - const getScrollHandler = useCallback(() => { - if (scrollHandler === 'wrapper') - return wrapperRef.current; - if (scrollHandler === 'content') - return componentNodeRef.current; - return scrollHandler.current || wrapperRef.current; - }, [scrollHandler]); - const handleEntered = useCallback((node, isAppearing) => { - scrollableNodeRef.current = getScrollHandler(); - addResizeHandle(); - if (scrollableNodeRef.current) { - scrollableNodeRef.current.addEventListener('scroll', handleScroll); - handleScroll(); - } - if (transitionProps.onEntered) { - transitionProps.onEntered(node, isAppearing); - } - if (onMount) - onMount(); - }, [addResizeHandle, getScrollHandler, handleScroll, onMount, transitionProps]); - const handleExited = useCallback((node) => { - removeResizeHandle(); - setExited(true); - if (scrollableNodeRef.current) { - scrollableNodeRef.current.removeEventListener('scroll', handleScroll); - } - if (transitionProps.onExited) { - transitionProps.onExited(node); - } - if (onUnmount) - onUnmount(); - if (restoreContainerStylesRef.current) { - restoreContainerStylesRef.current(); - } - }, [handleScroll, onUnmount, removeResizeHandle, transitionProps]); - useEffect(() => { - if (open && isExited) { - if (!disableBlockingScroll) { - const el = getContainer(); - const shouldIOSLock = iOSLock && os.isIOS(); - handleContainer(el, shouldIOSLock); - if (shouldIOSLock) { - syncHeight(); - lockScroll(); - } - restoreContainerStylesRef.current = () => { - restoreContainerStylesRef.current = null; - restoreContainerStyles(el); - }; - } - setExited(false); - } - if (!open) { - unlockScroll(); - } - }, [getContainer, open, disableBlockingScroll, isExited, iOSLock]); - useEffect(() => { - const ResizeObserver$1 = window.ResizeObserver || ResizeObserver; - resizeObserverRef.current = new ResizeObserver$1(checkToHasScrollBar); - return () => { - if (restoreContainerStylesRef.current) { - restoreContainerStylesRef.current(); - } - if (resizeObserverRef.current) { - resizeObserverRef.current.disconnect(); - } - }; - }, []); - useEffect(() => { - if (disableAutoFocus || !open) - return; - wrapperRef.current?.focus(); - }, [open, disableAutoFocus]); - const contextValue = useMemo(() => ({ - parentRef: wrapperRef, - componentRef: componentNodeRef, - hasHeader, - hasFooter, - hasScroll, - headerHighlighted, - footerHighlighted, - headerOffset, - setHeaderOffset, - contentRef, - setHasHeader, - setHasFooter, - onClose: handleClose, - }), [ - contentRef, - hasHeader, - hasFooter, - hasScroll, - headerHighlighted, - footerHighlighted, - headerOffset, - setHeaderOffset, - handleClose, - ]); - const renderContent = () => (React.createElement(Stack, { value: zIndex }, (computedZIndex) => (React.createElement(BaseModalContext.Provider, { value: contextValue }, - React.createElement(FocusLock, { disabled: disableFocusLock || !open, returnFocus: !disableRestoreFocus }, - Backdrop$1 && (React.createElement(Backdrop$1, { ...backdropProps, className: cn(backdropProps.className, styles.backdrop), open: open, style: { - zIndex: computedZIndex, - } })), - React.createElement("div", { ...wrapperProps, role: 'dialog', className: cn(styles.wrapper, wrapperClassName, wrapperProps?.className, { - [styles.hidden]: !open && isExited, - }), ref: mergeRefs([ - ref, - wrapperRef, - wrapperProps?.ref, - ]), onKeyDown: handleKeyDown, onMouseDown: handleBackdropMouseDown, onMouseUp: handleBackdropMouseUp, tabIndex: -1, "data-test-id": dataTestId, style: { - zIndex: computedZIndex, - } }, - React.createElement(CSSTransition, { appear: true, timeout: 200, classNames: styles, nodeRef: componentNodeRef, ...transitionProps, in: open, onEntered: handleEntered, onExited: handleExited }, - React.createElement("div", { ...componentDivProps, className: cn(styles.component, className, componentDivProps?.className), ref: mergeRefs([ - componentRef, - componentNodeRef, - componentDivProps?.ref || null, - ]) }, - React.createElement("div", { ...contentProps, className: cn(styles.content, contentClassName, contentProps?.className) }, children))))))))); - if (!shouldRender) - return null; - return usePortal ? (React.createElement(Portal, { getPortalContainer: container, immediateMount: true }, renderContent())) : (renderContent()); -}); -BaseModal.displayName = 'BaseModal'; -BaseModalContext.displayName = 'BaseModalContext'; - -export { BaseModal, BaseModalContext }; diff --git a/packages/base-modal/dist_side_poly/modern/helpers/lockScroll.d.ts b/packages/base-modal/dist_side_poly/modern/helpers/lockScroll.d.ts deleted file mode 100644 index 80e91475f8..0000000000 --- a/packages/base-modal/dist_side_poly/modern/helpers/lockScroll.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -declare const isScrollLocked: () => boolean; -declare const lockScroll: () => void; -declare const unlockScroll: () => void; -declare const syncHeight: () => void; -export { isScrollLocked, lockScroll, unlockScroll, syncHeight }; diff --git a/packages/base-modal/dist_side_poly/modern/helpers/lockScroll.js b/packages/base-modal/dist_side_poly/modern/helpers/lockScroll.js deleted file mode 100644 index 7d6a7f293e..0000000000 --- a/packages/base-modal/dist_side_poly/modern/helpers/lockScroll.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Хелпер для блокирования скроллинга в iOS - * В проекте используется overflow: hidden для блокировки, но в некоторых случаях этого недостаточно. Данный хелпер призван решать эту проблему - */ -let scrollY; -const isScrollLocked = () => document.body.classList.contains('is-locked'); -const lockScroll = () => { - scrollY = window.scrollY; - document.body.classList.add('is-locked'); -}; -const unlockScroll = () => { - if (!isScrollLocked()) - return; - document.body.classList.remove('is-locked'); - window.scrollTo(0, scrollY); -}; -const syncHeight = () => { - document.body.style.setProperty('--window-inner-scrollY', `${window.scrollY}px`); -}; - -export { isScrollLocked, lockScroll, syncHeight, unlockScroll }; diff --git a/packages/base-modal/dist_side_poly/modern/index.css b/packages/base-modal/dist_side_poly/modern/index.css deleted file mode 100644 index 717db4385d..0000000000 --- a/packages/base-modal/dist_side_poly/modern/index.css +++ /dev/null @@ -1,71 +0,0 @@ -/* hash: 5nduy */ -:root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ -} /* deprecated */ :root { - --color-light-modal-bg-primary: #fff; /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ -} :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ -} :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ -} :root { - - /* Hard */ - - /* Up */ - - /* Hard up */ -} :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ - - /* новые значения, используйте их */ -} :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ - - /* новые значения, используйте их */ - --gap-0: 0; -} :root { -} :root { -} /* сбрасывает синюю подсветку при нажатии */ :root { - --window-inner-scrollY: 10px; /* fallback value to prevent ci error */ -} body.is-locked { - margin-top: calc(var(--window-inner-scrollY) * -1); - position: fixed; - overflow: hidden; -} .base-modal__component_1y6m8 { - position: relative; - box-sizing: border-box; - background: var(--color-light-modal-bg-primary); - margin: auto; - flex-shrink: 0; -} .base-modal__wrapper_1y6m8 { - position: fixed; - top: var(--gap-0); - left: var(--gap-0); - right: var(--gap-0); - bottom: var(--gap-0); - - overflow: auto; - display: flex; - flex-direction: column; - align-items: center; - outline: 0; - overscroll-behavior: none; -} .base-modal__content_1y6m8 { - width: 100%; - height: 100%; - display: flex; - flex-direction: column; - flex: 1; -} .base-modal__hidden_1y6m8 { - display: none; -} .base-modal__backdrop_1y6m8 { - z-index: 0; -} .base-modal__appear_1y6m8, -.base-modal__enter_1y6m8 { - opacity: 0; -} .base-modal__appearActive_1y6m8, -.base-modal__enterActive_1y6m8 { - opacity: 1; - transition: opacity 200ms ease-in; -} .base-modal__exit_1y6m8 { - opacity: 1; -} .base-modal__exitActive_1y6m8, -.base-modal__exitDone_1y6m8 { - opacity: 0; - transition: opacity 200ms ease-out; -} diff --git a/packages/base-modal/dist_side_poly/modern/index.d.ts b/packages/base-modal/dist_side_poly/modern/index.d.ts deleted file mode 100644 index 61ae91968a..0000000000 --- a/packages/base-modal/dist_side_poly/modern/index.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from "./Component"; -export * from "./utils"; -export * from "./helpers/lockScroll"; diff --git a/packages/base-modal/dist_side_poly/modern/index.js b/packages/base-modal/dist_side_poly/modern/index.js deleted file mode 100644 index ee07c7a608..0000000000 --- a/packages/base-modal/dist_side_poly/modern/index.js +++ /dev/null @@ -1,3 +0,0 @@ -export { BaseModal, BaseModalContext } from './Component.js'; -export { handleContainer, hasScrollbar, isScrolledToBottom, isScrolledToTop, restoreContainerStyles } from './utils.js'; -export { isScrollLocked, lockScroll, syncHeight, unlockScroll } from './helpers/lockScroll.js'; diff --git a/packages/base-modal/dist_side_poly/modern/matches-polyfill.d.ts b/packages/base-modal/dist_side_poly/modern/matches-polyfill.d.ts deleted file mode 100644 index cb0ff5c3b5..0000000000 --- a/packages/base-modal/dist_side_poly/modern/matches-polyfill.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/packages/base-modal/dist_side_poly/modern/matches-polyfill.js b/packages/base-modal/dist_side_poly/modern/matches-polyfill.js deleted file mode 100644 index 931ad2a8ea..0000000000 --- a/packages/base-modal/dist_side_poly/modern/matches-polyfill.js +++ /dev/null @@ -1,18 +0,0 @@ -/* eslint-disable */ -// @ts-nocheck -if (typeof window !== 'undefined') { - if (Element && !Element.prototype.matches) { - Element.prototype.matches = - Element.prototype.matchesSelector || - Element.prototype.mozMatchesSelector || - Element.prototype.msMatchesSelector || - Element.prototype.oMatchesSelector || - Element.prototype.webkitMatchesSelector || - function (s) { - const matches = (this.document || this.ownerDocument).querySelectorAll(s); - let i = matches.length; - while (--i >= 0 && matches.item(i) !== this) { } - return i > -1; - }; - } -} diff --git a/packages/base-modal/dist_side_poly/modern/utils.d.ts b/packages/base-modal/dist_side_poly/modern/utils.d.ts deleted file mode 100644 index 75401779bb..0000000000 --- a/packages/base-modal/dist_side_poly/modern/utils.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -declare function isScrolledToTop(target: HTMLElement): boolean; -declare function isScrolledToBottom(target: HTMLElement): boolean; -declare function hasScrollbar(target: HTMLElement): boolean; -declare const restoreContainerStyles: (container: HTMLElement) => void; -declare const handleContainer: (container?: HTMLElement, shouldIOSLock?: boolean) => void; -export { isScrolledToTop, isScrolledToBottom, hasScrollbar, restoreContainerStyles, handleContainer }; diff --git a/packages/base-modal/dist_side_poly/modern/utils.js b/packages/base-modal/dist_side_poly/modern/utils.js deleted file mode 100644 index 6432752044..0000000000 --- a/packages/base-modal/dist_side_poly/modern/utils.js +++ /dev/null @@ -1,87 +0,0 @@ -import { getModalStore } from '@alfalab/core-components-global-store/modern'; -import { browser } from '@alfalab/core-components-shared/modern'; - -function isScrolledToTop(target) { - return target.scrollTop <= 0; -} -function isScrolledToBottom(target) { - return target.scrollHeight - target.offsetHeight <= target.scrollTop; -} -function hasScrollbar(target) { - return target.scrollHeight > target.clientHeight; -} -const isOverflowing = (container) => { - if (document.body === container) { - return window.innerWidth > document.documentElement.clientWidth; - } - return container.scrollHeight > container.clientHeight; -}; -const getPaddingRight = (node) => parseInt(window.getComputedStyle(node).paddingRight, 10) || 0; -const restoreContainerStyles = (container) => { - const modalRestoreStyles = getModalStore().getRestoreStyles(); - const index = modalRestoreStyles.findIndex((s) => s.container === container); - const existingStyles = modalRestoreStyles[index]; - if (!existingStyles) - return; - existingStyles.modals -= 1; - if (existingStyles.modals <= 0) { - modalRestoreStyles.splice(index, 1); - existingStyles.styles.forEach(({ value, el, key }) => { - if (value) { - el.style.setProperty(key, value); - } - else { - el.style.removeProperty(key); - } - }); - } -}; -const handleContainer = (container, shouldIOSLock = false) => { - if (!container) - return; - const modalRestoreStyles = getModalStore().getRestoreStyles(); - const existingStyles = modalRestoreStyles.find((s) => s.container === container); - if (existingStyles) { - existingStyles.modals += 1; - return; - } - const containerStyles = []; - if (isOverflowing(container)) { - // Вычисляет размер до применения `overflow hidden` для избежания скачков - const scrollbarSize = browser.getScrollbarSize(); - containerStyles.push({ - value: container.style.paddingRight, - key: 'padding-right', - el: container, - }); - // Вычисляем стили, чтобы получить реальный `padding` c шириной сколлбара - // eslint-disable-next-line no-param-reassign - container.style.paddingRight = `${getPaddingRight(container) + scrollbarSize}px`; - } - const parent = container.parentElement; - const scrollContainer = - // TODO: заменить на optional chaining - parent && - parent.nodeName === 'HTML' && - window.getComputedStyle(parent).overflowY === 'scroll' - ? parent - : container; - // Блокируем скролл даже если отсутствует скроллбар - if (scrollContainer.style.overflow !== 'hidden') { - containerStyles.push({ - value: scrollContainer.style.overflow, - key: 'overflow', - el: scrollContainer, - }); - } - if (!shouldIOSLock) { - scrollContainer.style.overflow = 'hidden'; - } - modalRestoreStyles.push({ - container, - modals: 1, - styles: containerStyles, - }); -}; - -export { handleContainer, hasScrollbar, isScrolledToBottom, isScrolledToTop, restoreContainerStyles }; diff --git a/packages/base-modal/dist_side_poly/moderncssm/Component.d.ts b/packages/base-modal/dist_side_poly/moderncssm/Component.d.ts deleted file mode 100644 index 44533e4e97..0000000000 --- a/packages/base-modal/dist_side_poly/moderncssm/Component.d.ts +++ /dev/null @@ -1,159 +0,0 @@ -/// -/// -import React from 'react'; -import { ComponentType, KeyboardEvent, MouseEvent, MutableRefObject, ReactNode, Ref } from "react"; -import { TransitionProps } from 'react-transition-group/Transition'; -import { BackdropProps } from "@alfalab/core-components-backdrop"; -import { PortalProps } from "@alfalab/core-components-portal"; -type BaseModalProps = { - /** - * Контент - */ - children?: ReactNode; - /** - * Компонент бэкдропа - */ - Backdrop?: ComponentType; - /** - * Свойства для Бэкдропа - */ - backdropProps?: Partial & Record; - /** - * Нода, компонент или функция возвращающая их - * - * Контейнер к которому будут добавляться порталы - */ - container?: PortalProps['getPortalContainer']; - /** - * Отключает автоматический перевод фокуса на модалку при открытии - * @default false - */ - disableAutoFocus?: boolean; - /** - * Отключает ловушку фокуса - * @default false - */ - disableFocusLock?: boolean; - /** - * Отключает восстановление фокуса на предыдущем элементе после закрытия модалки - * @default false - */ - disableRestoreFocus?: boolean; - /** - * Отключает вызов `callback` при нажатии Escape - * @default false - */ - disableEscapeKeyDown?: boolean; - /** - * Отключает вызов `callback` при клике на бэкдроп - * @default false - */ - disableBackdropClick?: boolean; - /** - * Отключает блокировку скролла при открытии модального окна - * @default false - */ - disableBlockingScroll?: boolean; - /** - * Содержимое модалки всегда в DOM - * @default false - */ - keepMounted?: boolean; - /** - * Управление видимостью модалки - */ - open: boolean; - /** - * Дополнительный класс - */ - className?: string; - /** - * Дополнительный класс - */ - contentClassName?: string; - /** - * Дополнительные пропсы на dialog wrapper - */ - wrapperProps?: React.DetailedHTMLProps, HTMLDivElement>; - /** - * Дополнительные пропсы на обертку контента - */ - contentProps?: React.DetailedHTMLProps, HTMLDivElement>; - /** - * Дополнительные пропсы на компонентную обертку контента - */ - componentDivProps?: React.DetailedHTMLProps, HTMLDivElement>; - /** - * Дополнительный класс для обертки (Modal) - */ - wrapperClassName?: string; - /** - * Обработчик скролла контента - */ - scrollHandler?: 'wrapper' | 'content' | MutableRefObject; - /** - * Пропсы для анимации (CSSTransition) - */ - transitionProps?: Partial; - /** - * Рендерить ли в контейнер через портал. - * @default true - */ - usePortal?: boolean; - /** - * Обработчик события нажатия на бэкдроп - */ - onBackdropClick?: (event: MouseEvent) => void; - /** - * Обработчик события нажатия на Escape - * - * Если `disableEscapeKeyDown` - false и модальное окно в фокусе - */ - onEscapeKeyDown?: (event: KeyboardEvent) => void; - /** - * Обработчик закрытия - */ - onClose?: (event: MouseEvent | KeyboardEvent, reason?: 'backdropClick' | 'escapeKeyDown' | 'closerClick') => void; - /** - * Обработчик события onEntered компонента Transition - */ - onMount?: () => void; - /** - * Обработчик события onExited компонента Transition - */ - onUnmount?: () => void; - /** - * Идентификатор для систем автоматизированного тестирования - */ - dataTestId?: string; - /** - * z-index компонента - */ - zIndex?: number; - /** - * Реф, который должен быть установлен компонентной области - */ - componentRef?: MutableRefObject; - /** - * Блокирует скролл когда модальное окно открыто. Работает только на iOS. - */ - iOSLock?: boolean; -}; -type BaseModalContext = { - parentRef: React.RefObject; - componentRef: React.RefObject; - hasFooter?: boolean; - hasHeader?: boolean; - hasScroll?: boolean; - headerHighlighted?: boolean; - footerHighlighted?: boolean; - headerOffset?: number; - setHeaderOffset: (offset: number) => void; - contentRef: Ref; - setHasHeader: (exists: boolean) => void; - setHasFooter: (exists: boolean) => void; - onClose: Required['onClose']; -}; -declare const BaseModalContext: React.Context; -declare const BaseModal: React.ForwardRefExoticComponent>; -export { BaseModalProps, BaseModalContext, BaseModal }; diff --git a/packages/base-modal/dist_side_poly/moderncssm/Component.js b/packages/base-modal/dist_side_poly/moderncssm/Component.js deleted file mode 100644 index 865b66f59b..0000000000 --- a/packages/base-modal/dist_side_poly/moderncssm/Component.js +++ /dev/null @@ -1,267 +0,0 @@ -import React, { forwardRef, useState, useRef, useCallback, useEffect, useMemo } from 'react'; -import FocusLock from 'react-focus-lock'; -import mergeRefs from 'react-merge-refs'; -import { CSSTransition } from 'react-transition-group'; -import { ResizeObserver } from '@juggle/resize-observer'; -import cn from 'classnames'; -import { Backdrop } from '@alfalab/core-components-backdrop/moderncssm'; -import { Portal } from '@alfalab/core-components-portal/moderncssm'; -import { os, browser } from '@alfalab/core-components-shared/moderncssm'; -import { Stack } from '@alfalab/core-components-stack/moderncssm'; -import { stackingOrder } from '@alfalab/stack-context'; -import { unlockScroll, syncHeight, lockScroll } from './helpers/lockScroll.js'; -import { isScrolledToTop, isScrolledToBottom, handleContainer, restoreContainerStyles, hasScrollbar } from './utils.js'; -import styles from './index.module.css'; -import './matches-polyfill.js'; - -/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */ -// eslint-disable-next-line @typescript-eslint/no-redeclare -const BaseModalContext = React.createContext({ - parentRef: { current: null }, - componentRef: { current: null }, - hasFooter: false, - hasHeader: false, - hasScroll: false, - headerHighlighted: false, - footerHighlighted: false, - headerOffset: 0, - setHeaderOffset: () => null, - contentRef: () => null, - setHasHeader: () => null, - setHasFooter: () => null, - onClose: () => null, -}); -const BaseModal = forwardRef(({ open, container, children, scrollHandler = 'wrapper', Backdrop: Backdrop$1 = Backdrop, backdropProps = {}, transitionProps = {}, disableBackdropClick, disableAutoFocus = false, disableFocusLock = false, disableEscapeKeyDown = false, disableRestoreFocus = false, disableBlockingScroll = false, keepMounted = false, className, contentClassName, wrapperProps, contentProps, componentDivProps, wrapperClassName, onBackdropClick, onClose, onEscapeKeyDown, onMount, onUnmount, dataTestId, zIndex = stackingOrder.MODAL, componentRef = null, usePortal = true, iOSLock = false, }, ref) => { - const [exited, setExited] = useState(null); - const [hasScroll, setHasScroll] = useState(false); - const [hasHeader, setHasHeader] = useState(false); - const [hasFooter, setHasFooter] = useState(false); - const [headerHighlighted, setHeaderHighlighted] = useState(false); - const [footerHighlighted, setFooterHighlighted] = useState(false); - const [headerOffset, setHeaderOffset] = useState(0); - const componentNodeRef = useRef(null); - const wrapperRef = useRef(null); - const scrollableNodeRef = useRef(null); - const contentNodeRef = useRef(null); - const restoreContainerStylesRef = useRef(null); - const mouseDownTarget = useRef(); - const resizeObserverRef = useRef(); - const checkToHasScrollBar = () => { - if (scrollableNodeRef.current) { - const scrollExists = hasScrollbar(scrollableNodeRef.current); - setFooterHighlighted(scrollExists); - setHasScroll(scrollExists); - } - }; - const isExited = exited || exited === null; - const shouldRender = keepMounted || open || !isExited; - const getContainer = useCallback(() => (container ? container() : document.body), [container]); - const addResizeHandle = useCallback(() => { - if (!resizeObserverRef.current) - return; - if (scrollableNodeRef.current) { - resizeObserverRef.current.observe(scrollableNodeRef.current); - } - if (contentNodeRef.current) { - resizeObserverRef.current.observe(contentNodeRef.current); - } - }, []); - const removeResizeHandle = useCallback(() => resizeObserverRef.current?.disconnect(), []); - const contentRef = useCallback((node) => { - if (node !== null) { - contentNodeRef.current = node; - if (resizeObserverRef.current) { - resizeObserverRef.current.observe(node); - } - checkToHasScrollBar(); - } - }, []); - const handleScroll = useCallback(() => { - if (!scrollableNodeRef.current || !componentNodeRef.current) - return; - if (hasHeader) { - setHeaderHighlighted(!isScrolledToTop(scrollableNodeRef.current) && - componentNodeRef.current.getBoundingClientRect().top - headerOffset <= 1); - } - if (hasFooter) { - setFooterHighlighted(!isScrolledToBottom(scrollableNodeRef.current) && - componentNodeRef.current.getBoundingClientRect().bottom >= - window.innerHeight - 1); - } - }, [hasFooter, hasHeader, headerOffset]); - const handleClose = useCallback((event, reason) => { - if (iOSLock && os.isIOS()) { - unlockScroll(); - } - if (onClose) { - onClose(event, reason); - } - if (reason === 'backdropClick' && onBackdropClick) { - onBackdropClick(event); - } - if (reason === 'escapeKeyDown' && onEscapeKeyDown) { - onEscapeKeyDown(event); - } - return null; - }, [onBackdropClick, onClose, onEscapeKeyDown, iOSLock]); - const handleBackdropMouseDown = (event) => { - let clickedOnScrollbar = false; - const clientWidth = event.target?.clientWidth; - if (event.clientX && clientWidth) { - // Устанавливаем смещение для абсолютно спозиционированного скроллбара в OSX в 17px. - const offset = browser.getScrollbarSize() === 0 ? 17 : 0; - clickedOnScrollbar = event.clientX + offset > clientWidth; - } - if (!disableBackdropClick && !clickedOnScrollbar) { - mouseDownTarget.current = event.target; - } - }; - const handleBackdropMouseUp = (event) => { - if (!disableBackdropClick && - event.target === wrapperRef.current && - mouseDownTarget.current === wrapperRef.current) { - handleClose(event, 'backdropClick'); - } - mouseDownTarget.current = undefined; - }; - const handleKeyDown = useCallback((event) => { - /* - * Чтобы сохранить дефолтное поведение элементов и событий форм, - * обработчик не устанавливает event.preventDefault() - */ - if (event.key !== 'Escape') { - return; - } - // Если есть обработчик escape на body - event.stopPropagation(); - if (!disableEscapeKeyDown && handleClose) { - handleClose(event, 'escapeKeyDown'); - } - }, [disableEscapeKeyDown, handleClose]); - const getScrollHandler = useCallback(() => { - if (scrollHandler === 'wrapper') - return wrapperRef.current; - if (scrollHandler === 'content') - return componentNodeRef.current; - return scrollHandler.current || wrapperRef.current; - }, [scrollHandler]); - const handleEntered = useCallback((node, isAppearing) => { - scrollableNodeRef.current = getScrollHandler(); - addResizeHandle(); - if (scrollableNodeRef.current) { - scrollableNodeRef.current.addEventListener('scroll', handleScroll); - handleScroll(); - } - if (transitionProps.onEntered) { - transitionProps.onEntered(node, isAppearing); - } - if (onMount) - onMount(); - }, [addResizeHandle, getScrollHandler, handleScroll, onMount, transitionProps]); - const handleExited = useCallback((node) => { - removeResizeHandle(); - setExited(true); - if (scrollableNodeRef.current) { - scrollableNodeRef.current.removeEventListener('scroll', handleScroll); - } - if (transitionProps.onExited) { - transitionProps.onExited(node); - } - if (onUnmount) - onUnmount(); - if (restoreContainerStylesRef.current) { - restoreContainerStylesRef.current(); - } - }, [handleScroll, onUnmount, removeResizeHandle, transitionProps]); - useEffect(() => { - if (open && isExited) { - if (!disableBlockingScroll) { - const el = getContainer(); - const shouldIOSLock = iOSLock && os.isIOS(); - handleContainer(el, shouldIOSLock); - if (shouldIOSLock) { - syncHeight(); - lockScroll(); - } - restoreContainerStylesRef.current = () => { - restoreContainerStylesRef.current = null; - restoreContainerStyles(el); - }; - } - setExited(false); - } - if (!open) { - unlockScroll(); - } - }, [getContainer, open, disableBlockingScroll, isExited, iOSLock]); - useEffect(() => { - const ResizeObserver$1 = window.ResizeObserver || ResizeObserver; - resizeObserverRef.current = new ResizeObserver$1(checkToHasScrollBar); - return () => { - if (restoreContainerStylesRef.current) { - restoreContainerStylesRef.current(); - } - if (resizeObserverRef.current) { - resizeObserverRef.current.disconnect(); - } - }; - }, []); - useEffect(() => { - if (disableAutoFocus || !open) - return; - wrapperRef.current?.focus(); - }, [open, disableAutoFocus]); - const contextValue = useMemo(() => ({ - parentRef: wrapperRef, - componentRef: componentNodeRef, - hasHeader, - hasFooter, - hasScroll, - headerHighlighted, - footerHighlighted, - headerOffset, - setHeaderOffset, - contentRef, - setHasHeader, - setHasFooter, - onClose: handleClose, - }), [ - contentRef, - hasHeader, - hasFooter, - hasScroll, - headerHighlighted, - footerHighlighted, - headerOffset, - setHeaderOffset, - handleClose, - ]); - const renderContent = () => (React.createElement(Stack, { value: zIndex }, (computedZIndex) => (React.createElement(BaseModalContext.Provider, { value: contextValue }, - React.createElement(FocusLock, { disabled: disableFocusLock || !open, returnFocus: !disableRestoreFocus }, - Backdrop$1 && (React.createElement(Backdrop$1, { ...backdropProps, className: cn(backdropProps.className, styles.backdrop), open: open, style: { - zIndex: computedZIndex, - } })), - React.createElement("div", { ...wrapperProps, role: 'dialog', className: cn(styles.wrapper, wrapperClassName, wrapperProps?.className, { - [styles.hidden]: !open && isExited, - }), ref: mergeRefs([ - ref, - wrapperRef, - wrapperProps?.ref, - ]), onKeyDown: handleKeyDown, onMouseDown: handleBackdropMouseDown, onMouseUp: handleBackdropMouseUp, tabIndex: -1, "data-test-id": dataTestId, style: { - zIndex: computedZIndex, - } }, - React.createElement(CSSTransition, { appear: true, timeout: 200, classNames: styles, nodeRef: componentNodeRef, ...transitionProps, in: open, onEntered: handleEntered, onExited: handleExited }, - React.createElement("div", { ...componentDivProps, className: cn(styles.component, className, componentDivProps?.className), ref: mergeRefs([ - componentRef, - componentNodeRef, - componentDivProps?.ref || null, - ]) }, - React.createElement("div", { ...contentProps, className: cn(styles.content, contentClassName, contentProps?.className) }, children))))))))); - if (!shouldRender) - return null; - return usePortal ? (React.createElement(Portal, { getPortalContainer: container, immediateMount: true }, renderContent())) : (renderContent()); -}); -BaseModal.displayName = 'BaseModal'; -BaseModalContext.displayName = 'BaseModalContext'; - -export { BaseModal, BaseModalContext }; diff --git a/packages/base-modal/dist_side_poly/moderncssm/helpers/lockScroll.d.ts b/packages/base-modal/dist_side_poly/moderncssm/helpers/lockScroll.d.ts deleted file mode 100644 index 80e91475f8..0000000000 --- a/packages/base-modal/dist_side_poly/moderncssm/helpers/lockScroll.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -declare const isScrollLocked: () => boolean; -declare const lockScroll: () => void; -declare const unlockScroll: () => void; -declare const syncHeight: () => void; -export { isScrollLocked, lockScroll, unlockScroll, syncHeight }; diff --git a/packages/base-modal/dist_side_poly/moderncssm/helpers/lockScroll.js b/packages/base-modal/dist_side_poly/moderncssm/helpers/lockScroll.js deleted file mode 100644 index 7d6a7f293e..0000000000 --- a/packages/base-modal/dist_side_poly/moderncssm/helpers/lockScroll.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Хелпер для блокирования скроллинга в iOS - * В проекте используется overflow: hidden для блокировки, но в некоторых случаях этого недостаточно. Данный хелпер призван решать эту проблему - */ -let scrollY; -const isScrollLocked = () => document.body.classList.contains('is-locked'); -const lockScroll = () => { - scrollY = window.scrollY; - document.body.classList.add('is-locked'); -}; -const unlockScroll = () => { - if (!isScrollLocked()) - return; - document.body.classList.remove('is-locked'); - window.scrollTo(0, scrollY); -}; -const syncHeight = () => { - document.body.style.setProperty('--window-inner-scrollY', `${window.scrollY}px`); -}; - -export { isScrollLocked, lockScroll, syncHeight, unlockScroll }; diff --git a/packages/base-modal/dist_side_poly/moderncssm/index.d.ts b/packages/base-modal/dist_side_poly/moderncssm/index.d.ts deleted file mode 100644 index 61ae91968a..0000000000 --- a/packages/base-modal/dist_side_poly/moderncssm/index.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from "./Component"; -export * from "./utils"; -export * from "./helpers/lockScroll"; diff --git a/packages/base-modal/dist_side_poly/moderncssm/index.js b/packages/base-modal/dist_side_poly/moderncssm/index.js deleted file mode 100644 index ee07c7a608..0000000000 --- a/packages/base-modal/dist_side_poly/moderncssm/index.js +++ /dev/null @@ -1,3 +0,0 @@ -export { BaseModal, BaseModalContext } from './Component.js'; -export { handleContainer, hasScrollbar, isScrolledToBottom, isScrolledToTop, restoreContainerStyles } from './utils.js'; -export { isScrollLocked, lockScroll, syncHeight, unlockScroll } from './helpers/lockScroll.js'; diff --git a/packages/base-modal/dist_side_poly/moderncssm/index.module.css b/packages/base-modal/dist_side_poly/moderncssm/index.module.css deleted file mode 100644 index 3454492221..0000000000 --- a/packages/base-modal/dist_side_poly/moderncssm/index.module.css +++ /dev/null @@ -1,71 +0,0 @@ -/* */ - -:root { - --window-inner-scrollY: 10px; /* fallback value to prevent ci error */ -} - -body:global(.is-locked) { - margin-top: calc(var(--window-inner-scrollY) * -1); - position: fixed; - overflow: hidden; -} - -.component { - position: relative; - box-sizing: border-box; - background: var(--color-light-modal-bg-primary); - margin: auto; - flex-shrink: 0; -} - -.wrapper { - position: fixed; - top: var(--gap-0); - left: var(--gap-0); - right: var(--gap-0); - bottom: var(--gap-0); - - overflow: auto; - display: flex; - flex-direction: column; - align-items: center; - outline: 0; - overscroll-behavior: none; -} - -.content { - width: 100%; - height: 100%; - display: flex; - flex-direction: column; - flex: 1; -} - -.hidden { - display: none; -} - -.backdrop { - z-index: 0; -} - -.appear, -.enter { - opacity: 0; -} - -.appearActive, -.enterActive { - opacity: 1; - transition: opacity 200ms ease-in; -} - -.exit { - opacity: 1; -} - -.exitActive, -.exitDone { - opacity: 0; - transition: opacity 200ms ease-out; -} diff --git a/packages/base-modal/dist_side_poly/moderncssm/matches-polyfill.d.ts b/packages/base-modal/dist_side_poly/moderncssm/matches-polyfill.d.ts deleted file mode 100644 index cb0ff5c3b5..0000000000 --- a/packages/base-modal/dist_side_poly/moderncssm/matches-polyfill.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/packages/base-modal/dist_side_poly/moderncssm/matches-polyfill.js b/packages/base-modal/dist_side_poly/moderncssm/matches-polyfill.js deleted file mode 100644 index 931ad2a8ea..0000000000 --- a/packages/base-modal/dist_side_poly/moderncssm/matches-polyfill.js +++ /dev/null @@ -1,18 +0,0 @@ -/* eslint-disable */ -// @ts-nocheck -if (typeof window !== 'undefined') { - if (Element && !Element.prototype.matches) { - Element.prototype.matches = - Element.prototype.matchesSelector || - Element.prototype.mozMatchesSelector || - Element.prototype.msMatchesSelector || - Element.prototype.oMatchesSelector || - Element.prototype.webkitMatchesSelector || - function (s) { - const matches = (this.document || this.ownerDocument).querySelectorAll(s); - let i = matches.length; - while (--i >= 0 && matches.item(i) !== this) { } - return i > -1; - }; - } -} diff --git a/packages/base-modal/dist_side_poly/moderncssm/utils.d.ts b/packages/base-modal/dist_side_poly/moderncssm/utils.d.ts deleted file mode 100644 index 75401779bb..0000000000 --- a/packages/base-modal/dist_side_poly/moderncssm/utils.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -declare function isScrolledToTop(target: HTMLElement): boolean; -declare function isScrolledToBottom(target: HTMLElement): boolean; -declare function hasScrollbar(target: HTMLElement): boolean; -declare const restoreContainerStyles: (container: HTMLElement) => void; -declare const handleContainer: (container?: HTMLElement, shouldIOSLock?: boolean) => void; -export { isScrolledToTop, isScrolledToBottom, hasScrollbar, restoreContainerStyles, handleContainer }; diff --git a/packages/base-modal/dist_side_poly/moderncssm/utils.js b/packages/base-modal/dist_side_poly/moderncssm/utils.js deleted file mode 100644 index a42cedaa29..0000000000 --- a/packages/base-modal/dist_side_poly/moderncssm/utils.js +++ /dev/null @@ -1,87 +0,0 @@ -import { getModalStore } from '@alfalab/core-components-global-store/moderncssm'; -import { browser } from '@alfalab/core-components-shared/moderncssm'; - -function isScrolledToTop(target) { - return target.scrollTop <= 0; -} -function isScrolledToBottom(target) { - return target.scrollHeight - target.offsetHeight <= target.scrollTop; -} -function hasScrollbar(target) { - return target.scrollHeight > target.clientHeight; -} -const isOverflowing = (container) => { - if (document.body === container) { - return window.innerWidth > document.documentElement.clientWidth; - } - return container.scrollHeight > container.clientHeight; -}; -const getPaddingRight = (node) => parseInt(window.getComputedStyle(node).paddingRight, 10) || 0; -const restoreContainerStyles = (container) => { - const modalRestoreStyles = getModalStore().getRestoreStyles(); - const index = modalRestoreStyles.findIndex((s) => s.container === container); - const existingStyles = modalRestoreStyles[index]; - if (!existingStyles) - return; - existingStyles.modals -= 1; - if (existingStyles.modals <= 0) { - modalRestoreStyles.splice(index, 1); - existingStyles.styles.forEach(({ value, el, key }) => { - if (value) { - el.style.setProperty(key, value); - } - else { - el.style.removeProperty(key); - } - }); - } -}; -const handleContainer = (container, shouldIOSLock = false) => { - if (!container) - return; - const modalRestoreStyles = getModalStore().getRestoreStyles(); - const existingStyles = modalRestoreStyles.find((s) => s.container === container); - if (existingStyles) { - existingStyles.modals += 1; - return; - } - const containerStyles = []; - if (isOverflowing(container)) { - // Вычисляет размер до применения `overflow hidden` для избежания скачков - const scrollbarSize = browser.getScrollbarSize(); - containerStyles.push({ - value: container.style.paddingRight, - key: 'padding-right', - el: container, - }); - // Вычисляем стили, чтобы получить реальный `padding` c шириной сколлбара - // eslint-disable-next-line no-param-reassign - container.style.paddingRight = `${getPaddingRight(container) + scrollbarSize}px`; - } - const parent = container.parentElement; - const scrollContainer = - // TODO: заменить на optional chaining - parent && - parent.nodeName === 'HTML' && - window.getComputedStyle(parent).overflowY === 'scroll' - ? parent - : container; - // Блокируем скролл даже если отсутствует скроллбар - if (scrollContainer.style.overflow !== 'hidden') { - containerStyles.push({ - value: scrollContainer.style.overflow, - key: 'overflow', - el: scrollContainer, - }); - } - if (!shouldIOSLock) { - scrollContainer.style.overflow = 'hidden'; - } - modalRestoreStyles.push({ - container, - modals: 1, - styles: containerStyles, - }); -}; - -export { handleContainer, hasScrollbar, isScrolledToBottom, isScrolledToTop, restoreContainerStyles }; diff --git a/packages/base-modal/dist_side_poly/package.json b/packages/base-modal/dist_side_poly/package.json deleted file mode 100644 index 6f0d2d4e13..0000000000 --- a/packages/base-modal/dist_side_poly/package.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "name": "@alfalab/core-components-base-modal", - "version": "5.8.6", - "description": "BaseModal component", - "keywords": [], - "license": "MIT", - "main": "index.js", - "module": "./esm/index.js", - "publishConfig": { - "access": "public", - "directory": "dist" - }, - "sideEffects": [ - "./matches-polyfill" - ], - "dependencies": { - "@alfalab/core-components-backdrop": "^3.4.3", - "@alfalab/core-components-global-store": "^2.1.0", - "@alfalab/core-components-portal": "^3.3.4", - "@alfalab/core-components-stack": "^5.0.1", - "@alfalab/core-components-shared": "^0.14.0", - "@juggle/resize-observer": "^3.3.1", - "classnames": "^2.5.1", - "react-focus-lock": "^2.12.1", - "react-merge-refs": "^1.1.0", - "react-transition-group": "^4.4.5", - "tslib": "^2.4.0" - }, - "devDependencies": { - "@types/react-transition-group": "^4.4.5" - }, - "peerDependencies": { - "react": "^16.9.0 || ^17.0.1 || ^18.0.0" - }, - "themesVersion": "13.6.0", - "varsVersion": "9.16.0" -} diff --git a/packages/base-modal/dist_side_poly/src/Component.tsx b/packages/base-modal/dist_side_poly/src/Component.tsx deleted file mode 100644 index bcd9d7e773..0000000000 --- a/packages/base-modal/dist_side_poly/src/Component.tsx +++ /dev/null @@ -1,654 +0,0 @@ -/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */ -import React, { - ComponentType, - forwardRef, - KeyboardEvent, - MouseEvent, - MutableRefObject, - ReactNode, - Ref, - useCallback, - useEffect, - useMemo, - useRef, - useState, -} from 'react'; -import FocusLock from 'react-focus-lock'; -import mergeRefs from 'react-merge-refs'; -import { CSSTransition } from 'react-transition-group'; -import { TransitionProps } from 'react-transition-group/Transition'; -import { ResizeObserver as ResizeObserverPolyfill } from '@juggle/resize-observer'; -import cn from 'classnames'; - -import { Backdrop as DefaultBackdrop, BackdropProps } from '@alfalab/core-components-backdrop'; -import { Portal, PortalProps } from '@alfalab/core-components-portal'; -import { browser, os } from '@alfalab/core-components-shared'; -import { Stack } from '@alfalab/core-components-stack'; -import { stackingOrder } from '@alfalab/stack-context'; - -import { lockScroll, syncHeight, unlockScroll } from './helpers/lockScroll'; -import { - handleContainer, - hasScrollbar, - isScrolledToBottom, - isScrolledToTop, - restoreContainerStyles, -} from './utils'; - -import styles from './index.module.css'; - -// TODO Без полифила крашится FocusLock в IE11. Выпилить в будущем!!!. -import './matches-polyfill'; - -export type BaseModalProps = { - /** - * Контент - */ - children?: ReactNode; - - /** - * Компонент бэкдропа - */ - Backdrop?: ComponentType; - - /** - * Свойства для Бэкдропа - */ - backdropProps?: Partial & Record; - - /** - * Нода, компонент или функция возвращающая их - * - * Контейнер к которому будут добавляться порталы - */ - container?: PortalProps['getPortalContainer']; - - /** - * Отключает автоматический перевод фокуса на модалку при открытии - * @default false - */ - disableAutoFocus?: boolean; - - /** - * Отключает ловушку фокуса - * @default false - */ - disableFocusLock?: boolean; - - /** - * Отключает восстановление фокуса на предыдущем элементе после закрытия модалки - * @default false - */ - disableRestoreFocus?: boolean; - - /** - * Отключает вызов `callback` при нажатии Escape - * @default false - */ - disableEscapeKeyDown?: boolean; - - /** - * Отключает вызов `callback` при клике на бэкдроп - * @default false - */ - disableBackdropClick?: boolean; - - /** - * Отключает блокировку скролла при открытии модального окна - * @default false - */ - disableBlockingScroll?: boolean; - - /** - * Содержимое модалки всегда в DOM - * @default false - */ - keepMounted?: boolean; - - /** - * Управление видимостью модалки - */ - open: boolean; - - /** - * Дополнительный класс - */ - className?: string; - - /** - * Дополнительный класс - */ - contentClassName?: string; - - /** - * Дополнительные пропсы на dialog wrapper - */ - wrapperProps?: React.DetailedHTMLProps, HTMLDivElement>; - - /** - * Дополнительные пропсы на обертку контента - */ - contentProps?: React.DetailedHTMLProps, HTMLDivElement>; - - /** - * Дополнительные пропсы на компонентную обертку контента - */ - componentDivProps?: React.DetailedHTMLProps< - React.HTMLAttributes, - HTMLDivElement - >; - - /** - * Дополнительный класс для обертки (Modal) - */ - wrapperClassName?: string; - - /** - * Обработчик скролла контента - */ - scrollHandler?: 'wrapper' | 'content' | MutableRefObject; - - /** - * Пропсы для анимации (CSSTransition) - */ - transitionProps?: Partial; - - /** - * Рендерить ли в контейнер через портал. - * @default true - */ - usePortal?: boolean; - - /** - * Обработчик события нажатия на бэкдроп - */ - onBackdropClick?: (event: MouseEvent) => void; - - /** - * Обработчик события нажатия на Escape - * - * Если `disableEscapeKeyDown` - false и модальное окно в фокусе - */ - onEscapeKeyDown?: (event: KeyboardEvent) => void; - - /** - * Обработчик закрытия - */ - onClose?: ( - event: MouseEvent | KeyboardEvent, - reason?: 'backdropClick' | 'escapeKeyDown' | 'closerClick', - ) => void; - - /** - * Обработчик события onEntered компонента Transition - */ - onMount?: () => void; - - /** - * Обработчик события onExited компонента Transition - */ - onUnmount?: () => void; - - /** - * Идентификатор для систем автоматизированного тестирования - */ - dataTestId?: string; - - /** - * z-index компонента - */ - zIndex?: number; - - /** - * Реф, который должен быть установлен компонентной области - */ - componentRef?: MutableRefObject; - - /** - * Блокирует скролл когда модальное окно открыто. Работает только на iOS. - */ - iOSLock?: boolean; -}; - -export type BaseModalContext = { - parentRef: React.RefObject; - componentRef: React.RefObject; - hasFooter?: boolean; - hasHeader?: boolean; - hasScroll?: boolean; - headerHighlighted?: boolean; - footerHighlighted?: boolean; - headerOffset?: number; - setHeaderOffset: (offset: number) => void; - contentRef: Ref; - setHasHeader: (exists: boolean) => void; - setHasFooter: (exists: boolean) => void; - onClose: Required['onClose']; -}; - -// eslint-disable-next-line @typescript-eslint/no-redeclare -export const BaseModalContext = React.createContext({ - parentRef: { current: null }, - componentRef: { current: null }, - hasFooter: false, - hasHeader: false, - hasScroll: false, - headerHighlighted: false, - footerHighlighted: false, - headerOffset: 0, - setHeaderOffset: () => null, - contentRef: () => null, - setHasHeader: () => null, - setHasFooter: () => null, - onClose: () => null, -}); - -export const BaseModal = forwardRef( - ( - { - open, - container, - children, - scrollHandler = 'wrapper', - Backdrop = DefaultBackdrop, - backdropProps = {}, - transitionProps = {}, - disableBackdropClick, - disableAutoFocus = false, - disableFocusLock = false, - disableEscapeKeyDown = false, - disableRestoreFocus = false, - disableBlockingScroll = false, - keepMounted = false, - className, - contentClassName, - wrapperProps, - contentProps, - componentDivProps, - wrapperClassName, - onBackdropClick, - onClose, - onEscapeKeyDown, - onMount, - onUnmount, - dataTestId, - zIndex = stackingOrder.MODAL, - componentRef = null, - usePortal = true, - iOSLock = false, - }, - ref, - ) => { - const [exited, setExited] = useState(null); - const [hasScroll, setHasScroll] = useState(false); - const [hasHeader, setHasHeader] = useState(false); - const [hasFooter, setHasFooter] = useState(false); - const [headerHighlighted, setHeaderHighlighted] = useState(false); - const [footerHighlighted, setFooterHighlighted] = useState(false); - const [headerOffset, setHeaderOffset] = useState(0); - - const componentNodeRef = useRef(null); - const wrapperRef = useRef(null); - const scrollableNodeRef = useRef(null); - const contentNodeRef = useRef(null); - const restoreContainerStylesRef = useRef void)>(null); - const mouseDownTarget = useRef(); - const resizeObserverRef = useRef(); - - const checkToHasScrollBar = () => { - if (scrollableNodeRef.current) { - const scrollExists = hasScrollbar(scrollableNodeRef.current); - - setFooterHighlighted(scrollExists); - setHasScroll(scrollExists); - } - }; - - const isExited = exited || exited === null; - const shouldRender = keepMounted || open || !isExited; - - const getContainer = useCallback( - () => (container ? container() : document.body) as HTMLElement, - [container], - ); - - const addResizeHandle = useCallback(() => { - if (!resizeObserverRef.current) return; - - if (scrollableNodeRef.current) { - resizeObserverRef.current.observe(scrollableNodeRef.current); - } - if (contentNodeRef.current) { - resizeObserverRef.current.observe(contentNodeRef.current); - } - }, []); - - const removeResizeHandle = useCallback(() => resizeObserverRef.current?.disconnect(), []); - - const contentRef = useCallback((node: HTMLDivElement) => { - if (node !== null) { - contentNodeRef.current = node; - if (resizeObserverRef.current) { - resizeObserverRef.current.observe(node); - } - checkToHasScrollBar(); - } - }, []); - - const handleScroll = useCallback(() => { - if (!scrollableNodeRef.current || !componentNodeRef.current) return; - - if (hasHeader) { - setHeaderHighlighted( - !isScrolledToTop(scrollableNodeRef.current) && - componentNodeRef.current.getBoundingClientRect().top - headerOffset <= 1, - ); - } - - if (hasFooter) { - setFooterHighlighted( - !isScrolledToBottom(scrollableNodeRef.current) && - componentNodeRef.current.getBoundingClientRect().bottom >= - window.innerHeight - 1, - ); - } - }, [hasFooter, hasHeader, headerOffset]); - - const handleClose = useCallback['onClose']>( - (event, reason) => { - if (iOSLock && os.isIOS()) { - unlockScroll(); - } - - if (onClose) { - onClose(event, reason); - } - - if (reason === 'backdropClick' && onBackdropClick) { - onBackdropClick(event as MouseEvent); - } - - if (reason === 'escapeKeyDown' && onEscapeKeyDown) { - onEscapeKeyDown(event as KeyboardEvent); - } - - return null; - }, - [onBackdropClick, onClose, onEscapeKeyDown, iOSLock], - ); - - const handleBackdropMouseDown = (event: MouseEvent) => { - let clickedOnScrollbar = false; - const clientWidth = (event.target as HTMLElement)?.clientWidth; - - if (event.clientX && clientWidth) { - // Устанавливаем смещение для абсолютно спозиционированного скроллбара в OSX в 17px. - const offset = browser.getScrollbarSize() === 0 ? 17 : 0; - - clickedOnScrollbar = event.clientX + offset > clientWidth; - } - - if (!disableBackdropClick && !clickedOnScrollbar) { - mouseDownTarget.current = event.target as HTMLElement; - } - }; - - const handleBackdropMouseUp = (event: MouseEvent) => { - if ( - !disableBackdropClick && - event.target === wrapperRef.current && - mouseDownTarget.current === wrapperRef.current - ) { - handleClose(event, 'backdropClick'); - } - - mouseDownTarget.current = undefined; - }; - - const handleKeyDown = useCallback( - (event: KeyboardEvent) => { - /* - * Чтобы сохранить дефолтное поведение элементов и событий форм, - * обработчик не устанавливает event.preventDefault() - */ - if (event.key !== 'Escape') { - return; - } - - // Если есть обработчик escape на body - event.stopPropagation(); - - if (!disableEscapeKeyDown && handleClose) { - handleClose(event, 'escapeKeyDown'); - } - }, - [disableEscapeKeyDown, handleClose], - ); - - const getScrollHandler = useCallback(() => { - if (scrollHandler === 'wrapper') return wrapperRef.current; - if (scrollHandler === 'content') return componentNodeRef.current; - - return scrollHandler.current || wrapperRef.current; - }, [scrollHandler]); - - const handleEntered: Required['onEntered'] = useCallback( - (node, isAppearing) => { - scrollableNodeRef.current = getScrollHandler(); - - addResizeHandle(); - - if (scrollableNodeRef.current) { - scrollableNodeRef.current.addEventListener('scroll', handleScroll); - handleScroll(); - } - - if (transitionProps.onEntered) { - transitionProps.onEntered(node, isAppearing); - } - - if (onMount) onMount(); - }, - [addResizeHandle, getScrollHandler, handleScroll, onMount, transitionProps], - ); - - const handleExited: Required['onExited'] = useCallback( - (node) => { - removeResizeHandle(); - - setExited(true); - - if (scrollableNodeRef.current) { - scrollableNodeRef.current.removeEventListener('scroll', handleScroll); - } - - if (transitionProps.onExited) { - transitionProps.onExited(node); - } - - if (onUnmount) onUnmount(); - - if (restoreContainerStylesRef.current) { - restoreContainerStylesRef.current(); - } - }, - [handleScroll, onUnmount, removeResizeHandle, transitionProps], - ); - - useEffect(() => { - if (open && isExited) { - if (!disableBlockingScroll) { - const el = getContainer(); - - const shouldIOSLock = iOSLock && os.isIOS(); - - handleContainer(el, shouldIOSLock); - if (shouldIOSLock) { - syncHeight(); - lockScroll(); - } - - restoreContainerStylesRef.current = () => { - restoreContainerStylesRef.current = null; - restoreContainerStyles(el); - }; - } - - setExited(false); - } - - if (!open) { - unlockScroll(); - } - }, [getContainer, open, disableBlockingScroll, isExited, iOSLock]); - - useEffect(() => { - const ResizeObserver = window.ResizeObserver || ResizeObserverPolyfill; - - resizeObserverRef.current = new ResizeObserver(checkToHasScrollBar); - - return () => { - if (restoreContainerStylesRef.current) { - restoreContainerStylesRef.current(); - } - - if (resizeObserverRef.current) { - resizeObserverRef.current.disconnect(); - } - }; - }, []); - - useEffect(() => { - if (disableAutoFocus || !open) return; - - wrapperRef.current?.focus(); - }, [open, disableAutoFocus]); - - const contextValue = useMemo( - () => ({ - parentRef: wrapperRef, - componentRef: componentNodeRef, - hasHeader, - hasFooter, - hasScroll, - headerHighlighted, - footerHighlighted, - headerOffset, - setHeaderOffset, - contentRef, - setHasHeader, - setHasFooter, - onClose: handleClose, - }), - [ - contentRef, - hasHeader, - hasFooter, - hasScroll, - headerHighlighted, - footerHighlighted, - headerOffset, - setHeaderOffset, - handleClose, - ], - ); - - const renderContent = () => ( - - {(computedZIndex) => ( - - - {Backdrop && ( - - )} -
, - ])} - onKeyDown={handleKeyDown} - onMouseDown={handleBackdropMouseDown} - onMouseUp={handleBackdropMouseUp} - tabIndex={-1} - data-test-id={dataTestId} - style={{ - zIndex: computedZIndex, - }} - > - -
-
- {children} -
-
-
-
-
-
- )} -
- ); - - if (!shouldRender) return null; - - return usePortal ? ( - - {renderContent()} - - ) : ( - renderContent() - ); - }, -); - -BaseModal.displayName = 'BaseModal'; -BaseModalContext.displayName = 'BaseModalContext'; diff --git a/packages/base-modal/dist_side_poly/src/helpers/lockScroll.ts b/packages/base-modal/dist_side_poly/src/helpers/lockScroll.ts deleted file mode 100644 index f2aedc0e6e..0000000000 --- a/packages/base-modal/dist_side_poly/src/helpers/lockScroll.ts +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Хелпер для блокирования скроллинга в iOS - * В проекте используется overflow: hidden для блокировки, но в некоторых случаях этого недостаточно. Данный хелпер призван решать эту проблему - */ - -let scrollY: number; - -export const isScrollLocked = () => document.body.classList.contains('is-locked'); - -export const lockScroll = () => { - scrollY = window.scrollY; - document.body.classList.add('is-locked'); -}; - -export const unlockScroll = () => { - if (!isScrollLocked()) return; - - document.body.classList.remove('is-locked'); - window.scrollTo(0, scrollY); -}; - -export const syncHeight = () => { - document.body.style.setProperty('--window-inner-scrollY', `${window.scrollY}px`); -}; diff --git a/packages/base-modal/dist_side_poly/src/index.module.css b/packages/base-modal/dist_side_poly/src/index.module.css deleted file mode 100644 index 4aa602362c..0000000000 --- a/packages/base-modal/dist_side_poly/src/index.module.css +++ /dev/null @@ -1,71 +0,0 @@ -@import '@alfalab/core-components-vars/src/index.css'; - -:root { - --window-inner-scrollY: 10px; /* fallback value to prevent ci error */ -} - -body:global(.is-locked) { - margin-top: calc(var(--window-inner-scrollY) * -1); - position: fixed; - overflow: hidden; -} - -.component { - position: relative; - box-sizing: border-box; - background: var(--color-light-modal-bg-primary); - margin: auto; - flex-shrink: 0; -} - -.wrapper { - position: fixed; - top: var(--gap-0); - left: var(--gap-0); - right: var(--gap-0); - bottom: var(--gap-0); - - overflow: auto; - display: flex; - flex-direction: column; - align-items: center; - outline: 0; - overscroll-behavior: none; -} - -.content { - width: 100%; - height: 100%; - display: flex; - flex-direction: column; - flex: 1; -} - -.hidden { - display: none; -} - -.backdrop { - z-index: 0; -} - -.appear, -.enter { - opacity: 0; -} - -.appearActive, -.enterActive { - opacity: 1; - transition: opacity 200ms ease-in; -} - -.exit { - opacity: 1; -} - -.exitActive, -.exitDone { - opacity: 0; - transition: opacity 200ms ease-out; -} diff --git a/packages/base-modal/dist_side_poly/src/index.ts b/packages/base-modal/dist_side_poly/src/index.ts deleted file mode 100644 index b48bf6698e..0000000000 --- a/packages/base-modal/dist_side_poly/src/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './Component'; -export * from './utils'; -export * from './helpers/lockScroll'; diff --git a/packages/base-modal/dist_side_poly/src/matches-polyfill.ts b/packages/base-modal/dist_side_poly/src/matches-polyfill.ts deleted file mode 100644 index a0c7e8a9f4..0000000000 --- a/packages/base-modal/dist_side_poly/src/matches-polyfill.ts +++ /dev/null @@ -1,19 +0,0 @@ -/* eslint-disable */ -// @ts-nocheck - -if (typeof window !== 'undefined') { - if (Element && !Element.prototype.matches) { - Element.prototype.matches = - Element.prototype.matchesSelector || - Element.prototype.mozMatchesSelector || - Element.prototype.msMatchesSelector || - Element.prototype.oMatchesSelector || - Element.prototype.webkitMatchesSelector || - function (s) { - const matches = (this.document || this.ownerDocument).querySelectorAll(s); - let i = matches.length; - while (--i >= 0 && matches.item(i) !== this) {} - return i > -1; - }; - } -} diff --git a/packages/base-modal/dist_side_poly/src/utils.ts b/packages/base-modal/dist_side_poly/src/utils.ts deleted file mode 100644 index 0958516019..0000000000 --- a/packages/base-modal/dist_side_poly/src/utils.ts +++ /dev/null @@ -1,106 +0,0 @@ -import { getModalStore, SavedStyle } from '@alfalab/core-components-global-store'; -import { browser } from '@alfalab/core-components-shared'; - -export function isScrolledToTop(target: HTMLElement) { - return target.scrollTop <= 0; -} - -export function isScrolledToBottom(target: HTMLElement) { - return target.scrollHeight - target.offsetHeight <= target.scrollTop; -} - -export function hasScrollbar(target: HTMLElement) { - return target.scrollHeight > target.clientHeight; -} - -const isOverflowing = (container: Element) => { - if (document.body === container) { - return window.innerWidth > document.documentElement.clientWidth; - } - - return container.scrollHeight > container.clientHeight; -}; - -const getPaddingRight = (node: Element) => - parseInt(window.getComputedStyle(node).paddingRight, 10) || 0; - -export const restoreContainerStyles = (container: HTMLElement) => { - const modalRestoreStyles = getModalStore().getRestoreStyles(); - - const index = modalRestoreStyles.findIndex((s) => s.container === container); - const existingStyles = modalRestoreStyles[index]; - - if (!existingStyles) return; - - existingStyles.modals -= 1; - - if (existingStyles.modals <= 0) { - modalRestoreStyles.splice(index, 1); - - existingStyles.styles.forEach(({ value, el, key }) => { - if (value) { - el.style.setProperty(key, value); - } else { - el.style.removeProperty(key); - } - }); - } -}; - -export const handleContainer = (container?: HTMLElement, shouldIOSLock = false) => { - if (!container) return; - - const modalRestoreStyles = getModalStore().getRestoreStyles(); - - const existingStyles = modalRestoreStyles.find((s) => s.container === container); - - if (existingStyles) { - existingStyles.modals += 1; - - return; - } - - const containerStyles: SavedStyle[] = []; - - if (isOverflowing(container)) { - // Вычисляет размер до применения `overflow hidden` для избежания скачков - const scrollbarSize = browser.getScrollbarSize(); - - containerStyles.push({ - value: container.style.paddingRight, - key: 'padding-right', - el: container, - }); - // Вычисляем стили, чтобы получить реальный `padding` c шириной сколлбара - // eslint-disable-next-line no-param-reassign - container.style.paddingRight = `${getPaddingRight(container) + scrollbarSize}px`; - } - - const parent = container.parentElement; - const scrollContainer = - // TODO: заменить на optional chaining - parent && - parent.nodeName === 'HTML' && - window.getComputedStyle(parent).overflowY === 'scroll' - ? parent - : container; - - // Блокируем скролл даже если отсутствует скроллбар - if (scrollContainer.style.overflow !== 'hidden') { - containerStyles.push({ - value: scrollContainer.style.overflow, - key: 'overflow', - el: scrollContainer, - }); - } - - if (!shouldIOSLock) { - scrollContainer.style.overflow = 'hidden'; - } - - modalRestoreStyles.push({ - container, - modals: 1, - styles: containerStyles, - }); -}; diff --git a/packages/base-modal/dist_side_poly/utils.d.ts b/packages/base-modal/dist_side_poly/utils.d.ts deleted file mode 100644 index 75401779bb..0000000000 --- a/packages/base-modal/dist_side_poly/utils.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -declare function isScrolledToTop(target: HTMLElement): boolean; -declare function isScrolledToBottom(target: HTMLElement): boolean; -declare function hasScrollbar(target: HTMLElement): boolean; -declare const restoreContainerStyles: (container: HTMLElement) => void; -declare const handleContainer: (container?: HTMLElement, shouldIOSLock?: boolean) => void; -export { isScrolledToTop, isScrolledToBottom, hasScrollbar, restoreContainerStyles, handleContainer }; diff --git a/packages/base-modal/dist_side_poly/utils.js b/packages/base-modal/dist_side_poly/utils.js deleted file mode 100644 index 02953e4ae2..0000000000 --- a/packages/base-modal/dist_side_poly/utils.js +++ /dev/null @@ -1,99 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, '__esModule', { value: true }); - -var coreComponentsGlobalStore = require('@alfalab/core-components-global-store'); -var coreComponentsShared = require('@alfalab/core-components-shared'); - -function isScrolledToTop(target) { - return target.scrollTop <= 0; -} -function isScrolledToBottom(target) { - return target.scrollHeight - target.offsetHeight <= target.scrollTop; -} -function hasScrollbar(target) { - return target.scrollHeight > target.clientHeight; -} -var isOverflowing = function (container) { - if (document.body === container) { - return window.innerWidth > document.documentElement.clientWidth; - } - return container.scrollHeight > container.clientHeight; -}; -var getPaddingRight = function (node) { - return parseInt(window.getComputedStyle(node).paddingRight, 10) || 0; -}; -var restoreContainerStyles = function (container) { - var modalRestoreStyles = coreComponentsGlobalStore.getModalStore().getRestoreStyles(); - var index = modalRestoreStyles.findIndex(function (s) { return s.container === container; }); - var existingStyles = modalRestoreStyles[index]; - if (!existingStyles) - return; - existingStyles.modals -= 1; - if (existingStyles.modals <= 0) { - modalRestoreStyles.splice(index, 1); - existingStyles.styles.forEach(function (_a) { - var value = _a.value, el = _a.el, key = _a.key; - if (value) { - el.style.setProperty(key, value); - } - else { - el.style.removeProperty(key); - } - }); - } -}; -var handleContainer = function (container, shouldIOSLock) { - if (shouldIOSLock === void 0) { shouldIOSLock = false; } - if (!container) - return; - var modalRestoreStyles = coreComponentsGlobalStore.getModalStore().getRestoreStyles(); - var existingStyles = modalRestoreStyles.find(function (s) { return s.container === container; }); - if (existingStyles) { - existingStyles.modals += 1; - return; - } - var containerStyles = []; - if (isOverflowing(container)) { - // Вычисляет размер до применения `overflow hidden` для избежания скачков - var scrollbarSize = coreComponentsShared.browser.getScrollbarSize(); - containerStyles.push({ - value: container.style.paddingRight, - key: 'padding-right', - el: container, - }); - // Вычисляем стили, чтобы получить реальный `padding` c шириной сколлбара - // eslint-disable-next-line no-param-reassign - container.style.paddingRight = "".concat(getPaddingRight(container) + scrollbarSize, "px"); - } - var parent = container.parentElement; - var scrollContainer = - // TODO: заменить на optional chaining - parent && - parent.nodeName === 'HTML' && - window.getComputedStyle(parent).overflowY === 'scroll' - ? parent - : container; - // Блокируем скролл даже если отсутствует скроллбар - if (scrollContainer.style.overflow !== 'hidden') { - containerStyles.push({ - value: scrollContainer.style.overflow, - key: 'overflow', - el: scrollContainer, - }); - } - if (!shouldIOSLock) { - scrollContainer.style.overflow = 'hidden'; - } - modalRestoreStyles.push({ - container: container, - modals: 1, - styles: containerStyles, - }); -}; - -exports.handleContainer = handleContainer; -exports.hasScrollbar = hasScrollbar; -exports.isScrolledToBottom = isScrolledToBottom; -exports.isScrolledToTop = isScrolledToTop; -exports.restoreContainerStyles = restoreContainerStyles; From f2b08f9c40ab9f9f2791ec825fcdf5a694054384 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Denis=20=F0=9F=8E=83=20Khripkov?= Date: Fri, 20 Dec 2024 00:25:14 +0300 Subject: [PATCH 5/6] fix: new md; --- .changeset/{nervous-ants-learn.md => smooth-monkeys-stare.md} | 1 - 1 file changed, 1 deletion(-) rename .changeset/{nervous-ants-learn.md => smooth-monkeys-stare.md} (96%) diff --git a/.changeset/nervous-ants-learn.md b/.changeset/smooth-monkeys-stare.md similarity index 96% rename from .changeset/nervous-ants-learn.md rename to .changeset/smooth-monkeys-stare.md index fd8c4a7508..b4aba8c36d 100644 --- a/.changeset/nervous-ants-learn.md +++ b/.changeset/smooth-monkeys-stare.md @@ -1,6 +1,5 @@ --- '@alfalab/core-components-drawer': patch -'@alfalab/core-components-form-control': patch '@alfalab/core-components-notification': patch '@alfalab/core-components-notification-manager': patch '@alfalab/core-components-number-input': patch From 664ee97d6ac4af4433e0c4c461652a0d9f686c07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Denis=20=F0=9F=8E=83=20Khripkov?= Date: Fri, 20 Dec 2024 07:48:08 +0300 Subject: [PATCH 6/6] fix: code; --- .changeset/smooth-monkeys-stare.md | 2 -- packages/gap/package.json | 1 + packages/pass-code-v1/package.json | 1 - packages/pass-code/package.json | 1 - 4 files changed, 1 insertion(+), 4 deletions(-) diff --git a/.changeset/smooth-monkeys-stare.md b/.changeset/smooth-monkeys-stare.md index b4aba8c36d..b44aeef07e 100644 --- a/.changeset/smooth-monkeys-stare.md +++ b/.changeset/smooth-monkeys-stare.md @@ -4,8 +4,6 @@ '@alfalab/core-components-notification-manager': patch '@alfalab/core-components-number-input': patch '@alfalab/core-components-pagination': patch -'@alfalab/core-components-pass-code': patch -'@alfalab/core-components-pass-code-v1': patch '@alfalab/core-components-password-input': patch '@alfalab/core-components-pattern-lock': patch '@alfalab/core-components-pattern-lock-v1': patch diff --git a/packages/gap/package.json b/packages/gap/package.json index 0c9804f8e5..19939751a9 100644 --- a/packages/gap/package.json +++ b/packages/gap/package.json @@ -10,6 +10,7 @@ "access": "public", "directory": "dist" }, + "sideEffects": false, "peerDependencies": { "react": "^16.9.0 || ^17.0.1 || ^18.0.0" }, diff --git a/packages/pass-code-v1/package.json b/packages/pass-code-v1/package.json index a2ca60babb..0b67f2a0c3 100644 --- a/packages/pass-code-v1/package.json +++ b/packages/pass-code-v1/package.json @@ -10,7 +10,6 @@ "access": "public", "directory": "dist" }, - "sideEffects": false, "peerDependencies": { "react": "^16.9.0 || ^17.0.1 || ^18.0.0", "react-dom": "^16.9.0 || ^17.0.1 || ^18.0.0" diff --git a/packages/pass-code/package.json b/packages/pass-code/package.json index 5dad207e06..334dbec0b3 100644 --- a/packages/pass-code/package.json +++ b/packages/pass-code/package.json @@ -10,7 +10,6 @@ "access": "public", "directory": "dist" }, - "sideEffects": false, "peerDependencies": { "react": "^16.9.0 || ^17.0.1 || ^18.0.0", "react-dom": "^16.9.0 || ^17.0.1 || ^18.0.0"