@royaloperahouse/harmonic 0.6.1 → 0.6.2

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.
@@ -1,4 +1,4 @@
1
- import { FunctionComponent } from 'react';
1
+ import React from 'react';
2
2
  import { IControlledDropdownProps } from '../../../types/types';
3
- declare const ControlledDropdown: FunctionComponent<IControlledDropdownProps>;
3
+ declare const ControlledDropdown: React.ForwardRefExoticComponent<IControlledDropdownProps & React.RefAttributes<HTMLDivElement>>;
4
4
  export default ControlledDropdown;
@@ -1,7 +1,7 @@
1
1
  import { IControlledDropdownHeaderProps } from '../../../types/types';
2
2
  export declare const ControlledDropdownWrapper: import("styled-components").StyledComponent<"div", any, {}, never>;
3
- export declare const ControlledDropdownHeaderContainer: import("styled-components").StyledComponent<"span", any, IControlledDropdownHeaderProps, never>;
4
- export declare const ControlledDropdownHeaderContainerLink: import("styled-components").StyledComponent<"span", any, IControlledDropdownHeaderProps & {
3
+ export declare const ControlledDropdownHeaderContainer: import("styled-components").StyledComponent<"button", any, IControlledDropdownHeaderProps, never>;
4
+ export declare const ControlledDropdownHeaderContainerLink: import("styled-components").StyledComponent<"button", any, IControlledDropdownHeaderProps & {
5
5
  as: string;
6
6
  }, "as">;
7
7
  export declare const IconWrapper: import("styled-components").StyledComponent<"span", any, {}, never>;
@@ -1,4 +1,4 @@
1
1
  import React from 'react';
2
2
  import { ISearchProps } from '../../../types/navigation';
3
- declare const Search: ({ selected, onClick, className }: ISearchProps) => React.JSX.Element;
3
+ declare const Search: React.ForwardRefExoticComponent<Pick<ISearchProps, "selected" | "onClick" | "className"> & React.RefAttributes<HTMLButtonElement>>;
4
4
  export default Search;
@@ -1,3 +1,3 @@
1
1
  import { ISearchProps } from '../../../types/navigation';
2
- export declare const SearchContainer: import("styled-components").StyledComponent<"div", any, ISearchProps, never>;
2
+ export declare const SearchContainer: import("styled-components").StyledComponent<"button", any, ISearchProps, never>;
3
3
  export declare const SvgContainer: import("styled-components").StyledComponent<"div", any, {}, never>;
@@ -1,4 +1,4 @@
1
1
  import React from 'react';
2
2
  import { INavTopProps } from '../../../types/navigation';
3
- declare const NavTop: ({ accountText, accountLink, accountIcon, accountOptions, onLink, basketText, basketExpiryUnixTimestamp, basketLink, basketNumItems, basketNumVirtualItems, onClickSearch, isShowSearch, className, }: INavTopProps) => React.JSX.Element;
3
+ declare const NavTop: ({ accountText, accountLink, accountIcon, accountOptions, onLink, basketText, basketExpiryUnixTimestamp, basketLink, basketNumItems, basketNumVirtualItems, onClickSearch, isShowSearch, className, searchButtonRef, }: INavTopProps) => React.JSX.Element;
4
4
  export default NavTop;
@@ -1,4 +1,4 @@
1
1
  import React from 'react';
2
2
  import { ISearchBarProps } from '../../../types/navigation';
3
- declare const SearchBar: ({ onClick, onClose, className }: ISearchBarProps) => React.JSX.Element;
3
+ declare const SearchBar: ({ onClick, onClose, className, inputRef }: ISearchBarProps) => React.JSX.Element;
4
4
  export default SearchBar;
@@ -1,6 +1,6 @@
1
1
  export declare const SearchBarContainer: import("styled-components").StyledComponent<"div", any, {}, never>;
2
2
  export declare const SvgContainerSearch: import("styled-components").StyledComponent<"div", any, {}, never>;
3
- export declare const SvgContainerClose: import("styled-components").StyledComponent<"div", any, {}, never>;
3
+ export declare const SvgContainerClose: import("styled-components").StyledComponent<"button", any, {}, never>;
4
4
  export declare const SearchUnavailableContainer: import("styled-components").StyledComponent<"div", any, {}, never>;
5
5
  export declare const InputContainer: import("styled-components").StyledComponent<"div", any, {}, never>;
6
6
  export declare const TextLinkWrapper: import("styled-components").StyledComponent<import("react").FunctionComponent<import("../../../types/types").ITextLinkProps>, any, {}, never>;
@@ -374,7 +374,7 @@ var HarmonicHeader = function HarmonicHeader(_ref2) {
374
374
  size = _ref2.size,
375
375
  em = _ref2.em,
376
376
  _ref2$color = _ref2.color,
377
- color = _ref2$color === void 0 ? 'primary' : _ref2$color,
377
+ color = _ref2$color === void 0 ? 'inherit' : _ref2$color,
378
378
  serif = _ref2.serif,
379
379
  Tag = _ref2.hierarchy,
380
380
  className = _ref2.className;
@@ -394,7 +394,7 @@ var HarmonicSubtitle = function HarmonicSubtitle(_ref3) {
394
394
  var children = _ref3.children,
395
395
  size = _ref3.size,
396
396
  _ref3$color = _ref3.color,
397
- color = _ref3$color === void 0 ? 'primary' : _ref3$color,
397
+ color = _ref3$color === void 0 ? 'inherit' : _ref3$color,
398
398
  className = _ref3.className;
399
399
  var classNames = createClassNames('subtitle', {
400
400
  size: size,
@@ -411,7 +411,7 @@ var BodyCopyHarmonic = function BodyCopyHarmonic(_ref4) {
411
411
  _ref4$size = _ref4.size,
412
412
  size = _ref4$size === void 0 ? 'medium' : _ref4$size,
413
413
  _ref4$color = _ref4.color,
414
- color = _ref4$color === void 0 ? 'primary' : _ref4$color,
414
+ color = _ref4$color === void 0 ? 'inherit' : _ref4$color,
415
415
  className = _ref4.className,
416
416
  props = _objectWithoutPropertiesLoose(_ref4, _excluded);
417
417
  var classNames = createClassNames('bodycopy', {
@@ -428,7 +428,7 @@ var HarmonicOverline = function HarmonicOverline(_ref5) {
428
428
  var children = _ref5.children,
429
429
  size = _ref5.size,
430
430
  _ref5$color = _ref5.color,
431
- color = _ref5$color === void 0 ? 'primary' : _ref5$color,
431
+ color = _ref5$color === void 0 ? 'inherit' : _ref5$color,
432
432
  className = _ref5.className,
433
433
  props = _objectWithoutPropertiesLoose(_ref5, _excluded2);
434
434
  var classNames = createClassNames('overline', {
@@ -444,7 +444,7 @@ var HarmonicOverline = function HarmonicOverline(_ref5) {
444
444
  var ButtonText = function ButtonText(_ref6) {
445
445
  var children = _ref6.children,
446
446
  _ref6$color = _ref6.color,
447
- color = _ref6$color === void 0 ? 'primary' : _ref6$color,
447
+ color = _ref6$color === void 0 ? 'inherit' : _ref6$color,
448
448
  className = _ref6.className;
449
449
  var classNames = createClassNames('buttontext', {
450
450
  color: color,
@@ -457,7 +457,7 @@ var ButtonText = function ButtonText(_ref6) {
457
457
  var Caption = function Caption(_ref7) {
458
458
  var children = _ref7.children,
459
459
  _ref7$color = _ref7.color,
460
- color = _ref7$color === void 0 ? 'primary' : _ref7$color,
460
+ color = _ref7$color === void 0 ? 'inherit' : _ref7$color,
461
461
  className = _ref7.className;
462
462
  var classNames = createClassNames('captiontext', {
463
463
  color: color,
@@ -470,7 +470,7 @@ var Caption = function Caption(_ref7) {
470
470
  var NavigationText = function NavigationText(_ref8) {
471
471
  var children = _ref8.children,
472
472
  _ref8$color = _ref8.color,
473
- color = _ref8$color === void 0 ? 'primary' : _ref8$color,
473
+ color = _ref8$color === void 0 ? 'inherit' : _ref8$color,
474
474
  className = _ref8.className;
475
475
  var classNames = createClassNames('navigationtext', {
476
476
  color: color,
@@ -2939,7 +2939,7 @@ var OptionsContainer = /*#__PURE__*/styled__default.div(_templateObject3 || (_te
2939
2939
 
2940
2940
  var _templateObject$7, _templateObject2$5, _templateObject3$1, _templateObject4;
2941
2941
  var ControlledDropdownWrapper = /*#__PURE__*/styled__default.div(_templateObject$7 || (_templateObject$7 = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n position: relative;\n width: fit-content;\n"])));
2942
- var ControlledDropdownHeaderContainer = /*#__PURE__*/styled__default.span(_templateObject2$5 || (_templateObject2$5 = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n display: flex;\n gap: 6px;\n border-bottom: 1px solid transparent;\n height: 24px;\n line-height: 24px;\n font-size: var(--harmonic-font-size-navigation);\n font-family: var(--font-family-sans);\n font-weight: var(--font-weight-navigation);\n letter-spacing: var(--harmonic-letter-spacing-navigation);\n color: var(--color-primary-black);\n text-decoration: none;\n cursor: pointer;\n width: max-content;\n\n ", "\n"])), function (_ref) {
2942
+ var ControlledDropdownHeaderContainer = /*#__PURE__*/styled__default.button(_templateObject2$5 || (_templateObject2$5 = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n all: unset;\n display: flex;\n gap: 6px;\n border-bottom: 1px solid transparent;\n height: 24px;\n line-height: 24px;\n font-size: var(--harmonic-font-size-navigation);\n font-family: var(--font-family-sans);\n font-weight: var(--font-weight-navigation);\n letter-spacing: var(--harmonic-letter-spacing-navigation);\n color: var(--color-primary-black);\n text-decoration: none;\n cursor: pointer;\n width: max-content;\n\n &:focus {\n outline: 2px solid var(--color-primary-black);\n outline-offset: 2px;\n }\n\n ", "\n"])), function (_ref) {
2943
2943
  var active = _ref.active;
2944
2944
  if (active) {
2945
2945
  return "\n & {\n color: var(--color-primary-red);\n }\n && svg path {\n fill: var(--color-primary-red);\n } \n ";
@@ -2947,12 +2947,12 @@ var ControlledDropdownHeaderContainer = /*#__PURE__*/styled__default.span(_templ
2947
2947
  return '';
2948
2948
  });
2949
2949
  var ControlledDropdownHeaderContainerLink = /*#__PURE__*/styled__default(ControlledDropdownHeaderContainer).attrs({
2950
- as: 'a'
2950
+ as: 'button'
2951
2951
  })(_templateObject3$1 || (_templateObject3$1 = /*#__PURE__*/_taggedTemplateLiteralLoose([""])));
2952
2952
  var IconWrapper = /*#__PURE__*/styled__default.span(_templateObject4 || (_templateObject4 = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n width: 24px;\n height: 24px;\n\n span > svg path {\n fill: var(--color-primary-black);\n }\n"])));
2953
2953
 
2954
2954
  /* eslint-disable no-useless-return */
2955
- var ControlledDropdown = function ControlledDropdown(_ref) {
2955
+ var ControlledDropdown = /*#__PURE__*/React__default.forwardRef(function (_ref, ref) {
2956
2956
  var text = _ref.text,
2957
2957
  options = _ref.options,
2958
2958
  active = _ref.active,
@@ -2960,32 +2960,22 @@ var ControlledDropdown = function ControlledDropdown(_ref) {
2960
2960
  onOptionClick = _ref.onOptionClick,
2961
2961
  _onMouseEnter = _ref.onMouseEnter,
2962
2962
  _onMouseLeave = _ref.onMouseLeave,
2963
+ _onFocusLeave = _ref.onFocusLeave,
2963
2964
  onReset = _ref.onReset,
2964
2965
  _onFocus = _ref.onFocus,
2965
2966
  _onBlur = _ref.onBlur,
2966
2967
  className = _ref.className;
2967
- var ref = React.useRef();
2968
- var resetHandler = React.useCallback(function () {
2968
+ ControlledDropdown.displayName = 'ControlledDropdown';
2969
+ var internalRef = React.useRef(null);
2970
+ React.useImperativeHandle(ref, function () {
2971
+ return internalRef.current;
2972
+ });
2973
+ var resetHandler = function resetHandler() {
2969
2974
  return onReset == null ? void 0 : onReset();
2970
- }, []);
2971
- React.useEffect(function () {
2972
- if (window.innerWidth > breakpoints.sm) {
2973
- var mouseClickHandler = function mouseClickHandler(e) {
2974
- var _ref$current;
2975
- if (ref != null && (_ref$current = ref.current) != null && _ref$current.contains(e.target)) {
2976
- return;
2977
- } else if (active) {
2978
- resetHandler();
2979
- }
2980
- };
2981
- document.addEventListener('click', mouseClickHandler);
2982
- return function () {
2983
- document.removeEventListener('click', mouseClickHandler);
2984
- };
2985
- }
2986
- // eslint-disable-next-line consistent-return
2987
- return;
2988
- }, [ref, resetHandler, active]);
2975
+ };
2976
+ var isDropdown = React.useMemo(function () {
2977
+ return !!(options != null && options.length);
2978
+ }, [options]);
2989
2979
  var handleOptionKeyDown = function handleOptionKeyDown(e, link) {
2990
2980
  if (e.key === 'Enter') {
2991
2981
  onOptionClick == null || onOptionClick(link);
@@ -3005,13 +2995,15 @@ var ControlledDropdown = function ControlledDropdown(_ref) {
3005
2995
  _onBlur == null || _onBlur();
3006
2996
  }
3007
2997
  };
3008
- var isDropdown = !!(options != null && options.length);
3009
2998
  var wrapperEvents = {
3010
2999
  onMouseEnter: function onMouseEnter() {
3011
3000
  return _onMouseEnter == null ? void 0 : _onMouseEnter();
3012
3001
  },
3013
3002
  onMouseLeave: function onMouseLeave() {
3014
3003
  return _onMouseLeave == null ? void 0 : _onMouseLeave();
3004
+ },
3005
+ onFocusLeave: function onFocusLeave() {
3006
+ return _onFocusLeave == null ? void 0 : _onFocusLeave();
3015
3007
  }
3016
3008
  };
3017
3009
  var headerEvents = {
@@ -3027,21 +3019,51 @@ var ControlledDropdown = function ControlledDropdown(_ref) {
3027
3019
  },
3028
3020
  onKeyDown: handleHeaderKeyDown
3029
3021
  };
3022
+ React.useEffect(function () {
3023
+ var mouseEvent = function mouseEvent(e) {
3024
+ var _internalRef$current;
3025
+ if (internalRef != null && (_internalRef$current = internalRef.current) != null && _internalRef$current.contains(e.target)) return;
3026
+ if (active) resetHandler();
3027
+ };
3028
+ if (window.innerWidth > breakpoints.sm) {
3029
+ document.addEventListener('click', mouseEvent);
3030
+ }
3031
+ return function () {
3032
+ document.removeEventListener('click', mouseEvent);
3033
+ };
3034
+ }, [resetHandler, active]);
3035
+ React.useEffect(function () {
3036
+ var handleFocusOut = function handleFocusOut(e) {
3037
+ if (internalRef.current && !internalRef.current.contains(e.relatedTarget)) {
3038
+ _onFocusLeave == null || _onFocusLeave();
3039
+ }
3040
+ };
3041
+ var node = internalRef.current;
3042
+ if (node) node.addEventListener('focusout', handleFocusOut);
3043
+ return function () {
3044
+ return node == null ? void 0 : node.removeEventListener('focusout', handleFocusOut);
3045
+ };
3046
+ }, [_onFocusLeave]);
3030
3047
  return /*#__PURE__*/React__default.createElement(ControlledDropdownWrapper, Object.assign({
3031
- ref: ref
3048
+ ref: internalRef
3032
3049
  }, wrapperEvents, {
3033
3050
  className: className
3034
3051
  }), isDropdown ? (/*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement(ControlledDropdownHeaderContainer, Object.assign({
3035
3052
  active: active
3036
3053
  }, headerEvents, {
3037
- tabIndex: 0,
3038
- "data-testid": "span-container"
3054
+ "data-testid": "span-container",
3055
+ role: "menuitem",
3056
+ "aria-controls": "dropdown-menu",
3057
+ "aria-haspopup": "menu",
3058
+ "aria-expanded": active
3039
3059
  }), text, /*#__PURE__*/React__default.createElement(IconWrapper, {
3040
3060
  "data-testid": "dropdown-icon"
3041
3061
  }, /*#__PURE__*/React__default.createElement(Icon, {
3042
3062
  iconName: "DropdownArrow"
3043
3063
  }))), active && options ? (/*#__PURE__*/React__default.createElement(OptionsContainer, {
3044
- withOptionsInMobile: true
3064
+ withOptionsInMobile: true,
3065
+ role: "menu",
3066
+ id: "dropdown-menu"
3045
3067
  }, options.map(function (optionItem, index) {
3046
3068
  return /*#__PURE__*/React__default.createElement(OptionItem, {
3047
3069
  key: "key-" + index + "-" + optionItem.option,
@@ -3055,15 +3077,18 @@ var ControlledDropdown = function ControlledDropdown(_ref) {
3055
3077
  onBlur: function onBlur() {
3056
3078
  return handleOptionBlur(index);
3057
3079
  },
3058
- href: optionItem.optionLink
3080
+ href: optionItem.optionLink,
3081
+ role: "menuitem"
3059
3082
  }, optionItem.option);
3060
3083
  }))) : null)) : (/*#__PURE__*/React__default.createElement(ControlledDropdownHeaderContainerLink, Object.assign({
3061
3084
  active: active
3062
3085
  }, headerEvents, {
3063
3086
  "data-testid": "link-container",
3087
+ "aria-label": text,
3088
+ role: "menuitem",
3064
3089
  tabIndex: 0
3065
3090
  }), text)));
3066
- };
3091
+ });
3067
3092
 
3068
3093
  var _templateObject$8;
3069
3094
  var Grid = /*#__PURE__*/styled__default.div(_templateObject$8 || (_templateObject$8 = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n display: grid;\n grid-template-columns: var(--grid-template-columns);\n grid-template-rows: max-content;\n gap: var(--grid-column-gap);\n margin: 0;\n"])));
@@ -5286,7 +5311,7 @@ var Basket$1 = function Basket(_ref) {
5286
5311
  };
5287
5312
 
5288
5313
  var _templateObject$A, _templateObject2$q;
5289
- var SearchContainer = /*#__PURE__*/styled__default.div(_templateObject$A || (_templateObject$A = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n display: inline-flex;\n flex-direction: row;\n justify-content: flex-start;\n align-items: center;\n cursor: pointer;\n border-bottom: 1px solid transparent;\n padding-top: 3px;\n padding-bottom: 3px;\n\n svg path {\n fill: var(--color-primary-black);\n }\n\n ", "\n\n :hover {\n border-bottom: 1px solid var(--color-primary-red);\n && svg path {\n fill: var(--color-primary-red);\n }\n }\n"])), function (_ref) {
5314
+ var SearchContainer = /*#__PURE__*/styled__default.button(_templateObject$A || (_templateObject$A = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n all: unset;\n display: inline-flex;\n flex-direction: row;\n justify-content: flex-start;\n align-items: center;\n cursor: pointer;\n border-bottom: 1px solid transparent;\n padding-top: 3px;\n padding-bottom: 3px;\n\n svg path {\n fill: var(--color-primary-black);\n }\n\n ", "\n\n :hover {\n border-bottom: 1px solid var(--color-primary-red);\n && svg path {\n fill: var(--color-primary-red);\n }\n }\n\n &:focus {\n outline: 2px solid var(--color-primary-black);\n outline-offset: 2px;\n }\n"])), function (_ref) {
5290
5315
  var selected = _ref.selected;
5291
5316
  if (selected) {
5292
5317
  return "\n border-bottom: 1px solid var(--color-primary-red);\n && svg path {\n fill: var(--color-primary-red);\n }\n ";
@@ -5295,31 +5320,26 @@ var SearchContainer = /*#__PURE__*/styled__default.div(_templateObject$A || (_te
5295
5320
  });
5296
5321
  var SvgContainer$1 = /*#__PURE__*/styled__default.div(_templateObject2$q || (_templateObject2$q = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n svg {\n width: var(--navigation-large-gap);\n height: var(--navigation-large-gap);\n }\n"])));
5297
5322
 
5298
- var Search$1 = function Search(_ref) {
5323
+ var Search$1 = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
5299
5324
  var _ref$selected = _ref.selected,
5300
5325
  selected = _ref$selected === void 0 ? false : _ref$selected,
5301
5326
  onClick = _ref.onClick,
5302
5327
  className = _ref.className;
5303
- var onKeyDownHandler = function onKeyDownHandler(e) {
5304
- if (e.key === 'Enter') {
5305
- onClick == null || onClick();
5306
- }
5307
- };
5328
+ Search$1.displayName = 'Search';
5308
5329
  return /*#__PURE__*/React__default.createElement(SearchContainer, {
5309
- role: "button",
5310
5330
  "aria-label": "Search",
5311
5331
  selected: selected,
5312
5332
  onClick: onClick,
5313
- onKeyDown: onKeyDownHandler,
5314
5333
  "data-testid": "search-icon",
5315
5334
  tabIndex: 0,
5316
- className: className
5335
+ className: className,
5336
+ ref: ref
5317
5337
  }, /*#__PURE__*/React__default.createElement(SvgContainer$1, {
5318
5338
  "aria-hidden": "true"
5319
5339
  }, /*#__PURE__*/React__default.createElement(Icon, {
5320
5340
  iconName: "Search"
5321
5341
  })));
5322
- };
5342
+ });
5323
5343
 
5324
5344
  /* eslint-disable react/jsx-no-useless-fragment */
5325
5345
  var Dropdown = function Dropdown(_ref) {
@@ -5534,12 +5554,14 @@ var NavTop = function NavTop(_ref) {
5534
5554
  onClickSearch = _ref.onClickSearch,
5535
5555
  _ref$isShowSearch = _ref.isShowSearch,
5536
5556
  isShowSearch = _ref$isShowSearch === void 0 ? false : _ref$isShowSearch,
5537
- className = _ref.className;
5557
+ className = _ref.className,
5558
+ searchButtonRef = _ref.searchButtonRef;
5538
5559
  return /*#__PURE__*/React__default.createElement(NavTopContainer$1, {
5539
5560
  className: className
5540
5561
  }, /*#__PURE__*/React__default.createElement(Search$1, {
5541
5562
  onClick: onClickSearch,
5542
- selected: isShowSearch
5563
+ selected: isShowSearch,
5564
+ ref: searchButtonRef
5543
5565
  }), /*#__PURE__*/React__default.createElement(Basket$1, {
5544
5566
  link: basketLink,
5545
5567
  text: basketText,
@@ -5585,6 +5607,7 @@ var Tabs = function Tabs(_ref) {
5585
5607
  var _useState3 = React.useState(-1),
5586
5608
  hoverOverDropdown = _useState3[0],
5587
5609
  setHoverOverDropdown = _useState3[1];
5610
+ var dropdownRefs = React.useRef([]);
5588
5611
  var onClickHandler = function onClickHandler(value) {
5589
5612
  setOpenMenu(value);
5590
5613
  if (onShowMenu) {
@@ -5624,23 +5647,25 @@ var Tabs = function Tabs(_ref) {
5624
5647
  setHoverOverDropdown(-1);
5625
5648
  }
5626
5649
  };
5627
- var _onFocus = function onFocus(i) {
5628
- return setActiveDropdown(i);
5650
+ var onDropdownFocusLeave = function onDropdownFocusLeave() {
5651
+ onResetActive();
5629
5652
  };
5630
- var _onBlur = function onBlur(i) {
5631
- var _items$length;
5632
- if (i === ((_items$length = items == null ? void 0 : items.length) != null ? _items$length : 0) - 1) {
5653
+ var handleBlur = function handleBlur(index) {
5654
+ var currentDropdown = dropdownRefs.current[index];
5655
+ var active = document.activeElement;
5656
+ if (currentDropdown && (!active || !currentDropdown.contains(active))) {
5633
5657
  onResetActive();
5634
5658
  }
5635
5659
  };
5636
5660
  return /*#__PURE__*/React__default.createElement(TabsContainer, {
5661
+ role: "menubar",
5637
5662
  className: className
5638
5663
  }, /*#__PURE__*/React__default.createElement(ItemsContainer, {
5639
5664
  showMenu: showMenu
5640
5665
  }, items.map(function (item, index) {
5641
5666
  return /*#__PURE__*/React__default.createElement(ControlledDropdown, {
5642
5667
  key: "key-" + item.title,
5643
- text: item.title,
5668
+ text: item.title || '',
5644
5669
  options: item.options,
5645
5670
  onClick: function onClick() {
5646
5671
  return onDropdownClick(index, item.titleLink);
@@ -5652,17 +5677,23 @@ var Tabs = function Tabs(_ref) {
5652
5677
  onMouseLeave: function onMouseLeave() {
5653
5678
  return onDropdownMouseLeave();
5654
5679
  },
5655
- onFocus: function onFocus() {
5656
- return _onFocus(index);
5680
+ onFocusLeave: function onFocusLeave() {
5681
+ return onDropdownFocusLeave();
5657
5682
  },
5658
5683
  onBlur: function onBlur() {
5659
- return _onBlur(index);
5684
+ return handleBlur(index);
5660
5685
  },
5661
5686
  onReset: onResetActive,
5662
- active: isActiveDropdown(index)
5687
+ active: isActiveDropdown(index),
5688
+ ref: function ref(el) {
5689
+ dropdownRefs.current[index] = el;
5690
+ }
5663
5691
  });
5664
5692
  })), !showMenu && (/*#__PURE__*/React__default.createElement(MenuContainer$1, null, openMenu ? (/*#__PURE__*/React__default.createElement("a", {
5665
5693
  "data-testid": "mobile-menu-close",
5694
+ role: "button",
5695
+ "aria-label": "Close menu",
5696
+ tabIndex: 0,
5666
5697
  onClick: function onClick(e) {
5667
5698
  e.preventDefault();
5668
5699
  onClickHandler(false);
@@ -5672,6 +5703,9 @@ var Tabs = function Tabs(_ref) {
5672
5703
  iconName: "Close"
5673
5704
  }))) : (/*#__PURE__*/React__default.createElement(MenuItem, null, /*#__PURE__*/React__default.createElement("a", {
5674
5705
  "data-testid": "mobile-menu-button",
5706
+ role: "button",
5707
+ "aria-label": "Open menu",
5708
+ tabIndex: 0,
5675
5709
  onClick: function onClick(e) {
5676
5710
  e.preventDefault();
5677
5711
  onClickHandler(true);
@@ -5682,30 +5716,56 @@ var Tabs = function Tabs(_ref) {
5682
5716
  var _templateObject$C, _templateObject2$s, _templateObject3$i, _templateObject5$a, _templateObject6$7, _templateObject7$4;
5683
5717
  var SearchBarContainer = /*#__PURE__*/styled__default.div(_templateObject$C || (_templateObject$C = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n display: flex;\n flex-direction: row;\n column-gap: 64px;\n justify-content: space-between;\n align-items: center;\n height: 100%;\n background-color: transparent;\n\n @media ", " {\n column-gap: 12px;\n }\n"])), devices.mobile);
5684
5718
  var SvgContainerSearch = /*#__PURE__*/styled__default.div(_templateObject2$s || (_templateObject2$s = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n svg {\n width: var(--navigation-xlarge-gap);\n height: var(--navigation-xlarge-gap);\n }\n"])));
5685
- var SvgContainerClose = /*#__PURE__*/styled__default.div(_templateObject3$i || (_templateObject3$i = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n svg {\n width: var(--navigation-large-gap);\n height: var(--navigation-large-gap);\n }\n\n :hover {\n cursor: pointer;\n && svg path {\n fill: var(--color-primary-red);\n }\n }\n"])));
5719
+ var SvgContainerClose = /*#__PURE__*/styled__default.button(_templateObject3$i || (_templateObject3$i = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n all: unset;\n\n svg {\n width: var(--navigation-large-gap);\n height: var(--navigation-large-gap);\n }\n\n :hover {\n cursor: pointer;\n && svg path {\n fill: var(--color-primary-red);\n }\n }\n\n &:focus {\n outline: 2px solid var(--color-primary-black);\n outline-offset: 2px;\n }\n"])));
5686
5720
  var InputContainer = /*#__PURE__*/styled__default.div(_templateObject5$a || (_templateObject5$a = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n background-color: blue;\n width: 100%;\n\n input {\n font-size: var(--font-size-search);\n font-family: var(--font-family-serif);\n border: none;\n border-radius: 0;\n outline: none;\n outline-color: var(--color-base-white);\n height: 48px;\n box-sizing: border-box;\n width: 100%;\n -webkit-appearance: none;\n\n &.search-input {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n @media ", " {\n column-gap: 24px;\n }\n }\n"])), devices.mobile);
5687
5721
  var TextLinkWrapper$1 = /*#__PURE__*/styled__default(TextLink)(_templateObject6$7 || (_templateObject6$7 = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n color: var(--color-primary-red);\n"])));
5688
5722
  var SearchArrowContainer = /*#__PURE__*/styled__default.a(_templateObject7$4 || (_templateObject7$4 = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n padding-right: 8px;\n\n svg {\n width: var(--navigation-large-gap);\n height: var(--navigation-large-gap);\n }\n"])));
5689
5723
 
5724
+ function useFocusTrap(containerRef, onEscape) {
5725
+ React.useEffect(function () {
5726
+ var container = containerRef.current;
5727
+ if (!container) return undefined;
5728
+ var focusableSelectors = 'input, button, select, textarea, a[href], [tabindex]:not([tabindex="-1"])';
5729
+ var focusableEls = container.querySelectorAll(focusableSelectors);
5730
+ var firstEl = focusableEls[0];
5731
+ var lastEl = focusableEls[focusableEls.length - 1];
5732
+ var handleKeyDown = function handleKeyDown(e) {
5733
+ if (e.key === 'Tab') {
5734
+ if (focusableEls.length === 0) return;
5735
+ if (e.shiftKey && document.activeElement === firstEl) {
5736
+ e.preventDefault();
5737
+ lastEl == null || lastEl.focus();
5738
+ } else if (!e.shiftKey && document.activeElement === lastEl) {
5739
+ e.preventDefault();
5740
+ firstEl == null || firstEl.focus();
5741
+ }
5742
+ }
5743
+ if (e.key === 'Escape') {
5744
+ onEscape == null || onEscape();
5745
+ }
5746
+ };
5747
+ document.addEventListener('keydown', handleKeyDown);
5748
+ return function () {
5749
+ return document.removeEventListener('keydown', handleKeyDown);
5750
+ };
5751
+ }, [containerRef, onEscape]);
5752
+ }
5753
+
5690
5754
  var SearchBar = function SearchBar(_ref) {
5691
5755
  var onClick = _ref.onClick,
5692
5756
  onClose = _ref.onClose,
5693
- className = _ref.className;
5757
+ className = _ref.className,
5758
+ inputRef = _ref.inputRef;
5694
5759
  var _useState = React.useState(false),
5695
5760
  showSearchLink = _useState[0],
5696
5761
  setShowSearchLink = _useState[1];
5697
5762
  var _useState2 = React.useState(''),
5698
5763
  searchValue = _useState2[0],
5699
5764
  setSearchValue = _useState2[1];
5700
- var inputRef = React.useRef(null);
5701
- React.useEffect(function () {
5702
- var _inputRef$current;
5703
- inputRef == null || (_inputRef$current = inputRef.current) == null || _inputRef$current.focus();
5704
- return function () {
5705
- var _inputRef$current2;
5706
- return inputRef == null || (_inputRef$current2 = inputRef.current) == null ? void 0 : _inputRef$current2.blur();
5707
- };
5708
- }, [inputRef]);
5765
+ var internalRef = React.useRef(null);
5766
+ var finalInputRef = inputRef != null ? inputRef : internalRef;
5767
+ var containerRef = React.useRef(null);
5768
+ useFocusTrap(containerRef, onClose);
5709
5769
  var onSearchHandler = function onSearchHandler(value) {
5710
5770
  onClick(value);
5711
5771
  setSearchValue('');
@@ -5741,12 +5801,13 @@ var SearchBar = function SearchBar(_ref) {
5741
5801
  var _useViewport = useViewport(),
5742
5802
  isDesktop = _useViewport.isDesktop;
5743
5803
  return /*#__PURE__*/React__default.createElement(SearchBarContainer, {
5744
- className: className
5804
+ className: className,
5805
+ ref: containerRef
5745
5806
  }, /*#__PURE__*/React__default.createElement(SvgContainerSearch, null, /*#__PURE__*/React__default.createElement(Icon, {
5746
5807
  iconName: "Search"
5747
5808
  })), /*#__PURE__*/React__default.createElement(InputContainer, null, /*#__PURE__*/React__default.createElement("input", {
5748
5809
  "data-testid": "input-html",
5749
- ref: inputRef,
5810
+ ref: finalInputRef,
5750
5811
  className: "search-input",
5751
5812
  placeholder: "Search the website...",
5752
5813
  type: "text",
@@ -5760,7 +5821,9 @@ var SearchBar = function SearchBar(_ref) {
5760
5821
  })), showSearchLink && (isDesktop ? (/*#__PURE__*/React__default.createElement("div", {
5761
5822
  "data-testid": "search-button"
5762
5823
  }, /*#__PURE__*/React__default.createElement(TextLinkWrapper$1, {
5824
+ role: "button",
5763
5825
  "data-testid": "search-link",
5826
+ "aria-label": "Submit search",
5764
5827
  onClick: function onClick() {
5765
5828
  return onSearchHandler(searchValue);
5766
5829
  },
@@ -5769,6 +5832,8 @@ var SearchBar = function SearchBar(_ref) {
5769
5832
  },
5770
5833
  tabIndex: 0
5771
5834
  }, "Search"))) : (/*#__PURE__*/React__default.createElement(SearchArrowContainer, {
5835
+ role: "button",
5836
+ "aria-label": "Submit search",
5772
5837
  "data-testid": "search-arrow-button",
5773
5838
  onClick: function onClick() {
5774
5839
  return onSearchHandler(searchValue);
@@ -5779,7 +5844,8 @@ var SearchBar = function SearchBar(_ref) {
5779
5844
  tabIndex: 0,
5780
5845
  onClick: onCloseHandler,
5781
5846
  onKeyDown: onKeyboardCloseHandler,
5782
- "data-testid": "close-icon"
5847
+ "data-testid": "close-icon",
5848
+ "aria-label": "Close search bar"
5783
5849
  }, /*#__PURE__*/React__default.createElement(Icon, {
5784
5850
  iconName: "Close"
5785
5851
  })));
@@ -5796,6 +5862,8 @@ var Navigation = function Navigation(_ref) {
5796
5862
  crest = _ref$crest === void 0 ? false : _ref$crest,
5797
5863
  className = _ref.className,
5798
5864
  logoLink = _ref.logoLink;
5865
+ var searchInputRef = React.useRef(null);
5866
+ var searchButtonRef = React.useRef(null);
5799
5867
  var _useState = React.useState(dataNavTop),
5800
5868
  navTopData = _useState[0],
5801
5869
  setNavTopData = _useState[1];
@@ -5828,9 +5896,7 @@ var Navigation = function Navigation(_ref) {
5828
5896
  setNavTopData(dataNavTop);
5829
5897
  }, [dataNavTop]);
5830
5898
  var onClickSearchHandler = function onClickSearchHandler() {
5831
- setshowSearch(function (prev) {
5832
- return !prev;
5833
- });
5899
+ setshowSearch(true);
5834
5900
  };
5835
5901
  var onLinkHandler = function onLinkHandler(link) {
5836
5902
  onLink(link);
@@ -5847,7 +5913,23 @@ var Navigation = function Navigation(_ref) {
5847
5913
  };
5848
5914
  var onCloseSearchHandler = function onCloseSearchHandler() {
5849
5915
  setshowSearch(false);
5916
+ setTimeout(function () {
5917
+ var _searchButtonRef$curr;
5918
+ (_searchButtonRef$curr = searchButtonRef.current) == null || _searchButtonRef$curr.focus();
5919
+ }, 0);
5850
5920
  };
5921
+ React.useEffect(function () {
5922
+ if (showSearch) {
5923
+ var timer = setTimeout(function () {
5924
+ var _searchInputRef$curre;
5925
+ (_searchInputRef$curre = searchInputRef.current) == null || _searchInputRef$curre.focus();
5926
+ }, 50);
5927
+ return function () {
5928
+ return clearTimeout(timer);
5929
+ };
5930
+ }
5931
+ return undefined;
5932
+ }, [showSearch]);
5851
5933
  var _useViewport = useViewport(),
5852
5934
  isMobile = _useViewport.isMobile;
5853
5935
  return /*#__PURE__*/React__default.createElement(NavigationWrapper, {
@@ -5889,7 +5971,8 @@ var Navigation = function Navigation(_ref) {
5889
5971
  basketNumVirtualItems: navTopData.basketNumVirtualItems,
5890
5972
  onClickSearch: onClickSearchHandler,
5891
5973
  onLink: onLinkHandler,
5892
- isShowSearch: showSearch
5974
+ isShowSearch: showSearch,
5975
+ searchButtonRef: searchButtonRef
5893
5976
  }))))), /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement(SearchBackground, {
5894
5977
  visible: showSearch
5895
5978
  }), /*#__PURE__*/React__default.createElement(GridItemSearch, {
@@ -5900,6 +5983,7 @@ var Navigation = function Navigation(_ref) {
5900
5983
  columnStartDevice: 2,
5901
5984
  columnSpanDevice: 12
5902
5985
  }, /*#__PURE__*/React__default.createElement(SearchBar, {
5986
+ inputRef: searchInputRef,
5903
5987
  onClick: onSearchHandler,
5904
5988
  onClose: onCloseSearchHandler
5905
5989
  })))), showMenu && (/*#__PURE__*/React__default.createElement(NavigationGridMobile, {