@box/blueprint-web 9.20.0 → 10.1.0

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.
Files changed (28) hide show
  1. package/README.md +1 -1
  2. package/dist/README.md +1 -1
  3. package/dist/lib-esm/index.css +229 -222
  4. package/dist/lib-esm/list-item/cell/cell.js +1 -1
  5. package/dist/lib-esm/list-item/index.d.ts +5 -2
  6. package/dist/lib-esm/list-item/index.js +15 -0
  7. package/dist/lib-esm/list-item/list-item.d.ts +5 -2
  8. package/dist/lib-esm/list-item/main.module.js +1 -1
  9. package/dist/lib-esm/list-item/table-column.js +1 -1
  10. package/dist/lib-esm/list-item/table-header-default.d.ts +9 -0
  11. package/dist/lib-esm/list-item/table-header-default.js +23 -0
  12. package/dist/lib-esm/list-item/table-header-dropdown.d.ts +9 -0
  13. package/dist/lib-esm/list-item/table-header-dropdown.js +66 -0
  14. package/dist/lib-esm/list-item/table-header.js +8 -4
  15. package/dist/lib-esm/list-item/table.d.ts +26 -2
  16. package/dist/lib-esm/list-item/table.js +60 -20
  17. package/dist/lib-esm/list-item/utils/{column-metadata.d.ts → column-visibility-context/column-metadata.d.ts} +1 -0
  18. package/dist/lib-esm/list-item/utils/{columnVisibilityContext.d.ts → column-visibility-context/columnVisibilityContext.d.ts} +2 -1
  19. package/dist/lib-esm/list-item/utils/{columnVisibilityContext.js → column-visibility-context/columnVisibilityContext.js} +4 -2
  20. package/dist/lib-esm/list-item/utils/{useColumnVisibilityManager.d.ts → column-visibility-context/useColumnVisibilityManager.d.ts} +2 -1
  21. package/dist/lib-esm/list-item/utils/{useColumnVisibilityManager.js → column-visibility-context/useColumnVisibilityManager.js} +13 -4
  22. package/dist/lib-esm/list-item/utils/table-sorting-context/tableSortingContext.d.ts +17 -0
  23. package/dist/lib-esm/list-item/utils/table-sorting-context/tableSortingContext.js +42 -0
  24. package/dist/lib-esm/list-item/utils/table-sorting-context/useSortingTableManager.d.ts +9 -0
  25. package/dist/lib-esm/list-item/utils/table-sorting-context/useSortingTableManager.js +36 -0
  26. package/package.json +1 -1
  27. /package/dist/lib-esm/list-item/utils/{useThrottledContainerResize.d.ts → column-visibility-context/useThrottledContainerResize.d.ts} +0 -0
  28. /package/dist/lib-esm/list-item/utils/{useThrottledContainerResize.js → column-visibility-context/useThrottledContainerResize.js} +0 -0
@@ -4,7 +4,7 @@ import { forwardRef } from 'react';
4
4
  import { Cell as Cell$1 } from 'react-aria-components';
5
5
  import { Ghost } from '../../ghost/ghost.js';
6
6
  import styles from '../main.module.js';
7
- import { useColumnVisibilityContext } from '../utils/columnVisibilityContext.js';
7
+ import { useColumnVisibilityContext } from '../utils/column-visibility-context/columnVisibilityContext.js';
8
8
 
9
9
  /**
10
10
  * Based on React Aria Components `Cell`
@@ -6,7 +6,10 @@ import { type TableHeaderProps } from './table-header';
6
6
  export declare const Table: import("react").ForwardRefExoticComponent<import("react-aria-components").TableProps & {
7
7
  isColumnDroppingEnabled?: boolean;
8
8
  isColumnResizingEnabled?: boolean;
9
- onVisibleColumnsChange?: import("./utils/column-metadata").OnColumnVisibilityChange;
9
+ onVisibleColumnsChange?: import("./utils/column-visibility-context/column-metadata").OnColumnVisibilityChange;
10
+ onSortChange?: (sortDescriptor: import("react-aria-components").SortDescriptor) => void;
11
+ sortDescriptor?: import("react-aria-components").SortDescriptor;
12
+ defaultSortDescriptor?: import("react-aria-components").SortDescriptor;
10
13
  } & import("react").RefAttributes<HTMLTableElement>>;
11
14
  export declare const Cell: import("react").ForwardRefExoticComponent<import("./cell/cell").CellProps & import("react").RefAttributes<HTMLTableCellElement>>;
12
15
  export declare const Column: (props: ColumnProps & {
@@ -23,4 +26,4 @@ export declare const Row: <T extends object>(props: RowProps<T> & {
23
26
  }) => ReturnType<(<T_1 extends object>(props: RowProps<T_1>, ref: import("react").ForwardedRef<HTMLTableRowElement>) => import("react/jsx-runtime").JSX.Element)>;
24
27
  export declare const ActionCell: import("react").ForwardRefExoticComponent<import("./cell/action-cell").ActionCellProps & import("react").RefAttributes<HTMLTableCellElement>>;
25
28
  export declare const DropIndicator: import("react").ForwardRefExoticComponent<import("react-aria-components").DropIndicatorProps & import("react").RefAttributes<HTMLElement>>;
26
- export type { RowProps, ColumnProps, TableProps, TableBodyProps, TableHeaderProps };
29
+ export type { ColumnProps, RowProps, TableBodyProps, TableHeaderProps, TableProps };
@@ -9,6 +9,21 @@ import 'lodash/noop';
9
9
  import '../utils/useBreakpoint.js';
10
10
  import 'react-aria';
11
11
  import '@ariakit/react';
12
+ import 'react-dom';
13
+ import '../button/button.js';
14
+ import '../primitives/dropdown-menu/dropdown-menu-checkbox-item.js';
15
+ import '../primitives/dropdown-menu/dropdown-menu-content.js';
16
+ import '../primitives/dropdown-menu/dropdown-menu-group.js';
17
+ import '../primitives/dropdown-menu/dropdown-menu-header.js';
18
+ import '../primitives/dropdown-menu/dropdown-menu-item.js';
19
+ import '../primitives/dropdown-menu/dropdown-menu-radio-group.js';
20
+ import '../primitives/dropdown-menu/dropdown-menu-radio-select-item.js';
21
+ import '../primitives/dropdown-menu/dropdown-menu-root.js';
22
+ import '../primitives/dropdown-menu/dropdown-menu-separator.js';
23
+ import '../primitives/dropdown-menu/dropdown-menu-sub-menu-content.js';
24
+ import '../primitives/dropdown-menu/dropdown-menu-sub-menu-root.js';
25
+ import '../primitives/dropdown-menu/dropdown-menu-sub-menu-trigger.js';
26
+ import '../primitives/dropdown-menu/dropdown-menu-trigger.js';
12
27
 
13
28
  const Cell = Cell$1;
14
29
 
@@ -6,7 +6,10 @@ import { type TableHeaderProps } from './table-header';
6
6
  export declare const Table: import("react").ForwardRefExoticComponent<import("react-aria-components").TableProps & {
7
7
  isColumnDroppingEnabled?: boolean;
8
8
  isColumnResizingEnabled?: boolean;
9
- onVisibleColumnsChange?: import("./utils/column-metadata").OnColumnVisibilityChange;
9
+ onVisibleColumnsChange?: import("./utils/column-visibility-context/column-metadata").OnColumnVisibilityChange;
10
+ onSortChange?: (sortDescriptor: import("react-aria-components").SortDescriptor) => void;
11
+ sortDescriptor?: import("react-aria-components").SortDescriptor;
12
+ defaultSortDescriptor?: import("react-aria-components").SortDescriptor;
10
13
  } & import("react").RefAttributes<HTMLTableElement>>;
11
14
  export declare const Cell: import("react").ForwardRefExoticComponent<import("./cell/cell").CellProps & import("react").RefAttributes<HTMLTableCellElement>>;
12
15
  export declare const Column: (props: ColumnProps & {
@@ -23,4 +26,4 @@ export declare const Row: <T extends object>(props: RowProps<T> & {
23
26
  }) => ReturnType<(<T_1 extends object>(props: RowProps<T_1>, ref: import("react").ForwardedRef<HTMLTableRowElement>) => import("react/jsx-runtime").JSX.Element)>;
24
27
  export declare const ActionCell: import("react").ForwardRefExoticComponent<import("./cell/action-cell").ActionCellProps & import("react").RefAttributes<HTMLTableCellElement>>;
25
28
  export declare const DropIndicator: import("react").ForwardRefExoticComponent<import("react-aria-components").DropIndicatorProps & import("react").RefAttributes<HTMLElement>>;
26
- export type { RowProps, ColumnProps, TableProps, TableBodyProps, TableHeaderProps };
29
+ export type { ColumnProps, RowProps, TableBodyProps, TableHeaderProps, TableProps };
@@ -1,4 +1,4 @@
1
1
  import '../index.css';
2
- var styles = {"resizableTableContainer":"bp_main_module_resizableTableContainer--4f8ab","resizableTable":"bp_main_module_resizableTable--4f8ab","tableHeader":"bp_main_module_tableHeader--4f8ab","column":"bp_main_module_column--4f8ab","columnNameWrapper":"bp_main_module_columnNameWrapper--4f8ab","columnName":"bp_main_module_columnName--4f8ab","focusVisible":"bp_main_module_focusVisible--4f8ab","rotateArrow":"bp_main_module_rotateArrow--4f8ab","sorted":"bp_main_module_sorted--4f8ab","sortingFlexWrapper":"bp_main_module_sortingFlexWrapper--4f8ab","columnResizer":"bp_main_module_columnResizer--4f8ab","droppableColumn":"bp_main_module_droppableColumn--4f8ab","actionColumn":"bp_main_module_actionColumn--4f8ab","hiddenColumn":"bp_main_module_hiddenColumn--4f8ab","tableBody":"bp_main_module_tableBody--4f8ab","row":"bp_main_module_row--4f8ab","cell":"bp_main_module_cell--4f8ab","actionsWrapper":"bp_main_module_actionsWrapper--4f8ab","actionChildren":"bp_main_module_actionChildren--4f8ab","actions":"bp_main_module_actions--4f8ab","isCellHidden":"bp_main_module_isCellHidden--4f8ab","dropIndicator":"bp_main_module_dropIndicator--4f8ab"};
2
+ var styles = {"tableSortingContainer":"bp_main_module_tableSortingContainer--1316e","resizableTableContainer":"bp_main_module_resizableTableContainer--1316e","resizableTable":"bp_main_module_resizableTable--1316e","tableHeader":"bp_main_module_tableHeader--1316e","column":"bp_main_module_column--1316e","columnNameWrapper":"bp_main_module_columnNameWrapper--1316e","columnName":"bp_main_module_columnName--1316e","focusVisible":"bp_main_module_focusVisible--1316e","rotateArrow":"bp_main_module_rotateArrow--1316e","sorted":"bp_main_module_sorted--1316e","sortingFlexWrapper":"bp_main_module_sortingFlexWrapper--1316e","columnResizer":"bp_main_module_columnResizer--1316e","droppableColumn":"bp_main_module_droppableColumn--1316e","actionColumn":"bp_main_module_actionColumn--1316e","hiddenColumn":"bp_main_module_hiddenColumn--1316e","tableBody":"bp_main_module_tableBody--1316e","row":"bp_main_module_row--1316e","cell":"bp_main_module_cell--1316e","actionsWrapper":"bp_main_module_actionsWrapper--1316e","actionChildren":"bp_main_module_actionChildren--1316e","actions":"bp_main_module_actions--1316e","isCellHidden":"bp_main_module_isCellHidden--1316e","dropIndicator":"bp_main_module_dropIndicator--1316e"};
3
3
 
4
4
  export { styles as default };
@@ -9,7 +9,7 @@ import { Focusable } from '../focusable/focusable.js';
9
9
  import { useBreakpoint, Breakpoint } from '../utils/useBreakpoint.js';
10
10
  import { VisuallyHidden } from '../visually-hidden/visually-hidden.js';
11
11
  import styles from './main.module.js';
12
- import { useColumnVisibilityContext } from './utils/columnVisibilityContext.js';
12
+ import { useColumnVisibilityContext } from './utils/column-visibility-context/columnVisibilityContext.js';
13
13
 
14
14
  function SortingArrowIcon({
15
15
  visibility = 'visible',
@@ -0,0 +1,9 @@
1
+ import { type ForwardedRef } from 'react';
2
+ import { type TableHeaderProps as PrimitiveTableHeaderProps } from 'react-aria-components';
3
+ import { type ColumnProps } from './table-column';
4
+ export type TableDefaultHeaderProps<T> = PrimitiveTableHeaderProps<T>;
5
+ declare const TableHeaderInner: <T extends ColumnProps>(props: TableDefaultHeaderProps<T>, ref: ForwardedRef<HTMLTableSectionElement>) => import("react/jsx-runtime").JSX.Element;
6
+ export declare const TableDefaultHeader: <T extends object>(props: TableDefaultHeaderProps<T> & {
7
+ ref?: ForwardedRef<HTMLTableSectionElement>;
8
+ }) => ReturnType<typeof TableHeaderInner>;
9
+ export {};
@@ -0,0 +1,23 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import clsx from 'clsx';
3
+ import { forwardRef } from 'react';
4
+ import { TableHeader } from 'react-aria-components';
5
+ import styles from './main.module.js';
6
+
7
+ const TableHeaderInner = (props, ref) => {
8
+ const {
9
+ children,
10
+ columns,
11
+ className,
12
+ ...rest
13
+ } = props;
14
+ return jsx(TableHeader, {
15
+ ...rest,
16
+ ref: ref,
17
+ className: clsx(styles.tableHeader, className),
18
+ children: children
19
+ });
20
+ };
21
+ const TableDefaultHeader = /*#__PURE__*/forwardRef(TableHeaderInner);
22
+
23
+ export { TableDefaultHeader };
@@ -0,0 +1,9 @@
1
+ import { type ForwardedRef } from 'react';
2
+ import { type TableHeaderProps as PrimitiveTableHeaderProps } from 'react-aria-components';
3
+ import { type ColumnProps } from './table-column';
4
+ export type TableDropdownHeaderProps<T> = PrimitiveTableHeaderProps<T>;
5
+ declare const TableHeaderInner: <T extends ColumnProps>({ children, className, ...props }: TableDropdownHeaderProps<T>, ref: ForwardedRef<HTMLTableSectionElement>) => import("react/jsx-runtime").JSX.Element;
6
+ export declare const TableDropdownHeader: <T extends object>(props: TableDropdownHeaderProps<T> & {
7
+ ref?: ForwardedRef<HTMLTableSectionElement>;
8
+ }) => ReturnType<typeof TableHeaderInner>;
9
+ export {};
@@ -0,0 +1,66 @@
1
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
+ import { forwardRef, useCallback } from 'react';
3
+ import { TableHeader } from 'react-aria-components';
4
+ import { ArrowUp, ArrowDown } from '@box/blueprint-web-assets/icons/Fill';
5
+ import { createPortal } from 'react-dom';
6
+ import { Button } from '../button/button.js';
7
+ import { DropdownMenu } from '../primitives/dropdown-menu/index.js';
8
+ import { useTableSortingContext } from './utils/table-sorting-context/tableSortingContext.js';
9
+
10
+ const TableHeaderInner = ({
11
+ children,
12
+ className,
13
+ ...props
14
+ }, ref) => {
15
+ const {
16
+ dropdownHeaderContainerRef,
17
+ sortDescriptor,
18
+ onSortDescriptorChange
19
+ } = useTableSortingContext();
20
+ const handleSelect = useCallback(columnId => onSortDescriptorChange({
21
+ column: columnId,
22
+ direction: sortDescriptor.direction
23
+ }), [onSortDescriptorChange, sortDescriptor.direction]);
24
+ const SortIcon = sortDescriptor?.direction === 'ascending' ? ArrowUp : ArrowDown;
25
+ const dropdownHeaderContainer = dropdownHeaderContainerRef.current;
26
+ const columnArray = Array.isArray(children) ? children : [children];
27
+ const columnLabel = columnArray.find(child => child?.props?.id === sortDescriptor.column)?.props.children || columnArray[0]?.props.children;
28
+ const createSelectHandler = useCallback(columnId => () => handleSelect(columnId), [handleSelect]);
29
+ return jsxs(Fragment, {
30
+ children: [jsx(TableHeader, {
31
+ ...props,
32
+ ref: ref,
33
+ style: {
34
+ display: 'none'
35
+ },
36
+ children: children
37
+ }), dropdownHeaderContainer && /*#__PURE__*/createPortal(jsxs(DropdownMenu.Root, {
38
+ children: [jsx(DropdownMenu.Trigger, {
39
+ children: jsx(Button, {
40
+ "aria-label": "sort-by",
41
+ "aria-sort": sortDescriptor.direction === 'ascending' ? 'ascending' : 'descending',
42
+ icon: SortIcon,
43
+ size: "small",
44
+ variant: "secondary",
45
+ children: columnLabel
46
+ })
47
+ }), jsx(DropdownMenu.Content, {
48
+ align: "start",
49
+ children: columnArray?.map(child => {
50
+ if (child.props.actionColumn) {
51
+ return null;
52
+ }
53
+ return jsx(DropdownMenu.Item
54
+ // eslint-disable-next-line no-underscore-dangle
55
+ , {
56
+ onSelect: createSelectHandler(child.props.id),
57
+ children: child.props.children
58
+ }, child.props.__ordinal);
59
+ })
60
+ })]
61
+ }), dropdownHeaderContainer)]
62
+ });
63
+ };
64
+ const TableDropdownHeader = /*#__PURE__*/forwardRef(TableHeaderInner);
65
+
66
+ export { TableDropdownHeader };
@@ -1,9 +1,10 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
2
  import clsx from 'clsx';
3
3
  import { forwardRef, useMemo, Children, isValidElement, cloneElement, useEffect } from 'react';
4
- import { TableHeader as TableHeader$1 } from 'react-aria-components';
5
4
  import styles from './main.module.js';
6
- import { useColumnVisibilityContext } from './utils/columnVisibilityContext.js';
5
+ import { TableDefaultHeader } from './table-header-default.js';
6
+ import { TableDropdownHeader } from './table-header-dropdown.js';
7
+ import { useColumnVisibilityContext } from './utils/column-visibility-context/columnVisibilityContext.js';
7
8
 
8
9
  /**
9
10
  * Based on React Aria Components `TableHeader`
@@ -17,7 +18,8 @@ const TableHeaderInner = (props, ref) => {
17
18
  ...rest
18
19
  } = props;
19
20
  const {
20
- setColumnsMetadata
21
+ setColumnsMetadata,
22
+ headerVariant
21
23
  } = useColumnVisibilityContext();
22
24
  const newChildren = useMemo(() => {
23
25
  // If `children` is a function, we are dynamically generating header cells.
@@ -49,7 +51,9 @@ const TableHeaderInner = (props, ref) => {
49
51
  useEffect(() => {
50
52
  setColumnsMetadata(columnsMetadata);
51
53
  }, [columnsMetadata, setColumnsMetadata]);
52
- return jsx(TableHeader$1, {
54
+ // When column dropping is enabled, in mobile mode, the button with dropdown options for each column replaces the table header.
55
+ const Header = headerVariant === 'table-dropdown-header' ? TableDropdownHeader : TableDefaultHeader;
56
+ return jsx(Header, {
53
57
  ...rest,
54
58
  ref: ref,
55
59
  className: clsx(styles.tableHeader, className),
@@ -1,5 +1,5 @@
1
- import { type TableProps as PrimitiveTableProps } from 'react-aria-components';
2
- import { type OnColumnVisibilityChange } from './utils/column-metadata';
1
+ import { type TableProps as PrimitiveTableProps, type SortDescriptor } from 'react-aria-components';
2
+ import { type OnColumnVisibilityChange } from './utils/column-visibility-context/column-metadata';
3
3
  export type TableProps = PrimitiveTableProps & {
4
4
  /**
5
5
  * Setting this to true enables the column dropping functionality.
@@ -16,6 +16,18 @@ export type TableProps = PrimitiveTableProps & {
16
16
  * - `hiddenColumns`: An array of column indexes that are currently hidden.
17
17
  */
18
18
  onVisibleColumnsChange?: OnColumnVisibilityChange;
19
+ /**
20
+ * Callback fired when the sort changes.
21
+ */
22
+ onSortChange?: (sortDescriptor: SortDescriptor) => void;
23
+ /**
24
+ * Sort descriptor to manage sorting state.
25
+ */
26
+ sortDescriptor?: SortDescriptor;
27
+ /**
28
+ * Default sort descriptor when uncontrolled.
29
+ */
30
+ defaultSortDescriptor?: SortDescriptor;
19
31
  };
20
32
  /**
21
33
  * Based on React Aria Components `Table`
@@ -37,4 +49,16 @@ export declare const Table: import("react").ForwardRefExoticComponent<PrimitiveT
37
49
  * - `hiddenColumns`: An array of column indexes that are currently hidden.
38
50
  */
39
51
  onVisibleColumnsChange?: OnColumnVisibilityChange;
52
+ /**
53
+ * Callback fired when the sort changes.
54
+ */
55
+ onSortChange?: (sortDescriptor: SortDescriptor) => void;
56
+ /**
57
+ * Sort descriptor to manage sorting state.
58
+ */
59
+ sortDescriptor?: SortDescriptor;
60
+ /**
61
+ * Default sort descriptor when uncontrolled.
62
+ */
63
+ defaultSortDescriptor?: SortDescriptor;
40
64
  } & import("react").RefAttributes<HTMLTableElement>>;
@@ -1,10 +1,11 @@
1
- import { jsx } from 'react/jsx-runtime';
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
2
  import noop from 'lodash/noop';
3
3
  import { forwardRef, useRef } from 'react';
4
4
  import { ResizableTableContainer, Table as Table$1 } from 'react-aria-components';
5
5
  import clsx from 'clsx';
6
6
  import styles from './main.module.js';
7
- import { ColumnVisibilityProvider } from './utils/columnVisibilityContext.js';
7
+ import { ColumnVisibilityProvider, useColumnVisibilityContext } from './utils/column-visibility-context/columnVisibilityContext.js';
8
+ import { TableSortingProvider, useTableSortingContext } from './utils/table-sorting-context/tableSortingContext.js';
8
9
 
9
10
  /**
10
11
  * Based on React Aria Components `Table`
@@ -18,28 +19,67 @@ const Table = /*#__PURE__*/forwardRef((props, ref) => {
18
19
  onVisibleColumnsChange,
19
20
  isColumnDroppingEnabled = false,
20
21
  isColumnResizingEnabled = false,
22
+ sortDescriptor,
23
+ defaultSortDescriptor,
24
+ onSortChange,
21
25
  ...rest
22
26
  } = props;
23
- const containerRef = useRef(null);
24
- return jsx(ColumnVisibilityProvider, {
25
- containerRef: containerRef,
26
- isColumnDroppingEnabled: isColumnDroppingEnabled,
27
- isColumnResizingEnabled: isColumnResizingEnabled,
28
- onVisibleColumnsChange: onVisibleColumnsChange,
29
- children: jsx(ResizableTableContainer, {
30
- ref: containerRef,
31
- className: styles.resizableTableContainer,
32
- children: jsx(Table$1, {
33
- ...rest,
34
- ref: ref,
35
- className: clsx({
36
- [styles.resizableTable]: isColumnResizingEnabled || isColumnDroppingEnabled
37
- }, className),
38
- onRowAction: onRowAction,
39
- children: children
40
- })
27
+ const resizableContainerRef = useRef(null);
28
+ const dropdownHeaderContainerRef = useRef(null);
29
+ return jsx(TableSortingProvider, {
30
+ defaultSortDescriptor: defaultSortDescriptor,
31
+ dropdownHeaderContainerRef: dropdownHeaderContainerRef,
32
+ onSortChange: onSortChange,
33
+ sortDescriptor: sortDescriptor,
34
+ children: jsxs("div", {
35
+ className: styles.tableSortingContainer,
36
+ children: [jsx("div", {
37
+ ref: dropdownHeaderContainerRef
38
+ }), jsx(ColumnVisibilityProvider, {
39
+ containerRef: resizableContainerRef,
40
+ isColumnDroppingEnabled: isColumnDroppingEnabled,
41
+ isColumnResizingEnabled: isColumnResizingEnabled,
42
+ onVisibleColumnsChange: onVisibleColumnsChange,
43
+ children: jsx(ResizableTableContainer, {
44
+ ref: resizableContainerRef,
45
+ className: styles.resizableTableContainer,
46
+ children: jsx(TableInner, {
47
+ ref: ref,
48
+ ...rest,
49
+ className: className,
50
+ onRowAction: onRowAction,
51
+ children: children
52
+ })
53
+ })
54
+ })]
41
55
  })
42
56
  });
43
57
  });
58
+ const TableInner = /*#__PURE__*/forwardRef(({
59
+ className,
60
+ onRowAction,
61
+ children,
62
+ ...rest
63
+ }, ref) => {
64
+ const {
65
+ sortDescriptor,
66
+ onSortDescriptorChange
67
+ } = useTableSortingContext();
68
+ const {
69
+ isColumnResizingEnabled,
70
+ isColumnDroppingEnabled
71
+ } = useColumnVisibilityContext();
72
+ return jsx(Table$1, {
73
+ ...rest,
74
+ ref: ref,
75
+ className: clsx({
76
+ [styles.resizableTable]: isColumnResizingEnabled || isColumnDroppingEnabled
77
+ }, className),
78
+ onRowAction: onRowAction,
79
+ onSortChange: onSortDescriptorChange,
80
+ sortDescriptor: sortDescriptor,
81
+ children: children
82
+ });
83
+ });
44
84
 
45
85
  export { Table };
@@ -3,6 +3,7 @@ export interface ColumnMetadata {
3
3
  ordinal: Ordinal;
4
4
  actionColumn?: boolean;
5
5
  }
6
+ export type HeaderVariant = 'table-default-header' | 'table-dropdown-header';
6
7
  export type ColumnMetadataSet = Array<ColumnMetadata>;
7
8
  export type OnColumnVisibilityChange = (columnVisibility: {
8
9
  visibleColumns: Ordinal[];
@@ -1,5 +1,5 @@
1
1
  import { type MutableRefObject, type ReactNode } from 'react';
2
- import { type ColumnMetadataSet, type OnColumnVisibilityChange, type Ordinal } from './column-metadata';
2
+ import { type ColumnMetadataSet, type HeaderVariant, type OnColumnVisibilityChange, type Ordinal } from './column-metadata';
3
3
  interface ColumnVisibilityContextValue {
4
4
  isColumnHidden: (ordinal: Ordinal) => boolean;
5
5
  setColumnsMetadata: (columnsMetadata: ColumnMetadataSet) => void;
@@ -7,6 +7,7 @@ interface ColumnVisibilityContextValue {
7
7
  columnsMetadata: ColumnMetadataSet;
8
8
  isColumnDroppingEnabled: boolean;
9
9
  isColumnResizingEnabled: boolean;
10
+ headerVariant: HeaderVariant;
10
11
  }
11
12
  interface ColumnVisibilityProviderProps {
12
13
  children: ReactNode;
@@ -14,7 +14,8 @@ const ColumnVisibilityProvider = ({
14
14
  isColumnHidden,
15
15
  setColumnsMetadata,
16
16
  isColumnResizable,
17
- columnsMetadata
17
+ columnsMetadata,
18
+ headerVariant
18
19
  } = useColumnVisibilityManager(containerRef, isColumnDroppingEnabled, isColumnResizingEnabled, onVisibleColumnsChange);
19
20
  const value = {
20
21
  isColumnHidden,
@@ -22,7 +23,8 @@ const ColumnVisibilityProvider = ({
22
23
  isColumnResizable,
23
24
  columnsMetadata,
24
25
  isColumnDroppingEnabled,
25
- isColumnResizingEnabled
26
+ isColumnResizingEnabled,
27
+ headerVariant
26
28
  };
27
29
  return jsx(ColumnVisibilityContext.Provider, {
28
30
  value: value,
@@ -1,7 +1,8 @@
1
- import { type ColumnMetadataSet, type OnColumnVisibilityChange, type Ordinal } from './column-metadata';
1
+ import { type ColumnMetadataSet, type HeaderVariant, type OnColumnVisibilityChange, type Ordinal } from './column-metadata';
2
2
  export declare const useColumnVisibilityManager: (containerRef: React.MutableRefObject<HTMLDivElement | null>, isColumnDroppingEnabled: boolean, isColumnResizingEnabled: boolean, onVisibleColumnsChange?: OnColumnVisibilityChange) => {
3
3
  isColumnHidden: (ordinal: Ordinal) => boolean;
4
4
  setColumnsMetadata: import("react").Dispatch<import("react").SetStateAction<ColumnMetadataSet>>;
5
5
  isColumnResizable: (ordinal: Ordinal) => boolean;
6
6
  columnsMetadata: ColumnMetadataSet;
7
+ headerVariant: HeaderVariant;
7
8
  };
@@ -1,5 +1,5 @@
1
1
  import { useState, useMemo, useCallback, useEffect } from 'react';
2
- import { useBreakpoint, Breakpoint } from '../../utils/useBreakpoint.js';
2
+ import { useBreakpoint, Breakpoint } from '../../../utils/useBreakpoint.js';
3
3
  import { useThrottledContainerResize } from './useThrottledContainerResize.js';
4
4
 
5
5
  const useColumnVisibilityManager = (containerRef, isColumnDroppingEnabled, isColumnResizingEnabled, onVisibleColumnsChange) => {
@@ -25,6 +25,12 @@ const useColumnVisibilityManager = (containerRef, isColumnDroppingEnabled, isCol
25
25
  // For remaining columns, hide those beyond maxVisibleColumns
26
26
  return ordinal > maxVisibleColumns;
27
27
  }, [columnsMetadata, isColumnDroppingEnabled, isMobile, maxVisibleColumns]);
28
+ const headerVariant = useMemo(() => {
29
+ if (isColumnDroppingEnabled && isMobile) {
30
+ return 'table-dropdown-header';
31
+ }
32
+ return 'table-default-header';
33
+ }, [isColumnDroppingEnabled, isMobile]);
28
34
  const {
29
35
  visibleColumns,
30
36
  hiddenColumns
@@ -34,7 +40,9 @@ const useColumnVisibilityManager = (containerRef, isColumnDroppingEnabled, isCol
34
40
  columnsMetadata.forEach(({
35
41
  ordinal
36
42
  }) => {
37
- if (isColumnHidden(ordinal)) {
43
+ if (headerVariant === 'table-dropdown-header') {
44
+ hidden.push(ordinal);
45
+ } else if (isColumnHidden(ordinal)) {
38
46
  hidden.push(ordinal);
39
47
  } else {
40
48
  visible.push(ordinal);
@@ -44,7 +52,7 @@ const useColumnVisibilityManager = (containerRef, isColumnDroppingEnabled, isCol
44
52
  visibleColumns: visible,
45
53
  hiddenColumns: hidden
46
54
  };
47
- }, [columnsMetadata, isColumnHidden]);
55
+ }, [columnsMetadata, isColumnHidden, headerVariant]);
48
56
  const isColumnResizable = useCallback(ordinal => {
49
57
  const column = columnsMetadata[ordinal];
50
58
  // Columns are not resizable when resizing is disabled
@@ -77,7 +85,8 @@ const useColumnVisibilityManager = (containerRef, isColumnDroppingEnabled, isCol
77
85
  isColumnHidden,
78
86
  setColumnsMetadata,
79
87
  isColumnResizable,
80
- columnsMetadata
88
+ columnsMetadata,
89
+ headerVariant
81
90
  };
82
91
  };
83
92
 
@@ -0,0 +1,17 @@
1
+ import { type MutableRefObject, type ReactNode } from 'react';
2
+ import { type SortDescriptor } from 'react-aria-components';
3
+ interface TableSortingContextValue {
4
+ sortDescriptor: SortDescriptor;
5
+ onSortDescriptorChange: (newSortDescriptor: SortDescriptor) => void;
6
+ dropdownHeaderContainerRef: MutableRefObject<HTMLDivElement | null>;
7
+ }
8
+ interface TableSortingProviderProps {
9
+ children: ReactNode;
10
+ sortDescriptor?: SortDescriptor;
11
+ defaultSortDescriptor?: SortDescriptor;
12
+ onSortChange?: (sortDescriptor: SortDescriptor) => void;
13
+ dropdownHeaderContainerRef: MutableRefObject<HTMLDivElement | null>;
14
+ }
15
+ export declare const TableSortingProvider: ({ children, sortDescriptor, defaultSortDescriptor, onSortChange, dropdownHeaderContainerRef, }: TableSortingProviderProps) => import("react/jsx-runtime").JSX.Element;
16
+ export declare const useTableSortingContext: () => TableSortingContextValue;
17
+ export {};
@@ -0,0 +1,42 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { useContext, createContext } from 'react';
3
+ import { useSortingTableManager } from './useSortingTableManager.js';
4
+
5
+ const TableSortingContext = /*#__PURE__*/createContext(null);
6
+ const TableSortingProvider = ({
7
+ children,
8
+ sortDescriptor,
9
+ defaultSortDescriptor,
10
+ onSortChange,
11
+ dropdownHeaderContainerRef
12
+ }) => {
13
+ const {
14
+ sortDescriptor: sortedDescriptor,
15
+ onSortDescriptorChange
16
+ } = useSortingTableManager({
17
+ sortDescriptor,
18
+ defaultSortDescriptor,
19
+ onSortChange
20
+ });
21
+ const value = {
22
+ dropdownHeaderContainerRef,
23
+ sortDescriptor: sortedDescriptor || {
24
+ column: '',
25
+ direction: 'ascending'
26
+ },
27
+ onSortDescriptorChange
28
+ };
29
+ return jsx(TableSortingContext.Provider, {
30
+ value: value,
31
+ children: children
32
+ });
33
+ };
34
+ const useTableSortingContext = () => {
35
+ const context = useContext(TableSortingContext);
36
+ if (context === null) {
37
+ throw new Error('useTableSortingContext must be used within a TableSortingProvider');
38
+ }
39
+ return context;
40
+ };
41
+
42
+ export { TableSortingProvider, useTableSortingContext };
@@ -0,0 +1,9 @@
1
+ import { type SortDescriptor } from 'react-aria-components';
2
+ export declare const useSortingTableManager: ({ sortDescriptor: propSortDescriptor, defaultSortDescriptor, onSortChange, }: {
3
+ sortDescriptor?: SortDescriptor;
4
+ defaultSortDescriptor?: SortDescriptor;
5
+ onSortChange?: (sortDescriptor: SortDescriptor) => void;
6
+ }) => {
7
+ sortDescriptor: SortDescriptor | undefined;
8
+ onSortDescriptorChange: (newSortDescriptor: SortDescriptor) => void;
9
+ };
@@ -0,0 +1,36 @@
1
+ import { useCallback } from 'react';
2
+ import { useControllableState } from '../../../utils/useControllableState.js';
3
+
4
+ const useSortingTableManager = ({
5
+ sortDescriptor: propSortDescriptor,
6
+ defaultSortDescriptor,
7
+ onSortChange
8
+ }) => {
9
+ const defaultSort = defaultSortDescriptor || {
10
+ column: '',
11
+ direction: 'descending'
12
+ };
13
+ const [sortDescriptor, setSortDescriptor] = useControllableState({
14
+ prop: propSortDescriptor,
15
+ defaultProp: defaultSort,
16
+ onChange: onSortChange
17
+ });
18
+ const onSortDescriptorChange = useCallback(newSortDescriptor => {
19
+ const isCurrentlySorted = sortDescriptor?.column === newSortDescriptor.column;
20
+ const nextDirection = isCurrentlySorted && sortDescriptor?.direction === 'ascending' ? 'descending' : 'ascending';
21
+ const updatedSortDescriptor = {
22
+ ...newSortDescriptor,
23
+ direction: nextDirection
24
+ };
25
+ if (!propSortDescriptor) {
26
+ setSortDescriptor(updatedSortDescriptor);
27
+ }
28
+ onSortChange?.(updatedSortDescriptor);
29
+ }, [propSortDescriptor, sortDescriptor, setSortDescriptor, onSortChange]);
30
+ return {
31
+ sortDescriptor,
32
+ onSortDescriptorChange
33
+ };
34
+ };
35
+
36
+ export { useSortingTableManager };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@box/blueprint-web",
3
- "version": "9.20.0",
3
+ "version": "10.1.0",
4
4
  "type": "module",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "publishConfig": {