@doyourjob/gravity-ui-page-constructor-addons 2.1.46 → 2.1.48
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -0
- package/build/cjs/components/HeaderStripe/HeaderStripe.css +10 -0
- package/build/cjs/components/HeaderStripe/HeaderStripe.js +18 -7
- package/build/cjs/components/Navigation/containers/Footer/GroupLinks/GroupLinks.js +3 -4
- package/build/cjs/components/NewHeader/NewHeader.css +5 -0
- package/build/cjs/components/NewHeader/NewHeader.js +3 -2
- package/build/cjs/components/NewHeader/components/NHLoginButton/NHLoginButton.css +18 -0
- package/build/cjs/components/NewHeader/components/NHLoginButton/NHLoginButton.js +18 -6
- package/build/cjs/components/NewHeader/components/NHMobileNavigation/NHMobileNavigation.css +10 -0
- package/build/cjs/components/NewHeader/components/NHMobileNavigation/NHMobileNavigation.js +8 -3
- package/build/cjs/components/NewHeader/components/NHMobileNavigationItem/NHMobileNavigationItem.css +5 -0
- package/build/cjs/components/NewHeader/components/NHMobileNavigationItem/NHMobileNavigationItem.js +2 -1
- package/build/cjs/components/NewHeader/components/NHMobileNavigationPopup/NHMobileNavigationPopup.d.ts +2 -1
- package/build/cjs/components/NewHeader/components/NHMobileNavigationPopup/NHMobileNavigationPopup.js +2 -2
- package/build/cjs/components/NewHeader/components/NHNavigation/NHNavigation.d.ts +4 -1
- package/build/cjs/components/NewHeader/components/NHNavigation/NHNavigation.js +72 -9
- package/build/cjs/components/NewHeader/components/NHNavigationItem/NHNavigationItem.css +5 -0
- package/build/cjs/components/NewHeader/components/NHNavigationItem/NHNavigationItem.d.ts +3 -0
- package/build/cjs/components/NewHeader/components/NHNavigationItem/NHNavigationItem.js +12 -3
- package/build/cjs/components/NewHeader/components/NHNavigationPopup/NHNavigationPopup.css +13 -2
- package/build/cjs/components/NewHeader/components/NHNavigationPopup/NHNavigationPopup.js +58 -6
- package/build/cjs/components/NewHeader/components/NHNavigationPopup/keyboardNavigation.d.ts +4 -0
- package/build/cjs/components/NewHeader/components/NHNavigationPopup/keyboardNavigation.js +43 -0
- package/build/cjs/components/NewHeader/components/NHPopupItem/NHPopupItem.css +5 -0
- package/build/esm/components/HeaderStripe/HeaderStripe.css +10 -0
- package/build/esm/components/HeaderStripe/HeaderStripe.js +18 -7
- package/build/esm/components/Navigation/containers/Footer/GroupLinks/GroupLinks.js +3 -4
- package/build/esm/components/NewHeader/NewHeader.css +5 -0
- package/build/esm/components/NewHeader/NewHeader.js +3 -2
- package/build/esm/components/NewHeader/components/NHLoginButton/NHLoginButton.css +18 -0
- package/build/esm/components/NewHeader/components/NHLoginButton/NHLoginButton.js +19 -7
- package/build/esm/components/NewHeader/components/NHMobileNavigation/NHMobileNavigation.css +10 -0
- package/build/esm/components/NewHeader/components/NHMobileNavigation/NHMobileNavigation.js +9 -4
- package/build/esm/components/NewHeader/components/NHMobileNavigationItem/NHMobileNavigationItem.css +5 -0
- package/build/esm/components/NewHeader/components/NHMobileNavigationItem/NHMobileNavigationItem.js +2 -1
- package/build/esm/components/NewHeader/components/NHMobileNavigationPopup/NHMobileNavigationPopup.d.ts +2 -1
- package/build/esm/components/NewHeader/components/NHMobileNavigationPopup/NHMobileNavigationPopup.js +2 -2
- package/build/esm/components/NewHeader/components/NHNavigation/NHNavigation.d.ts +4 -1
- package/build/esm/components/NewHeader/components/NHNavigation/NHNavigation.js +72 -9
- package/build/esm/components/NewHeader/components/NHNavigationItem/NHNavigationItem.css +5 -0
- package/build/esm/components/NewHeader/components/NHNavigationItem/NHNavigationItem.d.ts +3 -0
- package/build/esm/components/NewHeader/components/NHNavigationItem/NHNavigationItem.js +12 -3
- package/build/esm/components/NewHeader/components/NHNavigationPopup/NHNavigationPopup.css +13 -2
- package/build/esm/components/NewHeader/components/NHNavigationPopup/NHNavigationPopup.js +58 -6
- package/build/esm/components/NewHeader/components/NHNavigationPopup/keyboardNavigation.d.ts +4 -0
- package/build/esm/components/NewHeader/components/NHNavigationPopup/keyboardNavigation.js +38 -0
- package/build/esm/components/NewHeader/components/NHPopupItem/NHPopupItem.css +5 -0
- package/package.json +2 -1
|
@@ -2,17 +2,69 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.NHNavigationPopup = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
-
const react_1 = tslib_1.
|
|
5
|
+
const react_1 = tslib_1.__importStar(require("react"));
|
|
6
6
|
const react_dom_1 = tslib_1.__importDefault(require("react-dom"));
|
|
7
|
-
const FocusTrap_1 = require("../../../../utils/FocusTrap");
|
|
8
7
|
const cn_1 = require("../../../../utils/cn");
|
|
8
|
+
const keyboardNavigation_1 = require("./keyboardNavigation");
|
|
9
9
|
const b = (0, cn_1.block)('nh-navigation-popup');
|
|
10
|
+
const nextKeys = new Set(['ArrowDown', 'ArrowRight']);
|
|
11
|
+
const previousKeys = new Set(['ArrowUp', 'ArrowLeft']);
|
|
12
|
+
const getNextIndex = (currentIndex, offset, elementsCount) => {
|
|
13
|
+
if (currentIndex === -1) {
|
|
14
|
+
return offset > 0 ? 0 : elementsCount - 1;
|
|
15
|
+
}
|
|
16
|
+
return (currentIndex + offset + elementsCount) % elementsCount;
|
|
17
|
+
};
|
|
10
18
|
const NHNavigationPopup = ({ headerRef, children, id }) => {
|
|
19
|
+
const popupRef = (0, react_1.useRef)(null);
|
|
20
|
+
const focusRelativeElement = (0, react_1.useCallback)((offset) => {
|
|
21
|
+
const popup = popupRef.current;
|
|
22
|
+
const focusableElements = (0, keyboardNavigation_1.getFocusableElements)(popup);
|
|
23
|
+
if (!popup || !focusableElements.length) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const activeElement = popup.ownerDocument.activeElement;
|
|
27
|
+
const currentIndex = activeElement ? focusableElements.indexOf(activeElement) : -1;
|
|
28
|
+
const nextIndex = getNextIndex(currentIndex, offset, focusableElements.length);
|
|
29
|
+
(0, keyboardNavigation_1.focusFromKeyboard)(focusableElements[nextIndex], popup);
|
|
30
|
+
}, []);
|
|
31
|
+
(0, react_1.useEffect)(() => {
|
|
32
|
+
const popup = popupRef.current;
|
|
33
|
+
if (!popup) {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
const handleKeyDown = (event) => {
|
|
37
|
+
if (event.key === 'Tab') {
|
|
38
|
+
event.preventDefault();
|
|
39
|
+
focusRelativeElement(event.shiftKey ? -1 : 1);
|
|
40
|
+
}
|
|
41
|
+
else if (nextKeys.has(event.key)) {
|
|
42
|
+
event.preventDefault();
|
|
43
|
+
focusRelativeElement(1);
|
|
44
|
+
}
|
|
45
|
+
else if (previousKeys.has(event.key)) {
|
|
46
|
+
event.preventDefault();
|
|
47
|
+
focusRelativeElement(-1);
|
|
48
|
+
}
|
|
49
|
+
else if (event.key === 'Home') {
|
|
50
|
+
event.preventDefault();
|
|
51
|
+
const popupElement = popupRef.current;
|
|
52
|
+
(0, keyboardNavigation_1.focusFromKeyboard)((0, keyboardNavigation_1.getFocusableElements)(popupElement)[0], popupElement);
|
|
53
|
+
}
|
|
54
|
+
else if (event.key === 'End') {
|
|
55
|
+
event.preventDefault();
|
|
56
|
+
const popupElement = popupRef.current;
|
|
57
|
+
const focusableElements = (0, keyboardNavigation_1.getFocusableElements)(popupElement);
|
|
58
|
+
(0, keyboardNavigation_1.focusFromKeyboard)(focusableElements[focusableElements.length - 1], popupElement);
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
popup.addEventListener('keydown', handleKeyDown);
|
|
62
|
+
return () => {
|
|
63
|
+
popup.removeEventListener('keydown', handleKeyDown);
|
|
64
|
+
};
|
|
65
|
+
}, [focusRelativeElement]);
|
|
11
66
|
return (headerRef === null || headerRef === void 0 ? void 0 : headerRef.current)
|
|
12
|
-
? react_dom_1.default.createPortal(react_1.default.createElement(
|
|
13
|
-
react_1.default.createElement("div", {
|
|
14
|
-
// eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
|
|
15
|
-
tabIndex: 0, className: b(), id: id }, children)), headerRef.current)
|
|
67
|
+
? react_dom_1.default.createPortal(react_1.default.createElement("div", { className: b(), id: id, ref: popupRef }, children), headerRef.current)
|
|
16
68
|
: null;
|
|
17
69
|
};
|
|
18
70
|
exports.NHNavigationPopup = NHNavigationPopup;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const keyboardFocusAttribute = "data-keyboard-focus";
|
|
2
|
+
export declare const focusableElementSelector: string;
|
|
3
|
+
export declare const getFocusableElements: (root?: HTMLElement | null) => HTMLElement[];
|
|
4
|
+
export declare const focusFromKeyboard: (element?: HTMLElement | null, root?: ParentNode | null) => void;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.focusFromKeyboard = exports.getFocusableElements = exports.focusableElementSelector = exports.keyboardFocusAttribute = void 0;
|
|
4
|
+
exports.keyboardFocusAttribute = 'data-keyboard-focus';
|
|
5
|
+
exports.focusableElementSelector = [
|
|
6
|
+
'a[href]',
|
|
7
|
+
'button:not([disabled])',
|
|
8
|
+
'input:not([disabled])',
|
|
9
|
+
'select:not([disabled])',
|
|
10
|
+
'textarea:not([disabled])',
|
|
11
|
+
'[tabindex]:not([tabindex="-1"])',
|
|
12
|
+
].join(',');
|
|
13
|
+
const keyboardFocusSelector = `[${exports.keyboardFocusAttribute}='true']`;
|
|
14
|
+
const blurHandlers = new WeakMap();
|
|
15
|
+
const clearKeyboardFocus = (root) => {
|
|
16
|
+
root.querySelectorAll(keyboardFocusSelector).forEach((element) => {
|
|
17
|
+
const blurHandler = blurHandlers.get(element);
|
|
18
|
+
if (blurHandler) {
|
|
19
|
+
element.removeEventListener('blur', blurHandler);
|
|
20
|
+
blurHandlers.delete(element);
|
|
21
|
+
}
|
|
22
|
+
element.removeAttribute(exports.keyboardFocusAttribute);
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
const getFocusableElements = (root) => Array.from((root === null || root === void 0 ? void 0 : root.querySelectorAll(exports.focusableElementSelector)) || []);
|
|
26
|
+
exports.getFocusableElements = getFocusableElements;
|
|
27
|
+
const focusFromKeyboard = (element, root) => {
|
|
28
|
+
if (!element) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const focusRoot = root || element.ownerDocument;
|
|
32
|
+
const handleBlur = () => {
|
|
33
|
+
element.removeAttribute(exports.keyboardFocusAttribute);
|
|
34
|
+
element.removeEventListener('blur', handleBlur);
|
|
35
|
+
blurHandlers.delete(element);
|
|
36
|
+
};
|
|
37
|
+
clearKeyboardFocus(focusRoot);
|
|
38
|
+
element.setAttribute(exports.keyboardFocusAttribute, 'true');
|
|
39
|
+
element.addEventListener('blur', handleBlur);
|
|
40
|
+
blurHandlers.set(element, handleBlur);
|
|
41
|
+
element.focus({ preventScroll: true });
|
|
42
|
+
};
|
|
43
|
+
exports.focusFromKeyboard = focusFromKeyboard;
|
|
@@ -57,6 +57,11 @@ unpredictable css rules order in build */
|
|
|
57
57
|
opacity: 1;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
.pc-addons-nh-navigation-popup-item:focus, .pc-addons-nh-navigation-popup-item:focus-visible, .pc-addons-nh-navigation-popup-item[data-keyboard-focus=true] {
|
|
61
|
+
outline: 2px solid var(--g-color-line-focus);
|
|
62
|
+
outline-offset: 4px;
|
|
63
|
+
}
|
|
64
|
+
|
|
60
65
|
.pc-addons-nh-navigation-popup-item_disable {
|
|
61
66
|
pointer-events: none;
|
|
62
67
|
}
|
|
@@ -122,6 +122,11 @@ unpredictable css rules order in build */
|
|
|
122
122
|
text-decoration: none;
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
+
.pc-addons-header-stripe__item-link:focus-visible {
|
|
126
|
+
outline: 2px solid var(--g-color-line-focus);
|
|
127
|
+
outline-offset: -2px;
|
|
128
|
+
}
|
|
129
|
+
|
|
125
130
|
@media (min-width: 769px) {
|
|
126
131
|
.pc-addons-header-stripe__item-link {
|
|
127
132
|
overflow: hidden;
|
|
@@ -147,6 +152,11 @@ unpredictable css rules order in build */
|
|
|
147
152
|
opacity: 0.6;
|
|
148
153
|
}
|
|
149
154
|
|
|
155
|
+
.pc-addons-header-stripe__close:focus-visible {
|
|
156
|
+
outline: 2px solid var(--g-color-line-focus);
|
|
157
|
+
outline-offset: -2px;
|
|
158
|
+
}
|
|
159
|
+
|
|
150
160
|
@keyframes expand-mobile {
|
|
151
161
|
from {
|
|
152
162
|
max-height: 0;
|
|
@@ -7,12 +7,12 @@ import { CloseIcon } from './CloseIcon';
|
|
|
7
7
|
import i18n from './i18n';
|
|
8
8
|
import './HeaderStripe.css';
|
|
9
9
|
const b = block('header-stripe');
|
|
10
|
-
const renderItemContent = (item) => {
|
|
10
|
+
const renderItemContent = (item, isActive) => {
|
|
11
11
|
if (typeof item === 'string') {
|
|
12
12
|
return item;
|
|
13
13
|
}
|
|
14
14
|
else if (item.link) {
|
|
15
|
-
return (React.createElement("a", { className: b('item-link'), href: item.link, target: item.target }, item.text));
|
|
15
|
+
return (React.createElement("a", { className: b('item-link'), href: item.link, target: item.target, tabIndex: isActive ? undefined : -1 }, item.text));
|
|
16
16
|
}
|
|
17
17
|
else {
|
|
18
18
|
return item.text;
|
|
@@ -21,6 +21,7 @@ const renderItemContent = (item) => {
|
|
|
21
21
|
export const HeaderStripe = ({ duration = 8000, items, textColor, background, backgroundImage, onlyDesktop, canClose, onClose, newDesign, }) => {
|
|
22
22
|
const [activeIndex, setActiveIndex] = useState(0);
|
|
23
23
|
const [isClosing, setIsClosing] = useState(false);
|
|
24
|
+
const [isFocusInside, setIsFocusInside] = useState(false);
|
|
24
25
|
const isMobile = useMobile();
|
|
25
26
|
const filteredItems = useMemo(() => isMobile
|
|
26
27
|
? items.filter((item) => (typeof item === 'object' ? !item.onlyDesktop : true))
|
|
@@ -29,13 +30,23 @@ export const HeaderStripe = ({ duration = 8000, items, textColor, background, ba
|
|
|
29
30
|
setIsClosing(true);
|
|
30
31
|
onClose === null || onClose === void 0 ? void 0 : onClose();
|
|
31
32
|
}, [onClose]);
|
|
33
|
+
const handleFocus = useCallback(() => {
|
|
34
|
+
setIsFocusInside(true);
|
|
35
|
+
}, []);
|
|
36
|
+
const handleBlur = useCallback((event) => {
|
|
37
|
+
const nextFocusedElement = event.relatedTarget;
|
|
38
|
+
if (!(nextFocusedElement instanceof Node) ||
|
|
39
|
+
!event.currentTarget.contains(nextFocusedElement)) {
|
|
40
|
+
setIsFocusInside(false);
|
|
41
|
+
}
|
|
42
|
+
}, []);
|
|
32
43
|
useEffect(() => {
|
|
33
44
|
if (filteredItems.length > 0) {
|
|
34
45
|
setActiveIndex(0);
|
|
35
46
|
}
|
|
36
47
|
}, [filteredItems.length]);
|
|
37
48
|
useEffect(() => {
|
|
38
|
-
if (filteredItems.length <
|
|
49
|
+
if (filteredItems.length < 2 || isFocusInside)
|
|
39
50
|
return undefined;
|
|
40
51
|
const interval = setInterval(() => {
|
|
41
52
|
setActiveIndex((prevIndex) => (prevIndex + 1) % filteredItems.length);
|
|
@@ -43,7 +54,7 @@ export const HeaderStripe = ({ duration = 8000, items, textColor, background, ba
|
|
|
43
54
|
return () => {
|
|
44
55
|
clearInterval(interval);
|
|
45
56
|
};
|
|
46
|
-
}, [duration, filteredItems.length]);
|
|
57
|
+
}, [duration, filteredItems.length, isFocusInside]);
|
|
47
58
|
const rootStyle = useMemo(() => {
|
|
48
59
|
const properties = {};
|
|
49
60
|
if (background) {
|
|
@@ -78,7 +89,7 @@ export const HeaderStripe = ({ duration = 8000, items, textColor, background, ba
|
|
|
78
89
|
}), style: rootStyle },
|
|
79
90
|
React.createElement(Grid, null,
|
|
80
91
|
React.createElement(Col, null,
|
|
81
|
-
React.createElement("div", { className: b('content', { 'with-close': Boolean(onClose) }), style: contentStyle },
|
|
92
|
+
React.createElement("div", { className: b('content', { 'with-close': Boolean(onClose) }), style: contentStyle, onFocus: handleFocus, onBlur: handleBlur },
|
|
82
93
|
filteredItems.map((item, index) => {
|
|
83
94
|
const isActive = index === activeIndex;
|
|
84
95
|
const isPrev = filteredItems.length > 1 &&
|
|
@@ -89,8 +100,8 @@ export const HeaderStripe = ({ duration = 8000, items, textColor, background, ba
|
|
|
89
100
|
return (React.createElement("div", { key: String(index), className: b('item', {
|
|
90
101
|
active: isActive,
|
|
91
102
|
prev: isPrev,
|
|
92
|
-
}) },
|
|
93
|
-
React.createElement("div", { className: b('item-content') }, renderItemContent(item))));
|
|
103
|
+
}), "aria-hidden": !isActive },
|
|
104
|
+
React.createElement("div", { className: b('item-content') }, renderItemContent(item, isActive))));
|
|
94
105
|
}),
|
|
95
106
|
canClose && (React.createElement("button", { "aria-label": i18n('close'), className: b('close'), onClick: handleClose },
|
|
96
107
|
React.createElement(Icon, { data: newDesign ? CloseIcon : Xmark, className: b('close-icon'), size: 16 }))))))));
|
|
@@ -5,9 +5,8 @@ import './GroupLinks.css';
|
|
|
5
5
|
const b = block('group-links');
|
|
6
6
|
const GroupLinks = ({ columnGroup: { title, items }, className }) => {
|
|
7
7
|
return (React.createElement("div", { className: b(null, className), key: title },
|
|
8
|
-
React.createElement("
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
React.createElement(EnrichedLink, Object.assign({ className: b('item') }, item))))))));
|
|
8
|
+
title && React.createElement("h5", { className: b('group-title') }, title),
|
|
9
|
+
React.createElement("ul", { className: b('group'), "aria-label": title }, items.map((item) => (React.createElement("li", { key: item.title, className: b('item-wrapper') },
|
|
10
|
+
React.createElement(EnrichedLink, Object.assign({ className: b('item') }, item))))))));
|
|
12
11
|
};
|
|
13
12
|
export default GroupLinks;
|
|
@@ -172,6 +172,11 @@ unpredictable css rules order in build */
|
|
|
172
172
|
border-color: rgba(5, 43, 66, 0.25);
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
+
.pc-addons-new-header__button:focus-visible {
|
|
176
|
+
outline: 2px solid var(--g-color-line-focus);
|
|
177
|
+
outline-offset: 2px;
|
|
178
|
+
}
|
|
179
|
+
|
|
175
180
|
@media (max-width: 1081px) {
|
|
176
181
|
.pc-addons-new-header__left {
|
|
177
182
|
margin-right: 0;
|
|
@@ -16,6 +16,7 @@ export const NewHeader = ({ data, setupRouteChangeHandler, renderSearch, classNa
|
|
|
16
16
|
const [isSearchMode, setIsSearchMode] = useState(false);
|
|
17
17
|
const [isMobileNavigationOpen, setIsMobileNavigationOpen] = useState(false);
|
|
18
18
|
const [pageHasScroll, setPageHasScroll] = useState(false);
|
|
19
|
+
const [activeNavigationId, setActiveNavigationId] = useState(null);
|
|
19
20
|
const showButtonsContainer = Boolean(buttons);
|
|
20
21
|
const toggleSearch = useCallback((isActive) => setIsSearchMode(isActive), []);
|
|
21
22
|
const toggleMobileNavigationPopup = useCallback((isOpened) => {
|
|
@@ -55,10 +56,10 @@ export const NewHeader = ({ data, setupRouteChangeHandler, renderSearch, classNa
|
|
|
55
56
|
React.createElement("div", { className: b('left') },
|
|
56
57
|
logo && React.createElement(NHLogo, { data: logo }),
|
|
57
58
|
left ? (React.createElement("div", { className: b('navigation') },
|
|
58
|
-
React.createElement(NHNavigation, { data: left, headerRef: headerRef }))) : null),
|
|
59
|
+
React.createElement(NHNavigation, { activeNavigationId: activeNavigationId, data: left, headerRef: headerRef, navigationId: "left", setActiveNavigationId: setActiveNavigationId }))) : null),
|
|
59
60
|
React.createElement("div", { className: b('right') },
|
|
60
61
|
right ? (React.createElement("div", { className: b('navigation') },
|
|
61
|
-
React.createElement(NHNavigation, { data: right, headerRef: headerRef }))) : null,
|
|
62
|
+
React.createElement(NHNavigation, { activeNavigationId: activeNavigationId, data: right, headerRef: headerRef, navigationId: "right", setActiveNavigationId: setActiveNavigationId }))) : null,
|
|
62
63
|
React.createElement("div", { className: b('wrap') },
|
|
63
64
|
renderSearch && (React.createElement("div", { className: b('icons-container') }, renderSearch({ onActiveToggle: toggleSearch }))),
|
|
64
65
|
React.createElement("div", { className: b('buttons') },
|
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
/* use this for style redefinitions to awoid problems with
|
|
2
2
|
unpredictable css rules order in build */
|
|
3
|
+
.pc-addons-nh-login-button__wrapper {
|
|
4
|
+
display: flex;
|
|
5
|
+
}
|
|
6
|
+
|
|
3
7
|
.pc-addons-nh-login-button {
|
|
8
|
+
display: inline-block;
|
|
9
|
+
margin: 0;
|
|
10
|
+
padding: 0;
|
|
11
|
+
font: inherit;
|
|
12
|
+
border: none;
|
|
13
|
+
outline: none;
|
|
14
|
+
color: inherit;
|
|
15
|
+
background: none;
|
|
16
|
+
cursor: pointer;
|
|
4
17
|
display: flex;
|
|
5
18
|
align-items: center;
|
|
6
19
|
height: 36px;
|
|
@@ -17,4 +30,9 @@ unpredictable css rules order in build */
|
|
|
17
30
|
|
|
18
31
|
.pc-addons-nh-login-button:hover {
|
|
19
32
|
background: var(--g-color-base-brand-hover);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.pc-addons-nh-login-button:focus-visible {
|
|
36
|
+
outline: 2px solid var(--g-color-line-focus);
|
|
37
|
+
outline-offset: 2px;
|
|
20
38
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useState } from 'react';
|
|
2
|
-
import { Icon } from '@gravity-ui/uikit';
|
|
2
|
+
import { Icon, useUniqId } from '@gravity-ui/uikit';
|
|
3
3
|
import { block } from '../../../../utils/cn';
|
|
4
4
|
import { SWITCH_MENU_TAB_TIMEOUT } from '../../constants';
|
|
5
5
|
import { ChevronDown } from '../ChevronDown';
|
|
@@ -12,19 +12,30 @@ export const NHLoginButton = ({ data, headerRef, setupRouteChangeHandler }) => {
|
|
|
12
12
|
const [isActive, setIsActive] = useState(false);
|
|
13
13
|
const [pretendentActiveTab, setPretendentAciveTab] = useState(false);
|
|
14
14
|
const [previouslyFocusedElement, setPreviouslyFocusedElement] = useState(null);
|
|
15
|
+
const popupId = useUniqId();
|
|
15
16
|
const handleActiveTab = useCallback((val) => {
|
|
16
17
|
setPreviouslyFocusedElement(document.activeElement);
|
|
17
18
|
setPretendentAciveTab(val);
|
|
18
19
|
}, []);
|
|
19
20
|
const onEscapeKeyDown = useCallback((event) => {
|
|
20
|
-
if (event.key === 'Escape') {
|
|
21
|
+
if (event.key === 'Escape' && isActive) {
|
|
21
22
|
setIsActive(false);
|
|
22
23
|
setPretendentAciveTab(false);
|
|
23
24
|
previouslyFocusedElement === null || previouslyFocusedElement === void 0 ? void 0 : previouslyFocusedElement.focus({ preventScroll: true });
|
|
24
25
|
}
|
|
25
|
-
}, [previouslyFocusedElement]);
|
|
26
|
+
}, [isActive, previouslyFocusedElement]);
|
|
26
27
|
const handleMouseEnter = useCallback(() => handleActiveTab(true), [handleActiveTab]);
|
|
27
28
|
const handleMouseLeave = useCallback(() => handleActiveTab(false), [handleActiveTab]);
|
|
29
|
+
const handleToggle = useCallback(() => {
|
|
30
|
+
const focusedElement = document.activeElement;
|
|
31
|
+
const nextIsActive = !isActive;
|
|
32
|
+
setPreviouslyFocusedElement(focusedElement);
|
|
33
|
+
setPretendentAciveTab(nextIsActive);
|
|
34
|
+
setIsActive(nextIsActive);
|
|
35
|
+
if (!nextIsActive) {
|
|
36
|
+
focusedElement === null || focusedElement === void 0 ? void 0 : focusedElement.focus({ preventScroll: true });
|
|
37
|
+
}
|
|
38
|
+
}, [isActive]);
|
|
28
39
|
useEffect(() => {
|
|
29
40
|
const timerId = setTimeout(() => {
|
|
30
41
|
setIsActive(pretendentActiveTab);
|
|
@@ -40,9 +51,10 @@ export const NHLoginButton = ({ data, headerRef, setupRouteChangeHandler }) => {
|
|
|
40
51
|
useEffect(() => setupRouteChangeHandler === null || setupRouteChangeHandler === void 0 ? void 0 : setupRouteChangeHandler(() => {
|
|
41
52
|
handleMouseLeave();
|
|
42
53
|
}), [handleMouseLeave, setupRouteChangeHandler]);
|
|
43
|
-
return (React.createElement("div", { className: b(), onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave },
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
54
|
+
return (React.createElement("div", { className: b('wrapper'), onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave },
|
|
55
|
+
React.createElement("button", { className: b(), type: "button", onClick: handleToggle, "aria-expanded": isActive, "aria-controls": popupId },
|
|
56
|
+
data.text,
|
|
57
|
+
React.createElement(Icon, { data: isActive ? ChevronUp : ChevronDown, size: 16 })),
|
|
58
|
+
isActive && (React.createElement(NHNavigationPopup, { headerRef: headerRef, id: popupId },
|
|
47
59
|
React.createElement(NHLoginPopup, Object.assign({}, data))))));
|
|
48
60
|
};
|
|
@@ -29,6 +29,11 @@ unpredictable css rules order in build */
|
|
|
29
29
|
display: none;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
.pc-addons-nh-mobile-navigation__icon:focus-visible {
|
|
33
|
+
outline: 2px solid var(--g-color-line-focus);
|
|
34
|
+
outline-offset: 2px;
|
|
35
|
+
}
|
|
36
|
+
|
|
32
37
|
.pc-addons-nh-mobile-navigation__header {
|
|
33
38
|
position: sticky;
|
|
34
39
|
top: 0;
|
|
@@ -48,6 +53,11 @@ unpredictable css rules order in build */
|
|
|
48
53
|
gap: 8px;
|
|
49
54
|
}
|
|
50
55
|
|
|
56
|
+
.pc-addons-nh-mobile-navigation__close-button:focus-visible {
|
|
57
|
+
outline: 2px solid var(--g-color-line-focus);
|
|
58
|
+
outline-offset: 2px;
|
|
59
|
+
}
|
|
60
|
+
|
|
51
61
|
.pc-addons-nh-mobile-navigation__search-container {
|
|
52
62
|
display: flex;
|
|
53
63
|
align-items: center;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Button as PCButton } from '@doyourjob/gravity-ui-page-constructor';
|
|
3
3
|
import { Bars, Xmark } from '@gravity-ui/icons';
|
|
4
|
-
import { Button, Icon } from '@gravity-ui/uikit';
|
|
4
|
+
import { Button, Icon, useUniqId } from '@gravity-ui/uikit';
|
|
5
5
|
import { block } from '../../../../utils/cn';
|
|
6
6
|
import { NHLogo } from '../NHLogo/NHLogo';
|
|
7
7
|
import { NHMobileNavigationItem } from '../NHMobileNavigationItem/NHMobileNavigationItem';
|
|
@@ -11,17 +11,22 @@ import './NHMobileNavigation.css';
|
|
|
11
11
|
const b = block('nh-mobile-navigation');
|
|
12
12
|
export const NHMobileNavigation = ({ isOpened, toogleOpen, isSearchOpen, data, onMenuScroll, }) => {
|
|
13
13
|
var _a, _b;
|
|
14
|
+
const popupId = useUniqId();
|
|
14
15
|
return (React.createElement("div", { className: b() },
|
|
15
|
-
React.createElement(Button, { view: "flat", size: "l", className: b('icon', { hidden: isSearchOpen }),
|
|
16
|
+
React.createElement(Button, { view: "flat", size: "l", className: b('icon', { hidden: isSearchOpen }), extraProps: {
|
|
17
|
+
'aria-label': isOpened ? 'Close navigation menu' : 'Open navigation menu',
|
|
18
|
+
'aria-expanded': isOpened,
|
|
19
|
+
'aria-controls': popupId,
|
|
20
|
+
}, onClick: (e) => {
|
|
16
21
|
e.stopPropagation();
|
|
17
22
|
toogleOpen(!isOpened);
|
|
18
23
|
} },
|
|
19
24
|
React.createElement(Icon, { data: isOpened ? Xmark : Bars, size: 24 })),
|
|
20
|
-
React.createElement(NHMobileNavigationPopup, { isOpened: isOpened, onClose: () => toogleOpen(false), onMenuScroll: onMenuScroll },
|
|
25
|
+
React.createElement(NHMobileNavigationPopup, { id: popupId, isOpened: isOpened, onClose: () => toogleOpen(false), onMenuScroll: onMenuScroll },
|
|
21
26
|
React.createElement("div", { className: b('header') },
|
|
22
27
|
(data === null || data === void 0 ? void 0 : data.logo) && React.createElement(NHLogo, { data: data.logo }),
|
|
23
28
|
React.createElement("div", { className: b('header-right') },
|
|
24
|
-
React.createElement(Button, { view: "flat", size: "l", className: b('close-button'), onClick: () => toogleOpen(false) },
|
|
29
|
+
React.createElement(Button, { view: "flat", size: "l", className: b('close-button'), extraProps: { 'aria-label': 'Close navigation menu' }, onClick: () => toogleOpen(false) },
|
|
25
30
|
React.createElement(Icon, { data: Xmark, size: 24 })))),
|
|
26
31
|
React.createElement("nav", { className: b('nav') },
|
|
27
32
|
React.createElement("ul", { className: b('list') }, (_a = data === null || data === void 0 ? void 0 : data.left) === null || _a === void 0 ? void 0 : _a.map((item, index) => (React.createElement("li", { className: b('item'), key: index },
|
package/build/esm/components/NewHeader/components/NHMobileNavigationItem/NHMobileNavigationItem.css
CHANGED
|
@@ -8,6 +8,11 @@ unpredictable css rules order in build */
|
|
|
8
8
|
align-items: center;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
.pc-addons-nh-mobile-navigation-item:focus-visible {
|
|
12
|
+
outline: 2px solid var(--g-color-line-focus);
|
|
13
|
+
outline-offset: 2px;
|
|
14
|
+
}
|
|
15
|
+
|
|
11
16
|
.pc-addons-nh-mobile-navigation-item_type_link {
|
|
12
17
|
color: inherit;
|
|
13
18
|
text-decoration: none;
|
package/build/esm/components/NewHeader/components/NHMobileNavigationItem/NHMobileNavigationItem.js
CHANGED
|
@@ -12,6 +12,7 @@ export const NHMobileNavigationItem = ({ item }) => {
|
|
|
12
12
|
}, [isOpened]);
|
|
13
13
|
const handleKeyDown = useCallback((e) => {
|
|
14
14
|
if (e.key === 'Enter' || e.key === ' ') {
|
|
15
|
+
e.preventDefault();
|
|
15
16
|
toggleOpen();
|
|
16
17
|
}
|
|
17
18
|
}, [toggleOpen]);
|
|
@@ -20,7 +21,7 @@ export const NHMobileNavigationItem = ({ item }) => {
|
|
|
20
21
|
return (React.createElement("a", Object.assign({ href: item.data.url, className: b({ type: 'link' }) }, getLinkProps(item.data.url || '', undefined, item.data.target)), item.title));
|
|
21
22
|
}
|
|
22
23
|
return (React.createElement(Fragment, null,
|
|
23
|
-
React.createElement("div", { className: b(), onClick: toggleOpen, role: "button", tabIndex: 0, onKeyDown: handleKeyDown },
|
|
24
|
+
React.createElement("div", { className: b(), onClick: toggleOpen, role: "button", tabIndex: 0, "aria-expanded": isOpened, onKeyDown: handleKeyDown },
|
|
24
25
|
React.createElement("div", { className: b('text') }, item.title),
|
|
25
26
|
React.createElement("div", { className: b('arrow') },
|
|
26
27
|
React.createElement(ToggleArrow, { size: 12, type: "vertical", open: isOpened, iconType: "navigation" }))),
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import './NHMobileNavigationPopup.css';
|
|
3
3
|
interface MobileNavigationPopupProps {
|
|
4
|
+
id?: string;
|
|
4
5
|
isOpened: boolean;
|
|
5
6
|
onClose: () => void;
|
|
6
7
|
children: React.ReactNode;
|
|
7
8
|
onMenuScroll: (scrollTop: number) => void;
|
|
8
9
|
}
|
|
9
|
-
export declare const NHMobileNavigationPopup: ({ isOpened, onClose, children, onMenuScroll, }: MobileNavigationPopupProps) => React.ReactPortal | null;
|
|
10
|
+
export declare const NHMobileNavigationPopup: ({ id, isOpened, onClose, children, onMenuScroll, }: MobileNavigationPopupProps) => React.ReactPortal | null;
|
|
10
11
|
export {};
|
package/build/esm/components/NewHeader/components/NHMobileNavigationPopup/NHMobileNavigationPopup.js
CHANGED
|
@@ -7,7 +7,7 @@ import { block } from '../../../../utils/cn';
|
|
|
7
7
|
import './NHMobileNavigationPopup.css';
|
|
8
8
|
const b = block('nh-mobile-navigation-popup');
|
|
9
9
|
const TRANSITION_TIME = 400;
|
|
10
|
-
export const NHMobileNavigationPopup = ({ isOpened, onClose, children, onMenuScroll, }) => {
|
|
10
|
+
export const NHMobileNavigationPopup = ({ id, isOpened, onClose, children, onMenuScroll, }) => {
|
|
11
11
|
const [body, setBody] = useState();
|
|
12
12
|
const ref = useRef(null);
|
|
13
13
|
const handleScroll = useCallback(() => {
|
|
@@ -35,5 +35,5 @@ export const NHMobileNavigationPopup = ({ isOpened, onClose, children, onMenuScr
|
|
|
35
35
|
}
|
|
36
36
|
return ReactDOM.createPortal(React.createElement(CSSTransition, { in: isOpened, classNames: b('transition'), unmountOnExit: true, timeout: TRANSITION_TIME },
|
|
37
37
|
React.createElement(OutsideClick, { className: b(), onOutsideClick: onClose },
|
|
38
|
-
React.createElement("div", { ref: ref, className: b('container') }, children))), body);
|
|
38
|
+
React.createElement("div", { ref: ref, className: b('container'), id: id }, children))), body);
|
|
39
39
|
};
|
|
@@ -3,9 +3,12 @@ import React from 'react';
|
|
|
3
3
|
import { NHNavigationItemData, SetupRouteChangeHandler } from '../../models';
|
|
4
4
|
import './NHNavigation.css';
|
|
5
5
|
interface NavigationProps {
|
|
6
|
+
activeNavigationId: string | null;
|
|
6
7
|
data: NHNavigationItemData[];
|
|
7
8
|
headerRef?: RefObject<HTMLDivElement>;
|
|
9
|
+
navigationId: string;
|
|
8
10
|
setupRouteChangeHandler?: SetupRouteChangeHandler;
|
|
11
|
+
setActiveNavigationId: (navigationId: string | null) => void;
|
|
9
12
|
}
|
|
10
|
-
export declare const NHNavigation: ({ data, headerRef, setupRouteChangeHandler }: NavigationProps) => React.JSX.Element;
|
|
13
|
+
export declare const NHNavigation: ({ activeNavigationId, data, headerRef, navigationId, setupRouteChangeHandler, setActiveNavigationId, }: NavigationProps) => React.JSX.Element;
|
|
11
14
|
export {};
|
|
@@ -5,6 +5,7 @@ import { NHNavigationItemType } from '../../models';
|
|
|
5
5
|
import { NHDefaultPopup } from '../NHDefaultPopup/NHDefaultPopup';
|
|
6
6
|
import { NHNavigationItem } from '../NHNavigationItem/NHNavigationItem';
|
|
7
7
|
import { NHNavigationPopup } from '../NHNavigationPopup/NHNavigationPopup';
|
|
8
|
+
import { focusFromKeyboard, getFocusableElements } from '../NHNavigationPopup/keyboardNavigation';
|
|
8
9
|
import './NHNavigation.css';
|
|
9
10
|
const b = block('nh-navigation');
|
|
10
11
|
const tooltipPrefixId = 'navigation-item-key';
|
|
@@ -16,36 +17,98 @@ const getPopupContent = (sectionData) => {
|
|
|
16
17
|
return null;
|
|
17
18
|
}
|
|
18
19
|
};
|
|
19
|
-
export const NHNavigation = ({ data, headerRef, setupRouteChangeHandler }) => {
|
|
20
|
+
export const NHNavigation = ({ activeNavigationId, data, headerRef, navigationId, setupRouteChangeHandler, setActiveNavigationId, }) => {
|
|
20
21
|
const [activeTab, setActiveTab] = useState(NO_MENU_TAB_SELECTED);
|
|
21
22
|
const [pretendentActiveTab, setPretendentAciveTab] = useState(NO_MENU_TAB_SELECTED);
|
|
22
23
|
const [previouslyFocusedElement, setPreviouslyFocusedElement] = useState(null);
|
|
24
|
+
const [popupTabToFocus, setPopupTabToFocus] = useState(null);
|
|
25
|
+
const setNavigationTab = useCallback((currentIndex) => {
|
|
26
|
+
setPretendentAciveTab(currentIndex);
|
|
27
|
+
setActiveTab(currentIndex);
|
|
28
|
+
setPopupTabToFocus(null);
|
|
29
|
+
setActiveNavigationId(currentIndex === NO_MENU_TAB_SELECTED ? null : navigationId);
|
|
30
|
+
}, [navigationId, setActiveNavigationId]);
|
|
23
31
|
const handleActiveTab = useCallback((currentIndex) => {
|
|
24
32
|
setPreviouslyFocusedElement(document.activeElement);
|
|
25
33
|
setPretendentAciveTab(currentIndex);
|
|
26
34
|
}, []);
|
|
35
|
+
const handleToggleTab = useCallback((currentIndex) => {
|
|
36
|
+
const focusedElement = document.activeElement;
|
|
37
|
+
const nextActiveTab = activeTab === currentIndex ? NO_MENU_TAB_SELECTED : currentIndex;
|
|
38
|
+
setPreviouslyFocusedElement(focusedElement);
|
|
39
|
+
setNavigationTab(nextActiveTab);
|
|
40
|
+
if (nextActiveTab === NO_MENU_TAB_SELECTED) {
|
|
41
|
+
focusedElement === null || focusedElement === void 0 ? void 0 : focusedElement.focus({ preventScroll: true });
|
|
42
|
+
}
|
|
43
|
+
}, [activeTab, setNavigationTab]);
|
|
44
|
+
const handleFocusTabPopup = useCallback((currentIndex) => {
|
|
45
|
+
setPreviouslyFocusedElement(document.activeElement);
|
|
46
|
+
setPretendentAciveTab(currentIndex);
|
|
47
|
+
setActiveTab(currentIndex);
|
|
48
|
+
setPopupTabToFocus(currentIndex);
|
|
49
|
+
setActiveNavigationId(navigationId);
|
|
50
|
+
}, [navigationId, setActiveNavigationId]);
|
|
51
|
+
const handleFocusTab = useCallback((currentIndex) => {
|
|
52
|
+
if (activeNavigationId === null) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
setPreviouslyFocusedElement(document.activeElement);
|
|
56
|
+
setNavigationTab(currentIndex);
|
|
57
|
+
}, [activeNavigationId, setNavigationTab]);
|
|
58
|
+
const handleCloseTab = useCallback(() => {
|
|
59
|
+
setNavigationTab(NO_MENU_TAB_SELECTED);
|
|
60
|
+
previouslyFocusedElement === null || previouslyFocusedElement === void 0 ? void 0 : previouslyFocusedElement.focus({ preventScroll: true });
|
|
61
|
+
}, [previouslyFocusedElement, setNavigationTab]);
|
|
62
|
+
const handleBlur = useCallback((event) => {
|
|
63
|
+
if (activeTab === NO_MENU_TAB_SELECTED) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const nextFocusedElement = event.relatedTarget;
|
|
67
|
+
const popup = document.getElementById(`${tooltipPrefixId}-${activeTab}`);
|
|
68
|
+
if (nextFocusedElement &&
|
|
69
|
+
(event.currentTarget.contains(nextFocusedElement) ||
|
|
70
|
+
(popup === null || popup === void 0 ? void 0 : popup.contains(nextFocusedElement)))) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
setNavigationTab(NO_MENU_TAB_SELECTED);
|
|
74
|
+
}, [activeTab, setNavigationTab]);
|
|
27
75
|
const onEscapeKeyDown = useCallback((event) => {
|
|
28
|
-
if (event.key === 'Escape') {
|
|
29
|
-
|
|
30
|
-
setPretendentAciveTab(NO_MENU_TAB_SELECTED);
|
|
31
|
-
previouslyFocusedElement === null || previouslyFocusedElement === void 0 ? void 0 : previouslyFocusedElement.focus({ preventScroll: true });
|
|
76
|
+
if (event.key === 'Escape' && activeTab !== NO_MENU_TAB_SELECTED) {
|
|
77
|
+
handleCloseTab();
|
|
32
78
|
}
|
|
33
|
-
}, [
|
|
79
|
+
}, [activeTab, handleCloseTab]);
|
|
34
80
|
useEffect(() => setupRouteChangeHandler === null || setupRouteChangeHandler === void 0 ? void 0 : setupRouteChangeHandler(() => {
|
|
35
81
|
handleActiveTab(NO_MENU_TAB_SELECTED);
|
|
36
82
|
}), [setupRouteChangeHandler, handleActiveTab]);
|
|
37
83
|
useEffect(() => {
|
|
38
84
|
const timerId = setTimeout(() => {
|
|
39
85
|
setActiveTab(pretendentActiveTab);
|
|
86
|
+
setActiveNavigationId(pretendentActiveTab === NO_MENU_TAB_SELECTED ? null : navigationId);
|
|
40
87
|
}, SWITCH_MENU_TAB_TIMEOUT);
|
|
41
88
|
return () => clearTimeout(timerId);
|
|
42
|
-
}, [activeTab, pretendentActiveTab]);
|
|
89
|
+
}, [activeTab, navigationId, pretendentActiveTab, setActiveNavigationId]);
|
|
90
|
+
useEffect(() => {
|
|
91
|
+
if (activeNavigationId !== navigationId && activeTab !== NO_MENU_TAB_SELECTED) {
|
|
92
|
+
setActiveTab(NO_MENU_TAB_SELECTED);
|
|
93
|
+
setPretendentAciveTab(NO_MENU_TAB_SELECTED);
|
|
94
|
+
setPopupTabToFocus(null);
|
|
95
|
+
}
|
|
96
|
+
}, [activeNavigationId, activeTab, navigationId]);
|
|
97
|
+
useEffect(() => {
|
|
98
|
+
if (popupTabToFocus === null || activeTab !== popupTabToFocus) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const popup = document.getElementById(`${tooltipPrefixId}-${popupTabToFocus}`);
|
|
102
|
+
const [firstFocusableElement] = getFocusableElements(popup);
|
|
103
|
+
focusFromKeyboard(firstFocusableElement, popup);
|
|
104
|
+
setPopupTabToFocus(null);
|
|
105
|
+
}, [activeTab, popupTabToFocus]);
|
|
43
106
|
useEffect(() => {
|
|
44
107
|
document.addEventListener('keydown', onEscapeKeyDown);
|
|
45
108
|
return () => {
|
|
46
109
|
document.removeEventListener('keydown', onEscapeKeyDown);
|
|
47
110
|
};
|
|
48
111
|
}, [onEscapeKeyDown]);
|
|
49
|
-
return (React.createElement("nav",
|
|
50
|
-
React.createElement("ul", { className: b() }, data.map((item, i) => (React.createElement(NHNavigationItem, { key: i, item: item, handleActiveTab: handleActiveTab, index: i, isActive: activeTab === i, tooltipId: `${tooltipPrefixId}-${i}` }, activeTab === i && item.type !== NHNavigationItemType.Link && (React.createElement(NHNavigationPopup, { headerRef: headerRef, id: `${tooltipPrefixId}-${i}` }, getPopupContent(item)))))))));
|
|
112
|
+
return (React.createElement("nav", { onBlur: handleBlur },
|
|
113
|
+
React.createElement("ul", { className: b() }, data.map((item, i) => (React.createElement(NHNavigationItem, { key: i, item: item, handleActiveTab: handleActiveTab, handleFocusTabPopup: handleFocusTabPopup, handleFocusTab: handleFocusTab, handleToggleTab: handleToggleTab, index: i, isActive: activeTab === i, tooltipId: `${tooltipPrefixId}-${i}` }, activeTab === i && item.type !== NHNavigationItemType.Link && (React.createElement(NHNavigationPopup, { headerRef: headerRef, id: `${tooltipPrefixId}-${i}` }, getPopupContent(item)))))))));
|
|
51
114
|
};
|
|
@@ -55,6 +55,11 @@ unpredictable css rules order in build */
|
|
|
55
55
|
cursor: default;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
.pc-addons-nh-navigation-item__text:focus-visible {
|
|
59
|
+
outline: 2px solid var(--g-color-line-focus);
|
|
60
|
+
outline-offset: 2px;
|
|
61
|
+
}
|
|
62
|
+
|
|
58
63
|
.pc-addons-nh-navigation-item:first-child .pc-addons-nh-navigation-item__text {
|
|
59
64
|
margin-left: 0;
|
|
60
65
|
}
|