@redsift/design-system 8.0.0 → 8.0.1

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/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { I18nProvider, useLocalizedStringFormatter, useFocusRing, useNumberFormatter, useFocusWithin } from 'react-aria';
2
2
  export { I18nProvider, SSRProvider } from 'react-aria';
3
3
  import * as React from 'react';
4
- import React__default, { useState, useEffect, useContext, useMemo, useRef, useCallback, forwardRef, useReducer, useLayoutEffect, useId as useId$1 } from 'react';
4
+ import React__default, { useState, useEffect, useContext, useRef, useMemo, useCallback, forwardRef, useReducer, useLayoutEffect, useId as useId$1 } from 'react';
5
5
  import classNames from 'classnames';
6
6
  import { mdiClose, mdiAlert, mdiCheckCircle, mdiAlertCircle, mdiInformation, mdiMenu, mdiMenuOpen, mdiChevronDown, mdiChevronRight, mdiChevronUp, mdiCheckboxMarked, mdiMinusBox, mdiCheckboxBlankOutline, mdiPageLast, mdiKeyboardCaps, mdiRadioboxMarked, mdiRadioboxBlank } from '@redsift/icons';
7
7
  import styled, { css, keyframes } from 'styled-components';
@@ -592,7 +592,77 @@ const $704cf1d3b684cc5c$var$defaultContext = {
592
592
  isSSR: false
593
593
  };
594
594
  const $704cf1d3b684cc5c$var$SSRContext = /*#__PURE__*/ (React__default).createContext($704cf1d3b684cc5c$var$defaultContext);
595
+ let $704cf1d3b684cc5c$var$canUseDOM = Boolean(typeof window !== "undefined" && window.document && window.document.createElement);
596
+ let $704cf1d3b684cc5c$var$componentIds = new WeakMap();
597
+ function $704cf1d3b684cc5c$var$useCounter(isDisabled = false) {
598
+ let ctx = (useContext)($704cf1d3b684cc5c$var$SSRContext);
599
+ let ref = (useRef)(null);
600
+ // eslint-disable-next-line rulesdir/pure-render
601
+ if (ref.current === null && !isDisabled) {
602
+ var _React___SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, _React___SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED_ReactCurrentOwner;
603
+ // In strict mode, React renders components twice, and the ref will be reset to null on the second render.
604
+ // This means our id counter will be incremented twice instead of once. This is a problem because on the
605
+ // server, components are only rendered once and so ids generated on the server won't match the client.
606
+ // In React 18, useId was introduced to solve this, but it is not available in older versions. So to solve this
607
+ // we need to use some React internals to access the underlying Fiber instance, which is stable between renders.
608
+ // This is exposed as ReactCurrentOwner in development, which is all we need since StrictMode only runs in development.
609
+ // To ensure that we only increment the global counter once, we store the starting id for this component in
610
+ // a weak map associated with the Fiber. On the second render, we reset the global counter to this value.
611
+ // Since React runs the second render immediately after the first, this is safe.
612
+ // @ts-ignore
613
+ let currentOwner = (_React___SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = (React__default).__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED) === null || _React___SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED === void 0 ? void 0 : (_React___SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED_ReactCurrentOwner = _React___SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner) === null || _React___SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED_ReactCurrentOwner === void 0 ? void 0 : _React___SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED_ReactCurrentOwner.current;
614
+ if (currentOwner) {
615
+ let prevComponentValue = $704cf1d3b684cc5c$var$componentIds.get(currentOwner);
616
+ if (prevComponentValue == null) // On the first render, and first call to useId, store the id and state in our weak map.
617
+ $704cf1d3b684cc5c$var$componentIds.set(currentOwner, {
618
+ id: ctx.current,
619
+ state: currentOwner.memoizedState
620
+ });
621
+ else if (currentOwner.memoizedState !== prevComponentValue.state) {
622
+ // On the second render, the memoizedState gets reset by React.
623
+ // Reset the counter, and remove from the weak map so we don't
624
+ // do this for subsequent useId calls.
625
+ ctx.current = prevComponentValue.id;
626
+ $704cf1d3b684cc5c$var$componentIds.delete(currentOwner);
627
+ }
628
+ }
629
+ // eslint-disable-next-line rulesdir/pure-render
630
+ ref.current = ++ctx.current;
631
+ }
632
+ // eslint-disable-next-line rulesdir/pure-render
633
+ return ref.current;
634
+ }
635
+ function $704cf1d3b684cc5c$var$useLegacySSRSafeId(defaultId) {
636
+ let ctx = (useContext)($704cf1d3b684cc5c$var$SSRContext);
637
+ // If we are rendering in a non-DOM environment, and there's no SSRProvider,
638
+ // provide a warning to hint to the developer to add one.
639
+ if (ctx === $704cf1d3b684cc5c$var$defaultContext && !$704cf1d3b684cc5c$var$canUseDOM) console.warn("When server rendering, you must wrap your application in an <SSRProvider> to ensure consistent ids are generated between the client and server.");
640
+ let counter = $704cf1d3b684cc5c$var$useCounter(!!defaultId);
641
+ return defaultId || `react-aria${ctx.prefix}-${counter}`;
642
+ }
643
+ function $704cf1d3b684cc5c$var$useModernSSRSafeId(defaultId) {
644
+ // @ts-ignore
645
+ let id = (React__default).useId();
646
+ let [didSSR] = (useState)($704cf1d3b684cc5c$export$535bd6ca7f90a273());
647
+ let prefix = didSSR ? "react-aria" : `react-aria${$704cf1d3b684cc5c$var$defaultContext.prefix}`;
648
+ return defaultId || `${prefix}-${id}`;
649
+ }
650
+ typeof (React__default)["useId"] === "function" ? $704cf1d3b684cc5c$var$useModernSSRSafeId : $704cf1d3b684cc5c$var$useLegacySSRSafeId;
651
+ function $704cf1d3b684cc5c$var$getSnapshot() {
652
+ return false;
653
+ }
654
+ function $704cf1d3b684cc5c$var$getServerSnapshot() {
655
+ return true;
656
+ }
657
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
658
+ function $704cf1d3b684cc5c$var$subscribe(onStoreChange) {
659
+ // noop
660
+ return ()=>{};
661
+ }
595
662
  function $704cf1d3b684cc5c$export$535bd6ca7f90a273() {
663
+ // In React 18, we can use useSyncExternalStore to detect if we're server rendering or hydrating.
664
+ if (typeof (React__default)["useSyncExternalStore"] === "function") return (React__default)["useSyncExternalStore"]($704cf1d3b684cc5c$var$subscribe, $704cf1d3b684cc5c$var$getSnapshot, $704cf1d3b684cc5c$var$getServerSnapshot);
665
+ // eslint-disable-next-line react-hooks/rules-of-hooks
596
666
  let cur = (useContext)($704cf1d3b684cc5c$var$SSRContext);
597
667
  return cur.isSSR;
598
668
  }
@@ -847,6 +917,121 @@ function $fb18d541ea1ad717$var$getResolvedHourCycle(locale, options) {
847
917
  throw new Error("Unexpected hour cycle result");
848
918
  }
849
919
 
920
+ /*
921
+ * Copyright 2020 Adobe. All rights reserved.
922
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
923
+ * you may not use this file except in compliance with the License. You may obtain a copy
924
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
925
+ *
926
+ * Unless required by applicable law or agreed to in writing, software distributed under
927
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
928
+ * OF ANY KIND, either express or implied. See the License for the specific language
929
+ * governing permissions and limitations under the License.
930
+ */ /*
931
+ * Copyright 2020 Adobe. All rights reserved.
932
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
933
+ * you may not use this file except in compliance with the License. You may obtain a copy
934
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
935
+ *
936
+ * Unless required by applicable law or agreed to in writing, software distributed under
937
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
938
+ * OF ANY KIND, either express or implied. See the License for the specific language
939
+ * governing permissions and limitations under the License.
940
+ */
941
+ /*
942
+ * Copyright 2020 Adobe. All rights reserved.
943
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
944
+ * you may not use this file except in compliance with the License. You may obtain a copy
945
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
946
+ *
947
+ * Unless required by applicable law or agreed to in writing, software distributed under
948
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
949
+ * OF ANY KIND, either express or implied. See the License for the specific language
950
+ * governing permissions and limitations under the License.
951
+ */
952
+ typeof window !== "undefined" ? (React__default).useLayoutEffect : ()=>{};
953
+
954
+
955
+ /*
956
+ * Copyright 2020 Adobe. All rights reserved.
957
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
958
+ * you may not use this file except in compliance with the License. You may obtain a copy
959
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
960
+ *
961
+ * Unless required by applicable law or agreed to in writing, software distributed under
962
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
963
+ * OF ANY KIND, either express or implied. See the License for the specific language
964
+ * governing permissions and limitations under the License.
965
+ */ // We store a global list of elements that are currently transitioning,
966
+ // mapped to a set of CSS properties that are transitioning for that element.
967
+ // This is necessary rather than a simple count of transitions because of browser
968
+ // bugs, e.g. Chrome sometimes fires both transitionend and transitioncancel rather
969
+ // than one or the other. So we need to track what's actually transitioning so that
970
+ // we can ignore these duplicate events.
971
+ let $bbed8b41f857bcc0$var$transitionsByElement = new Map();
972
+ // A list of callbacks to call once there are no transitioning elements.
973
+ let $bbed8b41f857bcc0$var$transitionCallbacks = new Set();
974
+ function $bbed8b41f857bcc0$var$setupGlobalEvents() {
975
+ if (typeof window === "undefined") return;
976
+ let onTransitionStart = (e)=>{
977
+ // Add the transitioning property to the list for this element.
978
+ let transitions = $bbed8b41f857bcc0$var$transitionsByElement.get(e.target);
979
+ if (!transitions) {
980
+ transitions = new Set();
981
+ $bbed8b41f857bcc0$var$transitionsByElement.set(e.target, transitions);
982
+ // The transitioncancel event must be registered on the element itself, rather than as a global
983
+ // event. This enables us to handle when the node is deleted from the document while it is transitioning.
984
+ // In that case, the cancel event would have nowhere to bubble to so we need to handle it directly.
985
+ e.target.addEventListener("transitioncancel", onTransitionEnd);
986
+ }
987
+ transitions.add(e.propertyName);
988
+ };
989
+ let onTransitionEnd = (e)=>{
990
+ // Remove property from list of transitioning properties.
991
+ let properties = $bbed8b41f857bcc0$var$transitionsByElement.get(e.target);
992
+ if (!properties) return;
993
+ properties.delete(e.propertyName);
994
+ // If empty, remove transitioncancel event, and remove the element from the list of transitioning elements.
995
+ if (properties.size === 0) {
996
+ e.target.removeEventListener("transitioncancel", onTransitionEnd);
997
+ $bbed8b41f857bcc0$var$transitionsByElement.delete(e.target);
998
+ }
999
+ // If no transitioning elements, call all of the queued callbacks.
1000
+ if ($bbed8b41f857bcc0$var$transitionsByElement.size === 0) {
1001
+ for (let cb of $bbed8b41f857bcc0$var$transitionCallbacks)cb();
1002
+ $bbed8b41f857bcc0$var$transitionCallbacks.clear();
1003
+ }
1004
+ };
1005
+ document.body.addEventListener("transitionrun", onTransitionStart);
1006
+ document.body.addEventListener("transitionend", onTransitionEnd);
1007
+ }
1008
+ if (typeof document !== "undefined") {
1009
+ if (document.readyState !== "loading") $bbed8b41f857bcc0$var$setupGlobalEvents();
1010
+ else document.addEventListener("DOMContentLoaded", $bbed8b41f857bcc0$var$setupGlobalEvents);
1011
+ }
1012
+
1013
+
1014
+
1015
+ /*
1016
+ * Copyright 2023 Adobe. All rights reserved.
1017
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
1018
+ * you may not use this file except in compliance with the License. You may obtain a copy
1019
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
1020
+ *
1021
+ * Unless required by applicable law or agreed to in writing, software distributed under
1022
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
1023
+ * OF ANY KIND, either express or implied. See the License for the specific language
1024
+ * governing permissions and limitations under the License.
1025
+ */ /* eslint-disable rulesdir/pure-render */
1026
+ function $5a387cc49350e6db$export$722debc0e56fea39(value, isEqual) {
1027
+ // Using a ref during render is ok here because it's only an optimization – both values are equivalent.
1028
+ // If a render is thrown away, it'll still work the same no matter if the next render is the same or not.
1029
+ let lastValue = (useRef)(null);
1030
+ if (value && lastValue.current && isEqual(value, lastValue.current)) value = lastValue.current;
1031
+ lastValue.current = value;
1032
+ return value;
1033
+ }
1034
+
850
1035
  /*
851
1036
  * Copyright 2020 Adobe. All rights reserved.
852
1037
  * This file is licensed to you under the Apache License, Version 2.0 (the "License");
@@ -884,7 +1069,7 @@ try {
884
1069
  unit: "degree"
885
1070
  }).resolvedOptions().style === "unit";
886
1071
  // eslint-disable-next-line no-empty
887
- } catch (e1) {}
1072
+ } catch (e) {}
888
1073
  // Polyfill for units since Safari doesn't support them yet. See https://bugs.webkit.org/show_bug.cgi?id=215438.
889
1074
  // Currently only polyfilling the unit degree in narrow format for ColorSlider in our supported locales.
890
1075
  // Values were determined by switching to each locale manually in Chrome.
@@ -1222,11 +1407,10 @@ function $33bf17300c498528$export$a2f47a3d2973640(options = {}) {
1222
1407
  */
1223
1408
 
1224
1409
 
1410
+
1225
1411
  function $896ba0a80a8f4d36$export$85fd5fdf27bacc79(options) {
1226
1412
  // Reuse last options object if it is shallowly equal, which allows the useMemo result to also be reused.
1227
- let lastOptions = (useRef)(null);
1228
- if (options && lastOptions.current && $896ba0a80a8f4d36$var$isEqual(options, lastOptions.current)) options = lastOptions.current;
1229
- lastOptions.current = options;
1413
+ options = ($5a387cc49350e6db$export$722debc0e56fea39)(options, $896ba0a80a8f4d36$var$isEqual);
1230
1414
  let { locale: locale } = ($18f2051aff69b9bf$export$43bb16f9c6d9e3f7)();
1231
1415
  return (useMemo)(()=>new ($fb18d541ea1ad717$export$ad991b66133851cf)(locale, options), [
1232
1416
  locale,
@@ -2365,18 +2549,18 @@ const Button = /*#__PURE__*/forwardRef((props, ref) => {
2365
2549
  className: classNames(Button.className, className),
2366
2550
  disabled: isDisabled,
2367
2551
  ref: buttonRef
2368
- }), leftIcon ? /*#__PURE__*/React__default.createElement(Icon, {
2552
+ }), leftIcon ? typeof leftIcon === 'string' ? /*#__PURE__*/React__default.createElement(Icon, {
2369
2553
  icon: leftIcon,
2370
2554
  "aria-hidden": "true",
2371
2555
  className: "left"
2372
- }) : null, isLoading ? /*#__PURE__*/React__default.createElement(Spinner, {
2556
+ }) : leftIcon : null, isLoading ? /*#__PURE__*/React__default.createElement(Spinner, {
2373
2557
  size: "small",
2374
2558
  color: "no-data"
2375
- }) : null, /*#__PURE__*/React__default.createElement("span", null, children), rightIcon ? /*#__PURE__*/React__default.createElement(Icon, {
2559
+ }) : null, /*#__PURE__*/React__default.createElement("span", null, children), rightIcon ? typeof rightIcon === 'string' ? /*#__PURE__*/React__default.createElement(Icon, {
2376
2560
  icon: rightIcon,
2377
2561
  "aria-hidden": "true",
2378
2562
  className: "right"
2379
- }) : null);
2563
+ }) : rightIcon : null);
2380
2564
  });
2381
2565
  Button.className = CLASSNAME$I;
2382
2566
  Button.defaultProps = DEFAULT_PROPS$I;
@@ -3415,7 +3599,7 @@ Badge.className = CLASSNAME$A;
3415
3599
  Badge.defaultProps = DEFAULT_PROPS$A;
3416
3600
  Badge.displayName = COMPONENT_NAME$A;
3417
3601
 
3418
- const _excluded$x = ["badge", "badgeProps", "children", "className", "href", "icon", "iconProps", "iconRef", "isCurrent", "isDisabled", "isSecondLevel", "onClick", "onKeyDown", "tabIndex", "withoutIcons"];
3602
+ const _excluded$x = ["as", "badge", "badgeProps", "children", "className", "href", "icon", "iconProps", "iconRef", "isCurrent", "isDisabled", "isSecondLevel", "onClick", "onKeyDown", "tabIndex", "withoutIcons"];
3419
3603
  const COMPONENT_NAME$z = 'SideNavigationMenuItem';
3420
3604
  const CLASSNAME$z = 'redsift-side-navigation-menu-item';
3421
3605
  const DEFAULT_PROPS$z = {};
@@ -3426,6 +3610,7 @@ const DEFAULT_PROPS$z = {};
3426
3610
  const SideNavigationMenuItem = /*#__PURE__*/forwardRef((props, ref) => {
3427
3611
  const menuItemRef = ref || useRef();
3428
3612
  const {
3613
+ as,
3429
3614
  badge,
3430
3615
  badgeProps,
3431
3616
  children,
@@ -3478,6 +3663,7 @@ const SideNavigationMenuItem = /*#__PURE__*/forwardRef((props, ref) => {
3478
3663
  };
3479
3664
  }, [menuItems]);
3480
3665
  return /*#__PURE__*/React__default.createElement(StyledSideNavigationMenuItem, _extends$1({
3666
+ as: as,
3481
3667
  role: "menuitem"
3482
3668
  }, forwardedProps, {
3483
3669
  $isCurrent: isCurrent,
@@ -4319,7 +4505,7 @@ const StyledBreadcrumbItem = styled.a`
4319
4505
  }
4320
4506
  `;
4321
4507
 
4322
- const _excluded$t = ["children", "className", "href", "isCurrent", "isDisabled"];
4508
+ const _excluded$t = ["as", "children", "className", "href", "isCurrent", "isDisabled"];
4323
4509
  const COMPONENT_NAME$w = 'BreadcrumbItem';
4324
4510
  const CLASSNAME$w = 'redsift-breadcrumb-item';
4325
4511
  const DEFAULT_PROPS$w = {};
@@ -4329,6 +4515,7 @@ const DEFAULT_PROPS$w = {};
4329
4515
  */
4330
4516
  const BreadcrumbItem = /*#__PURE__*/forwardRef((props, ref) => {
4331
4517
  const {
4518
+ as,
4332
4519
  children,
4333
4520
  className,
4334
4521
  href,
@@ -4338,6 +4525,7 @@ const BreadcrumbItem = /*#__PURE__*/forwardRef((props, ref) => {
4338
4525
  forwardedProps = _objectWithoutProperties(props, _excluded$t);
4339
4526
  warnIfNoAccessibleLabelFound(props, [children]);
4340
4527
  return /*#__PURE__*/React__default.createElement(StyledBreadcrumbItem, _extends$1({
4528
+ as: as || 'a',
4341
4529
  role: "link",
4342
4530
  tabIndex: !isDisabled && !isCurrent ? 0 : undefined
4343
4531
  }, forwardedProps, {
@@ -4474,15 +4662,15 @@ const ButtonLink = /*#__PURE__*/forwardRef((props, ref) => {
4474
4662
  href: !isDisabled ? href : undefined,
4475
4663
  ref: ref,
4476
4664
  target: target
4477
- }), leftIcon ? /*#__PURE__*/React__default.createElement(Icon, {
4665
+ }), leftIcon ? typeof leftIcon === 'string' ? /*#__PURE__*/React__default.createElement(Icon, {
4478
4666
  icon: leftIcon,
4479
4667
  "aria-hidden": "true",
4480
4668
  className: "left"
4481
- }) : null, children, rightIcon ? /*#__PURE__*/React__default.createElement(Icon, {
4669
+ }) : leftIcon : null, children, rightIcon ? typeof rightIcon === 'string' ? /*#__PURE__*/React__default.createElement(Icon, {
4482
4670
  icon: rightIcon,
4483
4671
  "aria-hidden": "true",
4484
4672
  className: "right"
4485
- }) : null);
4673
+ }) : rightIcon : null);
4486
4674
  });
4487
4675
  ButtonLink.className = CLASSNAME$u;
4488
4676
  ButtonLink.defaultProps = DEFAULT_PROPS$u;
@@ -6249,7 +6437,7 @@ DetailedCardSectionItem.defaultProps = DEFAULT_PROPS$e;
6249
6437
  DetailedCardSectionItem.displayName = COMPONENT_NAME$e;
6250
6438
 
6251
6439
  /*!
6252
- * tabbable 6.1.2
6440
+ * tabbable 6.2.0
6253
6441
  * @license MIT, https://github.com/focus-trap/tabbable/blob/master/LICENSE
6254
6442
  */
6255
6443
  // NOTE: separate `:not()` selectors has broader browser support than the newer
@@ -6429,7 +6617,27 @@ var getCandidatesIteratively = function getCandidatesIteratively(elements, inclu
6429
6617
  }
6430
6618
  return candidates;
6431
6619
  };
6432
- var getTabindex = function getTabindex(node, isScope) {
6620
+
6621
+ /**
6622
+ * @private
6623
+ * Determines if the node has an explicitly specified `tabindex` attribute.
6624
+ * @param {HTMLElement} node
6625
+ * @returns {boolean} True if so; false if not.
6626
+ */
6627
+ var hasTabIndex = function hasTabIndex(node) {
6628
+ return !isNaN(parseInt(node.getAttribute('tabindex'), 10));
6629
+ };
6630
+
6631
+ /**
6632
+ * Determine the tab index of a given node.
6633
+ * @param {HTMLElement} node
6634
+ * @returns {number} Tab order (negative, 0, or positive number).
6635
+ * @throws {Error} If `node` is falsy.
6636
+ */
6637
+ var getTabIndex = function getTabIndex(node) {
6638
+ if (!node) {
6639
+ throw new Error('No node provided');
6640
+ }
6433
6641
  if (node.tabIndex < 0) {
6434
6642
  // in Chrome, <details/>, <audio controls/> and <video controls/> elements get a default
6435
6643
  // `tabIndex` of -1 when the 'tabindex' attribute isn't specified in the DOM,
@@ -6438,16 +6646,28 @@ var getTabindex = function getTabindex(node, isScope) {
6438
6646
  // order, consider their tab index to be 0.
6439
6647
  // Also browsers do not return `tabIndex` correctly for contentEditable nodes;
6440
6648
  // so if they don't have a tabindex attribute specifically set, assume it's 0.
6441
- //
6442
- // isScope is positive for custom element with shadow root or slot that by default
6443
- // have tabIndex -1, but need to be sorted by document order in order for their
6444
- // content to be inserted in the correct position
6445
- if ((isScope || /^(AUDIO|VIDEO|DETAILS)$/.test(node.tagName) || isContentEditable(node)) && isNaN(parseInt(node.getAttribute('tabindex'), 10))) {
6649
+ if ((/^(AUDIO|VIDEO|DETAILS)$/.test(node.tagName) || isContentEditable(node)) && !hasTabIndex(node)) {
6446
6650
  return 0;
6447
6651
  }
6448
6652
  }
6449
6653
  return node.tabIndex;
6450
6654
  };
6655
+
6656
+ /**
6657
+ * Determine the tab index of a given node __for sort order purposes__.
6658
+ * @param {HTMLElement} node
6659
+ * @param {boolean} [isScope] True for a custom element with shadow root or slot that, by default,
6660
+ * has tabIndex -1, but needs to be sorted by document order in order for its content to be
6661
+ * inserted into the correct sort position.
6662
+ * @returns {number} Tab order (negative, 0, or positive number).
6663
+ */
6664
+ var getSortOrderTabIndex = function getSortOrderTabIndex(node, isScope) {
6665
+ var tabIndex = getTabIndex(node);
6666
+ if (tabIndex < 0 && isScope && !hasTabIndex(node)) {
6667
+ return 0;
6668
+ }
6669
+ return tabIndex;
6670
+ };
6451
6671
  var sortOrderedTabbables = function sortOrderedTabbables(a, b) {
6452
6672
  return a.tabIndex === b.tabIndex ? a.documentOrder - b.documentOrder : a.tabIndex - b.tabIndex;
6453
6673
  };
@@ -6690,7 +6910,7 @@ var isNodeMatchingSelectorFocusable = function isNodeMatchingSelectorFocusable(o
6690
6910
  return true;
6691
6911
  };
6692
6912
  var isNodeMatchingSelectorTabbable = function isNodeMatchingSelectorTabbable(options, node) {
6693
- if (isNonTabbableRadio(node) || getTabindex(node) < 0 || !isNodeMatchingSelectorFocusable(options, node)) {
6913
+ if (isNonTabbableRadio(node) || getTabIndex(node) < 0 || !isNodeMatchingSelectorFocusable(options, node)) {
6694
6914
  return false;
6695
6915
  }
6696
6916
  return true;
@@ -6715,7 +6935,7 @@ var sortByOrder = function sortByOrder(candidates) {
6715
6935
  candidates.forEach(function (item, i) {
6716
6936
  var isScope = !!item.scopeParent;
6717
6937
  var element = isScope ? item.scopeParent : item;
6718
- var candidateTabindex = getTabindex(element, isScope);
6938
+ var candidateTabindex = getSortOrderTabIndex(element, isScope);
6719
6939
  var elements = isScope ? sortByOrder(item.candidates) : element;
6720
6940
  if (candidateTabindex === 0) {
6721
6941
  isScope ? regularTabbables.push.apply(regularTabbables, elements) : regularTabbables.push(element);
@@ -6734,18 +6954,18 @@ var sortByOrder = function sortByOrder(candidates) {
6734
6954
  return acc;
6735
6955
  }, []).concat(regularTabbables);
6736
6956
  };
6737
- var tabbable = function tabbable(el, options) {
6957
+ var tabbable = function tabbable(container, options) {
6738
6958
  options = options || {};
6739
6959
  var candidates;
6740
6960
  if (options.getShadowRoot) {
6741
- candidates = getCandidatesIteratively([el], options.includeContainer, {
6961
+ candidates = getCandidatesIteratively([container], options.includeContainer, {
6742
6962
  filter: isNodeMatchingSelectorTabbable.bind(null, options),
6743
6963
  flatten: false,
6744
6964
  getShadowRoot: options.getShadowRoot,
6745
6965
  shadowRootFilter: isValidShadowRootTabbable
6746
6966
  });
6747
6967
  } else {
6748
- candidates = getCandidates(el, options.includeContainer, isNodeMatchingSelectorTabbable.bind(null, options));
6968
+ candidates = getCandidates(container, options.includeContainer, isNodeMatchingSelectorTabbable.bind(null, options));
6749
6969
  }
6750
6970
  return sortByOrder(candidates);
6751
6971
  };
@@ -7087,7 +7307,7 @@ const arrow$1 = options => ({
7087
7307
  [axis]: coords[axis] - alignmentOffset,
7088
7308
  data: {
7089
7309
  [axis]: offset,
7090
- centerOffset: center - offset
7310
+ centerOffset: center - offset + alignmentOffset
7091
7311
  }
7092
7312
  };
7093
7313
  }
@@ -7433,7 +7653,13 @@ function isNode(value) {
7433
7653
  return value instanceof getWindow$1(value).Node;
7434
7654
  }
7435
7655
  function getNodeName(node) {
7436
- return isNode(node) ? (node.nodeName || '').toLowerCase() : '';
7656
+ if (isNode(node)) {
7657
+ return (node.nodeName || '').toLowerCase();
7658
+ }
7659
+ // Mocked nodes in testing environments may not be instances of Node. By
7660
+ // returning `#document` an infinite loop won't occur.
7661
+ // https://github.com/floating-ui/floating-ui/issues/2317
7662
+ return '#document';
7437
7663
  }
7438
7664
 
7439
7665
  function isHTMLElement$1(value) {
@@ -7447,8 +7673,7 @@ function isShadowRoot$1(node) {
7447
7673
  if (typeof ShadowRoot === 'undefined') {
7448
7674
  return false;
7449
7675
  }
7450
- const OwnElement = getWindow$1(node).ShadowRoot;
7451
- return node instanceof OwnElement || node instanceof ShadowRoot;
7676
+ return node instanceof getWindow$1(node).ShadowRoot || node instanceof ShadowRoot;
7452
7677
  }
7453
7678
  function isOverflowElement(element) {
7454
7679
  const {
@@ -7480,6 +7705,11 @@ function isLastTraversableNode(node) {
7480
7705
  const min = Math.min;
7481
7706
  const max = Math.max;
7482
7707
  const round = Math.round;
7708
+ const floor = Math.floor;
7709
+ const createEmptyCoords = v => ({
7710
+ x: v,
7711
+ y: v
7712
+ });
7483
7713
 
7484
7714
  function getCssDimensions(element) {
7485
7715
  const css = getComputedStyle$1(element);
@@ -7498,7 +7728,7 @@ function getCssDimensions(element) {
7498
7728
  return {
7499
7729
  width,
7500
7730
  height,
7501
- fallback: shouldFallback
7731
+ $: shouldFallback
7502
7732
  };
7503
7733
  }
7504
7734
 
@@ -7506,23 +7736,19 @@ function unwrapElement(element) {
7506
7736
  return !isElement$1(element) ? element.contextElement : element;
7507
7737
  }
7508
7738
 
7509
- const FALLBACK_SCALE = {
7510
- x: 1,
7511
- y: 1
7512
- };
7513
7739
  function getScale(element) {
7514
7740
  const domElement = unwrapElement(element);
7515
7741
  if (!isHTMLElement$1(domElement)) {
7516
- return FALLBACK_SCALE;
7742
+ return createEmptyCoords(1);
7517
7743
  }
7518
7744
  const rect = domElement.getBoundingClientRect();
7519
7745
  const {
7520
7746
  width,
7521
7747
  height,
7522
- fallback
7748
+ $
7523
7749
  } = getCssDimensions(domElement);
7524
- let x = (fallback ? round(rect.width) : rect.width) / width;
7525
- let y = (fallback ? round(rect.height) : rect.height) / height;
7750
+ let x = ($ ? round(rect.width) : rect.width) / width;
7751
+ let y = ($ ? round(rect.height) : rect.height) / height;
7526
7752
 
7527
7753
  // 0, NaN, or Infinity should always fallback to 1.
7528
7754
 
@@ -7538,10 +7764,7 @@ function getScale(element) {
7538
7764
  };
7539
7765
  }
7540
7766
 
7541
- const noOffsets = {
7542
- x: 0,
7543
- y: 0
7544
- };
7767
+ const noOffsets = /*#__PURE__*/createEmptyCoords(0);
7545
7768
  function getVisualOffsets(element, isFixed, floatingOffsetParent) {
7546
7769
  var _win$visualViewport, _win$visualViewport2;
7547
7770
  if (isFixed === void 0) {
@@ -7569,7 +7792,7 @@ function getBoundingClientRect(element, includeScale, isFixedStrategy, offsetPar
7569
7792
  }
7570
7793
  const clientRect = element.getBoundingClientRect();
7571
7794
  const domElement = unwrapElement(element);
7572
- let scale = FALLBACK_SCALE;
7795
+ let scale = createEmptyCoords(1);
7573
7796
  if (includeScale) {
7574
7797
  if (offsetParent) {
7575
7798
  if (isElement$1(offsetParent)) {
@@ -7592,14 +7815,14 @@ function getBoundingClientRect(element, includeScale, isFixedStrategy, offsetPar
7592
7815
  const iframeScale = getScale(currentIFrame);
7593
7816
  const iframeRect = currentIFrame.getBoundingClientRect();
7594
7817
  const css = getComputedStyle(currentIFrame);
7595
- iframeRect.x += (currentIFrame.clientLeft + parseFloat(css.paddingLeft)) * iframeScale.x;
7596
- iframeRect.y += (currentIFrame.clientTop + parseFloat(css.paddingTop)) * iframeScale.y;
7818
+ const left = iframeRect.left + (currentIFrame.clientLeft + parseFloat(css.paddingLeft)) * iframeScale.x;
7819
+ const top = iframeRect.top + (currentIFrame.clientTop + parseFloat(css.paddingTop)) * iframeScale.y;
7597
7820
  x *= iframeScale.x;
7598
7821
  y *= iframeScale.y;
7599
7822
  width *= iframeScale.x;
7600
7823
  height *= iframeScale.y;
7601
- x += iframeRect.x;
7602
- y += iframeRect.y;
7824
+ x += left;
7825
+ y += top;
7603
7826
  currentIFrame = getWindow$1(currentIFrame).frameElement;
7604
7827
  }
7605
7828
  }
@@ -7643,14 +7866,8 @@ function convertOffsetParentRelativeRectToViewportRelativeRect(_ref) {
7643
7866
  scrollLeft: 0,
7644
7867
  scrollTop: 0
7645
7868
  };
7646
- let scale = {
7647
- x: 1,
7648
- y: 1
7649
- };
7650
- const offsets = {
7651
- x: 0,
7652
- y: 0
7653
- };
7869
+ let scale = createEmptyCoords(1);
7870
+ const offsets = createEmptyCoords(0);
7654
7871
  if (isOffsetParentAnElement || !isOffsetParentAnElement && strategy !== 'fixed') {
7655
7872
  if (getNodeName(offsetParent) !== 'body' || isOverflowElement(documentElement)) {
7656
7873
  scroll = getNodeScroll(offsetParent);
@@ -7716,9 +7933,7 @@ function getParentNode(node) {
7716
7933
  function getNearestOverflowAncestor(node) {
7717
7934
  const parentNode = getParentNode(node);
7718
7935
  if (isLastTraversableNode(parentNode)) {
7719
- // `getParentNode` will never return a `Document` due to the fallback
7720
- // check, so it's either the <html> or <body> element.
7721
- return parentNode.ownerDocument.body;
7936
+ return node.ownerDocument ? node.ownerDocument.body : node.body;
7722
7937
  }
7723
7938
  if (isHTMLElement$1(parentNode) && isOverflowElement(parentNode)) {
7724
7939
  return parentNode;
@@ -7770,10 +7985,7 @@ function getInnerBoundingClientRect(element, strategy) {
7770
7985
  const clientRect = getBoundingClientRect(element, true, strategy === 'fixed');
7771
7986
  const top = clientRect.top + element.clientTop;
7772
7987
  const left = clientRect.left + element.clientLeft;
7773
- const scale = isHTMLElement$1(element) ? getScale(element) : {
7774
- x: 1,
7775
- y: 1
7776
- };
7988
+ const scale = isHTMLElement$1(element) ? getScale(element) : createEmptyCoords(1);
7777
7989
  const width = element.clientWidth * scale.x;
7778
7990
  const height = element.clientHeight * scale.y;
7779
7991
  const x = left * scale.x;
@@ -7924,10 +8136,7 @@ function getRectRelativeToOffsetParent(element, offsetParent, strategy) {
7924
8136
  scrollLeft: 0,
7925
8137
  scrollTop: 0
7926
8138
  };
7927
- const offsets = {
7928
- x: 0,
7929
- y: 0
7930
- };
8139
+ const offsets = createEmptyCoords(0);
7931
8140
  if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
7932
8141
  if (getNodeName(offsetParent) !== 'body' || isOverflowElement(documentElement)) {
7933
8142
  scroll = getNodeScroll(offsetParent);
@@ -7977,6 +8186,67 @@ const platform = {
7977
8186
  isRTL: element => getComputedStyle$1(element).direction === 'rtl'
7978
8187
  };
7979
8188
 
8189
+ // https://samthor.au/2021/observing-dom/
8190
+ function observeMove(element, onMove) {
8191
+ let io = null;
8192
+ let timeoutId;
8193
+ const root = getDocumentElement(element);
8194
+ function cleanup() {
8195
+ clearTimeout(timeoutId);
8196
+ io && io.disconnect();
8197
+ io = null;
8198
+ }
8199
+ function refresh(skip, threshold) {
8200
+ if (skip === void 0) {
8201
+ skip = false;
8202
+ }
8203
+ if (threshold === void 0) {
8204
+ threshold = 1;
8205
+ }
8206
+ cleanup();
8207
+ const {
8208
+ left,
8209
+ top,
8210
+ width,
8211
+ height
8212
+ } = element.getBoundingClientRect();
8213
+ if (!skip) {
8214
+ onMove();
8215
+ }
8216
+ if (!width || !height) {
8217
+ return;
8218
+ }
8219
+ const insetTop = floor(top);
8220
+ const insetRight = floor(root.clientWidth - (left + width));
8221
+ const insetBottom = floor(root.clientHeight - (top + height));
8222
+ const insetLeft = floor(left);
8223
+ const rootMargin = -insetTop + "px " + -insetRight + "px " + -insetBottom + "px " + -insetLeft + "px";
8224
+ let isFirstUpdate = true;
8225
+ io = new IntersectionObserver(entries => {
8226
+ const ratio = entries[0].intersectionRatio;
8227
+ if (ratio !== threshold) {
8228
+ if (!isFirstUpdate) {
8229
+ return refresh();
8230
+ }
8231
+ if (!ratio) {
8232
+ timeoutId = setTimeout(() => {
8233
+ refresh(false, 1e-7);
8234
+ }, 100);
8235
+ } else {
8236
+ refresh(false, ratio);
8237
+ }
8238
+ }
8239
+ isFirstUpdate = false;
8240
+ }, {
8241
+ rootMargin,
8242
+ threshold: max(0, min(1, threshold)) || 1
8243
+ });
8244
+ io.observe(element);
8245
+ }
8246
+ refresh(true);
8247
+ return cleanup;
8248
+ }
8249
+
7980
8250
  /**
7981
8251
  * Automatically updates the position of the floating element when necessary.
7982
8252
  * Should only be called when the floating element is mounted on the DOM or
@@ -7993,29 +8263,25 @@ function autoUpdate(reference, floating, update, options) {
7993
8263
  ancestorScroll = true,
7994
8264
  ancestorResize = true,
7995
8265
  elementResize = true,
8266
+ layoutShift = typeof IntersectionObserver === 'function',
7996
8267
  animationFrame = false
7997
8268
  } = options;
7998
- const ancestors = ancestorScroll || ancestorResize ? [...(isElement$1(reference) ? getOverflowAncestors(reference) : reference.contextElement ? getOverflowAncestors(reference.contextElement) : []), ...getOverflowAncestors(floating)] : [];
8269
+ const referenceEl = unwrapElement(reference);
8270
+ const ancestors = ancestorScroll || ancestorResize ? [...(referenceEl ? getOverflowAncestors(referenceEl) : []), ...getOverflowAncestors(floating)] : [];
7999
8271
  ancestors.forEach(ancestor => {
8000
- // ignores Window, checks for [object VisualViewport]
8001
- const isVisualViewport = !isElement$1(ancestor) && ancestor.toString().includes('V');
8002
- if (ancestorScroll && (animationFrame ? isVisualViewport : true)) {
8003
- ancestor.addEventListener('scroll', update, {
8004
- passive: true
8005
- });
8006
- }
8272
+ ancestorScroll && ancestor.addEventListener('scroll', update, {
8273
+ passive: true
8274
+ });
8007
8275
  ancestorResize && ancestor.addEventListener('resize', update);
8008
8276
  });
8009
- let observer = null;
8277
+ const cleanupIo = referenceEl && layoutShift ? observeMove(referenceEl, update) : null;
8278
+ let resizeObserver = null;
8010
8279
  if (elementResize) {
8011
- observer = new ResizeObserver(() => {
8012
- update();
8013
- });
8014
- isElement$1(reference) && !animationFrame && observer.observe(reference);
8015
- if (!isElement$1(reference) && reference.contextElement && !animationFrame) {
8016
- observer.observe(reference.contextElement);
8280
+ resizeObserver = new ResizeObserver(update);
8281
+ if (referenceEl && !animationFrame) {
8282
+ resizeObserver.observe(referenceEl);
8017
8283
  }
8018
- observer.observe(floating);
8284
+ resizeObserver.observe(floating);
8019
8285
  }
8020
8286
  let frameId;
8021
8287
  let prevRefRect = animationFrame ? getBoundingClientRect(reference) : null;
@@ -8032,13 +8298,13 @@ function autoUpdate(reference, floating, update, options) {
8032
8298
  }
8033
8299
  update();
8034
8300
  return () => {
8035
- var _observer;
8036
8301
  ancestors.forEach(ancestor => {
8037
8302
  ancestorScroll && ancestor.removeEventListener('scroll', update);
8038
8303
  ancestorResize && ancestor.removeEventListener('resize', update);
8039
8304
  });
8040
- (_observer = observer) == null ? void 0 : _observer.disconnect();
8041
- observer = null;
8305
+ cleanupIo && cleanupIo();
8306
+ resizeObserver && resizeObserver.disconnect();
8307
+ resizeObserver = null;
8042
8308
  if (animationFrame) {
8043
8309
  cancelAnimationFrame(frameId);
8044
8310
  }
@@ -10212,7 +10478,7 @@ const StyledLink = styled.a`
10212
10478
  }
10213
10479
  `;
10214
10480
 
10215
- const _excluded$7 = ["children", "className", "href", "isDisabled"];
10481
+ const _excluded$7 = ["as", "children", "className", "href", "isDisabled"];
10216
10482
  const COMPONENT_NAME$7 = 'Link';
10217
10483
  const CLASSNAME$7 = 'redsift-link';
10218
10484
  const DEFAULT_PROPS$7 = {};
@@ -10227,6 +10493,7 @@ const DEFAULT_PROPS$7 = {};
10227
10493
  */
10228
10494
  const Link = /*#__PURE__*/forwardRef((props, ref) => {
10229
10495
  const {
10496
+ as,
10230
10497
  children,
10231
10498
  className,
10232
10499
  href,
@@ -10234,6 +10501,7 @@ const Link = /*#__PURE__*/forwardRef((props, ref) => {
10234
10501
  } = props,
10235
10502
  forwardedProps = _objectWithoutProperties(props, _excluded$7);
10236
10503
  return /*#__PURE__*/React__default.createElement(StyledLink, _extends$1({
10504
+ as: as,
10237
10505
  "aria-disabled": isDisabled,
10238
10506
  role: "link",
10239
10507
  tabIndex: !isDisabled ? 0 : undefined