@dreamcommerce/aurora 2.4.0-19 → 2.4.0-20
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/build/cjs/packages/aurora/src/components/dropdown/components/content.js +22 -22
- package/build/cjs/packages/aurora/src/components/dropdown/hooks/use_toggle.js +3 -1
- package/build/cjs/packages/aurora/src/components/dropdown/hooks/use_toggle.js.map +1 -1
- package/build/cjs/packages/aurora/src/components/dropdown/index.js +2 -2
- package/build/cjs/packages/aurora/src/components/dropdown/utilities.js +4 -4
- package/build/cjs/packages/aurora/src/components/file_picker/components/selected_file_preview.js +1 -1
- package/build/cjs/packages/utilities/build/esm/packages/utilities/src/ui_dom_utils.js +96 -0
- package/build/cjs/packages/utilities/build/esm/packages/utilities/src/ui_dom_utils.js.map +1 -0
- package/build/esm/packages/aurora/src/components/dropdown/components/content.js +23 -23
- package/build/esm/packages/aurora/src/components/dropdown/context/types.d.ts +2 -0
- package/build/esm/packages/aurora/src/components/dropdown/hooks/use_toggle.d.ts +1 -1
- package/build/esm/packages/aurora/src/components/dropdown/hooks/use_toggle.js +3 -1
- package/build/esm/packages/aurora/src/components/dropdown/hooks/use_toggle.js.map +1 -1
- package/build/esm/packages/aurora/src/components/dropdown/index.js +2 -2
- package/build/esm/packages/aurora/src/components/dropdown/utilities.js +4 -4
- package/build/esm/packages/aurora/src/components/file_picker/components/selected_file_preview.js +1 -1
- package/build/esm/packages/utilities/build/esm/packages/utilities/src/ui_dom_utils.js +92 -0
- package/build/esm/packages/utilities/build/esm/packages/utilities/src/ui_dom_utils.js.map +1 -0
- package/package.json +2 -2
|
@@ -18,6 +18,7 @@ var main_module = require('../../../css/dropdown/main.module.less.js');
|
|
|
18
18
|
var utilities = require('../utilities.js');
|
|
19
19
|
var use_click_outside = require('../../../hooks/use_click_outside.js');
|
|
20
20
|
var icon_arrow = require('../../../assets/icon_arrow.js');
|
|
21
|
+
var ui_dom_utils = require('../../../../../utilities/build/esm/packages/utilities/src/ui_dom_utils.js');
|
|
21
22
|
|
|
22
23
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
23
24
|
|
|
@@ -32,7 +33,7 @@ var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
|
|
32
33
|
const Content = ({ headerComponent, headerGoBackText, headerGoBackIcon, children, arrowSide = 'left', portalContainer }) => {
|
|
33
34
|
const [t] = useTranslation.useTranslation();
|
|
34
35
|
const contentRef = React.useRef(null);
|
|
35
|
-
const { wrapperRef, toggleDropdown, isOpen } = index.useDropdownContext();
|
|
36
|
+
const { wrapperRef, toggleDropdown, isOpen, closeDropdown } = index.useDropdownContext();
|
|
36
37
|
const [styles, setStyles] = React.useState({
|
|
37
38
|
left: '0px',
|
|
38
39
|
top: '0px',
|
|
@@ -60,36 +61,35 @@ const Content = ({ headerComponent, headerGoBackText, headerGoBackIcon, children
|
|
|
60
61
|
toggleDropdown();
|
|
61
62
|
}
|
|
62
63
|
});
|
|
63
|
-
const getDropdownPositionStyles = (isInModal, modalWrapperRect) => {
|
|
64
|
-
const { x, y, height, top } = modalWrapperRect;
|
|
65
|
-
const yOffset = 10;
|
|
66
|
-
const { xModifier, yModifier } = utilities.getXYModifiersForNestedDropdowns(portalContainer === null || portalContainer === void 0 ? void 0 : portalContainer.current);
|
|
67
|
-
const positionTop = top + height + yOffset - yModifier + window.scrollY;
|
|
68
|
-
const positionBottom = windowHeightMinusYOffset - y + yOffset;
|
|
69
|
-
const positionLeft = x - xModifier;
|
|
70
|
-
const zIndex = isInModal ? constants.DROPDOWN_ON_MODAL_Z_INDEX : constants.DROPDOWN_Z_INDEX;
|
|
71
|
-
const topPositionValue = !dropdownIsOutsideBottomViewport ? `${positionTop}px` : 'auto';
|
|
72
|
-
const bottomPositionValue = dropdownIsOutsideBottomViewport ? `${positionBottom}px` : 'auto';
|
|
73
|
-
return screenWidthName === responsive_breakpoints.SCREEN_XS
|
|
74
|
-
? { left: `0px`, top: `0px`, bottom: 'auto', zIndex }
|
|
75
|
-
: { left: `${positionLeft}px`, top: topPositionValue, bottom: bottomPositionValue, zIndex };
|
|
76
|
-
};
|
|
77
64
|
React.useEffect(() => {
|
|
78
65
|
if (wrapperRef === null || wrapperRef === void 0 ? void 0 : wrapperRef.current) {
|
|
66
|
+
const { x, y, height } = wrapperRef.current.getBoundingClientRect();
|
|
67
|
+
const yOffset = 10;
|
|
68
|
+
const { xModifier, yModifier } = utilities.getXYModifiersForNestedDropdowns(portalContainer === null || portalContainer === void 0 ? void 0 : portalContainer.current);
|
|
69
|
+
const positionTop = height + y + yOffset - yModifier;
|
|
70
|
+
const positionBottom = windowHeightMinusYOffset - y + yOffset;
|
|
71
|
+
const positionLeft = x - xModifier;
|
|
79
72
|
const isInModal = utilities.isChildOfModal(wrapperRef);
|
|
80
|
-
|
|
73
|
+
const zIndex = isInModal ? constants.DROPDOWN_ON_MODAL_Z_INDEX : constants.DROPDOWN_Z_INDEX;
|
|
74
|
+
const topPositionValue = !dropdownIsOutsideBottomViewport ? `${positionTop}px` : 'auto';
|
|
75
|
+
const bottomPositionValue = dropdownIsOutsideBottomViewport ? `${positionBottom}px` : 'auto';
|
|
76
|
+
screenWidthName === responsive_breakpoints.SCREEN_XS
|
|
77
|
+
? setStyles({ left: `0px`, top: `0px`, bottom: 'auto', zIndex })
|
|
78
|
+
: setStyles({ left: `${positionLeft}px`, top: topPositionValue, bottom: bottomPositionValue, zIndex });
|
|
81
79
|
}
|
|
82
80
|
}, [portalContainer, screenWidthName, wrapperRef, isOpen, dropdownIsOutsideBottomViewport]);
|
|
83
81
|
React.useEffect(() => {
|
|
82
|
+
var _a;
|
|
83
|
+
if (!(wrapperRef === null || wrapperRef === void 0 ? void 0 : wrapperRef.current) || !isOpen)
|
|
84
|
+
return;
|
|
85
|
+
const scrollableParent = (_a = ui_dom_utils.UiDomUtils.getFirstScrollableParent(wrapperRef.current)) !== null && _a !== void 0 ? _a : document.body;
|
|
84
86
|
const handleWindowScroll = () => {
|
|
85
|
-
if (
|
|
86
|
-
|
|
87
|
-
setStyles(getDropdownPositionStyles(isInModal, wrapperRef.current.getBoundingClientRect()));
|
|
87
|
+
if (typeof closeDropdown === 'function') {
|
|
88
|
+
closeDropdown();
|
|
88
89
|
}
|
|
89
90
|
};
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}, []);
|
|
91
|
+
scrollableParent.addEventListener('scroll', handleWindowScroll, { once: true });
|
|
92
|
+
}, [isOpen]);
|
|
93
93
|
return reactDom.createPortal(React__default['default'].createElement(reactTransitionGroup.TransitionGroup, { component: null }, isOpen === true ? (React__default['default'].createElement(reactTransitionGroup.CSSTransition, { timeout: 200, classNames: {
|
|
94
94
|
enter: main_module['default']['dropdown-enter'],
|
|
95
95
|
enterActive: main_module['default']['dropdown-enter-active'],
|
|
@@ -14,12 +14,14 @@ var use_effect_after_mount = require('../../../hooks/use_effect_after_mount.js')
|
|
|
14
14
|
function useToggle(defaultIsOpen = false, onToggleCb) {
|
|
15
15
|
const [isOpen, setIsOpen] = React.useState(defaultIsOpen);
|
|
16
16
|
const onToggle = React.useCallback(() => setIsOpen((oldIsOpen) => !oldIsOpen), []);
|
|
17
|
+
const open = React.useCallback(() => setIsOpen(true), []);
|
|
18
|
+
const close = React.useCallback(() => setIsOpen(false), []);
|
|
17
19
|
use_effect_after_mount.useEffectAfterMount(() => {
|
|
18
20
|
if (typeof onToggleCb === 'function') {
|
|
19
21
|
onToggleCb(isOpen);
|
|
20
22
|
}
|
|
21
23
|
}, [isOpen]);
|
|
22
|
-
return [isOpen, onToggle];
|
|
24
|
+
return [isOpen, onToggle, open, close];
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
exports.useToggle = useToggle;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":null,"sources":[null],"sourcesContent":[null],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;"}
|
|
1
|
+
{"version":3,"file":null,"sources":[null],"sourcesContent":[null],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;"}
|
|
@@ -44,11 +44,11 @@ var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
|
|
44
44
|
*/
|
|
45
45
|
const Dropdown = ({ defaultIsOpen = false, onToggle, children }) => {
|
|
46
46
|
const wrapperRef = React.useRef(null);
|
|
47
|
-
const [isOpen, toggleDropdown] = use_toggle.useToggle(defaultIsOpen, onToggle);
|
|
47
|
+
const [isOpen, toggleDropdown, openDropdown, closeDropdown] = use_toggle.useToggle(defaultIsOpen, onToggle);
|
|
48
48
|
/**
|
|
49
49
|
* context values, they may be used with useContext in any component which is part of Dropdown composition
|
|
50
50
|
*/
|
|
51
|
-
const value = React__default['default'].useMemo(() => ({ wrapperRef, isOpen, toggleDropdown }), [isOpen, toggleDropdown]);
|
|
51
|
+
const value = React__default['default'].useMemo(() => ({ wrapperRef, isOpen, toggleDropdown, openDropdown, closeDropdown }), [isOpen, toggleDropdown, openDropdown, closeDropdown]);
|
|
52
52
|
return (React__default['default'].createElement(index.DropdownContext.Provider, { value: value },
|
|
53
53
|
React__default['default'].createElement("div", { ref: wrapperRef, className: main_module['default'].dropdown }, children)));
|
|
54
54
|
};
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
require('react');
|
|
6
|
-
var main_module = require('../../css/modal/main.module.less.js');
|
|
6
|
+
var main_module$1 = require('../../css/modal/main.module.less.js');
|
|
7
7
|
var css_classes = require('./css_classes.js');
|
|
8
8
|
var fuzzy_search = require('../../utilities/fuzzy_search/fuzzy_search.js');
|
|
9
|
-
var main_module
|
|
9
|
+
var main_module = require('../../css/dropdown/main.module.less.js');
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* checks if the given option is selected within array of selectedValues array
|
|
@@ -47,7 +47,7 @@ const getXYModifiersForNestedDropdowns = (portalContainer) => {
|
|
|
47
47
|
let xModifier = 0;
|
|
48
48
|
let yModifier = 0;
|
|
49
49
|
if (portalContainer) {
|
|
50
|
-
const $parentDropdownContent = portalContainer.closest(`.${main_module
|
|
50
|
+
const $parentDropdownContent = portalContainer.closest(`.${main_module['default'][css_classes.cssDropdownContent]}`);
|
|
51
51
|
if ($parentDropdownContent) {
|
|
52
52
|
const { x: portalX, y: portalY } = $parentDropdownContent.getBoundingClientRect();
|
|
53
53
|
xModifier = portalX;
|
|
@@ -63,7 +63,7 @@ const isChildOfModal = (ref) => {
|
|
|
63
63
|
var _a;
|
|
64
64
|
let currentParent = (_a = ref.current) === null || _a === void 0 ? void 0 : _a.parentElement;
|
|
65
65
|
while (currentParent) {
|
|
66
|
-
if (currentParent.classList.contains(main_module['default']['modal-window'])) {
|
|
66
|
+
if (currentParent.classList.contains(main_module$1['default']['modal-window'])) {
|
|
67
67
|
return true;
|
|
68
68
|
}
|
|
69
69
|
currentParent = currentParent === null || currentParent === void 0 ? void 0 : currentParent.parentElement;
|
package/build/cjs/packages/aurora/src/components/file_picker/components/selected_file_preview.js
CHANGED
|
@@ -4,9 +4,9 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
var React = require('react');
|
|
6
6
|
var useTranslation = require('../../../../../../external/react-i18next/dist/es/useTranslation.js');
|
|
7
|
+
var file_utils = require('../../../../../utilities/build/esm/packages/utilities/src/file_utils.js');
|
|
7
8
|
var main_module = require('../../../css/file_picker/main.module.less.js');
|
|
8
9
|
var css_classes = require('../css_classes.js');
|
|
9
|
-
var file_utils = require('../../../../../utilities/build/esm/packages/utilities/src/file_utils.js');
|
|
10
10
|
var icon_delete = require('../../../assets/icon_delete.js');
|
|
11
11
|
|
|
12
12
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
class UiDomUtils {
|
|
6
|
+
static show($el) {
|
|
7
|
+
$el.removeAttribute('hidden');
|
|
8
|
+
}
|
|
9
|
+
static hide($el) {
|
|
10
|
+
$el.setAttribute('hidden', '');
|
|
11
|
+
}
|
|
12
|
+
static empty($el) {
|
|
13
|
+
$el.innerHTML = '';
|
|
14
|
+
}
|
|
15
|
+
static makeUnnavigable($el) {
|
|
16
|
+
$el.setAttribute('tabindex', '-1');
|
|
17
|
+
}
|
|
18
|
+
static makeNavigable($el) {
|
|
19
|
+
$el.setAttribute('tabindex', '0');
|
|
20
|
+
}
|
|
21
|
+
static getFocusableSelector() {
|
|
22
|
+
return ('' +
|
|
23
|
+
// Namespace problems of [xlink:href] explained in https://stackoverflow.com/a/23047888/515124
|
|
24
|
+
// svg a[*|href] does not match in IE9, but since we're filtering
|
|
25
|
+
// through is/focusable we can include all <a> from SVG
|
|
26
|
+
'svg a,' +
|
|
27
|
+
// may behave as 'svg, svg *,' in chrome as *every* svg element with a focus event listener is focusable
|
|
28
|
+
// navigational elements
|
|
29
|
+
'a[href],' +
|
|
30
|
+
// validity determined by is/valid-area.js
|
|
31
|
+
'area[href],' +
|
|
32
|
+
// validity determined by is/disabled.js
|
|
33
|
+
'input:not([type="hidden"]), select, textarea, button,' +
|
|
34
|
+
// browsing context containers
|
|
35
|
+
'iframe, object, embed,' +
|
|
36
|
+
// interactive content
|
|
37
|
+
'keygen,' +
|
|
38
|
+
// validity determined by is/valid-tabindex.js
|
|
39
|
+
'[tabindex]:not([tabindex="-1"]),' +
|
|
40
|
+
// editing hosts
|
|
41
|
+
'[contenteditable]');
|
|
42
|
+
}
|
|
43
|
+
static getFocusableElements($container) {
|
|
44
|
+
return [...$container.querySelectorAll(this.getFocusableSelector())].filter(($el) => !this._isNotFocusable($el));
|
|
45
|
+
}
|
|
46
|
+
static getFocusableElement($container) {
|
|
47
|
+
return [...$container.querySelectorAll(this.getFocusableSelector())].filter(($el) => !this._isNotFocusable($el))[0];
|
|
48
|
+
}
|
|
49
|
+
static _isNotFocusable($el) {
|
|
50
|
+
const displayValue = getComputedStyle($el).getPropertyValue('display');
|
|
51
|
+
return !!($el.hasAttribute('disabled') || $el.getAttribute('aria-hidden') || $el.hasAttribute('hidden') || displayValue === 'none');
|
|
52
|
+
}
|
|
53
|
+
static isFocusable($element) {
|
|
54
|
+
return $element.matches(this.getFocusableSelector());
|
|
55
|
+
}
|
|
56
|
+
static setFocusToFirstFocusableElementInContainer($container) {
|
|
57
|
+
var _a;
|
|
58
|
+
(_a = this.getFocusableElement($container)) === null || _a === void 0 ? void 0 : _a.focus();
|
|
59
|
+
}
|
|
60
|
+
static getDirectChildren($el, selector) {
|
|
61
|
+
return selector ? [...$el.children].filter((child) => child.matches(selector)) : [...$el.children];
|
|
62
|
+
}
|
|
63
|
+
static getAllClosest($el, selector, elements = []) {
|
|
64
|
+
if (!$el)
|
|
65
|
+
return elements;
|
|
66
|
+
const $closestEl = $el.closest(selector);
|
|
67
|
+
if ($closestEl)
|
|
68
|
+
elements.push($closestEl);
|
|
69
|
+
if (!$closestEl)
|
|
70
|
+
return elements;
|
|
71
|
+
return UiDomUtils.getAllClosest($closestEl.parentElement, selector, elements);
|
|
72
|
+
}
|
|
73
|
+
static getFirstParentNonStaticElement($el) {
|
|
74
|
+
let $currentEl = $el.parentElement;
|
|
75
|
+
while ($currentEl) {
|
|
76
|
+
if ($currentEl && window.getComputedStyle($currentEl).position !== 'static') {
|
|
77
|
+
return $currentEl;
|
|
78
|
+
}
|
|
79
|
+
$currentEl = $currentEl.parentElement;
|
|
80
|
+
}
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
static getFirstScrollableParent($el) {
|
|
84
|
+
let currentParent = $el.parentElement;
|
|
85
|
+
while (currentParent) {
|
|
86
|
+
if (currentParent.scrollHeight > currentParent.clientHeight) {
|
|
87
|
+
return currentParent;
|
|
88
|
+
}
|
|
89
|
+
currentParent = currentParent === null || currentParent === void 0 ? void 0 : currentParent.parentElement;
|
|
90
|
+
}
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
exports.UiDomUtils = UiDomUtils;
|
|
96
|
+
//# sourceMappingURL=ui_dom_utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":null,"sources":[null],"sourcesContent":[null],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;"}
|
|
@@ -11,9 +11,10 @@ import { TransitionGroup, CSSTransition } from 'react-transition-group';
|
|
|
11
11
|
import { DROPDOWN_Z_INDEX, DROPDOWN_ON_MODAL_Z_INDEX } from '../constants.js';
|
|
12
12
|
import { cssDropdownContent, cssDropdownArrowHorizontalDirectionRight, cssDropdownArrowVerticalDirectionBottom, cssDropdownHeader, cssDropdownHeaderContent, cssDropdownHeaderTitle } from '../css_classes.js';
|
|
13
13
|
import cssClasses from '../../../css/dropdown/main.module.less.js';
|
|
14
|
-
import {
|
|
14
|
+
import { getXYModifiersForNestedDropdowns, isChildOfModal } from '../utilities.js';
|
|
15
15
|
import { useClickOutside } from '../../../hooks/use_click_outside.js';
|
|
16
16
|
import IconArrow from '../../../assets/icon_arrow.js';
|
|
17
|
+
import { UiDomUtils } from '../../../../../utilities/build/esm/packages/utilities/src/ui_dom_utils.js';
|
|
17
18
|
|
|
18
19
|
/**
|
|
19
20
|
* Dropdown.Content component. This togglable part of dropdown.
|
|
@@ -24,7 +25,7 @@ import IconArrow from '../../../assets/icon_arrow.js';
|
|
|
24
25
|
const Content = ({ headerComponent, headerGoBackText, headerGoBackIcon, children, arrowSide = 'left', portalContainer }) => {
|
|
25
26
|
const [t] = useTranslation();
|
|
26
27
|
const contentRef = useRef(null);
|
|
27
|
-
const { wrapperRef, toggleDropdown, isOpen } = useDropdownContext();
|
|
28
|
+
const { wrapperRef, toggleDropdown, isOpen, closeDropdown } = useDropdownContext();
|
|
28
29
|
const [styles, setStyles] = useState({
|
|
29
30
|
left: '0px',
|
|
30
31
|
top: '0px',
|
|
@@ -52,36 +53,35 @@ const Content = ({ headerComponent, headerGoBackText, headerGoBackIcon, children
|
|
|
52
53
|
toggleDropdown();
|
|
53
54
|
}
|
|
54
55
|
});
|
|
55
|
-
const getDropdownPositionStyles = (isInModal, modalWrapperRect) => {
|
|
56
|
-
const { x, y, height, top } = modalWrapperRect;
|
|
57
|
-
const yOffset = 10;
|
|
58
|
-
const { xModifier, yModifier } = getXYModifiersForNestedDropdowns(portalContainer === null || portalContainer === void 0 ? void 0 : portalContainer.current);
|
|
59
|
-
const positionTop = top + height + yOffset - yModifier + window.scrollY;
|
|
60
|
-
const positionBottom = windowHeightMinusYOffset - y + yOffset;
|
|
61
|
-
const positionLeft = x - xModifier;
|
|
62
|
-
const zIndex = isInModal ? DROPDOWN_ON_MODAL_Z_INDEX : DROPDOWN_Z_INDEX;
|
|
63
|
-
const topPositionValue = !dropdownIsOutsideBottomViewport ? `${positionTop}px` : 'auto';
|
|
64
|
-
const bottomPositionValue = dropdownIsOutsideBottomViewport ? `${positionBottom}px` : 'auto';
|
|
65
|
-
return screenWidthName === SCREEN_XS
|
|
66
|
-
? { left: `0px`, top: `0px`, bottom: 'auto', zIndex }
|
|
67
|
-
: { left: `${positionLeft}px`, top: topPositionValue, bottom: bottomPositionValue, zIndex };
|
|
68
|
-
};
|
|
69
56
|
useEffect(() => {
|
|
70
57
|
if (wrapperRef === null || wrapperRef === void 0 ? void 0 : wrapperRef.current) {
|
|
58
|
+
const { x, y, height } = wrapperRef.current.getBoundingClientRect();
|
|
59
|
+
const yOffset = 10;
|
|
60
|
+
const { xModifier, yModifier } = getXYModifiersForNestedDropdowns(portalContainer === null || portalContainer === void 0 ? void 0 : portalContainer.current);
|
|
61
|
+
const positionTop = height + y + yOffset - yModifier;
|
|
62
|
+
const positionBottom = windowHeightMinusYOffset - y + yOffset;
|
|
63
|
+
const positionLeft = x - xModifier;
|
|
71
64
|
const isInModal = isChildOfModal(wrapperRef);
|
|
72
|
-
|
|
65
|
+
const zIndex = isInModal ? DROPDOWN_ON_MODAL_Z_INDEX : DROPDOWN_Z_INDEX;
|
|
66
|
+
const topPositionValue = !dropdownIsOutsideBottomViewport ? `${positionTop}px` : 'auto';
|
|
67
|
+
const bottomPositionValue = dropdownIsOutsideBottomViewport ? `${positionBottom}px` : 'auto';
|
|
68
|
+
screenWidthName === SCREEN_XS
|
|
69
|
+
? setStyles({ left: `0px`, top: `0px`, bottom: 'auto', zIndex })
|
|
70
|
+
: setStyles({ left: `${positionLeft}px`, top: topPositionValue, bottom: bottomPositionValue, zIndex });
|
|
73
71
|
}
|
|
74
72
|
}, [portalContainer, screenWidthName, wrapperRef, isOpen, dropdownIsOutsideBottomViewport]);
|
|
75
73
|
useEffect(() => {
|
|
74
|
+
var _a;
|
|
75
|
+
if (!(wrapperRef === null || wrapperRef === void 0 ? void 0 : wrapperRef.current) || !isOpen)
|
|
76
|
+
return;
|
|
77
|
+
const scrollableParent = (_a = UiDomUtils.getFirstScrollableParent(wrapperRef.current)) !== null && _a !== void 0 ? _a : document.body;
|
|
76
78
|
const handleWindowScroll = () => {
|
|
77
|
-
if (
|
|
78
|
-
|
|
79
|
-
setStyles(getDropdownPositionStyles(isInModal, wrapperRef.current.getBoundingClientRect()));
|
|
79
|
+
if (typeof closeDropdown === 'function') {
|
|
80
|
+
closeDropdown();
|
|
80
81
|
}
|
|
81
82
|
};
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}, []);
|
|
83
|
+
scrollableParent.addEventListener('scroll', handleWindowScroll, { once: true });
|
|
84
|
+
}, [isOpen]);
|
|
85
85
|
return createPortal(React.createElement(TransitionGroup, { component: null }, isOpen === true ? (React.createElement(CSSTransition, { timeout: 200, classNames: {
|
|
86
86
|
enter: cssClasses['dropdown-enter'],
|
|
87
87
|
enterActive: cssClasses['dropdown-enter-active'],
|
|
@@ -4,4 +4,4 @@
|
|
|
4
4
|
* @param onToggleCb callback onToggle
|
|
5
5
|
* @returns {Array} tuple - open state and and method to change open state
|
|
6
6
|
*/
|
|
7
|
-
export declare function useToggle(defaultIsOpen?: boolean, onToggleCb?: (isOpen: boolean) => void): [boolean, () => void];
|
|
7
|
+
export declare function useToggle(defaultIsOpen?: boolean, onToggleCb?: (isOpen: boolean) => void): [boolean, () => void, () => void, () => void];
|
|
@@ -10,12 +10,14 @@ import { useEffectAfterMount } from '../../../hooks/use_effect_after_mount.js';
|
|
|
10
10
|
function useToggle(defaultIsOpen = false, onToggleCb) {
|
|
11
11
|
const [isOpen, setIsOpen] = useState(defaultIsOpen);
|
|
12
12
|
const onToggle = useCallback(() => setIsOpen((oldIsOpen) => !oldIsOpen), []);
|
|
13
|
+
const open = useCallback(() => setIsOpen(true), []);
|
|
14
|
+
const close = useCallback(() => setIsOpen(false), []);
|
|
13
15
|
useEffectAfterMount(() => {
|
|
14
16
|
if (typeof onToggleCb === 'function') {
|
|
15
17
|
onToggleCb(isOpen);
|
|
16
18
|
}
|
|
17
19
|
}, [isOpen]);
|
|
18
|
-
return [isOpen, onToggle];
|
|
20
|
+
return [isOpen, onToggle, open, close];
|
|
19
21
|
}
|
|
20
22
|
|
|
21
23
|
export { useToggle };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":null,"sources":[null],"sourcesContent":[null],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;"}
|
|
1
|
+
{"version":3,"file":null,"sources":[null],"sourcesContent":[null],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;"}
|
|
@@ -36,11 +36,11 @@ import { useToggle } from './hooks/use_toggle.js';
|
|
|
36
36
|
*/
|
|
37
37
|
const Dropdown = ({ defaultIsOpen = false, onToggle, children }) => {
|
|
38
38
|
const wrapperRef = useRef(null);
|
|
39
|
-
const [isOpen, toggleDropdown] = useToggle(defaultIsOpen, onToggle);
|
|
39
|
+
const [isOpen, toggleDropdown, openDropdown, closeDropdown] = useToggle(defaultIsOpen, onToggle);
|
|
40
40
|
/**
|
|
41
41
|
* context values, they may be used with useContext in any component which is part of Dropdown composition
|
|
42
42
|
*/
|
|
43
|
-
const value = React.useMemo(() => ({ wrapperRef, isOpen, toggleDropdown }), [isOpen, toggleDropdown]);
|
|
43
|
+
const value = React.useMemo(() => ({ wrapperRef, isOpen, toggleDropdown, openDropdown, closeDropdown }), [isOpen, toggleDropdown, openDropdown, closeDropdown]);
|
|
44
44
|
return (React.createElement(DropdownContext.Provider, { value: value },
|
|
45
45
|
React.createElement("div", { ref: wrapperRef, className: cssClasses.dropdown }, children)));
|
|
46
46
|
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import 'react';
|
|
2
|
-
import cssClasses from '../../css/modal/main.module.less.js';
|
|
2
|
+
import cssClasses$1 from '../../css/modal/main.module.less.js';
|
|
3
3
|
import { cssDropdownContent } from './css_classes.js';
|
|
4
4
|
import { fuzzySearch } from '../../utilities/fuzzy_search/fuzzy_search.js';
|
|
5
|
-
import cssClasses
|
|
5
|
+
import cssClasses from '../../css/dropdown/main.module.less.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* checks if the given option is selected within array of selectedValues array
|
|
@@ -43,7 +43,7 @@ const getXYModifiersForNestedDropdowns = (portalContainer) => {
|
|
|
43
43
|
let xModifier = 0;
|
|
44
44
|
let yModifier = 0;
|
|
45
45
|
if (portalContainer) {
|
|
46
|
-
const $parentDropdownContent = portalContainer.closest(`.${cssClasses
|
|
46
|
+
const $parentDropdownContent = portalContainer.closest(`.${cssClasses[cssDropdownContent]}`);
|
|
47
47
|
if ($parentDropdownContent) {
|
|
48
48
|
const { x: portalX, y: portalY } = $parentDropdownContent.getBoundingClientRect();
|
|
49
49
|
xModifier = portalX;
|
|
@@ -59,7 +59,7 @@ const isChildOfModal = (ref) => {
|
|
|
59
59
|
var _a;
|
|
60
60
|
let currentParent = (_a = ref.current) === null || _a === void 0 ? void 0 : _a.parentElement;
|
|
61
61
|
while (currentParent) {
|
|
62
|
-
if (currentParent.classList.contains(cssClasses['modal-window'])) {
|
|
62
|
+
if (currentParent.classList.contains(cssClasses$1['modal-window'])) {
|
|
63
63
|
return true;
|
|
64
64
|
}
|
|
65
65
|
currentParent = currentParent === null || currentParent === void 0 ? void 0 : currentParent.parentElement;
|
package/build/esm/packages/aurora/src/components/file_picker/components/selected_file_preview.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { useTranslation } from '../../../../../../external/react-i18next/dist/es/useTranslation.js';
|
|
3
|
+
import { FileUtils } from '../../../../../utilities/build/esm/packages/utilities/src/file_utils.js';
|
|
3
4
|
import styles from '../../../css/file_picker/main.module.less.js';
|
|
4
5
|
import CSS_CLASSES from '../css_classes.js';
|
|
5
|
-
import { FileUtils } from '../../../../../utilities/build/esm/packages/utilities/src/file_utils.js';
|
|
6
6
|
import IconDelete from '../../../assets/icon_delete.js';
|
|
7
7
|
|
|
8
8
|
const SelectedFilePreview = ({ file, isPreview, onPreviewError, onFileDelete }) => {
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
class UiDomUtils {
|
|
2
|
+
static show($el) {
|
|
3
|
+
$el.removeAttribute('hidden');
|
|
4
|
+
}
|
|
5
|
+
static hide($el) {
|
|
6
|
+
$el.setAttribute('hidden', '');
|
|
7
|
+
}
|
|
8
|
+
static empty($el) {
|
|
9
|
+
$el.innerHTML = '';
|
|
10
|
+
}
|
|
11
|
+
static makeUnnavigable($el) {
|
|
12
|
+
$el.setAttribute('tabindex', '-1');
|
|
13
|
+
}
|
|
14
|
+
static makeNavigable($el) {
|
|
15
|
+
$el.setAttribute('tabindex', '0');
|
|
16
|
+
}
|
|
17
|
+
static getFocusableSelector() {
|
|
18
|
+
return ('' +
|
|
19
|
+
// Namespace problems of [xlink:href] explained in https://stackoverflow.com/a/23047888/515124
|
|
20
|
+
// svg a[*|href] does not match in IE9, but since we're filtering
|
|
21
|
+
// through is/focusable we can include all <a> from SVG
|
|
22
|
+
'svg a,' +
|
|
23
|
+
// may behave as 'svg, svg *,' in chrome as *every* svg element with a focus event listener is focusable
|
|
24
|
+
// navigational elements
|
|
25
|
+
'a[href],' +
|
|
26
|
+
// validity determined by is/valid-area.js
|
|
27
|
+
'area[href],' +
|
|
28
|
+
// validity determined by is/disabled.js
|
|
29
|
+
'input:not([type="hidden"]), select, textarea, button,' +
|
|
30
|
+
// browsing context containers
|
|
31
|
+
'iframe, object, embed,' +
|
|
32
|
+
// interactive content
|
|
33
|
+
'keygen,' +
|
|
34
|
+
// validity determined by is/valid-tabindex.js
|
|
35
|
+
'[tabindex]:not([tabindex="-1"]),' +
|
|
36
|
+
// editing hosts
|
|
37
|
+
'[contenteditable]');
|
|
38
|
+
}
|
|
39
|
+
static getFocusableElements($container) {
|
|
40
|
+
return [...$container.querySelectorAll(this.getFocusableSelector())].filter(($el) => !this._isNotFocusable($el));
|
|
41
|
+
}
|
|
42
|
+
static getFocusableElement($container) {
|
|
43
|
+
return [...$container.querySelectorAll(this.getFocusableSelector())].filter(($el) => !this._isNotFocusable($el))[0];
|
|
44
|
+
}
|
|
45
|
+
static _isNotFocusable($el) {
|
|
46
|
+
const displayValue = getComputedStyle($el).getPropertyValue('display');
|
|
47
|
+
return !!($el.hasAttribute('disabled') || $el.getAttribute('aria-hidden') || $el.hasAttribute('hidden') || displayValue === 'none');
|
|
48
|
+
}
|
|
49
|
+
static isFocusable($element) {
|
|
50
|
+
return $element.matches(this.getFocusableSelector());
|
|
51
|
+
}
|
|
52
|
+
static setFocusToFirstFocusableElementInContainer($container) {
|
|
53
|
+
var _a;
|
|
54
|
+
(_a = this.getFocusableElement($container)) === null || _a === void 0 ? void 0 : _a.focus();
|
|
55
|
+
}
|
|
56
|
+
static getDirectChildren($el, selector) {
|
|
57
|
+
return selector ? [...$el.children].filter((child) => child.matches(selector)) : [...$el.children];
|
|
58
|
+
}
|
|
59
|
+
static getAllClosest($el, selector, elements = []) {
|
|
60
|
+
if (!$el)
|
|
61
|
+
return elements;
|
|
62
|
+
const $closestEl = $el.closest(selector);
|
|
63
|
+
if ($closestEl)
|
|
64
|
+
elements.push($closestEl);
|
|
65
|
+
if (!$closestEl)
|
|
66
|
+
return elements;
|
|
67
|
+
return UiDomUtils.getAllClosest($closestEl.parentElement, selector, elements);
|
|
68
|
+
}
|
|
69
|
+
static getFirstParentNonStaticElement($el) {
|
|
70
|
+
let $currentEl = $el.parentElement;
|
|
71
|
+
while ($currentEl) {
|
|
72
|
+
if ($currentEl && window.getComputedStyle($currentEl).position !== 'static') {
|
|
73
|
+
return $currentEl;
|
|
74
|
+
}
|
|
75
|
+
$currentEl = $currentEl.parentElement;
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
static getFirstScrollableParent($el) {
|
|
80
|
+
let currentParent = $el.parentElement;
|
|
81
|
+
while (currentParent) {
|
|
82
|
+
if (currentParent.scrollHeight > currentParent.clientHeight) {
|
|
83
|
+
return currentParent;
|
|
84
|
+
}
|
|
85
|
+
currentParent = currentParent === null || currentParent === void 0 ? void 0 : currentParent.parentElement;
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export { UiDomUtils };
|
|
92
|
+
//# sourceMappingURL=ui_dom_utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":null,"sources":[null],"sourcesContent":[null],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;"}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@dreamcommerce/aurora",
|
|
3
3
|
"packageManager": "yarn@3.2.0",
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"version": "2.4.0-
|
|
5
|
+
"version": "2.4.0-20",
|
|
6
6
|
"description": "aurora",
|
|
7
7
|
"author": "k0ssak",
|
|
8
8
|
"license": "MIT",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"update-visuals": "jest -c .config/jest/jest.config.visual.js --updateSnapshot"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@dreamcommerce/utilities": "^1.
|
|
47
|
+
"@dreamcommerce/utilities": "^1.7.0",
|
|
48
48
|
"@shoper/jest_config": "^0.0.0",
|
|
49
49
|
"@shoper/tsconfig": "^0.0.0",
|
|
50
50
|
"@storybook/react": "6.5.7",
|