@royaloperahouse/harmonic 0.6.0-a → 0.6.0-b

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.
@@ -2962,7 +2962,7 @@ var OptionsContainer = /*#__PURE__*/styled.div(_templateObject3 || (_templateObj
2962
2962
 
2963
2963
  var _templateObject$7, _templateObject2$5, _templateObject3$1, _templateObject4;
2964
2964
  var ControlledDropdownWrapper = /*#__PURE__*/styled.div(_templateObject$7 || (_templateObject$7 = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n position: relative;\n width: fit-content;\n"])));
2965
- var ControlledDropdownHeaderContainer = /*#__PURE__*/styled.button(_templateObject2$5 || (_templateObject2$5 = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n all: unset;\n\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) {
2965
+ var ControlledDropdownHeaderContainer = /*#__PURE__*/styled.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) {
2966
2966
  var active = _ref.active;
2967
2967
  if (active) {
2968
2968
  return "\n & {\n color: var(--color-primary-red);\n }\n && svg path {\n fill: var(--color-primary-red);\n } \n ";
@@ -5337,7 +5337,7 @@ var Basket$1 = function Basket(_ref) {
5337
5337
  };
5338
5338
 
5339
5339
  var _templateObject$A, _templateObject2$q;
5340
- var SearchContainer = /*#__PURE__*/styled.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) {
5340
+ var SearchContainer = /*#__PURE__*/styled.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) {
5341
5341
  var selected = _ref.selected;
5342
5342
  if (selected) {
5343
5343
  return "\n border-bottom: 1px solid var(--color-primary-red);\n && svg path {\n fill: var(--color-primary-red);\n }\n ";
@@ -5346,31 +5346,26 @@ var SearchContainer = /*#__PURE__*/styled.div(_templateObject$A || (_templateObj
5346
5346
  });
5347
5347
  var SvgContainer$1 = /*#__PURE__*/styled.div(_templateObject2$q || (_templateObject2$q = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n svg {\n width: var(--navigation-large-gap);\n height: var(--navigation-large-gap);\n }\n"])));
5348
5348
 
5349
- var Search$1 = function Search(_ref) {
5349
+ var Search$1 = /*#__PURE__*/forwardRef(function (_ref, ref) {
5350
5350
  var _ref$selected = _ref.selected,
5351
5351
  selected = _ref$selected === void 0 ? false : _ref$selected,
5352
5352
  onClick = _ref.onClick,
5353
5353
  className = _ref.className;
5354
- var onKeyDownHandler = function onKeyDownHandler(e) {
5355
- if (e.key === 'Enter') {
5356
- onClick == null || onClick();
5357
- }
5358
- };
5354
+ Search$1.displayName = 'Search';
5359
5355
  return /*#__PURE__*/React__default.createElement(SearchContainer, {
5360
- role: "button",
5361
5356
  "aria-label": "Search",
5362
5357
  selected: selected,
5363
5358
  onClick: onClick,
5364
- onKeyDown: onKeyDownHandler,
5365
5359
  "data-testid": "search-icon",
5366
5360
  tabIndex: 0,
5367
- className: className
5361
+ className: className,
5362
+ ref: ref
5368
5363
  }, /*#__PURE__*/React__default.createElement(SvgContainer$1, {
5369
5364
  "aria-hidden": "true"
5370
5365
  }, /*#__PURE__*/React__default.createElement(Icon, {
5371
5366
  iconName: "Search"
5372
5367
  })));
5373
- };
5368
+ });
5374
5369
 
5375
5370
  /* eslint-disable react/jsx-no-useless-fragment */
5376
5371
  var Dropdown = function Dropdown(_ref) {
@@ -5588,12 +5583,14 @@ var NavTop = function NavTop(_ref) {
5588
5583
  onClickSearch = _ref.onClickSearch,
5589
5584
  _ref$isShowSearch = _ref.isShowSearch,
5590
5585
  isShowSearch = _ref$isShowSearch === void 0 ? false : _ref$isShowSearch,
5591
- className = _ref.className;
5586
+ className = _ref.className,
5587
+ searchButtonRef = _ref.searchButtonRef;
5592
5588
  return /*#__PURE__*/React__default.createElement(NavTopContainer$1, {
5593
5589
  className: className
5594
5590
  }, /*#__PURE__*/React__default.createElement(Search$1, {
5595
5591
  onClick: onClickSearch,
5596
- selected: isShowSearch
5592
+ selected: isShowSearch,
5593
+ ref: searchButtonRef
5597
5594
  }), /*#__PURE__*/React__default.createElement(Basket$1, {
5598
5595
  link: basketLink,
5599
5596
  text: basketText,
@@ -5742,30 +5739,56 @@ var Tabs = function Tabs(_ref) {
5742
5739
  var _templateObject$C, _templateObject2$s, _templateObject3$i, _templateObject5$a, _templateObject6$7, _templateObject7$4;
5743
5740
  var SearchBarContainer = /*#__PURE__*/styled.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);
5744
5741
  var SvgContainerSearch = /*#__PURE__*/styled.div(_templateObject2$s || (_templateObject2$s = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n svg {\n width: var(--navigation-xlarge-gap);\n height: var(--navigation-xlarge-gap);\n }\n"])));
5745
- var SvgContainerClose = /*#__PURE__*/styled.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"])));
5742
+ var SvgContainerClose = /*#__PURE__*/styled.div(_templateObject3$i || (_templateObject3$i = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n as: button;\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"])));
5746
5743
  var InputContainer = /*#__PURE__*/styled.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);
5747
5744
  var TextLinkWrapper$1 = /*#__PURE__*/styled(TextLink)(_templateObject6$7 || (_templateObject6$7 = /*#__PURE__*/_taggedTemplateLiteralLoose(["\n color: var(--color-primary-red);\n"])));
5748
5745
  var SearchArrowContainer = /*#__PURE__*/styled.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"])));
5749
5746
 
5747
+ function useFocusTrap(containerRef, onEscape) {
5748
+ useEffect(function () {
5749
+ var container = containerRef.current;
5750
+ if (!container) return undefined;
5751
+ var focusableSelectors = 'input, button, select, textarea, a[href], [tabindex]:not([tabindex="-1"])';
5752
+ var focusableEls = container.querySelectorAll(focusableSelectors);
5753
+ var firstEl = focusableEls[0];
5754
+ var lastEl = focusableEls[focusableEls.length - 1];
5755
+ var handleKeyDown = function handleKeyDown(e) {
5756
+ if (e.key === 'Tab') {
5757
+ if (focusableEls.length === 0) return;
5758
+ if (e.shiftKey && document.activeElement === firstEl) {
5759
+ e.preventDefault();
5760
+ lastEl == null || lastEl.focus();
5761
+ } else if (!e.shiftKey && document.activeElement === lastEl) {
5762
+ e.preventDefault();
5763
+ firstEl == null || firstEl.focus();
5764
+ }
5765
+ }
5766
+ if (e.key === 'Escape') {
5767
+ onEscape == null || onEscape();
5768
+ }
5769
+ };
5770
+ document.addEventListener('keydown', handleKeyDown);
5771
+ return function () {
5772
+ return document.removeEventListener('keydown', handleKeyDown);
5773
+ };
5774
+ }, [containerRef, onEscape]);
5775
+ }
5776
+
5750
5777
  var SearchBar = function SearchBar(_ref) {
5751
5778
  var onClick = _ref.onClick,
5752
5779
  onClose = _ref.onClose,
5753
- className = _ref.className;
5780
+ className = _ref.className,
5781
+ inputRef = _ref.inputRef;
5754
5782
  var _useState = useState(false),
5755
5783
  showSearchLink = _useState[0],
5756
5784
  setShowSearchLink = _useState[1];
5757
5785
  var _useState2 = useState(''),
5758
5786
  searchValue = _useState2[0],
5759
5787
  setSearchValue = _useState2[1];
5760
- var inputRef = useRef(null);
5761
- useEffect(function () {
5762
- var _inputRef$current;
5763
- inputRef == null || (_inputRef$current = inputRef.current) == null || _inputRef$current.focus();
5764
- return function () {
5765
- var _inputRef$current2;
5766
- return inputRef == null || (_inputRef$current2 = inputRef.current) == null ? void 0 : _inputRef$current2.blur();
5767
- };
5768
- }, [inputRef]);
5788
+ var internalRef = useRef(null);
5789
+ var finalInputRef = inputRef != null ? inputRef : internalRef;
5790
+ var containerRef = useRef(null);
5791
+ useFocusTrap(containerRef, onClose);
5769
5792
  var onSearchHandler = function onSearchHandler(value) {
5770
5793
  onClick(value);
5771
5794
  setSearchValue('');
@@ -5801,12 +5824,13 @@ var SearchBar = function SearchBar(_ref) {
5801
5824
  var _useViewport = useViewport(),
5802
5825
  isDesktop = _useViewport.isDesktop;
5803
5826
  return /*#__PURE__*/React__default.createElement(SearchBarContainer, {
5804
- className: className
5827
+ className: className,
5828
+ ref: containerRef
5805
5829
  }, /*#__PURE__*/React__default.createElement(SvgContainerSearch, null, /*#__PURE__*/React__default.createElement(Icon, {
5806
5830
  iconName: "Search"
5807
5831
  })), /*#__PURE__*/React__default.createElement(InputContainer, null, /*#__PURE__*/React__default.createElement("input", {
5808
5832
  "data-testid": "input-html",
5809
- ref: inputRef,
5833
+ ref: finalInputRef,
5810
5834
  className: "search-input",
5811
5835
  placeholder: "Search the website...",
5812
5836
  type: "text",
@@ -5839,7 +5863,8 @@ var SearchBar = function SearchBar(_ref) {
5839
5863
  tabIndex: 0,
5840
5864
  onClick: onCloseHandler,
5841
5865
  onKeyDown: onKeyboardCloseHandler,
5842
- "data-testid": "close-icon"
5866
+ "data-testid": "close-icon",
5867
+ "aria-label": "Close search bar"
5843
5868
  }, /*#__PURE__*/React__default.createElement(Icon, {
5844
5869
  iconName: "Close"
5845
5870
  })));
@@ -5856,6 +5881,8 @@ var Navigation = function Navigation(_ref) {
5856
5881
  crest = _ref$crest === void 0 ? false : _ref$crest,
5857
5882
  className = _ref.className,
5858
5883
  logoLink = _ref.logoLink;
5884
+ var searchInputRef = useRef(null);
5885
+ var searchButtonRef = useRef(null);
5859
5886
  var _useState = useState(dataNavTop),
5860
5887
  navTopData = _useState[0],
5861
5888
  setNavTopData = _useState[1];
@@ -5888,9 +5915,7 @@ var Navigation = function Navigation(_ref) {
5888
5915
  setNavTopData(dataNavTop);
5889
5916
  }, [dataNavTop]);
5890
5917
  var onClickSearchHandler = function onClickSearchHandler() {
5891
- setshowSearch(function (prev) {
5892
- return !prev;
5893
- });
5918
+ setshowSearch(true);
5894
5919
  };
5895
5920
  var onLinkHandler = function onLinkHandler(link) {
5896
5921
  onLink(link);
@@ -5907,7 +5932,23 @@ var Navigation = function Navigation(_ref) {
5907
5932
  };
5908
5933
  var onCloseSearchHandler = function onCloseSearchHandler() {
5909
5934
  setshowSearch(false);
5935
+ setTimeout(function () {
5936
+ var _searchButtonRef$curr;
5937
+ (_searchButtonRef$curr = searchButtonRef.current) == null || _searchButtonRef$curr.focus();
5938
+ }, 0);
5910
5939
  };
5940
+ useEffect(function () {
5941
+ if (showSearch) {
5942
+ var timer = setTimeout(function () {
5943
+ var _searchInputRef$curre;
5944
+ (_searchInputRef$curre = searchInputRef.current) == null || _searchInputRef$curre.focus();
5945
+ }, 50);
5946
+ return function () {
5947
+ return clearTimeout(timer);
5948
+ };
5949
+ }
5950
+ return undefined;
5951
+ }, [showSearch]);
5911
5952
  var _useViewport = useViewport(),
5912
5953
  isMobile = _useViewport.isMobile;
5913
5954
  return /*#__PURE__*/React__default.createElement(NavigationWrapper, {
@@ -5949,7 +5990,8 @@ var Navigation = function Navigation(_ref) {
5949
5990
  basketNumVirtualItems: navTopData.basketNumVirtualItems,
5950
5991
  onClickSearch: onClickSearchHandler,
5951
5992
  onLink: onLinkHandler,
5952
- isShowSearch: showSearch
5993
+ isShowSearch: showSearch,
5994
+ searchButtonRef: searchButtonRef
5953
5995
  }))))), /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement(SearchBackground, {
5954
5996
  visible: showSearch
5955
5997
  }), /*#__PURE__*/React__default.createElement(GridItemSearch, {
@@ -5960,6 +6002,7 @@ var Navigation = function Navigation(_ref) {
5960
6002
  columnStartDevice: 2,
5961
6003
  columnSpanDevice: 12
5962
6004
  }, /*#__PURE__*/React__default.createElement(SearchBar, {
6005
+ inputRef: searchInputRef,
5963
6006
  onClick: onSearchHandler,
5964
6007
  onClose: onCloseSearchHandler
5965
6008
  })))), showMenu && (/*#__PURE__*/React__default.createElement(NavigationGridMobile, {