@deque/cauldron-react 6.11.0 → 6.12.0-canary.67739754

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.
@@ -0,0 +1,20 @@
1
+ import { type Placement } from '@floating-ui/dom';
2
+ import React from 'react';
3
+ declare const AnchoredOverlay: React.ForwardRefExoticComponent<{
4
+ /** A target element or ref to attach the overlay anchor element. */
5
+ target: HTMLElement | React.RefObject<HTMLElement> | React.MutableRefObject<HTMLElement>;
6
+ /** Positional placement value to anchor the overlay element relative to its anchored target. */
7
+ placement?: "auto" | Placement | "auto-start" | "auto-end" | undefined;
8
+ /** Determines if the overlay anchor is currently visible. */
9
+ open?: boolean | undefined;
10
+ /** A callback function that is called when the overlay state changes. */
11
+ onOpenChange?: ((open: boolean) => void) | undefined;
12
+ /** A callback function that is called when the placement of the overlay changes. */
13
+ onPlacementChange?: ((placement: Placement) => void) | undefined;
14
+ /** An optional offset number to position the anchor element from its anchored target. */
15
+ offset?: number | undefined;
16
+ children?: React.ReactNode;
17
+ } & React.HTMLAttributes<HTMLElement> & {
18
+ as?: React.ElementType<any, keyof React.JSX.IntrinsicElements> | undefined;
19
+ } & React.RefAttributes<HTMLElement>>;
20
+ export default AnchoredOverlay;
@@ -2,15 +2,29 @@ import React from 'react';
2
2
  import type { ListboxOption } from './ListboxContext';
3
3
  import type { ListboxValue } from './ListboxOption';
4
4
  import type { PolymorphicProps, PolymorphicComponent } from '../../utils/polymorphicComponent';
5
- interface ListboxProps extends PolymorphicProps<Omit<React.HTMLAttributes<HTMLElement>, 'onSelect'>> {
6
- value?: ListboxValue;
5
+ interface BaseListboxProps extends PolymorphicProps<Omit<React.HTMLAttributes<HTMLElement>, 'onSelect' | 'defaultValue'>> {
7
6
  navigation?: 'cycle' | 'bound';
8
- onSelectionChange?: <T extends HTMLElement = HTMLElement>({ value }: {
7
+ onActiveChange?: (option: ListboxOption) => void;
8
+ }
9
+ interface SingleSelectListboxProps extends BaseListboxProps {
10
+ multiselect?: false;
11
+ value?: ListboxValue;
12
+ defaultValue?: ListboxValue;
13
+ onSelectionChange?: <T extends HTMLElement = HTMLElement>(props: {
9
14
  target: T;
10
15
  previousValue: ListboxValue;
11
16
  value: ListboxValue;
12
17
  }) => void;
13
- onActiveChange?: (option: ListboxOption) => void;
14
18
  }
15
- declare const Listbox: PolymorphicComponent<ListboxProps>;
19
+ interface MultiSelectListboxProps extends BaseListboxProps {
20
+ multiselect: true;
21
+ value?: ListboxValue[];
22
+ defaultValue?: ListboxValue[];
23
+ onSelectionChange?: <T extends HTMLElement = HTMLElement>(props: {
24
+ target: T;
25
+ previousValue: ListboxValue[];
26
+ value: ListboxValue[];
27
+ }) => void;
28
+ }
29
+ declare const Listbox: PolymorphicComponent<SingleSelectListboxProps | MultiSelectListboxProps>;
16
30
  export default Listbox;
@@ -8,7 +8,8 @@ type ListboxOption<Element = HTMLElement, Value = string | number> = {
8
8
  type ListboxContext<T extends ListboxOption> = {
9
9
  options: T[];
10
10
  active: T | null;
11
- selected: T | null;
11
+ selected: T[] | null;
12
+ multiselect: boolean;
12
13
  setOptions: React.Dispatch<React.SetStateAction<T[]>>;
13
14
  onSelect: (option: T) => void;
14
15
  };
@@ -19,9 +20,10 @@ declare const ListboxContext: React.Context<{
19
20
  options: never[];
20
21
  active: null;
21
22
  selected: null;
23
+ multiselect: boolean;
22
24
  setOptions: () => null;
23
25
  onSelect: () => null;
24
26
  }>;
25
- declare function ListboxProvider<T extends ListboxOption>({ options, active, selected, setOptions, onSelect, children }: ListboxProvider<T>): React.JSX.Element;
27
+ declare function ListboxProvider<T extends ListboxOption>({ options, active, selected, multiselect, setOptions, onSelect, children }: ListboxProvider<T>): React.JSX.Element;
26
28
  declare function useListboxContext<T extends ListboxOption>(): ListboxContext<T>;
27
29
  export { ListboxProvider, useListboxContext, ListboxOption };
@@ -4,6 +4,7 @@ export type ListboxValue = Readonly<string | number | undefined>;
4
4
  interface ListboxOptionProps extends PolymorphicProps<React.HTMLAttributes<HTMLElement>> {
5
5
  value?: ListboxValue;
6
6
  disabled?: boolean;
7
+ selected?: boolean;
7
8
  activeClass?: string;
8
9
  }
9
10
  declare const ListboxOption: PolymorphicComponent<ListboxOptionProps>;
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { Placement } from '@popperjs/core';
2
+ import type AnchoredOverlay from '../AnchoredOverlay';
3
3
  import { ContentNode } from '../../types';
4
4
  interface Props extends React.HTMLAttributes<HTMLDivElement> {
5
5
  totalItems: number;
@@ -15,7 +15,7 @@ interface Props extends React.HTMLAttributes<HTMLDivElement> {
15
15
  onPreviousPageClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;
16
16
  onFirstPageClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;
17
17
  onLastPageClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;
18
- tooltipPlacement?: Placement;
18
+ tooltipPlacement?: React.ComponentProps<typeof AnchoredOverlay>['placement'];
19
19
  thin?: boolean;
20
20
  className?: string;
21
21
  }
@@ -1,13 +1,13 @@
1
1
  import React, { ReactNode } from 'react';
2
- import { Placement } from '@popperjs/core';
3
2
  import { Cauldron } from '../../types';
3
+ import AnchoredOverlay from '../AnchoredOverlay';
4
4
  export type PopoverVariant = 'prompt' | 'custom';
5
5
  type BaseProps = React.HTMLAttributes<HTMLDivElement> & {
6
6
  target: React.RefObject<HTMLElement> | HTMLElement;
7
7
  variant?: PopoverVariant;
8
8
  show: boolean;
9
9
  onClose: () => void;
10
- placement?: Placement;
10
+ placement?: React.ComponentProps<typeof AnchoredOverlay>['placement'];
11
11
  portal?: React.RefObject<HTMLElement> | HTMLElement;
12
12
  };
13
13
  type CustomProps = BaseProps & {
@@ -1,9 +1,21 @@
1
- import React, { TableHTMLAttributes } from 'react';
2
- interface TableProps extends TableHTMLAttributes<HTMLTableElement> {
1
+ import React from 'react';
2
+ export type Column = {
3
+ align: ColumnAlignment;
4
+ width?: ColumnWidth;
5
+ };
6
+ export type ColumnAlignment = 'start' | 'center' | 'end';
7
+ export type ColumnWidth = 'auto' | 'min-content' | 'max-content' | `${number}` | `${number}%` | `${number}fr`;
8
+ export type RowAlignment = 'start' | 'center';
9
+ type TableBaseProps = {
10
+ layout: never;
11
+ columns: never;
12
+ variant?: 'border';
13
+ };
14
+ type TableGridProps = {
15
+ layout: 'grid';
16
+ columns?: Array<Column> | number;
3
17
  variant?: 'border';
4
- }
5
- declare const Table: {
6
- ({ children, className, variant, ...other }: TableProps): React.JSX.Element;
7
- displayName: string;
8
18
  };
19
+ type TableProps = (TableBaseProps | Partial<TableGridProps>) & React.TableHTMLAttributes<HTMLTableElement>;
20
+ declare const Table: React.ForwardRefExoticComponent<TableProps & React.RefAttributes<HTMLTableElement>>;
9
21
  export default Table;
@@ -1,6 +1,5 @@
1
- import React, { HTMLAttributes } from 'react';
2
- declare const TableBody: {
3
- ({ children, className, ...other }: HTMLAttributes<HTMLTableSectionElement>): React.JSX.Element;
4
- displayName: string;
5
- };
1
+ import React from 'react';
2
+ declare const TableBody: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableSectionElement> & {
3
+ className?: string | undefined;
4
+ } & React.RefAttributes<HTMLTableSectionElement>>;
6
5
  export default TableBody;
@@ -1,6 +1,7 @@
1
- import React, { TdHTMLAttributes } from 'react';
2
- declare const TableCell: {
3
- ({ children, className, ...other }: TdHTMLAttributes<HTMLTableCellElement>): React.JSX.Element;
4
- displayName: string;
5
- };
1
+ import type { ColumnAlignment } from './Table';
2
+ import React from 'react';
3
+ interface TableCellProps extends Omit<React.TdHTMLAttributes<HTMLTableDataCellElement>, 'align'> {
4
+ align?: ColumnAlignment;
5
+ }
6
+ declare const TableCell: React.ForwardRefExoticComponent<TableCellProps & React.RefAttributes<HTMLTableCellElement>>;
6
7
  export default TableCell;
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ import type { Column } from './Table';
3
+ type TableContext = {
4
+ layout: 'table' | 'grid';
5
+ columns: Array<Column>;
6
+ };
7
+ type TableProvider = {
8
+ children: React.ReactNode;
9
+ layout: 'table' | 'grid';
10
+ columns: Array<Column>;
11
+ };
12
+ declare const TableContext: React.Context<TableContext>;
13
+ declare function TableProvider({ children, layout, columns }: TableProvider): JSX.Element;
14
+ declare function useTable(): TableContext;
15
+ export { TableProvider, useTable };
@@ -1,6 +1,5 @@
1
- import React, { HTMLAttributes } from 'react';
2
- declare const TableFooter: {
3
- ({ children, className, ...other }: HTMLAttributes<HTMLTableSectionElement>): React.JSX.Element;
4
- displayName: string;
5
- };
1
+ import React from 'react';
2
+ declare const TableFooter: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableSectionElement> & {
3
+ className?: string | undefined;
4
+ } & React.RefAttributes<HTMLTableSectionElement>>;
6
5
  export default TableFooter;
@@ -1,6 +1,5 @@
1
- import React, { HTMLAttributes } from 'react';
2
- declare const TableHead: {
3
- ({ children, className, ...other }: HTMLAttributes<HTMLTableSectionElement>): React.JSX.Element;
4
- displayName: string;
5
- };
1
+ import React from 'react';
2
+ declare const TableHead: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableSectionElement> & {
3
+ className?: string | undefined;
4
+ } & React.RefAttributes<HTMLTableSectionElement>>;
6
5
  export default TableHead;
@@ -1,13 +1,12 @@
1
- import React, { ThHTMLAttributes } from 'react';
1
+ import type { ColumnAlignment } from './Table';
2
+ import React from 'react';
2
3
  type SortDirection = 'ascending' | 'descending' | 'none';
3
- interface TableHeaderProps extends ThHTMLAttributes<HTMLTableCellElement> {
4
+ interface TableHeaderProps extends Omit<React.ThHTMLAttributes<HTMLTableHeaderCellElement>, 'align'> {
4
5
  sortDirection?: SortDirection;
5
6
  onSort?: () => void;
6
7
  sortAscendingAnnouncement?: string;
7
8
  sortDescendingAnnouncement?: string;
9
+ align?: ColumnAlignment;
8
10
  }
9
- declare const TableHeader: {
10
- ({ children, sortDirection, onSort, className, sortAscendingAnnouncement, sortDescendingAnnouncement, ...other }: TableHeaderProps): React.JSX.Element;
11
- displayName: string;
12
- };
11
+ declare const TableHeader: React.ForwardRefExoticComponent<TableHeaderProps & React.RefAttributes<HTMLTableHeaderCellElement>>;
13
12
  export default TableHeader;
@@ -0,0 +1,10 @@
1
+ import type { useTable } from './TableContext';
2
+ import type { Column, ColumnAlignment } from './Table';
3
+ interface useTableGridStylesParameters<E extends HTMLTableCellElement = HTMLTableCellElement> {
4
+ elementRef: React.RefObject<E | null>;
5
+ align?: ColumnAlignment;
6
+ layout: ReturnType<typeof useTable>['layout'];
7
+ columns: Array<Column>;
8
+ }
9
+ export default function useTableGridStyles<E extends HTMLTableCellElement>({ elementRef, align, layout, columns }: useTableGridStylesParameters<E>): React.CSSProperties;
10
+ export {};
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { Placement } from '@popperjs/core';
2
+ import AnchoredOverlay from '../AnchoredOverlay';
3
3
  export interface TooltipProps extends React.HTMLAttributes<HTMLDivElement> {
4
4
  children: React.ReactNode;
5
5
  className?: string;
@@ -8,7 +8,7 @@ export interface TooltipProps extends React.HTMLAttributes<HTMLDivElement> {
8
8
  association?: 'aria-labelledby' | 'aria-describedby' | 'none';
9
9
  show?: boolean | undefined;
10
10
  defaultShow?: boolean;
11
- placement?: Placement;
11
+ placement?: React.ComponentProps<typeof AnchoredOverlay>['placement'];
12
12
  portal?: React.RefObject<HTMLElement> | HTMLElement;
13
13
  hideElementOnHidden?: boolean;
14
14
  }
package/lib/index.d.ts CHANGED
@@ -61,6 +61,7 @@ export { default as TextEllipsis } from './components/TextEllipsis';
61
61
  export { default as CopyButton } from './components/CopyButton';
62
62
  export { default as Drawer } from './components/Drawer';
63
63
  export { default as BottomSheet } from './components/BottomSheet';
64
+ export { default as AnchoredOverlay } from './components/AnchoredOverlay';
64
65
  /**
65
66
  * Helpers / Utils
66
67
  */
package/lib/index.js CHANGED
@@ -9,7 +9,8 @@ var nextId = require('react-id-generator');
9
9
  var keyname = require('keyname');
10
10
  var reactDom = require('react-dom');
11
11
  var FocusTrap = require('focus-trap-react');
12
- var reactPopper = require('react-popper');
12
+ var dom = require('@floating-ui/dom');
13
+ var reactDom$1 = require('@floating-ui/react-dom');
13
14
  var SyntaxHighlighter = require('react-syntax-highlighter/dist/cjs/light');
14
15
  var js = require('react-syntax-highlighter/dist/cjs/languages/hljs/javascript');
15
16
  var css = require('react-syntax-highlighter/dist/cjs/languages/hljs/css');
@@ -1282,7 +1283,7 @@ var SideBar = /** @class */ (function (_super) {
1282
1283
  }(React.Component));
1283
1284
 
1284
1285
  var SideBarItem = function (_a) {
1285
- var children = _a.children, autoClickLink = _a.autoClickLink, other = tslib.__rest(_a, ["children", "autoClickLink"]);
1286
+ var children = _a.children, _b = _a.autoClickLink, autoClickLink = _b === void 0 ? true : _b, other = tslib.__rest(_a, ["children", "autoClickLink"]);
1286
1287
  var onClick = function (e) {
1287
1288
  if (!autoClickLink) {
1288
1289
  return;
@@ -1294,9 +1295,6 @@ var SideBarItem = function (_a) {
1294
1295
  /* eslint-enable jsx-a11y/no-noninteractive-element-interactions, jsx-a11y/click-events-have-key-events */
1295
1296
  };
1296
1297
  SideBarItem.displayName = 'SideBarItem';
1297
- SideBarItem.defaultProps = {
1298
- autoClickLink: true
1299
- };
1300
1298
 
1301
1299
  /**
1302
1300
  * Handles aria-hidden for dialogs.
@@ -1587,40 +1585,25 @@ var Button = React.forwardRef(function (_a, ref) {
1587
1585
  Button.displayName = 'Button';
1588
1586
 
1589
1587
  /**
1590
- * Returns a unique set of id refs from the provided string
1591
- * @param ids - string of id refs
1592
- */
1593
- function idRefs(ids) {
1594
- if (!ids || !ids.trim()) {
1595
- return new Set();
1596
- }
1597
- return new Set(ids.trim().split(/\s+/));
1598
- }
1599
- /**
1600
- * Returns an updated id ref string with the provided id value added
1601
- * @param ids - string of id refs
1602
- * @param id - id to add
1603
- */
1604
- function addIdRef(ids, id) {
1605
- return tslib.__spreadArray([], tslib.__read(idRefs(ids).add(id)), false).join(' ');
1606
- }
1607
- /**
1608
- * Returns an updated id ref string with the provided id value removed
1609
- * @param ids - string of id refs
1610
- * @param id - id to remove
1611
- */
1612
- function removeIdRef(_ids, id) {
1613
- var ids = idRefs(_ids);
1614
- ids.delete(id);
1615
- return tslib.__spreadArray([], tslib.__read(ids), false).join(' ');
1616
- }
1617
- /**
1618
- * Returns if an id ref string contains the provided id value
1619
- * @param ids - string of id refs
1620
- * @param id - id to check if it exists in the provided idRef string
1588
+ * When a component needs to track an internal ref on a component that has a
1589
+ * forwarded ref, useSharedRef will return a MutableRefObject<T> that will
1590
+ * correctly invoke the parent ref as well providing an internal ref.
1591
+ *
1592
+ * @example
1593
+ * React.forwardRef(function Component({ children }, ref) {
1594
+ * const internalRef = useSharedRef<HTMLElement>(ref)
1595
+ * if (internalRef.current) {
1596
+ * // do something with the internal ref...
1597
+ * }
1598
+ * return (<div ref={internalRef}>...</div>)
1599
+ * })
1621
1600
  */
1622
- function hasIdRef(ids, id) {
1623
- return idRefs(ids).has(id);
1601
+ function useSharedRef(ref) {
1602
+ var internalRef = React.useRef();
1603
+ React.useEffect(function () {
1604
+ setRef(ref, internalRef.current);
1605
+ }, [ref]);
1606
+ return internalRef;
1624
1607
  }
1625
1608
 
1626
1609
  var isEscapeKey = function (event) {
@@ -1663,6 +1646,99 @@ function useEscapeKey(options, dependencies) {
1663
1646
  ], tslib.__read(dependencies), false));
1664
1647
  }
1665
1648
 
1649
+ function getAutoAlignment(placement) {
1650
+ switch (placement) {
1651
+ case 'auto-start':
1652
+ return 'start';
1653
+ case 'auto-end':
1654
+ return 'end';
1655
+ default:
1656
+ return null;
1657
+ }
1658
+ }
1659
+ var AnchoredOverlay = React.forwardRef(function (_a, refProp) {
1660
+ var as = _a.as, _b = _a.placement, initialPlacement = _b === void 0 ? 'auto' : _b, target = _a.target, children = _a.children, style = _a.style, _c = _a.open, open = _c === void 0 ? false : _c, offset = _a.offset, onOpenChange = _a.onOpenChange, onPlacementChange = _a.onPlacementChange, props = tslib.__rest(_a, ["as", "placement", "target", "children", "style", "open", "offset", "onOpenChange", "onPlacementChange"]);
1661
+ var ref = useSharedRef(refProp);
1662
+ var Component = as || 'div';
1663
+ var _d = reactDom$1.useFloating({
1664
+ open: open,
1665
+ // default to initial placement on top when placement is auto
1666
+ // @ts-expect-error auto placement is not a valid placement for floating-ui
1667
+ placement: initialPlacement.startsWith('auto') ? 'top' : initialPlacement,
1668
+ middleware: [
1669
+ reactDom$1.offset(offset !== null && offset !== void 0 ? offset : 0),
1670
+ initialPlacement.startsWith('auto')
1671
+ ? reactDom$1.autoPlacement({
1672
+ alignment: getAutoAlignment(initialPlacement)
1673
+ })
1674
+ : reactDom$1.flip()
1675
+ ].filter(Boolean),
1676
+ elements: {
1677
+ reference: resolveElement(target),
1678
+ floating: ref.current
1679
+ },
1680
+ whileElementsMounted: dom.autoUpdate
1681
+ }), floatingStyles = _d.floatingStyles, placement = _d.placement;
1682
+ useEscapeKey({
1683
+ active: open,
1684
+ capture: true,
1685
+ defaultPrevented: true,
1686
+ callback: function (event) {
1687
+ // when an anchored overlay is open, we want to prevent other potential "escape"
1688
+ // keypress events, like the closing of modals from occurring
1689
+ event.preventDefault();
1690
+ // istanbul ignore else
1691
+ if (typeof onOpenChange === 'function') {
1692
+ onOpenChange(!open);
1693
+ }
1694
+ }
1695
+ });
1696
+ React.useEffect(function () {
1697
+ if (typeof onPlacementChange === 'function') {
1698
+ onPlacementChange(placement);
1699
+ }
1700
+ }, [placement]);
1701
+ return (React__default["default"].createElement(Component, tslib.__assign({ ref: ref }, props, { style: tslib.__assign(tslib.__assign({}, floatingStyles), style) }), children));
1702
+ });
1703
+ AnchoredOverlay.displayName = 'AnchoredOverlay';
1704
+
1705
+ /**
1706
+ * Returns a unique set of id refs from the provided string
1707
+ * @param ids - string of id refs
1708
+ */
1709
+ function idRefs(ids) {
1710
+ if (!ids || !ids.trim()) {
1711
+ return new Set();
1712
+ }
1713
+ return new Set(ids.trim().split(/\s+/));
1714
+ }
1715
+ /**
1716
+ * Returns an updated id ref string with the provided id value added
1717
+ * @param ids - string of id refs
1718
+ * @param id - id to add
1719
+ */
1720
+ function addIdRef(ids, id) {
1721
+ return tslib.__spreadArray([], tslib.__read(idRefs(ids).add(id)), false).join(' ');
1722
+ }
1723
+ /**
1724
+ * Returns an updated id ref string with the provided id value removed
1725
+ * @param ids - string of id refs
1726
+ * @param id - id to remove
1727
+ */
1728
+ function removeIdRef(_ids, id) {
1729
+ var ids = idRefs(_ids);
1730
+ ids.delete(id);
1731
+ return tslib.__spreadArray([], tslib.__read(ids), false).join(' ');
1732
+ }
1733
+ /**
1734
+ * Returns if an id ref string contains the provided id value
1735
+ * @param ids - string of id refs
1736
+ * @param id - id to check if it exists in the provided idRef string
1737
+ */
1738
+ function hasIdRef(ids, id) {
1739
+ return idRefs(ids).has(id);
1740
+ }
1741
+
1666
1742
  var TIP_HIDE_DELAY = 100;
1667
1743
  // fires a custom "cauldron:tooltip:show" / "cauldron:tooltip:hide" event
1668
1744
  // to allow projects using cauldron to hook into when a tooltip is shown/hidden
@@ -1681,50 +1757,27 @@ function Tooltip(_a) {
1681
1757
  var _g = tslib.__read(propId ? [propId] : nextId.useId(1, 'tooltip'), 1), id = _g[0];
1682
1758
  var hideTimeoutRef = React.useRef(null);
1683
1759
  var _h = tslib.__read(React.useState(!!showProp || defaultShow), 2), showTooltip = _h[0], setShowTooltip = _h[1];
1684
- var _j = tslib.__read(React.useState(null), 2), targetElement = _j[0], setTargetElement = _j[1];
1685
- var _k = tslib.__read(React.useState(null), 2), tooltipElement = _k[0], setTooltipElement = _k[1];
1686
- var _l = tslib.__read(React.useState(null), 2), arrowElement = _l[0], setArrowElement = _l[1];
1760
+ var _j = tslib.__read(React.useState(null), 2), tooltipElement = _j[0], setTooltipElement = _j[1];
1761
+ var _k = tslib.__read(React.useState(initialPlacement), 2), placement = _k[0], setPlacement = _k[1];
1687
1762
  var hasAriaAssociation = association !== 'none';
1688
- var _m = reactPopper.usePopper(targetElement, tooltipElement, {
1689
- placement: initialPlacement,
1690
- modifiers: [
1691
- { name: 'preventOverflow', options: { padding: 8 } },
1692
- {
1693
- name: 'flip',
1694
- options: { fallbackPlacements: ['left', 'right', 'top', 'bottom'] }
1695
- },
1696
- { name: 'offset', options: { offset: [0, 8] } },
1697
- { name: 'arrow', options: { padding: 5, element: arrowElement } }
1698
- ]
1699
- }), styles = _m.styles, attributes = _m.attributes, update = _m.update;
1700
1763
  // Show the tooltip
1701
1764
  var show = React.useCallback(function () { return tslib.__awaiter(_this, void 0, void 0, function () {
1765
+ var targetElement;
1702
1766
  return tslib.__generator(this, function (_a) {
1703
- switch (_a.label) {
1704
- case 0:
1705
- // Clear the hide timeout if there was one pending
1706
- if (hideTimeoutRef.current) {
1707
- clearTimeout(hideTimeoutRef.current);
1708
- hideTimeoutRef.current = null;
1709
- }
1710
- if (!update) return [3 /*break*/, 2];
1711
- return [4 /*yield*/, update()];
1712
- case 1:
1713
- _a.sent();
1714
- _a.label = 2;
1715
- case 2:
1716
- setShowTooltip(true);
1717
- fireCustomEvent(true, targetElement);
1718
- return [2 /*return*/];
1767
+ targetElement = resolveElement(target);
1768
+ // Clear the hide timeout if there was one pending
1769
+ if (hideTimeoutRef.current) {
1770
+ clearTimeout(hideTimeoutRef.current);
1771
+ hideTimeoutRef.current = null;
1719
1772
  }
1773
+ setShowTooltip(true);
1774
+ fireCustomEvent(true, targetElement);
1775
+ return [2 /*return*/];
1720
1776
  });
1721
- }); }, [
1722
- targetElement,
1723
- // update starts off as null
1724
- update
1725
- ]);
1777
+ }); }, [target]);
1726
1778
  // Hide the tooltip
1727
1779
  var hide = React.useCallback(function () {
1780
+ var targetElement = resolveElement(target);
1728
1781
  if (!hideTimeoutRef.current) {
1729
1782
  hideTimeoutRef.current = setTimeout(function () {
1730
1783
  hideTimeoutRef.current = null;
@@ -1735,32 +1788,15 @@ function Tooltip(_a) {
1735
1788
  return function () {
1736
1789
  clearTimeout(hideTimeoutRef.current);
1737
1790
  };
1738
- }, [targetElement]);
1739
- // Keep targetElement in sync with target prop
1740
- React.useEffect(function () {
1741
- var targetElement = target && 'current' in target ? target.current : target;
1742
- setTargetElement(targetElement);
1743
1791
  }, [target]);
1744
1792
  React.useEffect(function () {
1745
1793
  if (typeof showProp === 'boolean') {
1746
1794
  setShowTooltip(showProp);
1747
1795
  }
1748
1796
  }, [showProp]);
1749
- // Get popper placement
1750
- var placement = (attributes.popper &&
1751
- attributes.popper['data-popper-placement']) ||
1752
- initialPlacement;
1753
- // Only listen to key ups when the tooltip is visible
1754
- useEscapeKey({
1755
- callback: function (event) {
1756
- event.preventDefault();
1757
- setShowTooltip(false);
1758
- },
1759
- capture: true,
1760
- active: showTooltip && typeof showProp !== 'boolean'
1761
- }, [setShowTooltip]);
1762
1797
  // Handle hover and focus events for the targetElement
1763
1798
  React.useEffect(function () {
1799
+ var targetElement = resolveElement(target);
1764
1800
  if (typeof showProp !== 'boolean') {
1765
1801
  targetElement === null || targetElement === void 0 ? void 0 : targetElement.addEventListener('mouseenter', show);
1766
1802
  targetElement === null || targetElement === void 0 ? void 0 : targetElement.addEventListener('mouseleave', hide);
@@ -1773,7 +1809,7 @@ function Tooltip(_a) {
1773
1809
  targetElement === null || targetElement === void 0 ? void 0 : targetElement.removeEventListener('focusin', show);
1774
1810
  targetElement === null || targetElement === void 0 ? void 0 : targetElement.removeEventListener('focusout', hide);
1775
1811
  };
1776
- }, [targetElement, show, hide, showProp]);
1812
+ }, [target, show, hide, showProp]);
1777
1813
  // Handle hover events for the tooltipElement
1778
1814
  React.useEffect(function () {
1779
1815
  if (typeof showProp !== 'boolean') {
@@ -1787,6 +1823,7 @@ function Tooltip(_a) {
1787
1823
  }, [tooltipElement, show, hide, showProp]);
1788
1824
  // Keep the target's id in sync
1789
1825
  React.useEffect(function () {
1826
+ var targetElement = resolveElement(target);
1790
1827
  if (hasAriaAssociation) {
1791
1828
  var idRefs = targetElement === null || targetElement === void 0 ? void 0 : targetElement.getAttribute(association);
1792
1829
  if (!hasIdRef(idRefs, id)) {
@@ -1799,14 +1836,14 @@ function Tooltip(_a) {
1799
1836
  targetElement.setAttribute(association, removeIdRef(idRefs, id));
1800
1837
  }
1801
1838
  };
1802
- }, [targetElement, id, association]);
1839
+ }, [target, id, association]);
1803
1840
  return (React__default["default"].createElement(React__default["default"].Fragment, null, (showTooltip || hideElementOnHidden) && isBrowser()
1804
- ? reactDom.createPortal(React__default["default"].createElement("div", tslib.__assign({ id: id, className: classNames__default["default"]('Tooltip', "Tooltip--".concat(placement), className, {
1841
+ ? reactDom.createPortal(React__default["default"].createElement(AnchoredOverlay, tslib.__assign({ id: id, target: target, placement: initialPlacement, onPlacementChange: setPlacement, open: showTooltip && typeof showProp !== 'boolean', onOpenChange: setShowTooltip, className: classNames__default["default"]('Tooltip', "Tooltip--".concat(placement), className, {
1805
1842
  TooltipInfo: variant === 'info',
1806
1843
  'Tooltip--hidden': !showTooltip && hideElementOnHidden,
1807
1844
  'Tooltip--big': variant === 'big'
1808
- }), ref: setTooltipElement, role: "tooltip", style: styles.popper }, attributes.popper, props),
1809
- variant !== 'big' && (React__default["default"].createElement("div", { className: "TooltipArrow", ref: setArrowElement, style: styles.arrow })),
1845
+ }), ref: setTooltipElement, role: "tooltip", offset: 8 }, props),
1846
+ variant !== 'big' && React__default["default"].createElement("div", { className: "TooltipArrow" }),
1810
1847
  children), (portal && 'current' in portal ? portal.current : portal) ||
1811
1848
  (
1812
1849
  // eslint-disable-next-line ssr-friendly/no-dom-globals-in-react-fc
@@ -2522,28 +2559,6 @@ var SearchField = React.forwardRef(function (_a, ref) {
2522
2559
  });
2523
2560
  SearchField.displayName = 'SearchField';
2524
2561
 
2525
- /**
2526
- * When a component needs to track an internal ref on a component that has a
2527
- * forwarded ref, useSharedRef will return a MutableRefObject<T> that will
2528
- * correctly invoke the parent ref as well providing an internal ref.
2529
- *
2530
- * @example
2531
- * React.forwardRef(function Component({ children }, ref) {
2532
- * const internalRef = useSharedRef<HTMLElement>(ref)
2533
- * if (internalRef.current) {
2534
- * // do something with the internal ref...
2535
- * }
2536
- * return (<div ref={internalRef}>...</div>)
2537
- * })
2538
- */
2539
- function useSharedRef(ref) {
2540
- var internalRef = React.useRef();
2541
- React.useEffect(function () {
2542
- setRef(ref, internalRef.current);
2543
- }, [ref]);
2544
- return internalRef;
2545
- }
2546
-
2547
2562
  function copyTextToClipboard(text) {
2548
2563
  return tslib.__awaiter(this, void 0, void 0, function () {
2549
2564
  var copied, element, range, selection;
@@ -2783,32 +2798,138 @@ var TagButton = React__default["default"].forwardRef(function (_a, ref) {
2783
2798
  });
2784
2799
  TagButton.displayName = 'TagButton';
2785
2800
 
2786
- var Table = function (_a) {
2787
- var children = _a.children, className = _a.className, variant = _a.variant, other = tslib.__rest(_a, ["children", "className", "variant"]);
2788
- return (React__default["default"].createElement("table", tslib.__assign({ className: classNames__default["default"]('Table', variant === 'border' && 'Table--border', className) }, other), children));
2789
- };
2801
+ var TableContext = React.createContext({
2802
+ layout: 'table',
2803
+ columns: []
2804
+ });
2805
+ function TableProvider(_a) {
2806
+ var children = _a.children, layout = _a.layout, columns = _a.columns;
2807
+ var Provider = TableContext.Provider;
2808
+ var contextValue = React.useMemo(function () { return ({
2809
+ layout: layout,
2810
+ columns: columns
2811
+ }); }, [layout, columns]);
2812
+ return React__default["default"].createElement(Provider, { value: contextValue }, children);
2813
+ }
2814
+ function useTable() {
2815
+ return React.useContext(TableContext);
2816
+ }
2817
+
2818
+ var Table = React__default["default"].forwardRef(function (_a, ref) {
2819
+ var children = _a.children, className = _a.className, variant = _a.variant, layout = _a.layout, _b = _a.columns, columnsProp = _b === void 0 ? [] : _b, style = _a.style, other = tslib.__rest(_a, ["children", "className", "variant", "layout", "columns", "style"]);
2820
+ var isGridLayout = layout === 'grid';
2821
+ var columns = React.useMemo(function () {
2822
+ if (typeof columnsProp === 'number') {
2823
+ return columnsProp > 0
2824
+ ? Array(columnsProp).fill({ align: 'start' })
2825
+ : [{ align: 'start' }];
2826
+ }
2827
+ return columnsProp;
2828
+ }, [columnsProp]);
2829
+ var styleTemplateColumns = React.useMemo(function () {
2830
+ if (layout !== 'grid') {
2831
+ return;
2832
+ }
2833
+ if (!columns) {
2834
+ return 'auto';
2835
+ }
2836
+ return columns
2837
+ .map(function (_a) {
2838
+ var width = _a.width;
2839
+ return width || 'auto';
2840
+ })
2841
+ .join(' ');
2842
+ }, [layout, columns]);
2843
+ var tableGridStyles = isGridLayout
2844
+ ? {
2845
+ '--table-grid-template-columns': styleTemplateColumns
2846
+ }
2847
+ : {};
2848
+ return (React__default["default"].createElement("table", tslib.__assign({ ref: ref, style: tslib.__assign(tslib.__assign({}, tableGridStyles), style), className: classNames__default["default"]('Table', className, {
2849
+ 'Table--border': variant === 'border',
2850
+ TableGrid: isGridLayout
2851
+ }) }, other),
2852
+ React__default["default"].createElement(TableProvider, { layout: isGridLayout ? 'grid' : 'table', columns: columns }, children)));
2853
+ });
2790
2854
  Table.displayName = 'Table';
2791
2855
 
2792
- var TableBody = function (_a) {
2856
+ var TableBody = React.forwardRef(function (_a, ref) {
2793
2857
  var children = _a.children, className = _a.className, other = tslib.__rest(_a, ["children", "className"]);
2794
- return (React__default["default"].createElement("tbody", tslib.__assign({ className: classNames__default["default"]('TableBody', className) }, other), children));
2795
- };
2858
+ return (React__default["default"].createElement("tbody", tslib.__assign({ ref: ref, className: classNames__default["default"]('TableBody', className) }, other), children));
2859
+ });
2796
2860
  TableBody.displayName = 'TableBody';
2797
2861
 
2798
- var TableCell = function (_a) {
2799
- var children = _a.children, className = _a.className, other = tslib.__rest(_a, ["children", "className"]);
2800
- return (React__default["default"].createElement("td", tslib.__assign({ className: classNames__default["default"]('TableCell', className) }, other), children));
2801
- };
2862
+ function useTableGridStyles(_a) {
2863
+ var elementRef = _a.elementRef, align = _a.align, layout = _a.layout, columns = _a.columns;
2864
+ var isGridLayout = layout === 'grid';
2865
+ var _b = tslib.__read(React.useState(align || 'start'), 2), columnAlignment = _b[0], setColumnAlignment = _b[1];
2866
+ var _c = tslib.__read(React.useState(1), 2), gridColumnSpan = _c[0], setGridColumnSpan = _c[1];
2867
+ var _d = tslib.__read(React.useState(1), 2), gridRowSpan = _d[0], setGridRowSpan = _d[1];
2868
+ React.useEffect(function () {
2869
+ var _a;
2870
+ if (!isGridLayout) {
2871
+ return;
2872
+ }
2873
+ var element = elementRef.current;
2874
+ var column = typeof columns !== 'number' && columns[(_a = element === null || element === void 0 ? void 0 : element.cellIndex) !== null && _a !== void 0 ? _a : -1];
2875
+ if (!column) {
2876
+ setColumnAlignment(align || 'start');
2877
+ }
2878
+ else {
2879
+ setColumnAlignment(column.align);
2880
+ }
2881
+ if (element === null || element === void 0 ? void 0 : element.colSpan) {
2882
+ setGridColumnSpan(element.colSpan);
2883
+ }
2884
+ else {
2885
+ setGridColumnSpan(1);
2886
+ }
2887
+ if (element === null || element === void 0 ? void 0 : element.rowSpan) {
2888
+ setGridRowSpan(element.rowSpan);
2889
+ }
2890
+ else {
2891
+ setGridRowSpan(1);
2892
+ }
2893
+ }, [isGridLayout, columns, align]);
2894
+ return isGridLayout
2895
+ ? {
2896
+ textAlign: columnAlignment,
2897
+ gridColumn: gridColumnSpan > 1 ? "span ".concat(gridColumnSpan) : undefined,
2898
+ gridRow: gridRowSpan > 1 ? "span ".concat(gridRowSpan) : undefined
2899
+ }
2900
+ : {};
2901
+ }
2902
+
2903
+ var TableCell = React.forwardRef(function (_a, ref) {
2904
+ var children = _a.children, className = _a.className, align = _a.align, style = _a.style, other = tslib.__rest(_a, ["children", "className", "align", "style"]);
2905
+ var tableCellRef = useSharedRef(ref);
2906
+ var _b = useTable(), layout = _b.layout, columns = _b.columns;
2907
+ var tableGridStyles = useTableGridStyles({
2908
+ elementRef: tableCellRef,
2909
+ align: align,
2910
+ columns: columns,
2911
+ layout: layout
2912
+ });
2913
+ return (React__default["default"].createElement("td", tslib.__assign({ ref: tableCellRef, style: tslib.__assign(tslib.__assign({}, tableGridStyles), style), className: classNames__default["default"]('TableCell', className) }, other), children));
2914
+ });
2802
2915
  TableCell.displayName = 'TableCell';
2803
2916
 
2804
- var TableHead = function (_a) {
2917
+ var TableHead = React.forwardRef(function (_a, ref) {
2805
2918
  var children = _a.children, className = _a.className, other = tslib.__rest(_a, ["children", "className"]);
2806
- return (React__default["default"].createElement("thead", tslib.__assign({ className: classNames__default["default"]('TableHead', className) }, other), children));
2807
- };
2919
+ return (React__default["default"].createElement("thead", tslib.__assign({ ref: ref, className: classNames__default["default"]('TableHead', className) }, other), children));
2920
+ });
2808
2921
  TableHead.displayName = 'TableHead';
2809
2922
 
2810
- var TableHeader = function (_a) {
2811
- var children = _a.children, sortDirection = _a.sortDirection, onSort = _a.onSort, className = _a.className, _b = _a.sortAscendingAnnouncement, sortAscendingAnnouncement = _b === void 0 ? 'sorted ascending' : _b, _c = _a.sortDescendingAnnouncement, sortDescendingAnnouncement = _c === void 0 ? 'sorted descending' : _c, other = tslib.__rest(_a, ["children", "sortDirection", "onSort", "className", "sortAscendingAnnouncement", "sortDescendingAnnouncement"]);
2923
+ var TableHeader = React.forwardRef(function (_a, ref) {
2924
+ var children = _a.children, sortDirection = _a.sortDirection, onSort = _a.onSort, className = _a.className, _b = _a.sortAscendingAnnouncement, sortAscendingAnnouncement = _b === void 0 ? 'sorted ascending' : _b, _c = _a.sortDescendingAnnouncement, sortDescendingAnnouncement = _c === void 0 ? 'sorted descending' : _c, align = _a.align, style = _a.style, other = tslib.__rest(_a, ["children", "sortDirection", "onSort", "className", "sortAscendingAnnouncement", "sortDescendingAnnouncement", "align", "style"]);
2925
+ var tableHeaderRef = useSharedRef(ref);
2926
+ var _d = useTable(), layout = _d.layout, columns = _d.columns;
2927
+ var tableGridStyles = useTableGridStyles({
2928
+ elementRef: tableHeaderRef,
2929
+ align: align,
2930
+ columns: columns,
2931
+ layout: layout
2932
+ });
2812
2933
  // When the sort direction changes, we want to announce the change in a live region
2813
2934
  // because changes to the sort value is not widely supported yet
2814
2935
  // see: https://a11ysupport.io/tech/aria/aria-sort_attribute
@@ -2817,15 +2938,15 @@ var TableHeader = function (_a) {
2817
2938
  : sortDirection === 'descending'
2818
2939
  ? sortDescendingAnnouncement
2819
2940
  : '';
2820
- return (React__default["default"].createElement("th", tslib.__assign({ "aria-sort": sortDirection, className: classNames__default["default"]('TableHeader', className, {
2941
+ return (React__default["default"].createElement("th", tslib.__assign({ ref: tableHeaderRef, "aria-sort": sortDirection, className: classNames__default["default"]('TableHeader', className, {
2821
2942
  'TableHeader--sort-ascending': sortDirection === 'ascending',
2822
2943
  'TableHeader--sort-descending': sortDirection === 'descending'
2823
- }) }, other), !!onSort && !!sortDirection ? (React__default["default"].createElement("button", { onClick: onSort, className: "TableHeader__sort-button", type: "button" },
2944
+ }), style: tslib.__assign(tslib.__assign({}, tableGridStyles), style) }, other), !!onSort && !!sortDirection ? (React__default["default"].createElement("button", { onClick: onSort, className: "TableHeader__sort-button", type: "button" },
2824
2945
  children,
2825
2946
  React__default["default"].createElement("span", { "aria-hidden": "true" }, sortDirection === 'none' ? (React__default["default"].createElement(Icon, { type: "sort-triangle" })) : sortDirection === 'ascending' ? (React__default["default"].createElement(Icon, { type: "table-sort-ascending" })) : (React__default["default"].createElement(Icon, { type: "table-sort-descending" }))),
2826
2947
  React__default["default"].createElement(Offscreen, null,
2827
2948
  React__default["default"].createElement("span", { role: "status", "aria-live": "polite" }, announcement)))) : (children)));
2828
- };
2949
+ });
2829
2950
  TableHeader.displayName = 'TableHeader';
2830
2951
 
2831
2952
  var TableRow = function (_a) {
@@ -2834,10 +2955,10 @@ var TableRow = function (_a) {
2834
2955
  };
2835
2956
  TableRow.displayName = 'TableRow';
2836
2957
 
2837
- var TableFooter = function (_a) {
2958
+ var TableFooter = React.forwardRef(function (_a, ref) {
2838
2959
  var children = _a.children, className = _a.className, other = tslib.__rest(_a, ["children", "className"]);
2839
- return (React__default["default"].createElement("tfoot", tslib.__assign({ className: classNames__default["default"]('TableFooter', className) }, other), children));
2840
- };
2960
+ return (React__default["default"].createElement("tfoot", tslib.__assign({ ref: ref, className: classNames__default["default"]('TableFooter', className) }, other), children));
2961
+ });
2841
2962
  TableFooter.displayName = 'TableFooter';
2842
2963
 
2843
2964
  var Tab = React__default["default"].forwardRef(function (_a, ref) {
@@ -3341,19 +3462,21 @@ var ListboxContext = React.createContext({
3341
3462
  options: [],
3342
3463
  active: null,
3343
3464
  selected: null,
3465
+ multiselect: false,
3344
3466
  setOptions: function () { return null; },
3345
3467
  onSelect: function () { return null; }
3346
3468
  });
3347
3469
  function ListboxProvider(_a) {
3348
- var options = _a.options, active = _a.active, selected = _a.selected, setOptions = _a.setOptions, onSelect = _a.onSelect, children = _a.children;
3470
+ var options = _a.options, active = _a.active, selected = _a.selected, multiselect = _a.multiselect, setOptions = _a.setOptions, onSelect = _a.onSelect, children = _a.children;
3349
3471
  var Provider = ListboxContext.Provider;
3350
3472
  var value = React.useMemo(function () { return ({
3351
3473
  options: options,
3352
3474
  active: active,
3353
3475
  selected: selected,
3476
+ multiselect: multiselect,
3354
3477
  setOptions: setOptions,
3355
3478
  onSelect: onSelect
3356
- }); }, [options, active, selected, setOptions]);
3479
+ }); }, [options, active, selected, multiselect, setOptions]);
3357
3480
  return React__default["default"].createElement(Provider, { value: value }, children);
3358
3481
  }
3359
3482
  function useListboxContext() {
@@ -3375,40 +3498,78 @@ var optionMatchesValue = function (option, value) {
3375
3498
  option.value === value;
3376
3499
  };
3377
3500
  var Listbox = React.forwardRef(function (_a, ref) {
3378
- var _b = _a.as, Component = _b === void 0 ? 'ul' : _b, children = _a.children, defaultValue = _a.defaultValue, value = _a.value, _c = _a.navigation, navigation = _c === void 0 ? 'bound' : _c, onKeyDown = _a.onKeyDown, onFocus = _a.onFocus, onSelectionChange = _a.onSelectionChange, onActiveChange = _a.onActiveChange, props = tslib.__rest(_a, ["as", "children", "defaultValue", "value", "navigation", "onKeyDown", "onFocus", "onSelectionChange", "onActiveChange"]);
3379
- var _d = tslib.__read(React.useState([]), 2), options = _d[0], setOptions = _d[1];
3380
- var _e = tslib.__read(React.useState(null), 2), activeOption = _e[0], setActiveOption = _e[1];
3381
- var _f = tslib.__read(React.useState(null), 2), selectedOption = _f[0], setSelectedOption = _f[1];
3501
+ var _b = _a.as, Component = _b === void 0 ? 'ul' : _b, children = _a.children, defaultValue = _a.defaultValue, value = _a.value, _c = _a.navigation, navigation = _c === void 0 ? 'bound' : _c, _d = _a.multiselect, multiselect = _d === void 0 ? false : _d, onKeyDown = _a.onKeyDown, onFocus = _a.onFocus, onSelectionChange = _a.onSelectionChange, onActiveChange = _a.onActiveChange, props = tslib.__rest(_a, ["as", "children", "defaultValue", "value", "navigation", "multiselect", "onKeyDown", "onFocus", "onSelectionChange", "onActiveChange"]);
3502
+ var _e = tslib.__read(React.useState([]), 2), options = _e[0], setOptions = _e[1];
3503
+ var _f = tslib.__read(React.useState(null), 2), activeOption = _f[0], setActiveOption = _f[1];
3504
+ var _g = tslib.__read(React.useState([]), 2), selectedOptions = _g[0], setSelectedOptions = _g[1];
3382
3505
  var listboxRef = useSharedRef(ref);
3383
3506
  var isControlled = typeof value !== 'undefined';
3384
3507
  React.useLayoutEffect(function () {
3385
- if (!isControlled && selectedOption) {
3508
+ if (!isControlled && selectedOptions.length > 0) {
3386
3509
  return;
3387
3510
  }
3388
3511
  var listboxValue = isControlled ? value : defaultValue;
3389
- var matchingOption = options.find(function (option) {
3390
- return optionMatchesValue(option, listboxValue);
3391
- });
3392
- setSelectedOption(matchingOption || null);
3393
- setActiveOption(matchingOption || null);
3394
- }, [isControlled, options, value]);
3512
+ if (!listboxValue) {
3513
+ return;
3514
+ }
3515
+ if (multiselect) {
3516
+ var matchingOptions = options.filter(function (option) {
3517
+ return listboxValue.find(function (value) {
3518
+ return optionMatchesValue(option, value);
3519
+ });
3520
+ });
3521
+ setSelectedOptions(matchingOptions);
3522
+ setActiveOption(matchingOptions[0] || null);
3523
+ }
3524
+ else {
3525
+ var matchingOption = options.find(function (option) {
3526
+ return optionMatchesValue(option, listboxValue);
3527
+ });
3528
+ setSelectedOptions(matchingOption ? [matchingOption] : []);
3529
+ setActiveOption(matchingOption || null);
3530
+ }
3531
+ }, [isControlled, options, value, defaultValue]);
3395
3532
  React.useEffect(function () {
3396
3533
  if (activeOption) {
3397
3534
  onActiveChange === null || onActiveChange === void 0 ? void 0 : onActiveChange(activeOption);
3398
3535
  }
3399
3536
  }, [activeOption]);
3400
3537
  var handleSelect = React.useCallback(function (option) {
3538
+ var _a;
3401
3539
  setActiveOption(option);
3540
+ var optionIsSelected = selectedOptions.some(function (selected) { return selected.element === option.element; });
3541
+ var previousValues = selectedOptions.map(function (selected) { return selected.value; });
3402
3542
  // istanbul ignore else
3403
3543
  if (!isControlled) {
3404
- setSelectedOption(option);
3544
+ if (!multiselect) {
3545
+ setSelectedOptions([option]);
3546
+ }
3547
+ else {
3548
+ setSelectedOptions(optionIsSelected
3549
+ ? tslib.__spreadArray([], tslib.__read(selectedOptions.filter(function (selected) { return selected.element !== option.element; })), false) : tslib.__spreadArray(tslib.__spreadArray([], tslib.__read(selectedOptions), false), [option], false));
3550
+ }
3405
3551
  }
3406
- onSelectionChange === null || onSelectionChange === void 0 ? void 0 : onSelectionChange({
3407
- target: option.element,
3408
- value: option.value,
3409
- previousValue: selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.value
3410
- });
3411
- }, [isControlled, selectedOption]);
3552
+ if (multiselect) {
3553
+ onSelectionChange === null || onSelectionChange === void 0 ? void 0 : onSelectionChange({
3554
+ target: option.element,
3555
+ value: optionIsSelected
3556
+ ? selectedOptions
3557
+ .filter(function (selectedOption) {
3558
+ return selectedOption.element !== option.element;
3559
+ })
3560
+ .map(function (selectedOption) { return selectedOption.value; })
3561
+ : tslib.__spreadArray(tslib.__spreadArray([], tslib.__read(previousValues), false), [option.value], false),
3562
+ previousValue: previousValues
3563
+ });
3564
+ }
3565
+ else {
3566
+ onSelectionChange === null || onSelectionChange === void 0 ? void 0 : onSelectionChange({
3567
+ target: option.element,
3568
+ value: option.value,
3569
+ previousValue: (_a = selectedOptions[0]) === null || _a === void 0 ? void 0 : _a.value
3570
+ });
3571
+ }
3572
+ }, [isControlled, selectedOptions, multiselect, onSelectionChange]);
3412
3573
  var handleKeyDown = React.useCallback(function (event) {
3413
3574
  onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(event);
3414
3575
  if (!keys.includes(event.key)) {
@@ -3458,9 +3619,9 @@ var Listbox = React.forwardRef(function (_a, ref) {
3458
3619
  activeOption && handleSelect(activeOption);
3459
3620
  break;
3460
3621
  }
3461
- }, [options, activeOption, navigation]);
3622
+ }, [options, activeOption, navigation, handleSelect]);
3462
3623
  var handleFocus = React.useCallback(function (event) {
3463
- if (!activeOption && !selectedOption) {
3624
+ if (!activeOption) {
3464
3625
  var firstOption = options.find(function (option) { return !isDisabledOption(option); });
3465
3626
  // istanbul ignore else
3466
3627
  if (firstOption) {
@@ -3468,13 +3629,14 @@ var Listbox = React.forwardRef(function (_a, ref) {
3468
3629
  }
3469
3630
  // istanbul ignore else
3470
3631
  }
3471
- else if (event.target === listboxRef.current) {
3472
- setActiveOption(selectedOption);
3632
+ else if (selectedOptions.length &&
3633
+ event.target === listboxRef.current) {
3634
+ setActiveOption(selectedOptions[selectedOptions.length - 1]);
3473
3635
  }
3474
3636
  onFocus === null || onFocus === void 0 ? void 0 : onFocus(event);
3475
- }, [options, activeOption, selectedOption]);
3476
- return (React__default["default"].createElement(Component, tslib.__assign({ role: "listbox", ref: listboxRef, tabIndex: "0", onKeyDown: handleKeyDown, onFocus: handleFocus, "aria-activedescendant": activeOption ? getOptionId(activeOption) : undefined }, props),
3477
- React__default["default"].createElement(ListboxProvider, { options: options, active: activeOption, selected: selectedOption, setOptions: setOptions, onSelect: handleSelect }, children)));
3637
+ }, [options, activeOption, selectedOptions]);
3638
+ return (React__default["default"].createElement(Component, tslib.__assign({ role: "listbox", ref: listboxRef, tabIndex: "0", onKeyDown: handleKeyDown, onFocus: handleFocus, "aria-multiselectable": multiselect ? true : undefined, "aria-activedescendant": activeOption ? getOptionId(activeOption) : undefined }, props),
3639
+ React__default["default"].createElement(ListboxProvider, { options: options, active: activeOption, multiselect: multiselect, selected: selectedOptions, setOptions: setOptions, onSelect: handleSelect }, children)));
3478
3640
  });
3479
3641
  Listbox.displayName = 'Listbox';
3480
3642
 
@@ -3484,12 +3646,15 @@ function isElementPreceding(a, b) {
3484
3646
  var ListboxOption = React.forwardRef(function (_a, ref) {
3485
3647
  var _b;
3486
3648
  var _c;
3487
- var propId = _a.id, className = _a.className, _d = _a.as, Component = _d === void 0 ? 'li' : _d, children = _a.children, value = _a.value, disabled = _a.disabled, _e = _a.activeClass, activeClass = _e === void 0 ? 'ListboxOption--active' : _e, onClick = _a.onClick, props = tslib.__rest(_a, ["id", "className", "as", "children", "value", "disabled", "activeClass", "onClick"]);
3649
+ var propId = _a.id, className = _a.className, _d = _a.as, Component = _d === void 0 ? 'li' : _d, children = _a.children, value = _a.value, disabled = _a.disabled, selectedProp = _a.selected, _e = _a.activeClass, activeClass = _e === void 0 ? 'ListboxOption--active' : _e, onClick = _a.onClick, props = tslib.__rest(_a, ["id", "className", "as", "children", "value", "disabled", "selected", "activeClass", "onClick"]);
3488
3650
  var _f = useListboxContext(), active = _f.active, selected = _f.selected, setOptions = _f.setOptions, onSelect = _f.onSelect;
3489
3651
  var listboxOptionRef = useSharedRef(ref);
3490
3652
  var _g = tslib.__read(propId ? [propId] : nextId.useId(1, 'listbox-option'), 1), id = _g[0];
3491
- var isActive = active !== null && active.element === listboxOptionRef.current;
3492
- var isSelected = selected !== null && selected.element === listboxOptionRef.current;
3653
+ var isActive = (active === null || active === void 0 ? void 0 : active.element) === listboxOptionRef.current;
3654
+ var isSelected = typeof selectedProp === 'boolean'
3655
+ ? selectedProp
3656
+ : selected !== null &&
3657
+ !!selected.find(function (option) { return option.element === listboxOptionRef.current; });
3493
3658
  var optionValue = typeof value !== 'undefined'
3494
3659
  ? value
3495
3660
  : (_c = listboxOptionRef.current) === null || _c === void 0 ? void 0 : _c.innerText;
@@ -3539,7 +3704,7 @@ var ListboxOption = React.forwardRef(function (_a, ref) {
3539
3704
  }
3540
3705
  onSelect({ element: listboxOptionRef.current, value: optionValue });
3541
3706
  onClick === null || onClick === void 0 ? void 0 : onClick(event);
3542
- }, [optionValue]);
3707
+ }, [optionValue, onSelect, onClick, disabled]);
3543
3708
  return (React__default["default"].createElement(Component, tslib.__assign({ id: id, className: classNames__default["default"](className, (_b = {},
3544
3709
  _b[activeClass] = isActive,
3545
3710
  _b)), role: "option", ref: listboxOptionRef, "aria-disabled": typeof disabled === 'boolean' ? disabled : undefined, "aria-selected": isSelected, onClick: handleClick }, props), children));
@@ -3661,17 +3826,20 @@ var ComboboxMatch = function (_a) {
3661
3826
  React__default["default"].createElement("span", null, matchAfter)));
3662
3827
  };
3663
3828
  var ComboboxOption = React.forwardRef(function (_a, ref) {
3829
+ var _b;
3664
3830
  var className = _a.className, children = _a.children, disabled = _a.disabled, propId = _a.id, description = _a.description, propValue = _a.value, formValue = _a.formValue, props = tslib.__rest(_a, ["className", "children", "disabled", "id", "description", "value", "formValue"]);
3665
- var _b = tslib.__read(propId ? [propId] : nextId.useId(1, 'combobox-option'), 1), id = _b[0];
3666
- var _c = useListboxContext(), selected = _c.selected, active = _c.active;
3667
- var _d = useComboboxContext(), selectedValue = _d.selectedValue, matches = _d.matches, setMatchingOptions = _d.setMatchingOptions, setFormValue = _d.setFormValue;
3831
+ var _c = tslib.__read(propId ? [propId] : nextId.useId(1, 'combobox-option'), 1), id = _c[0];
3832
+ var _d = useListboxContext(), selected = _d.selected, active = _d.active;
3833
+ var _e = useComboboxContext(), selectedValue = _e.selectedValue, matches = _e.matches, setMatchingOptions = _e.setMatchingOptions, setFormValue = _e.setFormValue;
3668
3834
  var comboboxOptionRef = useSharedRef(ref);
3669
3835
  var intersectionRef = useIntersectionRef(comboboxOptionRef, {
3670
3836
  root: null,
3671
3837
  threshold: 1.0
3672
3838
  });
3673
3839
  var isActive = !!(active === null || active === void 0 ? void 0 : active.element) && active.element === comboboxOptionRef.current;
3674
- var isSelected = !!(selected === null || selected === void 0 ? void 0 : selected.element) && selected.element === comboboxOptionRef.current;
3840
+ var isSelected = !!(selected &&
3841
+ !!((_b = selected[0]) === null || _b === void 0 ? void 0 : _b.element) &&
3842
+ selected[0].element === comboboxOptionRef.current);
3675
3843
  var isMatching = (typeof matches === 'boolean' && matches) ||
3676
3844
  (typeof matches === 'function' && matches(children));
3677
3845
  // istanbul ignore next
@@ -4007,19 +4175,7 @@ var Popover = React.forwardRef(function (_a, ref) {
4007
4175
  var _f = tslib.__read(React.useState(null), 2), targetElement = _f[0], setTargetElement = _f[1];
4008
4176
  var _g = tslib.__read(React.useState(null), 2), isolator = _g[0], setIsolator = _g[1];
4009
4177
  var popoverRef = useSharedRef(ref);
4010
- var _h = tslib.__read(React.useState(null), 2), arrowElement = _h[0], setArrowElement = _h[1];
4011
- var _j = reactPopper.usePopper(targetElement, popoverRef === null || popoverRef === void 0 ? void 0 : popoverRef.current, {
4012
- placement: initialPlacement,
4013
- modifiers: [
4014
- { name: 'preventOverflow', options: { padding: 8 } },
4015
- { name: 'flip' },
4016
- { name: 'offset', options: { offset: [0, 8] } },
4017
- { name: 'arrow', options: { padding: 5, element: arrowElement } }
4018
- ]
4019
- }), styles = _j.styles, attributes = _j.attributes;
4020
- var placement = (attributes.popper &&
4021
- attributes.popper['data-popper-placement']) ||
4022
- initialPlacement;
4178
+ var _h = tslib.__read(React.useState(initialPlacement), 2), placement = _h[0], setPlacement = _h[1];
4023
4179
  var additionalProps = variant === 'prompt' && !props['aria-label']
4024
4180
  ? { 'aria-labelledby': "".concat(id, "-label") }
4025
4181
  : {};
@@ -4100,11 +4256,11 @@ var Popover = React.forwardRef(function (_a, ref) {
4100
4256
  fallbackFocus: '.Popover__borderLeft'
4101
4257
  } },
4102
4258
  React__default["default"].createElement(ClickOutsideListener$1, { onClickOutside: handleClickOutside },
4103
- React__default["default"].createElement("div", tslib.__assign({ id: id, className: classNames__default["default"]('Popover', "Popover--".concat(placement), className, {
4259
+ React__default["default"].createElement(AnchoredOverlay, tslib.__assign({ id: id, className: classNames__default["default"]('Popover', "Popover--".concat(placement), className, {
4104
4260
  'Popover--hidden': !show,
4105
4261
  'Popover--prompt': variant === 'prompt'
4106
- }), ref: popoverRef, role: "dialog", style: styles.popper }, attributes.popper, additionalProps, props),
4107
- React__default["default"].createElement("div", { className: "Popover__popoverArrow", ref: setArrowElement, style: styles.arrow }),
4262
+ }), ref: popoverRef, role: "dialog", target: target, open: show, placement: initialPlacement, onPlacementChange: setPlacement, offset: 8 }, additionalProps, props),
4263
+ React__default["default"].createElement("div", { className: "Popover__popoverArrow" }),
4108
4264
  React__default["default"].createElement("div", { className: "Popover__borderLeft" }),
4109
4265
  variant === 'prompt' ? (React__default["default"].createElement(PromptPopoverContent, { applyButtonText: applyButtonText, onApply: onApply, closeButtonText: closeButtonText, infoText: infoText || '', onClose: handleClosePopover, infoTextId: "".concat(id, "-label") })) : (children)))), (portal && 'current' in portal ? portal.current : portal) ||
4110
4266
  // Dependent on "isBrowser" check above:
@@ -4373,6 +4529,7 @@ exports.AddressLine = AddressLine;
4373
4529
  exports.Alert = Alert;
4374
4530
  exports.AlertActions = AlertActions;
4375
4531
  exports.AlertContent = AlertContent;
4532
+ exports.AnchoredOverlay = AnchoredOverlay;
4376
4533
  exports.AriaIsolate = AriaIsolate;
4377
4534
  exports.Badge = Badge;
4378
4535
  exports.BadgeLabel = BadgeLabel;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deque/cauldron-react",
3
- "version": "6.11.0",
3
+ "version": "6.12.0-canary.67739754",
4
4
  "license": "MPL-2.0",
5
5
  "description": "Fully accessible react components library for Deque Cauldron",
6
6
  "homepage": "https://cauldron.dequelabs.com/",
@@ -23,13 +23,12 @@
23
23
  "test": "jest --maxWorkers=1 --coverage"
24
24
  },
25
25
  "dependencies": {
26
- "@popperjs/core": "^2.5.4",
26
+ "@floating-ui/react-dom": "^2.1.2",
27
27
  "classnames": "^2.2.6",
28
28
  "focus-trap-react": "^10.2.3",
29
29
  "focusable": "^2.3.0",
30
30
  "keyname": "^0.1.0",
31
31
  "react-id-generator": "^3.0.1",
32
- "react-popper": "^2.2.4",
33
32
  "react-syntax-highlighter": "^15.5.0",
34
33
  "tslib": "^2.4.0"
35
34
  },