@hh.ru/magritte-ui-modal-deprecated 1.0.39 → 1.0.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Modal.d.ts +2 -2
- package/Modal.js +255 -189
- package/Modal.js.map +1 -1
- package/ModalContentWithHeader-CxF78N1S.js +243 -0
- package/{ModalContentWithHeader-B7tpHFBW.js.map → ModalContentWithHeader-CxF78N1S.js.map} +1 -1
- package/ModalContentWithHeader.d.ts +1 -1
- package/ModalContentWithHeader.js +1 -1
- package/ModalHeader.d.ts +1 -1
- package/ModalHeader.js +105 -29
- package/ModalHeader.js.map +1 -1
- package/index.css +123 -123
- package/index.d.ts +2 -2
- package/index.js +1 -1
- package/index.mock.js +7 -3
- package/index.mock.js.map +1 -1
- package/package.json +12 -12
- package/useModalOrder.js +69 -76
- package/useModalOrder.js.map +1 -1
- package/ModalContentWithHeader-B7tpHFBW.js +0 -150
package/useModalOrder.js
CHANGED
|
@@ -2,90 +2,83 @@ import './index.css';
|
|
|
2
2
|
import { useState, useLayoutEffect, useEffect } from 'react';
|
|
3
3
|
import { useDomStoredUniqueId, getValueFromDom, storeValueInDom } from '@hh.ru/magritte-common-dom-storage';
|
|
4
4
|
|
|
5
|
-
const STORAGE_NAME =
|
|
5
|
+
const STORAGE_NAME = "_MAGRITTE_MODAL_COUNTER_";
|
|
6
6
|
const getState = () => {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
7
|
+
const state = getValueFromDom(STORAGE_NAME);
|
|
8
|
+
if (state === void 0) {
|
|
9
|
+
return {
|
|
10
|
+
prevVisiblility: {},
|
|
11
|
+
positions: {},
|
|
12
|
+
subscribers: {},
|
|
13
|
+
count: 0
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
return state;
|
|
17
17
|
};
|
|
18
18
|
const storeState = (state) => {
|
|
19
|
-
|
|
19
|
+
storeValueInDom(STORAGE_NAME, state);
|
|
20
20
|
};
|
|
21
21
|
const counterFactory = () => {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
},
|
|
59
|
-
};
|
|
22
|
+
return {
|
|
23
|
+
updateVisiblility: (id, visible) => {
|
|
24
|
+
const state = getState();
|
|
25
|
+
const prevVisible = !!state.prevVisiblility[id];
|
|
26
|
+
if (visible === prevVisible) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
state.prevVisiblility[id] = visible;
|
|
30
|
+
if (visible) {
|
|
31
|
+
state.count += 1;
|
|
32
|
+
state.positions[id] = state.count;
|
|
33
|
+
} else {
|
|
34
|
+
state.count -= 1;
|
|
35
|
+
const currentPosition = state.positions[id];
|
|
36
|
+
state.positions[id] = 0;
|
|
37
|
+
Object.entries(state.positions).forEach(([key, value]) => {
|
|
38
|
+
state.positions[key] = value > currentPosition ? value - 1 : value;
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
storeState(state);
|
|
42
|
+
},
|
|
43
|
+
subscribe: (id, callback) => {
|
|
44
|
+
const state = getState();
|
|
45
|
+
state.subscribers[id] = callback;
|
|
46
|
+
storeState(state);
|
|
47
|
+
},
|
|
48
|
+
unsubscribe: (id) => {
|
|
49
|
+
const state = getState();
|
|
50
|
+
delete state.subscribers[id];
|
|
51
|
+
storeState(state);
|
|
52
|
+
},
|
|
53
|
+
notifyAll: () => {
|
|
54
|
+
const { subscribers, count, positions } = getState();
|
|
55
|
+
Object.entries(subscribers).forEach(([id, callback]) => callback({ position: positions[id], count }));
|
|
56
|
+
}
|
|
57
|
+
};
|
|
60
58
|
};
|
|
61
59
|
const counter = counterFactory();
|
|
62
60
|
const useModalOrder = (visible, modalRef) => {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
!modalRef.current?.contains(document.activeElement)) {
|
|
85
|
-
modalRef.current?.focus();
|
|
86
|
-
}
|
|
87
|
-
}, [position, modalRef]);
|
|
88
|
-
return [position.position, position.count];
|
|
61
|
+
const [position, setPosition] = useState({ position: 0, count: 0 });
|
|
62
|
+
const id = useDomStoredUniqueId();
|
|
63
|
+
useLayoutEffect(() => {
|
|
64
|
+
counter.updateVisiblility(id, visible);
|
|
65
|
+
counter.notifyAll();
|
|
66
|
+
}, [visible]);
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
counter.subscribe(id, setPosition);
|
|
69
|
+
counter.updateVisiblility(id, visible);
|
|
70
|
+
return () => {
|
|
71
|
+
counter.unsubscribe(id);
|
|
72
|
+
counter.updateVisiblility(id, false);
|
|
73
|
+
counter.notifyAll();
|
|
74
|
+
};
|
|
75
|
+
}, [id]);
|
|
76
|
+
useLayoutEffect(() => {
|
|
77
|
+
if (position.position === position.count && position.count > 0 && !modalRef.current?.contains(document.activeElement)) {
|
|
78
|
+
modalRef.current?.focus();
|
|
79
|
+
}
|
|
80
|
+
}, [position, modalRef]);
|
|
81
|
+
return [position.position, position.count];
|
|
89
82
|
};
|
|
90
83
|
|
|
91
84
|
export { useModalOrder };
|
package/useModalOrder.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useModalOrder.js","sources":["src/useModalOrder.ts"],"sourcesContent":["import { RefObject, useEffect, useLayoutEffect, useState } from 'react';\n\nimport { storeValueInDom, getValueFromDom, useDomStoredUniqueId } from '@hh.ru/magritte-common-dom-storage';\n\ntype NotifyCallbackArg = { position: number; count: number };\n\ntype Subscribers = Record<string, (position: NotifyCallbackArg) => void>;\ntype VisibilityMap = Record<string, boolean>;\ntype PositionMap = Record<string, number>;\n\ntype ModalCounterState = {\n prevVisiblility: VisibilityMap;\n positions: PositionMap;\n subscribers: Subscribers;\n count: number;\n};\n\nconst STORAGE_NAME = '_MAGRITTE_MODAL_COUNTER_';\n\nconst getState = (): ModalCounterState => {\n const state = getValueFromDom<ModalCounterState>(STORAGE_NAME);\n if (state === undefined) {\n return {\n prevVisiblility: {},\n positions: {},\n subscribers: {},\n count: 0,\n };\n }\n return state;\n};\n\nconst storeState = (state: ModalCounterState): void => {\n storeValueInDom(STORAGE_NAME, state);\n};\n\nconst counterFactory = () => {\n return {\n updateVisiblility: (id: string, visible: boolean) => {\n // eslint-disable-next-line prefer-const\n const state = getState();\n const prevVisible = !!state.prevVisiblility[id];\n if (visible === prevVisible) {\n return;\n }\n state.prevVisiblility[id] = visible;\n if (visible) {\n state.count += 1;\n state.positions[id] = state.count;\n } else {\n state.count -= 1;\n const currentPosition = state.positions[id];\n state.positions[id] = 0;\n Object.entries(state.positions).forEach(([key, value]) => {\n state.positions[key] = value > currentPosition ? value - 1 : value;\n });\n }\n storeState(state);\n },\n subscribe: (id: string, callback: (position: NotifyCallbackArg) => void) => {\n const state = getState();\n state.subscribers[id] = callback;\n storeState(state);\n },\n unsubscribe: (id: string) => {\n const state = getState();\n delete state.subscribers[id];\n storeState(state);\n },\n notifyAll: () => {\n const { subscribers, count, positions } = getState();\n Object.entries(subscribers).forEach(([id, callback]) => callback({ position: positions[id], count }));\n },\n };\n};\n\nconst counter = counterFactory();\n\nexport const useModalOrder = (visible: boolean, modalRef: RefObject<HTMLDivElement>): [number, number] => {\n const [position, setPosition] = useState<{ position: number; count: number }>({ position: 0, count: 0 });\n const id = useDomStoredUniqueId();\n\n useLayoutEffect(() => {\n counter.updateVisiblility(id, visible);\n counter.notifyAll();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [visible]);\n\n useEffect(() => {\n counter.subscribe(id, setPosition);\n counter.updateVisiblility(id, visible);\n return () => {\n counter.unsubscribe(id);\n counter.updateVisiblility(id, false);\n counter.notifyAll();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [id]);\n\n useLayoutEffect(() => {\n // Если это самый \"верхний\" модал передаем туда фокус\n if (\n position.position === position.count &&\n position.count > 0 &&\n !modalRef.current?.contains(document.activeElement)\n ) {\n modalRef.current?.focus();\n }\n }, [position, modalRef]);\n\n return [position.position, position.count];\n};\n"],"names":[],"mappings":";;;AAiBA,MAAM,
|
|
1
|
+
{"version":3,"file":"useModalOrder.js","sources":["src/useModalOrder.ts"],"sourcesContent":["import { RefObject, useEffect, useLayoutEffect, useState } from 'react';\n\nimport { storeValueInDom, getValueFromDom, useDomStoredUniqueId } from '@hh.ru/magritte-common-dom-storage';\n\ntype NotifyCallbackArg = { position: number; count: number };\n\ntype Subscribers = Record<string, (position: NotifyCallbackArg) => void>;\ntype VisibilityMap = Record<string, boolean>;\ntype PositionMap = Record<string, number>;\n\ntype ModalCounterState = {\n prevVisiblility: VisibilityMap;\n positions: PositionMap;\n subscribers: Subscribers;\n count: number;\n};\n\nconst STORAGE_NAME = '_MAGRITTE_MODAL_COUNTER_';\n\nconst getState = (): ModalCounterState => {\n const state = getValueFromDom<ModalCounterState>(STORAGE_NAME);\n if (state === undefined) {\n return {\n prevVisiblility: {},\n positions: {},\n subscribers: {},\n count: 0,\n };\n }\n return state;\n};\n\nconst storeState = (state: ModalCounterState): void => {\n storeValueInDom(STORAGE_NAME, state);\n};\n\nconst counterFactory = () => {\n return {\n updateVisiblility: (id: string, visible: boolean) => {\n // eslint-disable-next-line prefer-const\n const state = getState();\n const prevVisible = !!state.prevVisiblility[id];\n if (visible === prevVisible) {\n return;\n }\n state.prevVisiblility[id] = visible;\n if (visible) {\n state.count += 1;\n state.positions[id] = state.count;\n } else {\n state.count -= 1;\n const currentPosition = state.positions[id];\n state.positions[id] = 0;\n Object.entries(state.positions).forEach(([key, value]) => {\n state.positions[key] = value > currentPosition ? value - 1 : value;\n });\n }\n storeState(state);\n },\n subscribe: (id: string, callback: (position: NotifyCallbackArg) => void) => {\n const state = getState();\n state.subscribers[id] = callback;\n storeState(state);\n },\n unsubscribe: (id: string) => {\n const state = getState();\n delete state.subscribers[id];\n storeState(state);\n },\n notifyAll: () => {\n const { subscribers, count, positions } = getState();\n Object.entries(subscribers).forEach(([id, callback]) => callback({ position: positions[id], count }));\n },\n };\n};\n\nconst counter = counterFactory();\n\nexport const useModalOrder = (visible: boolean, modalRef: RefObject<HTMLDivElement>): [number, number] => {\n const [position, setPosition] = useState<{ position: number; count: number }>({ position: 0, count: 0 });\n const id = useDomStoredUniqueId();\n\n useLayoutEffect(() => {\n counter.updateVisiblility(id, visible);\n counter.notifyAll();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [visible]);\n\n useEffect(() => {\n counter.subscribe(id, setPosition);\n counter.updateVisiblility(id, visible);\n return () => {\n counter.unsubscribe(id);\n counter.updateVisiblility(id, false);\n counter.notifyAll();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [id]);\n\n useLayoutEffect(() => {\n // Если это самый \"верхний\" модал передаем туда фокус\n if (\n position.position === position.count &&\n position.count > 0 &&\n !modalRef.current?.contains(document.activeElement)\n ) {\n modalRef.current?.focus();\n }\n }, [position, modalRef]);\n\n return [position.position, position.count];\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import './index.css';
|
|
2
|
-
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
3
|
-
import { useRef, useState, useCallback, useLayoutEffect } from 'react';
|
|
4
|
-
import classnames from 'classnames';
|
|
5
|
-
import { requestAnimation } from '@hh.ru/magritte-common-func-utils';
|
|
6
|
-
import { useMultipleRefs } from '@hh.ru/magritte-common-use-multiple-refs';
|
|
7
|
-
import { ContentOverlayRoot } from '@hh.ru/magritte-ui-content-overlay';
|
|
8
|
-
import { Divider } from '@hh.ru/magritte-ui-divider';
|
|
9
|
-
import { ModalHeader } from './ModalHeader.js';
|
|
10
|
-
import { useScrollbar, Scrollbar } from '@hh.ru/magritte-ui-scrollbar';
|
|
11
|
-
import { TextAreaGrowLimiter } from '@hh.ru/magritte-ui-textarea';
|
|
12
|
-
|
|
13
|
-
var styles = {"modal-overlay":"magritte-modal-overlay___uurgp_1-0-39","modalOverlay":"magritte-modal-overlay___uurgp_1-0-39","modal-overlay-with-background":"magritte-modal-overlay-with-background___mR-T0_1-0-39","modalOverlayWithBackground":"magritte-modal-overlay-with-background___mR-T0_1-0-39","modal":"magritte-modal___2Wc4s_1-0-39","modal-overlay-left":"magritte-modal-overlay-left___qaiC9_1-0-39","modalOverlayLeft":"magritte-modal-overlay-left___qaiC9_1-0-39","modal-overlay-right":"magritte-modal-overlay-right___-HTKs_1-0-39","modalOverlayRight":"magritte-modal-overlay-right___-HTKs_1-0-39","size-small":"magritte-size-small___nSBwy_1-0-39","sizeSmall":"magritte-size-small___nSBwy_1-0-39","size-medium":"magritte-size-medium___Zuz-t_1-0-39","sizeMedium":"magritte-size-medium___Zuz-t_1-0-39","no-vertical-paddings":"magritte-no-vertical-paddings___XgMGS_1-0-39","noVerticalPaddings":"magritte-no-vertical-paddings___XgMGS_1-0-39","no-horizontal-paddings":"magritte-no-horizontal-paddings___MJDv4_1-0-39","noHorizontalPaddings":"magritte-no-horizontal-paddings___MJDv4_1-0-39","modal-full-height":"magritte-modal-full-height___UThtH_1-0-39","modalFullHeight":"magritte-modal-full-height___UThtH_1-0-39","modal-with-border":"magritte-modal-with-border___bqsql_1-0-39","modalWithBorder":"magritte-modal-with-border___bqsql_1-0-39","modal-content-wrapper":"magritte-modal-content-wrapper___-eFo3_1-0-39","modalContentWrapper":"magritte-modal-content-wrapper___-eFo3_1-0-39","modal-content":"magritte-modal-content___KY9ma_1-0-39","modalContent":"magritte-modal-content___KY9ma_1-0-39","modal-scroll-container":"magritte-modal-scroll-container___dg8jC_1-0-39","modalScrollContainer":"magritte-modal-scroll-container___dg8jC_1-0-39","modal-content-wrapper__one-line":"magritte-modal-content-wrapper__one-line___ZkEgT_1-0-39","modalContentWrapperOneLine":"magritte-modal-content-wrapper__one-line___ZkEgT_1-0-39","content-sticky-container":"magritte-content-sticky-container___VkZxO_1-0-39","contentStickyContainer":"magritte-content-sticky-container___VkZxO_1-0-39","divider-container":"magritte-divider-container___jKyxB_1-0-39","dividerContainer":"magritte-divider-container___jKyxB_1-0-39","divider-container-hidden":"magritte-divider-container-hidden___20nI5_1-0-39","dividerContainerHidden":"magritte-divider-container-hidden___20nI5_1-0-39","modal-footer":"magritte-modal-footer___TbH6x_1-0-39","modalFooter":"magritte-modal-footer___TbH6x_1-0-39","modal-buttons-container":"magritte-modal-buttons-container___9hXUo_1-0-39","modalButtonsContainer":"magritte-modal-buttons-container___9hXUo_1-0-39","animation-timeout":"magritte-animation-timeout___vK6nU_1-0-39","animationTimeout":"magritte-animation-timeout___vK6nU_1-0-39","animation-enter-center":"magritte-animation-enter-center___9zWOQ_1-0-39","animationEnterCenter":"magritte-animation-enter-center___9zWOQ_1-0-39","animation-enter-center-active":"magritte-animation-enter-center-active___dfICf_1-0-39","animationEnterCenterActive":"magritte-animation-enter-center-active___dfICf_1-0-39","animation-exit-center":"magritte-animation-exit-center___mrTCE_1-0-39","animationExitCenter":"magritte-animation-exit-center___mrTCE_1-0-39","animation-exit-center-active":"magritte-animation-exit-center-active___WZXYp_1-0-39","animationExitCenterActive":"magritte-animation-exit-center-active___WZXYp_1-0-39","animation-enter-left":"magritte-animation-enter-left___XiXzr_1-0-39","animationEnterLeft":"magritte-animation-enter-left___XiXzr_1-0-39","animation-enter-left-active":"magritte-animation-enter-left-active___4Uaz6_1-0-39","animationEnterLeftActive":"magritte-animation-enter-left-active___4Uaz6_1-0-39","animation-exit-left":"magritte-animation-exit-left___NHvvO_1-0-39","animationExitLeft":"magritte-animation-exit-left___NHvvO_1-0-39","animation-exit-left-active":"magritte-animation-exit-left-active___oDszE_1-0-39","animationExitLeftActive":"magritte-animation-exit-left-active___oDszE_1-0-39","animation-enter-right":"magritte-animation-enter-right___1bqPX_1-0-39","animationEnterRight":"magritte-animation-enter-right___1bqPX_1-0-39","animation-enter-right-active":"magritte-animation-enter-right-active___OR65U_1-0-39","animationEnterRightActive":"magritte-animation-enter-right-active___OR65U_1-0-39","animation-exit-right":"magritte-animation-exit-right___hyYBh_1-0-39","animationExitRight":"magritte-animation-exit-right___hyYBh_1-0-39","animation-exit-right-active":"magritte-animation-exit-right-active___ft6Lz_1-0-39","animationExitRightActive":"magritte-animation-exit-right-active___ft6Lz_1-0-39","space-preserver":"magritte-space-preserver___nz3Nw_1-0-39","spacePreserver":"magritte-space-preserver___nz3Nw_1-0-39","tree-selector-container":"magritte-tree-selector-container___XZh1C_1-0-39","treeSelectorContainer":"magritte-tree-selector-container___XZh1C_1-0-39","grow-limiter":"magritte-grow-limiter___SPuoT_1-0-39","growLimiter":"magritte-grow-limiter___SPuoT_1-0-39"};
|
|
14
|
-
|
|
15
|
-
const checkIsScrolledToBottom = (el) => {
|
|
16
|
-
return Math.abs(el.scrollHeight - el.scrollTop - el.clientHeight) < 1;
|
|
17
|
-
};
|
|
18
|
-
const clamp = (value, min, max) => Math.min(Math.max(value, min), max);
|
|
19
|
-
// Минимальная высота до которой может сжаться хедер
|
|
20
|
-
const HEADER_SHRINK_MIN_HEIGHT = 148;
|
|
21
|
-
// Минимальная высота отступа между хедером и контентом
|
|
22
|
-
const HEADER_MARGIN_MIN_HEIGHT = 12;
|
|
23
|
-
// Максимальная высота отступа между хедером и контентом
|
|
24
|
-
const HEADER_MARGIN_MAX_HEIGHT = 24;
|
|
25
|
-
const HEADER_MARGIN_HEIGHT_DELTA = HEADER_MARGIN_MAX_HEIGHT - HEADER_MARGIN_MIN_HEIGHT;
|
|
26
|
-
// Вычисляет минимальную высоту до которой может сжаться хедер с учетом высоты контента, чтобы не спровоцировать
|
|
27
|
-
// изменение размера модалки
|
|
28
|
-
const calcHeaderShrinkLimit = (headerHeight, headerMaxHeight, contentHeight, contentScrollHeight, marginHeight) => {
|
|
29
|
-
// Высота контента скрытого под скроллом когда хедер и марджин под ним имеет максимальную допустимую высоту
|
|
30
|
-
const contentScrollDelta = contentScrollHeight - // Высота контента скрытого под скроллом в текущем состоянии
|
|
31
|
-
contentHeight + // Высота контейнера содержащего контент
|
|
32
|
-
(HEADER_MARGIN_MAX_HEIGHT - marginHeight) + // Дельта между текущей высотой марджина и максимальной допустимой
|
|
33
|
-
(headerMaxHeight - headerHeight); // Дельта между текущей высотой хедера и максимальной допустимой
|
|
34
|
-
const headerShrinkMinHeight = headerMaxHeight - (contentScrollDelta - HEADER_MARGIN_HEIGHT_DELTA);
|
|
35
|
-
return Math.max(headerShrinkMinHeight, HEADER_SHRINK_MIN_HEIGHT);
|
|
36
|
-
};
|
|
37
|
-
const shrinkByDelta = (headerImageContainer, headerWrapper, headerMinHeight, headerMaxHeight, scrollDeltaY) => {
|
|
38
|
-
if (!headerImageContainer || !headerWrapper) {
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
const marginHeight = clamp(HEADER_MARGIN_MAX_HEIGHT - scrollDeltaY, HEADER_MARGIN_MIN_HEIGHT, HEADER_MARGIN_MAX_HEIGHT);
|
|
42
|
-
headerWrapper.style.marginBottom = `${marginHeight}px`;
|
|
43
|
-
const headerHeight = clamp(
|
|
44
|
-
// Тут прибаляем дельту марджина потому что сначала должен сжаться отступ
|
|
45
|
-
Math.floor(headerMaxHeight - scrollDeltaY + HEADER_MARGIN_HEIGHT_DELTA), headerMinHeight, headerMaxHeight);
|
|
46
|
-
headerImageContainer.style.height = `${headerHeight}px`;
|
|
47
|
-
};
|
|
48
|
-
const ModalContentWithHeader = ({ labelId, children, headerHeight: _headerHeight = 0, isTreeSelectorChild, height, showDivider = true, ...modalHeaderProps }) => {
|
|
49
|
-
const { title, headerImageUrl, headerImage, actions, actionLink, options } = modalHeaderProps;
|
|
50
|
-
const bottomDividerVisibleRef = useRef(false);
|
|
51
|
-
const contentContainerRef = useRef(null);
|
|
52
|
-
const headerImageContainerRef = useRef(null);
|
|
53
|
-
const headerWrapperRef = useRef(null);
|
|
54
|
-
const spacePreserverRef = useRef(null);
|
|
55
|
-
const stickyContainerRef = useRef(null);
|
|
56
|
-
const hasHeaderImageRef = useRef(!!headerImageUrl || !!headerImage);
|
|
57
|
-
hasHeaderImageRef.current = !!headerImageUrl || !!headerImage;
|
|
58
|
-
const headerHeightRef = useRef(0);
|
|
59
|
-
headerHeightRef.current = hasHeaderImageRef.current ? Math.max(_headerHeight, 200) : 0;
|
|
60
|
-
const minHeaderHeightRef = useRef(0);
|
|
61
|
-
const contentOverlayRef = useRef(null);
|
|
62
|
-
const bottomDividerContainerRef = useRef(null);
|
|
63
|
-
const topDividerContainerRef = useRef(null);
|
|
64
|
-
const withoutHeader = !title && !hasHeaderImageRef.current && !actions && !actionLink && !options;
|
|
65
|
-
const onlyActions = !title && !hasHeaderImageRef.current && !options && (actions || actionLink);
|
|
66
|
-
const [growLimiterContextValue, _] = useState(() => ({
|
|
67
|
-
containerRef: contentContainerRef,
|
|
68
|
-
}));
|
|
69
|
-
const isTopDividerVisible = () => {
|
|
70
|
-
if (!contentContainerRef.current) {
|
|
71
|
-
return false;
|
|
72
|
-
}
|
|
73
|
-
const topDividerVisible = hasHeaderImageRef.current
|
|
74
|
-
? contentContainerRef.current.scrollTop >
|
|
75
|
-
headerHeightRef.current - minHeaderHeightRef.current + HEADER_MARGIN_HEIGHT_DELTA
|
|
76
|
-
: contentContainerRef.current.scrollTop !== 0;
|
|
77
|
-
return topDividerVisible && (options || !hasHeaderImageRef.current) && !onlyActions && !withoutHeader;
|
|
78
|
-
};
|
|
79
|
-
const recalcContentOverlayPosition = useCallback(() => {
|
|
80
|
-
if (contentOverlayRef.current !== null && contentContainerRef.current !== null) {
|
|
81
|
-
contentOverlayRef.current.style.height = `${contentContainerRef.current.clientHeight}px`;
|
|
82
|
-
}
|
|
83
|
-
}, []);
|
|
84
|
-
const updateHeaderDimensions = useCallback(() => {
|
|
85
|
-
if (!headerImageContainerRef.current ||
|
|
86
|
-
!headerWrapperRef.current ||
|
|
87
|
-
!stickyContainerRef.current ||
|
|
88
|
-
!spacePreserverRef.current ||
|
|
89
|
-
!contentContainerRef.current) {
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
if (!hasHeaderImageRef.current) {
|
|
93
|
-
spacePreserverRef.current.style.height = '0';
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
minHeaderHeightRef.current = calcHeaderShrinkLimit(headerImageContainerRef.current.clientHeight, headerHeightRef.current, contentContainerRef.current.clientHeight, stickyContainerRef.current.scrollHeight, parseInt(headerWrapperRef.current.style.marginBottom || '0', 10));
|
|
97
|
-
shrinkByDelta(headerImageContainerRef.current, headerWrapperRef.current, minHeaderHeightRef.current, headerHeightRef.current, contentContainerRef.current.scrollTop);
|
|
98
|
-
const preserverSize = headerHeightRef.current - minHeaderHeightRef.current + HEADER_MARGIN_HEIGHT_DELTA;
|
|
99
|
-
spacePreserverRef.current.style.height = `${preserverSize}px`;
|
|
100
|
-
}, []);
|
|
101
|
-
useLayoutEffect(() => {
|
|
102
|
-
if (contentContainerRef.current) {
|
|
103
|
-
const observer = new ResizeObserver(requestAnimation(() => {
|
|
104
|
-
if (!contentContainerRef.current) {
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
|
-
const isScrollable = contentContainerRef.current.scrollHeight > contentContainerRef.current.clientHeight;
|
|
108
|
-
const hasScroll = isScrollable && !checkIsScrolledToBottom(contentContainerRef.current);
|
|
109
|
-
bottomDividerVisibleRef.current = hasScroll;
|
|
110
|
-
bottomDividerContainerRef.current?.classList.toggle(styles.dividerContainerHidden, !bottomDividerVisibleRef.current);
|
|
111
|
-
updateHeaderDimensions();
|
|
112
|
-
recalcContentOverlayPosition();
|
|
113
|
-
}));
|
|
114
|
-
observer.observe(contentContainerRef.current);
|
|
115
|
-
return () => observer.disconnect();
|
|
116
|
-
}
|
|
117
|
-
return undefined;
|
|
118
|
-
}, [updateHeaderDimensions, recalcContentOverlayPosition]);
|
|
119
|
-
useLayoutEffect(() => {
|
|
120
|
-
updateHeaderDimensions();
|
|
121
|
-
recalcContentOverlayPosition();
|
|
122
|
-
if (!options && (headerImageUrl || headerImage)) {
|
|
123
|
-
topDividerContainerRef.current?.classList.toggle(styles.dividerContainerHidden, true);
|
|
124
|
-
}
|
|
125
|
-
}, [headerImageUrl, headerImage, updateHeaderDimensions, recalcContentOverlayPosition, options]);
|
|
126
|
-
const handleScroll = () => {
|
|
127
|
-
if (!contentContainerRef.current) {
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
|
-
bottomDividerVisibleRef.current = !checkIsScrolledToBottom(contentContainerRef.current);
|
|
131
|
-
bottomDividerContainerRef.current?.classList.toggle(styles.dividerContainerHidden, !bottomDividerVisibleRef.current);
|
|
132
|
-
topDividerContainerRef.current?.classList.toggle(styles.dividerContainerHidden, !isTopDividerVisible());
|
|
133
|
-
if (hasHeaderImageRef.current) {
|
|
134
|
-
shrinkByDelta(headerImageContainerRef.current, headerWrapperRef.current, minHeaderHeightRef.current, headerHeightRef.current, contentContainerRef.current.scrollTop);
|
|
135
|
-
}
|
|
136
|
-
};
|
|
137
|
-
const { hasVerticalScroll, verticalScrollbarProps, ...scrollbar } = useScrollbar({ axis: 'vertical' });
|
|
138
|
-
const contentContainerRefCallback = useMultipleRefs(contentContainerRef, scrollbar.scrollContainerRef);
|
|
139
|
-
const stickyContainerRefCallback = useMultipleRefs(stickyContainerRef, scrollbar.contentWrapperRef);
|
|
140
|
-
return (jsxs(Fragment, { children: [jsxs("div", { className: classnames(styles.modalContentWrapper, {
|
|
141
|
-
[styles.modalContentWrapperOneLine]: onlyActions,
|
|
142
|
-
}), children: [jsx(ModalHeader, { ...modalHeaderProps, headerHeight: headerHeightRef.current, labelId: labelId, wrapperRef: headerWrapperRef, ref: headerImageContainerRef }), jsx("div", { className: classnames(styles.dividerContainer, {
|
|
143
|
-
[styles.dividerContainerHidden]: !isTopDividerVisible(),
|
|
144
|
-
}), ref: topDividerContainerRef, children: jsx(Divider, {}) }), jsx("div", { className: classnames(styles.modalContent, scrollbar.hoverContainerCssClass), children: jsx(ContentOverlayRoot, { ref: contentOverlayRef, children: isTreeSelectorChild ? (jsx("div", { className: styles.treeSelectorContainer, children: children })) : (jsxs(Fragment, { children: [jsxs("div", { className: classnames(styles.modalScrollContainer), ref: contentContainerRefCallback, onScroll: handleScroll, "data-qa": "modal-content-scroll-container", children: [jsx("div", { className: classnames(styles.contentStickyContainer), ref: stickyContainerRefCallback, children: jsx(TextAreaGrowLimiter, { ...growLimiterContextValue, className: styles.growLimiter, children: children }) }), jsx("div", { className: styles.spacePreserver, ref: spacePreserverRef })] }), hasVerticalScroll && jsx(Scrollbar, { ...verticalScrollbarProps })] })) }) })] }), showDivider && (jsx("div", { className: classnames(styles.dividerContainer, {
|
|
145
|
-
[styles.dividerContainerHidden]: !bottomDividerVisibleRef.current,
|
|
146
|
-
}), ref: bottomDividerContainerRef, children: jsx(Divider, {}) }))] }));
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
export { ModalContentWithHeader as M, styles as s };
|
|
150
|
-
//# sourceMappingURL=ModalContentWithHeader-B7tpHFBW.js.map
|