@planningcenter/tapestry 4.11.0-rc.0 → 4.11.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 (52) hide show
  1. package/dist/components/DataTable/DataTable.d.ts +7 -5
  2. package/dist/components/DataTable/DataTable.d.ts.map +1 -1
  3. package/dist/components/DataTable/DataTable.js.map +1 -1
  4. package/dist/components/DataTable/SavedViewsBar.d.ts +5 -2
  5. package/dist/components/DataTable/SavedViewsBar.d.ts.map +1 -1
  6. package/dist/components/DataTable/SavedViewsBar.js +17 -18
  7. package/dist/components/DataTable/SavedViewsBar.js.map +1 -1
  8. package/dist/components/DataTable/savedViews.d.ts +5 -4
  9. package/dist/components/DataTable/savedViews.d.ts.map +1 -1
  10. package/dist/components/DataTable/savedViews.js +4 -3
  11. package/dist/components/DataTable/savedViews.js.map +1 -1
  12. package/dist/components/DataTable/useActiveSavedView.d.ts +7 -0
  13. package/dist/components/DataTable/useActiveSavedView.d.ts.map +1 -0
  14. package/dist/components/DataTable/useActiveSavedView.js +23 -0
  15. package/dist/components/DataTable/useActiveSavedView.js.map +1 -0
  16. package/dist/components/link/IconLink.d.ts +3 -3
  17. package/dist/components/segmented-control/IconSegment.d.ts +1 -1
  18. package/dist/components/segmented-control/Segment.d.ts +1 -1
  19. package/dist/components/segmented-control/SegmentBase.d.ts +1 -1
  20. package/dist/components/sidenav/Sidenav.d.ts.map +1 -1
  21. package/dist/components/sidenav/Sidenav.js +14 -3
  22. package/dist/components/sidenav/Sidenav.js.map +1 -1
  23. package/dist/components/sidenav/SidenavItem.d.ts.map +1 -1
  24. package/dist/components/sidenav/SidenavItem.js +4 -2
  25. package/dist/components/sidenav/SidenavItem.js.map +1 -1
  26. package/dist/components/sidenav/SidenavSection.d.ts +21 -11
  27. package/dist/components/sidenav/SidenavSection.d.ts.map +1 -1
  28. package/dist/components/sidenav/SidenavSection.js +14 -3
  29. package/dist/components/sidenav/SidenavSection.js.map +1 -1
  30. package/dist/components/sidenav/index.js +1 -0
  31. package/dist/components/sidenav/index.js.map +1 -1
  32. package/dist/components/sidenav/private/SidenavResponsiveHeader.d.ts +6 -0
  33. package/dist/components/sidenav/private/SidenavResponsiveHeader.d.ts.map +1 -0
  34. package/dist/components/sidenav/private/SidenavResponsiveHeader.js +12 -0
  35. package/dist/components/sidenav/private/SidenavResponsiveHeader.js.map +1 -0
  36. package/dist/components/sidenav/private/withSlotChildrenAsActions.d.ts +15 -0
  37. package/dist/components/sidenav/private/withSlotChildrenAsActions.d.ts.map +1 -0
  38. package/dist/components/sidenav/private/withSlotChildrenAsActions.js +62 -0
  39. package/dist/components/sidenav/private/withSlotChildrenAsActions.js.map +1 -0
  40. package/dist/index.css +6 -2
  41. package/dist/index.css.map +1 -1
  42. package/dist/reactRender.css +896 -892
  43. package/dist/reactRender.css.map +1 -1
  44. package/dist/reactRenderLegacy.css +896 -892
  45. package/dist/reactRenderLegacy.css.map +1 -1
  46. package/dist/tapestryMount.css +896 -892
  47. package/dist/tapestryMount.css.map +1 -1
  48. package/dist/tapestryMountLegacy.css +896 -892
  49. package/dist/tapestryMountLegacy.css.map +1 -1
  50. package/dist/unstable.css +6 -2
  51. package/dist/unstable.css.map +1 -1
  52. package/package.json +2 -2
@@ -116,11 +116,11 @@ interface DataTableBaseProps {
116
116
  onRowClick?: (row: unknown) => void;
117
117
  /**
118
118
  * Called with the new view when the user saves the current filters, sort,
119
- * and columns as a view. Without it, the new view button is hidden. The
120
- * view arrives without an `id`; pass it back in `savedViews` with one once
121
- * it's saved.
119
+ * and columns as a view. Without it, the new view button is hidden. Return
120
+ * the view's id, or a promise of it, once it's saved; that view is selected
121
+ * once it's passed back in `savedViews`.
122
122
  */
123
- onSavedViewCreate?: (savedView: Omit<SavedView, "id">) => void;
123
+ onSavedViewCreate?: (savedView: Omit<SavedView, "id">) => Promise<SavedView["id"]> | SavedView["id"];
124
124
  /** Callback invoked when the sort state changes. */
125
125
  onSortChange?: (sort: Sort) => void;
126
126
  /**
@@ -188,7 +188,9 @@ interface DataTableBaseProps {
188
188
  rowActions?: RowAction[];
189
189
  /**
190
190
  * Named sets of filters, sort, and hidden columns the user can apply. The
191
- * active view is derived: the first view matching the current state.
191
+ * first view matching the state on mount starts selected; after that, the
192
+ * selection follows the view the user last applied or created, even once
193
+ * the filters, sort, or columns change.
192
194
  */
193
195
  savedViews?: SavedView[];
194
196
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"DataTable.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/DataTable.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DataTable.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/DataTable.tsx"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"DataTable.js","sources":["../../../src/components/DataTable/DataTable.tsx"],"sourcesContent":["import \"./index.css\"\nimport \"./filters.css\"\n\nimport { LoadingSpinner } from \"@components/internal\"\nimport { Pagination } from \"@components/internal/pagination\"\nimport Icon from \"@utilities/Icon\"\nimport type { CombineAriaPropsWithCustomProps } from \"@utilities/reactAriaProps\"\nimport { useId } from \"@utilities/useId\"\nimport classNames from \"classnames\"\nimport React, {\n type ReactNode,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\"\nimport {\n Cell,\n Checkbox,\n Column,\n Row,\n type SortDescriptor,\n Table,\n TableBody,\n TableHeader,\n type TableProps as AriaTableProps,\n} from \"react-aria-components/Table\"\n\nimport { ActiveFilters } from \"./ActiveFilters\"\nimport type { DataTableColumn } from \"./DataTableColumn\"\nimport { prepareColumn, type PreparedColumn } from \"./DataTableColumnTypes\"\nimport { getRowKey } from \"./DataTableRow\"\nimport { FiltersProvider } from \"./FilterContext\"\nimport { FilterControls } from \"./FilterControls\"\nimport { useFilterOpenRequest } from \"./FilterOpenRequest\"\nimport type { ActiveFilter, FilterNode } from \"./FilterTypes\"\nimport { usePendingFilters } from \"./PendingFilterContext\"\nimport {\n hasResultsCount,\n resolveResultNounLabel,\n type ResultNoun,\n ResultsCount,\n} from \"./ResultsCount\"\nimport { type RowAction, RowActions } from \"./RowActions\"\nimport { type SavedView, type SavedViewsOptions } from \"./savedViews\"\nimport { SavedViewsBar } from \"./SavedViewsBar\"\nimport { SelectAllBanner } from \"./SelectAllBanner\"\nimport { type TableAction, TableActions } from \"./TableActions\"\nimport { TableSearch } from \"./TableSearch\"\nimport { useColumnVisibility } from \"./useColumnVisibility\"\nimport {\n type DataTableSelection,\n DataTableSelectionContext,\n useDataTableSelection,\n} from \"./useDataTableSelection\"\nimport { useRowPressBoundary } from \"./useRowPressBoundary\"\nimport { useSearchFilter } from \"./useSearchFilter\"\nimport { useShelfExpanded } from \"./useShelfExpanded\"\nimport { ViewSettingsToggle } from \"./ViewSettingsToggle\"\n\nexport type { DataTableSelection, ResultNoun, RowAction, TableAction }\n\nexport type Sort = { column: string; direction: \"asc\" | \"desc\" }\n\nexport type DataTableLoadingState = \"error\" | \"idle\" | \"loading\"\n\ninterface DataTableBaseProps {\n activeFilters?: ActiveFilter[]\n /**\n * Columns define what data is displayed and how. Pass a stable reference\n * (e.g. a module constant or memoized value); columns are prepared per array\n * identity, so an inline array rebuilds each column's formatter every render.\n */\n columns: DataTableColumn[]\n /**\n * The 1-indexed current page. Only used by the default `\"paged\"` pagination,\n * where `totalPages` is set, and defaults to `1`.\n */\n currentPage?: number\n /** The array of rows to display. */\n data: unknown[]\n /**\n * Row keys that can't be selected. Keys are the values returned by `getRowId`\n * (or `row.id`, or the row's index) — the same keys used by `selectedKeys`.\n * Only selection is disabled: the row's checkbox renders disabled and \"select\n * all\" skips it, while the row itself stays clickable, navigable, and\n * focusable. Has no effect unless the table is `selectable`.\n */\n disabledKeys?: (number | string)[]\n /** Rendered in place of the table body when there is no data. */\n emptyState?: ReactNode\n /** Rendered in place of the table body when `loadingState` is `\"error\"`. */\n errorState?: ReactNode\n /**\n * The filter tree shown in the \"Add filter\" popover. Renders the filter\n * controls in the header when set; omit to leave filtering off entirely.\n */\n filters?: FilterNode[]\n /** Returns a stable identity for each row. Defaults to `row.id`. */\n getRowId?: (row: unknown) => number | string\n /**\n * Returns a URL to navigate to when the row is clicked. Rows with a link\n * render as navigable elements (clickable, keyboard-focusable, and\n * openable in a new tab). Works alongside `onRowClick` and `selectable`.\n */\n getRowLink?: (row: unknown) => string\n /**\n * Whether a page exists after the current one. Only used by\n * `paginationType=\"indexed\"`, which has no page count to derive it from;\n * `false` (the default) disables the Next button.\n */\n hasNextPage?: boolean\n /**\n * Whether a page exists before the current one. Only used by\n * `paginationType=\"indexed\"`, which has no page count to derive it from;\n * `false` (the default) disables the Previous button.\n */\n hasPreviousPage?: boolean\n /**\n * An `id` for the table element. When omitted, a stable generated id is used\n * so the results count can be linked to the table via `aria-describedby`.\n */\n id?: string\n /**\n * Async loading state for the table body.\n * - `\"loading\"`: While `data` is empty, replaces the empty state with a\n * centered spinner. While `data` has rows, keeps them on screen with a\n * spinner over them until new `data` arrives, so a search doesn't blank\n * the table. When requests can overlap, apply only the latest response.\n * - `\"error\"`: While `data` is empty, replaces the empty state with\n * `errorState` (or a default error message).\n * - `\"idle\"` (default): Normal rendering.\n */\n loadingState?: DataTableLoadingState\n /**\n * Called when the active filters change.\n * Provides an argument with the updated active filters array.\n */\n onActiveFiltersChange?: (activeFilters: ActiveFilter[]) => void\n /**\n * Called when the Next button is activated. Only used by\n * `paginationType=\"indexed\"`; load the following page's rows and pass them\n * back in through `data` in response.\n */\n onNextPageClick?: () => void\n /**\n * Called with the 1-indexed page the user navigated to. The table doesn't\n * page `data` itself — pass the rows for the new page back in through `data`\n * (and update `currentPage`) in response. Only used by the default `\"paged\"`\n * pagination; the indexed type has no page number to report.\n */\n onPageChange?: (page: number) => void\n /**\n * Called when the Previous button is activated. Only used by\n * `paginationType=\"indexed\"`; load the preceding page's rows and pass them\n * back in through `data` in response.\n */\n onPreviousPageClick?: () => void\n /**\n * Called with the row when it is clicked. Rows with a click handler render\n * as interactive elements (clickable and keyboard-focusable). When\n * `getRowLink` is also set, both run and the row navigates.\n */\n onRowClick?: (row: unknown) => void\n /**\n * Called with the new view when the user saves the current filters, sort,\n * and columns as a view. Without it, the new view button is hidden. The\n * view arrives without an `id`; pass it back in `savedViews` with one once\n * it's saved.\n */\n onSavedViewCreate?: (savedView: Omit<SavedView, \"id\">) => void\n /** Callback invoked when the sort state changes. */\n onSortChange?: (sort: Sort) => void\n /**\n * Called with the full ordered list of visible column names when the\n * visibility toggle changes. Always-visible columns are included, so the\n * value can be passed straight back as `visibleColumnNames`. Column\n * visibility is controlled, so the table only updates once\n * `visibleColumnNames` changes.\n */\n onVisibleColumnNamesChange?: (visibleColumnNames: string[]) => void\n /**\n * Which shape the page controls take, forwarded to the `Pagination` control's\n * `type`.\n * - `\"paged\"` (the default): a numbered run of pages. Driven by `totalPages`,\n * `currentPage`, and `onPageChange`, and rendered only once `totalPages` is\n * set and greater than `1`.\n * - `\"indexed\"`: a labeled Previous/Next pair, for a result set that can only\n * be stepped through — a cursor-paged API, say, which reports whether a\n * neighboring page exists but not how many there are. Driven by\n * `hasPreviousPage`/`hasNextPage` and `onPreviousPageClick`/\n * `onNextPageClick`; `totalPages` and `currentPage` play no part. With no\n * page count there's no threshold to hide the controls below, so they\n * always render — a single page of results shows both buttons disabled.\n */\n paginationType?: \"indexed\" | \"paged\"\n /**\n * Overrides the number shown by the `resultNoun` count, which otherwise\n * uses the length of `data`. Use this when the table renders only part of\n * the result set — a paginated or virtualized table — so the count reflects\n * the whole set. It also sizes an all-pages selection when\n * `canSelectAllPages` is true, including the count used by table actions and\n * the select-all banner. Without a result count, the banner isn't offered\n * because the table can't accurately describe the all-pages selection.\n * Otherwise, it has no effect unless `resultNoun` is set.\n */\n resultCount?: number\n /**\n * Displays the number of results (the length of `data`, or `resultCount`\n * when supplied) above the table, followed by a noun that matches the count.\n * Pass a string to use it as the singular noun and append `\"s\"` for the\n * plural (e.g. `\"result\"` → `\"results\"`), or a `[singular, plural]` tuple to\n * supply an irregular plural explicitly (e.g. `[\"person\", \"people\"]`). Pass\n * `true` to use `\"result\"`.\n * When `false` or omitted, no count is rendered. The count is formatted with\n * `Intl.NumberFormat` and the singular form is used only when the count is\n * exactly `1`. When the table is `selectable` and rows are selected, the\n * count instead reflects the selection as `\"{selected} of {total}\"`, e.g.\n * `\"2 of 100\"`, with a visually-hidden suffix naming the noun so assistive\n * tech reads the unambiguous `\"2 of 100 people selected\"`.\n * The count is linked to the table with `aria-describedby` so\n * screen readers announce it as a description of the table. When a string or\n * `[singular, plural]` tuple is provided, the noun also supplies the table's\n * `aria-label` in its plural form (e.g. `\"items\"` or `\"people\"`) unless an\n * `aria-label` is passed directly, which always takes precedence; `true`\n * never provides a label. The same plural noun also names the pagination\n * landmark (e.g. `\"people table pagination\"`), which otherwise falls back to\n * `\"Pagination\"`.\n */\n resultNoun?: ResultNoun\n /**\n * Displays a sticky column to the right that holds row-scoped actions.\n * Renders as a dropdown with 2+ actions or a single button with one. Each\n * action's `onAction` or `getHref` receives the row.\n */\n rowActions?: RowAction[]\n /**\n * Named sets of filters, sort, and hidden columns the user can apply. The\n * active view is derived: the first view matching the current state.\n */\n savedViews?: SavedView[]\n /**\n * Turns off creating, editing, or deleting saved views for the whole table.\n * Creating is allowed by default when `onSavedViewCreate` is set.\n */\n savedViewsOptions?: SavedViewsOptions\n /** Ref to the scroll container the sticky header should track. Takes priority over `scrollContainerSelector`. Only used when `stickyHeader` is true. */\n scrollContainerRef?: React.RefObject<HTMLElement>\n /** CSS selector for the scroll container the sticky header should track. Only used when `stickyHeader` is true. Defaults to \".content-wrap\" */\n scrollContainerSelector?: string\n /**\n * Displays a search input above the table. The query is kept in\n * `activeFilters` as a `q` filter and reported through\n * `onActiveFiltersChange` once typing pauses.\n */\n searchable?: boolean\n /**\n * Enables row selection via checkboxes, including a \"select all\" checkbox in\n * the header for the loaded page. Without a row action (`onRowClick` or\n * `getRowLink`), pressing anywhere in a row toggles the row selection.\n */\n selectable?: boolean\n /** The current sort state for the table. */\n sortBy?: Sort\n /** Enables a sticky header that tracks an outer scroll container. Progressive enhancement: Relies on `animation-timeline: scroll()`, which isn't supported in all browsers (e.g. Firefox) — the header scrolls with the table body instead of sticking in those cases. */\n stickyHeader?: boolean\n /**\n * The number of disabled rows across the whole result set. Used to size an\n * all-pages selection when disabled rows exist on unloaded pages. Replaces\n * the count inferred from `disabledKeys` rather than adding to it. Values are\n * clamped to the result count, and zero is used as supplied.\n */\n totalDisabledCount?: number\n /**\n * The total number of pages in the result set. Setting it renders the page\n * controls below the table; leaving it unset renders no pagination at all.\n * A single page has nothing to navigate to, so the controls only render once\n * there are two or more pages. Only used by the default `\"paged\"` pagination\n * — an indexed result set has no page count, which is the reason to reach for\n * `paginationType=\"indexed\"` in the first place.\n *\n * The table displays whatever rows it is given — paging is the caller's job.\n * `data` should hold only the current page's rows, `resultCount` the size of\n * the whole result set, and `onPageChange` should load the next page.\n */\n totalPages?: number\n /**\n * The names of the columns currently visible. Only columns marked `hideable`\n * are affected — every other column stays visible. Omitting this leaves all\n * columns visible. Unknown names are ignored and display order always\n * follows `columns`.\n */\n visibleColumnNames?: string[]\n}\n\ninterface DataTableExplicitSelectionProps {\n /** Keeps selection values as arrays of row keys. */\n canSelectAllPages?: false\n /** Called with the selected row keys whenever selection changes. */\n onSelectedChange?: (keys: (number | string)[]) => void\n /** The selected row keys. */\n selectedKeys?: (number | string)[]\n /** Table actions whose callbacks receive the selected row keys. */\n tableActions?: TableAction[]\n}\n\ninterface DataTableAllPagesSelectionProps {\n /**\n * Enables tagged selection values that can represent every page plus\n * exclusions. Explicit arrays and the header checkbox remain page-scoped.\n * When `resultCount` proves more selectable results exist, selecting the\n * loaded page reveals a banner that widens the selection to every page or\n * clears it again. This works with both paged and indexed pagination.\n */\n canSelectAllPages: true\n /** Called with the current explicit or all-pages selection. */\n onSelectedChange?: (selection: DataTableSelection) => void\n /**\n * The current explicit or all-pages selection. Use\n * `{ keys: \"all\", excludedKeys: [] }` for every selectable result; a bare\n * `\"all\"` value is not accepted.\n */\n selectedKeys?: DataTableSelection\n /** Table actions whose callbacks receive the current selection. */\n tableActions?: TableAction<DataTableSelection>[]\n}\n\nexport type DataTableProps = DataTableBaseProps &\n (DataTableAllPagesSelectionProps | DataTableExplicitSelectionProps)\n\nconst DEFAULT_ERROR_STATE = \"Something went wrong.\"\n\ntype AriaTablePropsToOmit = \"children\" | \"slot\"\n\ntype AriaTablePropsToInclude = never\n\nexport type DataTableElementProps = CombineAriaPropsWithCustomProps<\n AriaTableProps,\n DataTableProps,\n AriaTablePropsToOmit,\n AriaTablePropsToInclude\n>\n\n/**\n * A table for displaying tabular data. Built on React Aria's `Table`.\n *\n * Each column declares a `type` that controls how its cell values are\n * formatted: `string`, `number`, `currency`, `date`, `datetime`, `boolean`,\n * `enum`, and `custom`. A column's `render` function always takes precedence\n * over the built-in type formatting.\n *\n * Setting `totalPages` renders page controls below the table; the table itself\n * never slices `data`, so `onPageChange` is where the caller loads the page.\n * `paginationType=\"indexed\"` swaps the numbered run for a labeled\n * Previous/Next pair, for a result set with no known page count.\n *\n * Filtering, presets, and other RFC features are not yet implemented.\n *\n * @component\n */\nexport const DataTable = ({\n activeFilters = [],\n filters = [],\n ...props\n}: DataTableElementProps) => (\n <FiltersProvider activeFilters={activeFilters} filters={filters}>\n <DataTableInner\n {...props}\n activeFilters={activeFilters}\n filters={filters}\n />\n </FiltersProvider>\n)\n\nconst DataTableInner = ({\n activeFilters = [],\n className,\n canSelectAllPages,\n columns,\n currentPage = 1,\n data,\n disabledKeys,\n emptyState,\n errorState,\n filters = [],\n getRowId,\n getRowLink,\n hasNextPage = false,\n hasPreviousPage = false,\n id,\n loadingState = \"idle\",\n paginationType = \"paged\",\n resultCount,\n resultNoun,\n scrollContainerRef,\n scrollContainerSelector = \".content-wrap\",\n rowActions,\n savedViews,\n searchable,\n selectable,\n selectedKeys: controlledSelectedKeys,\n stickyHeader,\n sortBy,\n tableActions,\n totalDisabledCount,\n totalPages,\n visibleColumnNames,\n onActiveFiltersChange = () => {},\n onNextPageClick,\n onPageChange,\n onPreviousPageClick,\n onRowClick,\n onSavedViewCreate,\n onSelectedChange,\n onSortChange,\n onVisibleColumnNamesChange,\n savedViewsOptions,\n ...restProps\n}: DataTableElementProps) => {\n const hasRowPressAction = Boolean(onRowClick || getRowLink)\n const rowsAreInteractive = hasRowPressAction || Boolean(selectable)\n const combinedClassName = classNames(\"tds-data-table-grid\", className)\n const sortDescriptor = useSortDescriptor(sortBy)\n const { hasScrollContainer, wrapperRef } = useStickyHeader(\n stickyHeader,\n scrollContainerRef,\n scrollContainerSelector\n )\n const scrollRef = useRef<HTMLDivElement>(null)\n // A `Button` or `Link` in a cell keeps its presses to itself, so activating\n // one doesn't also press the row it's in.\n const cellBoundaryProps = useRowPressBoundary(scrollRef, rowsAreInteractive)\n\n // React Aria only invokes `renderEmptyState` when the collection is empty, so\n // the loading spinner and error message only take over the body while `data`\n // is empty; once rows exist they always render.\n const emptyStateContent = getEmptyStateContent({\n emptyState,\n errorState,\n loadingState,\n })\n const renderEmptyState = emptyStateContent\n ? () => emptyStateContent\n : undefined\n // With rows on screen, loading keeps them in place under a spinner instead.\n const showLoadingOverlay = loadingState === \"loading\" && data.length > 0\n\n // Keyed on column names rather than the `columns` array identity so a fresh\n // `columns` literal each render doesn't rebuild every formatter. `columns` is\n // intentionally omitted from the deps.\n const columnKey = columns.map((c) => `${c.name}/${c.type}`).join(\"|\")\n const preparedColumns = useMemo<PreparedColumn[]>(\n () => columns.map(prepareColumn),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [columnKey]\n )\n\n const {\n hideableColumns,\n isColumnVisible,\n onColumnVisibilityChange,\n visibleHideableColumns,\n } = useColumnVisibility({\n columns,\n onVisibleColumnNamesChange,\n visibleColumnNames,\n })\n\n const applySavedView = (savedView: SavedView) => {\n onActiveFiltersChange(savedView.activeFilters)\n if (savedView.sort) onSortChange?.(savedView.sort)\n if (savedView.hiddenColumnNames) {\n const hiddenNames = new Set(savedView.hiddenColumnNames)\n onColumnVisibilityChange(\n hideableColumns\n .filter(({ name }) => !hiddenNames.has(name))\n .map(({ name }) => name)\n )\n }\n }\n\n const visiblePreparedColumns = useMemo(\n () => preparedColumns.filter(({ column }) => isColumnVisible(column)),\n [preparedColumns, isColumnVisible]\n )\n\n const selectionModel = useDataTableSelection({\n canSelectAllPages,\n data,\n disabledKeys,\n getRowId,\n hasRowPressAction,\n onSelectedChange,\n resultCount,\n selectable,\n selectedKeys: controlledSelectedKeys,\n totalDisabledCount,\n })\n const {\n headerCheckboxProps,\n rowPressSelects,\n selectedCount,\n tableProps: selectionProps,\n totalCount,\n } = selectionModel\n\n // Associate the visible results count with the table so screen readers\n // announce it as a description of the table. `Table` doesn't support a real\n // `<caption>` (its children go through a collection builder), so we link the\n // count via `aria-describedby`, merging with any caller-supplied value.\n const stableId = useId()\n const tableId = id || `tds-data-table-${stableId}`\n const resultsCountId = `${tableId}-results-count`\n const describedBy = hasResultsCount(resultNoun)\n ? [restProps[\"aria-describedby\"], resultsCountId].filter(Boolean).join(\" \")\n : restProps[\"aria-describedby\"]\n\n // A caller-supplied `aria-label` always wins; otherwise the results noun\n // provides the table's accessible name so a label is present whenever a noun\n // is given. Array nouns are transformed to their plural form.\n const resultNounLabel = resolveResultNounLabel(resultNoun)\n const ariaLabel = restProps[\"aria-label\"] || resultNounLabel\n const paginationLabel = resultNounLabel\n ? `${resultNounLabel} table pagination`\n : undefined\n const searchLabel = ariaLabel ? `Search ${ariaLabel}` : \"Search table\"\n\n const hasActions = (tableActions?.length ?? 0) > 0\n const hasFilters = (filters.length ?? 0) > 0\n const hasViewSettingsToggle = hideableColumns.length > 0\n const hasTrailingControls = searchable || hasFilters || hasViewSettingsToggle\n const hasResults = hasResultsCount(resultNoun) || hasActions\n const showHeader = hasResults || Boolean(hasTrailingControls)\n const hasRowActions = (rowActions?.length ?? 0) > 0\n const { pendingFilters } = usePendingFilters()\n const {\n chipFilters,\n clearFilters,\n onChipFiltersChange,\n onSearchChange,\n searchQuery,\n } = useSearchFilter(activeFilters, onActiveFiltersChange)\n const hasEditableFilters = chipFilters.length + pendingFilters.length > 0\n const { filterOpenRequest } = useFilterOpenRequest()\n const [isShelfExpanded, toggleShelf] = useShelfExpanded(\n chipFilters.length + pendingFilters.length,\n pendingFilters.length,\n filterOpenRequest\n )\n // Keeps collapsed shelf content out of tab order/a11y tree. Needs a string,\n // not a boolean — `inert` isn't in `@types/react@18` or recognized by\n // react-dom as a boolean attribute before React 19.\n const shelfInertProps = { inert: isShelfExpanded ? undefined : \"\" } as {\n inert?: string\n }\n // A lone page has nothing to navigate to, so the paged controls stay out of\n // the frame entirely rather than rendering a single inert page marker. The\n // indexed type has no page count to measure against — stepping is the only\n // way through the set — so asking for it always renders the controls, and a\n // set that fits on one page shows both buttons disabled.\n const isIndexedPagination = paginationType === \"indexed\"\n const showPagination =\n isIndexedPagination || (totalPages !== undefined && totalPages > 1)\n\n return (\n <div\n className={classNames(\"tds-data-table\", {\n \"tds-data-table--sticky-header\": hasScrollContainer,\n })}\n >\n {Array.isArray(savedViews) && (\n <SavedViewsBar\n savedViews={savedViews}\n onApply={applySavedView}\n onCreate={\n savedViewsOptions?.creatable === false\n ? undefined\n : onSavedViewCreate\n }\n activeFilters={activeFilters}\n hideableColumns={hideableColumns}\n isColumnVisible={isColumnVisible}\n savedViewsOptions={savedViewsOptions}\n sortBy={sortBy}\n />\n )}\n <div className=\"tds-data-table-frame\">\n <DataTableSelectionContext.Provider value={selectionModel}>\n {showHeader && (\n <div className=\"tds-data-table-frame-header\">\n <div className=\"tds-data-table-frame-header-content\">\n {hasResults && (\n <div className=\"tds-data-table-frame-header-results\">\n <ResultsCount\n id={resultsCountId}\n resultNoun={resultNoun}\n selectable={selectable}\n selectedCount={selectedCount}\n totalCount={totalCount}\n />\n {hasActions && (\n <TableActions\n actions={\n tableActions as TableAction<DataTableSelection>[]\n }\n resultNoun={resultNoun}\n />\n )}\n </div>\n )}\n {hasTrailingControls && (\n <div className=\"tds-data-table-frame-header-controls\">\n {searchable && (\n <TableSearch\n label={searchLabel}\n tableId={tableId}\n value={searchQuery}\n onChange={onSearchChange}\n />\n )}\n {hasFilters && (\n <FilterControls\n activeFilters={chipFilters}\n filters={filters}\n isShelfExpanded={isShelfExpanded}\n onToggleShelf={toggleShelf}\n />\n )}\n {hasViewSettingsToggle && (\n <ViewSettingsToggle\n columns={hideableColumns}\n onColumnVisibilityChange={onColumnVisibilityChange}\n visibleColumnNames={visibleHideableColumns}\n />\n )}\n </div>\n )}\n </div>\n </div>\n )}\n {(hasFilters || hasEditableFilters) && (\n <div\n className={classNames(\"tds-data-table-filters-shelf\", {\n \"tds-data-table-filters-shelf--collapsed\": !isShelfExpanded,\n })}\n {...shelfInertProps}\n >\n <div className=\"tds-data-table-filters\">\n {hasEditableFilters && (\n <ActiveFilters\n activeFilters={chipFilters}\n hasFilters={hasFilters}\n onActiveFiltersChange={onChipFiltersChange}\n onClear={clearFilters}\n />\n )}\n </div>\n </div>\n )}\n <SelectAllBanner resultNoun={resultNoun} />\n </DataTableSelectionContext.Provider>\n <div ref={wrapperRef} className=\"tds-data-table-scroll-wrapper\">\n <div\n ref={scrollRef}\n className=\"tds-data-table-scroll\"\n // Set here because RAC's `Table` doesn't forward `aria-busy`.\n aria-busy={showLoadingOverlay || undefined}\n >\n <Table\n {...restProps}\n {...selectionProps}\n {...(ariaLabel ? { \"aria-label\": ariaLabel } : {})}\n {...(describedBy ? { \"aria-describedby\": describedBy } : {})}\n // RAC's `Table` forwards `id` to the underlying table element at\n // runtime (via `filterDOMProps({ global: true })`) but omits `id`\n // from its prop types, so spread it through a cast.\n {...({ id: tableId } as Partial<AriaTableProps>)}\n className={combinedClassName}\n // Pinned rather than exposed as a prop: `disabledKeys` only ever\n // turns off selection here, leaving the row clickable and\n // focusable. React Aria defaults this to \"all\", which would also\n // disable `onRowClick`/`getRowLink` and drop the row out of the\n // focus order, so it has to be set explicitly.\n disabledBehavior=\"selection\"\n disabledKeys={disabledKeys}\n sortDescriptor={sortDescriptor}\n onSortChange={(sort) => {\n onSortChange?.(serializeSort(sort))\n }}\n >\n <TableHeader className=\"tds-data-table-header\">\n {/*\n Rendered as a sibling before the `preparedColumns.map` below\n (not folded into it) so the map's `index` still starts at 0\n for the first *data* column — that's what keeps\n `isRowHeader={index === 0}` pointing at the first data\n column instead of this selection column.\n */}\n {selectable && (\n <Column className=\"tds-data-table-column tds-data-table-column--selectable\">\n {headerCheckboxProps ? (\n <Checkbox\n {...headerCheckboxProps}\n aria-label=\"Select all\"\n slot={null}\n className=\"tds-data-table-selectable-checkbox\"\n />\n ) : (\n <Checkbox\n slot=\"selection\"\n className=\"tds-data-table-selectable-checkbox\"\n />\n )}\n </Column>\n )}\n {visiblePreparedColumns.map(({ align, column }, index) => (\n <Column\n key={column.name}\n id={column.name}\n isRowHeader={index === 0}\n className={classNames(\"tds-data-table-column\", {\n [`tds-data-table-column--align-${align}`]:\n align !== \"start\",\n })}\n allowsSorting={column.sortable}\n >\n {column.hideLabel ? (\n <span className=\"tds-data-table-column-label--hidden\">\n {column.headerLabel}\n </span>\n ) : (\n column.headerLabel\n )}\n {column.sortable && (\n <Icon\n className=\"tds-data-table-column-icon tds-data-table-column-icon--sort\"\n symbol=\"general#up-caret\"\n aria-hidden={true}\n />\n )}\n </Column>\n ))}\n {hasRowActions && (\n <Column className=\"tds-data-table-column tds-data-table-column--actions\">\n <span className=\"tds-data-table-column-label--hidden\">\n Actions\n </span>\n </Column>\n )}\n </TableHeader>\n <TableBody\n className=\"tds-data-table-body\"\n renderEmptyState={renderEmptyState}\n >\n {data.map((row, rowIndex) => {\n const rowKey = getRowKey(row, rowIndex, getRowId)\n return (\n <Row\n key={rowKey}\n id={rowKey}\n href={getRowLink?.(row)}\n onAction={onRowClick ? () => onRowClick(row) : undefined}\n className={classNames(\"tds-data-table-row\", {\n \"tds-data-table-row--interactive\": rowsAreInteractive,\n \"tds-data-table-row--press-selects\": rowPressSelects,\n })}\n >\n {selectable && (\n <Cell className=\"tds-data-table-cell tds-data-table-cell--selectable\">\n <Checkbox\n slot=\"selection\"\n className=\"tds-data-table-selectable-checkbox\"\n />\n </Cell>\n )}\n {visiblePreparedColumns.map((prepared) => (\n <Cell\n key={prepared.column.name}\n {...cellBoundaryProps}\n data-pii={prepared.column.pii || undefined}\n className={classNames(\"tds-data-table-cell\", {\n [`tds-data-table-cell--align-${prepared.align}`]:\n prepared.align !== \"start\",\n \"tds-data-table-cell--numeric\": prepared.isNumeric,\n })}\n >\n {prepared.renderCell(row)}\n </Cell>\n ))}\n {hasRowActions && (\n <Cell\n {...cellBoundaryProps}\n className=\"tds-data-table-cell tds-data-table-cell--actions\"\n >\n <RowActions\n actions={rowActions!} // Safe to assert non-null here because of `hasRowActions`\n row={row}\n rowKey={rowKey}\n />\n </Cell>\n )}\n </Row>\n )\n })}\n </TableBody>\n </Table>\n </div>\n {showLoadingOverlay && (\n <div className=\"tds-data-table-loading-overlay\" role=\"status\">\n <span className=\"tds-data-table-loading-label--hidden\">\n Loading\n </span>\n <span\n className=\"tds-data-table-loading-spinner\"\n aria-hidden=\"true\"\n >\n <LoadingSpinner />\n </span>\n </div>\n )}\n </div>\n {showPagination && (\n <div className=\"tds-data-table-frame-footer\">\n {/*\n `Pagination`'s two shapes are a discriminated union, so each is\n spelled out in full rather than assembled from one prop bag.\n */}\n {isIndexedPagination ? (\n <Pagination\n aria-label={paginationLabel}\n hasNextPage={hasNextPage}\n hasPreviousPage={hasPreviousPage}\n onNextPageClick={onNextPageClick}\n onPreviousPageClick={onPreviousPageClick}\n type=\"indexed\"\n />\n ) : (\n <Pagination\n aria-label={paginationLabel}\n currentPage={currentPage}\n onPageChange={onPageChange}\n totalPages={totalPages!}\n />\n )}\n </div>\n )}\n </div>\n </div>\n )\n}\n\nDataTable.displayName = \"DataTable\"\n\n/**\n * Resolves the content rendered in the table body's empty-state slot based on\n * `loadingState`, falling back to `emptyState`. Returns `null` when nothing\n * should render (idle with no `emptyState`).\n */\nfunction getEmptyStateContent({\n emptyState,\n errorState,\n loadingState,\n}: {\n emptyState: ReactNode\n errorState: ReactNode\n loadingState: DataTableLoadingState\n}): ReactNode {\n if (loadingState === \"loading\") {\n return (\n <div className=\"tds-data-table-loading\" role=\"status\">\n <span className=\"tds-data-table-cell-label--hidden\">Loading</span>\n <span className=\"tds-data-table-loading-spinner\" aria-hidden=\"true\">\n <LoadingSpinner />\n </span>\n </div>\n )\n }\n\n // Error and empty share the same container; they differ only in content.\n const content =\n loadingState === \"error\" ? (errorState ?? DEFAULT_ERROR_STATE) : emptyState\n if (content == null) return null\n\n return <div className=\"tds-data-table-empty\">{content}</div>\n}\n\nfunction useSortDescriptor(\n sortBy: Sort | undefined\n): SortDescriptor | undefined {\n return useMemo(() => {\n if (!sortBy) return undefined\n return deserializeSort(sortBy)\n }, [sortBy])\n}\n\nfunction deserializeSort(sort: Sort): SortDescriptor {\n if (sort.direction === \"desc\")\n return { column: sort.column, direction: \"descending\" }\n return { column: sort.column, direction: \"ascending\" }\n}\n\nfunction serializeSort(sort: SortDescriptor): Sort {\n if (sort.direction === \"descending\")\n return { column: sort.column as string, direction: \"desc\" }\n return { column: sort.column as string, direction: \"asc\" }\n}\n\nfunction useStickyHeader(\n stickyHeader: boolean | undefined,\n scrollContainerRef: React.RefObject<HTMLElement> | undefined,\n scrollContainerSelector: string | undefined\n) {\n const wrapperRef = useRef<HTMLDivElement>(null)\n const [hasScrollContainer, setHasScrollContainer] = useState(false)\n\n useLayoutEffect(() => {\n setHasScrollContainer(false)\n if (!stickyHeader) return\n if (typeof ResizeObserver === \"undefined\") return\n const wrapper = wrapperRef.current\n if (!wrapper) return\n\n const scrollContainer = getScrollContainer(\n scrollContainerRef,\n scrollContainerSelector,\n wrapper\n )\n if (!scrollContainer) return\n\n setHasScrollContainer(true)\n\n let thead: HTMLElement | null = null\n\n const resizeObserver = new ResizeObserver(() => {\n if (!thead) {\n thead = wrapper.querySelector<HTMLElement>(\".tds-data-table-header\")\n if (!thead) return\n scrollContainer.style.setProperty(\n \"scroll-timeline-name\",\n \"--_sticky-header-scroll\"\n )\n }\n\n const { top: wrapperTop, bottom: wrapperBottom } =\n wrapper.getBoundingClientRect()\n const { top: scrollContainerTop } =\n scrollContainer.getBoundingClientRect()\n // Derive headerTop from the untransformed wrapper to avoid reading the\n // scroll-driven translateY that getBoundingClientRect() includes on thead.\n const headerTop = wrapperTop + wrapper.clientTop\n const start = scrollContainer.scrollTop + (headerTop - scrollContainerTop)\n const max = Math.max(0, wrapperBottom - headerTop - thead.offsetHeight)\n wrapper.style.setProperty(\"--_sticky-header-scroll-start\", `${start}px`)\n wrapper.style.setProperty(\"--_sticky-header-scroll-max\", `${max}px`)\n })\n\n resizeObserver.observe(wrapper)\n // The banner moves the wrapper without changing its size.\n if (wrapper.parentElement) resizeObserver.observe(wrapper.parentElement)\n resizeObserver.observe(scrollContainer)\n\n return () => {\n resizeObserver.disconnect()\n wrapper.style.removeProperty(\"--_sticky-header-scroll-start\")\n wrapper.style.removeProperty(\"--_sticky-header-scroll-max\")\n }\n }, [stickyHeader, scrollContainerRef, scrollContainerSelector])\n\n return { hasScrollContainer, wrapperRef }\n}\n\nfunction getScrollContainer(\n scrollContainerRef: React.RefObject<HTMLElement> | undefined,\n scrollContainerSelector: string | undefined,\n wrapper: HTMLElement\n): HTMLElement | undefined {\n const element =\n scrollContainerRef?.current ??\n getScrollContainerFromSelector(scrollContainerSelector, wrapper)\n if (element instanceof Window) return\n return element\n}\n\nfunction getScrollContainerFromSelector(\n scrollContainerSelector: string | undefined,\n wrapper: HTMLElement\n): HTMLElement | undefined {\n return scrollContainerSelector\n ? (wrapper.parentElement?.closest<HTMLElement>(scrollContainerSelector) ??\n undefined)\n : undefined\n}\n"],"names":["React"],"mappings":"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"}
1
+ {"version":3,"file":"DataTable.js","sources":["../../../src/components/DataTable/DataTable.tsx"],"sourcesContent":["import \"./index.css\"\nimport \"./filters.css\"\n\nimport { LoadingSpinner } from \"@components/internal\"\nimport { Pagination } from \"@components/internal/pagination\"\nimport Icon from \"@utilities/Icon\"\nimport type { CombineAriaPropsWithCustomProps } from \"@utilities/reactAriaProps\"\nimport { useId } from \"@utilities/useId\"\nimport classNames from \"classnames\"\nimport React, {\n type ReactNode,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\"\nimport {\n Cell,\n Checkbox,\n Column,\n Row,\n type SortDescriptor,\n Table,\n TableBody,\n TableHeader,\n type TableProps as AriaTableProps,\n} from \"react-aria-components/Table\"\n\nimport { ActiveFilters } from \"./ActiveFilters\"\nimport type { DataTableColumn } from \"./DataTableColumn\"\nimport { prepareColumn, type PreparedColumn } from \"./DataTableColumnTypes\"\nimport { getRowKey } from \"./DataTableRow\"\nimport { FiltersProvider } from \"./FilterContext\"\nimport { FilterControls } from \"./FilterControls\"\nimport { useFilterOpenRequest } from \"./FilterOpenRequest\"\nimport type { ActiveFilter, FilterNode } from \"./FilterTypes\"\nimport { usePendingFilters } from \"./PendingFilterContext\"\nimport {\n hasResultsCount,\n resolveResultNounLabel,\n type ResultNoun,\n ResultsCount,\n} from \"./ResultsCount\"\nimport { type RowAction, RowActions } from \"./RowActions\"\nimport { type SavedView, type SavedViewsOptions } from \"./savedViews\"\nimport { SavedViewsBar } from \"./SavedViewsBar\"\nimport { SelectAllBanner } from \"./SelectAllBanner\"\nimport { type TableAction, TableActions } from \"./TableActions\"\nimport { TableSearch } from \"./TableSearch\"\nimport { useColumnVisibility } from \"./useColumnVisibility\"\nimport {\n type DataTableSelection,\n DataTableSelectionContext,\n useDataTableSelection,\n} from \"./useDataTableSelection\"\nimport { useRowPressBoundary } from \"./useRowPressBoundary\"\nimport { useSearchFilter } from \"./useSearchFilter\"\nimport { useShelfExpanded } from \"./useShelfExpanded\"\nimport { ViewSettingsToggle } from \"./ViewSettingsToggle\"\n\nexport type { DataTableSelection, ResultNoun, RowAction, TableAction }\n\nexport type Sort = { column: string; direction: \"asc\" | \"desc\" }\n\nexport type DataTableLoadingState = \"error\" | \"idle\" | \"loading\"\n\ninterface DataTableBaseProps {\n activeFilters?: ActiveFilter[]\n /**\n * Columns define what data is displayed and how. Pass a stable reference\n * (e.g. a module constant or memoized value); columns are prepared per array\n * identity, so an inline array rebuilds each column's formatter every render.\n */\n columns: DataTableColumn[]\n /**\n * The 1-indexed current page. Only used by the default `\"paged\"` pagination,\n * where `totalPages` is set, and defaults to `1`.\n */\n currentPage?: number\n /** The array of rows to display. */\n data: unknown[]\n /**\n * Row keys that can't be selected. Keys are the values returned by `getRowId`\n * (or `row.id`, or the row's index) — the same keys used by `selectedKeys`.\n * Only selection is disabled: the row's checkbox renders disabled and \"select\n * all\" skips it, while the row itself stays clickable, navigable, and\n * focusable. Has no effect unless the table is `selectable`.\n */\n disabledKeys?: (number | string)[]\n /** Rendered in place of the table body when there is no data. */\n emptyState?: ReactNode\n /** Rendered in place of the table body when `loadingState` is `\"error\"`. */\n errorState?: ReactNode\n /**\n * The filter tree shown in the \"Add filter\" popover. Renders the filter\n * controls in the header when set; omit to leave filtering off entirely.\n */\n filters?: FilterNode[]\n /** Returns a stable identity for each row. Defaults to `row.id`. */\n getRowId?: (row: unknown) => number | string\n /**\n * Returns a URL to navigate to when the row is clicked. Rows with a link\n * render as navigable elements (clickable, keyboard-focusable, and\n * openable in a new tab). Works alongside `onRowClick` and `selectable`.\n */\n getRowLink?: (row: unknown) => string\n /**\n * Whether a page exists after the current one. Only used by\n * `paginationType=\"indexed\"`, which has no page count to derive it from;\n * `false` (the default) disables the Next button.\n */\n hasNextPage?: boolean\n /**\n * Whether a page exists before the current one. Only used by\n * `paginationType=\"indexed\"`, which has no page count to derive it from;\n * `false` (the default) disables the Previous button.\n */\n hasPreviousPage?: boolean\n /**\n * An `id` for the table element. When omitted, a stable generated id is used\n * so the results count can be linked to the table via `aria-describedby`.\n */\n id?: string\n /**\n * Async loading state for the table body.\n * - `\"loading\"`: While `data` is empty, replaces the empty state with a\n * centered spinner. While `data` has rows, keeps them on screen with a\n * spinner over them until new `data` arrives, so a search doesn't blank\n * the table. When requests can overlap, apply only the latest response.\n * - `\"error\"`: While `data` is empty, replaces the empty state with\n * `errorState` (or a default error message).\n * - `\"idle\"` (default): Normal rendering.\n */\n loadingState?: DataTableLoadingState\n /**\n * Called when the active filters change.\n * Provides an argument with the updated active filters array.\n */\n onActiveFiltersChange?: (activeFilters: ActiveFilter[]) => void\n /**\n * Called when the Next button is activated. Only used by\n * `paginationType=\"indexed\"`; load the following page's rows and pass them\n * back in through `data` in response.\n */\n onNextPageClick?: () => void\n /**\n * Called with the 1-indexed page the user navigated to. The table doesn't\n * page `data` itself — pass the rows for the new page back in through `data`\n * (and update `currentPage`) in response. Only used by the default `\"paged\"`\n * pagination; the indexed type has no page number to report.\n */\n onPageChange?: (page: number) => void\n /**\n * Called when the Previous button is activated. Only used by\n * `paginationType=\"indexed\"`; load the preceding page's rows and pass them\n * back in through `data` in response.\n */\n onPreviousPageClick?: () => void\n /**\n * Called with the row when it is clicked. Rows with a click handler render\n * as interactive elements (clickable and keyboard-focusable). When\n * `getRowLink` is also set, both run and the row navigates.\n */\n onRowClick?: (row: unknown) => void\n /**\n * Called with the new view when the user saves the current filters, sort,\n * and columns as a view. Without it, the new view button is hidden. Return\n * the view's id, or a promise of it, once it's saved; that view is selected\n * once it's passed back in `savedViews`.\n */\n onSavedViewCreate?: (\n savedView: Omit<SavedView, \"id\">\n ) => Promise<SavedView[\"id\"]> | SavedView[\"id\"]\n /** Callback invoked when the sort state changes. */\n onSortChange?: (sort: Sort) => void\n /**\n * Called with the full ordered list of visible column names when the\n * visibility toggle changes. Always-visible columns are included, so the\n * value can be passed straight back as `visibleColumnNames`. Column\n * visibility is controlled, so the table only updates once\n * `visibleColumnNames` changes.\n */\n onVisibleColumnNamesChange?: (visibleColumnNames: string[]) => void\n /**\n * Which shape the page controls take, forwarded to the `Pagination` control's\n * `type`.\n * - `\"paged\"` (the default): a numbered run of pages. Driven by `totalPages`,\n * `currentPage`, and `onPageChange`, and rendered only once `totalPages` is\n * set and greater than `1`.\n * - `\"indexed\"`: a labeled Previous/Next pair, for a result set that can only\n * be stepped through — a cursor-paged API, say, which reports whether a\n * neighboring page exists but not how many there are. Driven by\n * `hasPreviousPage`/`hasNextPage` and `onPreviousPageClick`/\n * `onNextPageClick`; `totalPages` and `currentPage` play no part. With no\n * page count there's no threshold to hide the controls below, so they\n * always render — a single page of results shows both buttons disabled.\n */\n paginationType?: \"indexed\" | \"paged\"\n /**\n * Overrides the number shown by the `resultNoun` count, which otherwise\n * uses the length of `data`. Use this when the table renders only part of\n * the result set — a paginated or virtualized table — so the count reflects\n * the whole set. It also sizes an all-pages selection when\n * `canSelectAllPages` is true, including the count used by table actions and\n * the select-all banner. Without a result count, the banner isn't offered\n * because the table can't accurately describe the all-pages selection.\n * Otherwise, it has no effect unless `resultNoun` is set.\n */\n resultCount?: number\n /**\n * Displays the number of results (the length of `data`, or `resultCount`\n * when supplied) above the table, followed by a noun that matches the count.\n * Pass a string to use it as the singular noun and append `\"s\"` for the\n * plural (e.g. `\"result\"` → `\"results\"`), or a `[singular, plural]` tuple to\n * supply an irregular plural explicitly (e.g. `[\"person\", \"people\"]`). Pass\n * `true` to use `\"result\"`.\n * When `false` or omitted, no count is rendered. The count is formatted with\n * `Intl.NumberFormat` and the singular form is used only when the count is\n * exactly `1`. When the table is `selectable` and rows are selected, the\n * count instead reflects the selection as `\"{selected} of {total}\"`, e.g.\n * `\"2 of 100\"`, with a visually-hidden suffix naming the noun so assistive\n * tech reads the unambiguous `\"2 of 100 people selected\"`.\n * The count is linked to the table with `aria-describedby` so\n * screen readers announce it as a description of the table. When a string or\n * `[singular, plural]` tuple is provided, the noun also supplies the table's\n * `aria-label` in its plural form (e.g. `\"items\"` or `\"people\"`) unless an\n * `aria-label` is passed directly, which always takes precedence; `true`\n * never provides a label. The same plural noun also names the pagination\n * landmark (e.g. `\"people table pagination\"`), which otherwise falls back to\n * `\"Pagination\"`.\n */\n resultNoun?: ResultNoun\n /**\n * Displays a sticky column to the right that holds row-scoped actions.\n * Renders as a dropdown with 2+ actions or a single button with one. Each\n * action's `onAction` or `getHref` receives the row.\n */\n rowActions?: RowAction[]\n /**\n * Named sets of filters, sort, and hidden columns the user can apply. The\n * first view matching the state on mount starts selected; after that, the\n * selection follows the view the user last applied or created, even once\n * the filters, sort, or columns change.\n */\n savedViews?: SavedView[]\n /**\n * Turns off creating, editing, or deleting saved views for the whole table.\n * Creating is allowed by default when `onSavedViewCreate` is set.\n */\n savedViewsOptions?: SavedViewsOptions\n /** Ref to the scroll container the sticky header should track. Takes priority over `scrollContainerSelector`. Only used when `stickyHeader` is true. */\n scrollContainerRef?: React.RefObject<HTMLElement>\n /** CSS selector for the scroll container the sticky header should track. Only used when `stickyHeader` is true. Defaults to \".content-wrap\" */\n scrollContainerSelector?: string\n /**\n * Displays a search input above the table. The query is kept in\n * `activeFilters` as a `q` filter and reported through\n * `onActiveFiltersChange` once typing pauses.\n */\n searchable?: boolean\n /**\n * Enables row selection via checkboxes, including a \"select all\" checkbox in\n * the header for the loaded page. Without a row action (`onRowClick` or\n * `getRowLink`), pressing anywhere in a row toggles the row selection.\n */\n selectable?: boolean\n /** The current sort state for the table. */\n sortBy?: Sort\n /** Enables a sticky header that tracks an outer scroll container. Progressive enhancement: Relies on `animation-timeline: scroll()`, which isn't supported in all browsers (e.g. Firefox) — the header scrolls with the table body instead of sticking in those cases. */\n stickyHeader?: boolean\n /**\n * The number of disabled rows across the whole result set. Used to size an\n * all-pages selection when disabled rows exist on unloaded pages. Replaces\n * the count inferred from `disabledKeys` rather than adding to it. Values are\n * clamped to the result count, and zero is used as supplied.\n */\n totalDisabledCount?: number\n /**\n * The total number of pages in the result set. Setting it renders the page\n * controls below the table; leaving it unset renders no pagination at all.\n * A single page has nothing to navigate to, so the controls only render once\n * there are two or more pages. Only used by the default `\"paged\"` pagination\n * — an indexed result set has no page count, which is the reason to reach for\n * `paginationType=\"indexed\"` in the first place.\n *\n * The table displays whatever rows it is given — paging is the caller's job.\n * `data` should hold only the current page's rows, `resultCount` the size of\n * the whole result set, and `onPageChange` should load the next page.\n */\n totalPages?: number\n /**\n * The names of the columns currently visible. Only columns marked `hideable`\n * are affected — every other column stays visible. Omitting this leaves all\n * columns visible. Unknown names are ignored and display order always\n * follows `columns`.\n */\n visibleColumnNames?: string[]\n}\n\ninterface DataTableExplicitSelectionProps {\n /** Keeps selection values as arrays of row keys. */\n canSelectAllPages?: false\n /** Called with the selected row keys whenever selection changes. */\n onSelectedChange?: (keys: (number | string)[]) => void\n /** The selected row keys. */\n selectedKeys?: (number | string)[]\n /** Table actions whose callbacks receive the selected row keys. */\n tableActions?: TableAction[]\n}\n\ninterface DataTableAllPagesSelectionProps {\n /**\n * Enables tagged selection values that can represent every page plus\n * exclusions. Explicit arrays and the header checkbox remain page-scoped.\n * When `resultCount` proves more selectable results exist, selecting the\n * loaded page reveals a banner that widens the selection to every page or\n * clears it again. This works with both paged and indexed pagination.\n */\n canSelectAllPages: true\n /** Called with the current explicit or all-pages selection. */\n onSelectedChange?: (selection: DataTableSelection) => void\n /**\n * The current explicit or all-pages selection. Use\n * `{ keys: \"all\", excludedKeys: [] }` for every selectable result; a bare\n * `\"all\"` value is not accepted.\n */\n selectedKeys?: DataTableSelection\n /** Table actions whose callbacks receive the current selection. */\n tableActions?: TableAction<DataTableSelection>[]\n}\n\nexport type DataTableProps = DataTableBaseProps &\n (DataTableAllPagesSelectionProps | DataTableExplicitSelectionProps)\n\nconst DEFAULT_ERROR_STATE = \"Something went wrong.\"\n\ntype AriaTablePropsToOmit = \"children\" | \"slot\"\n\ntype AriaTablePropsToInclude = never\n\nexport type DataTableElementProps = CombineAriaPropsWithCustomProps<\n AriaTableProps,\n DataTableProps,\n AriaTablePropsToOmit,\n AriaTablePropsToInclude\n>\n\n/**\n * A table for displaying tabular data. Built on React Aria's `Table`.\n *\n * Each column declares a `type` that controls how its cell values are\n * formatted: `string`, `number`, `currency`, `date`, `datetime`, `boolean`,\n * `enum`, and `custom`. A column's `render` function always takes precedence\n * over the built-in type formatting.\n *\n * Setting `totalPages` renders page controls below the table; the table itself\n * never slices `data`, so `onPageChange` is where the caller loads the page.\n * `paginationType=\"indexed\"` swaps the numbered run for a labeled\n * Previous/Next pair, for a result set with no known page count.\n *\n * Filtering, presets, and other RFC features are not yet implemented.\n *\n * @component\n */\nexport const DataTable = ({\n activeFilters = [],\n filters = [],\n ...props\n}: DataTableElementProps) => (\n <FiltersProvider activeFilters={activeFilters} filters={filters}>\n <DataTableInner\n {...props}\n activeFilters={activeFilters}\n filters={filters}\n />\n </FiltersProvider>\n)\n\nconst DataTableInner = ({\n activeFilters = [],\n className,\n canSelectAllPages,\n columns,\n currentPage = 1,\n data,\n disabledKeys,\n emptyState,\n errorState,\n filters = [],\n getRowId,\n getRowLink,\n hasNextPage = false,\n hasPreviousPage = false,\n id,\n loadingState = \"idle\",\n paginationType = \"paged\",\n resultCount,\n resultNoun,\n scrollContainerRef,\n scrollContainerSelector = \".content-wrap\",\n rowActions,\n savedViews,\n searchable,\n selectable,\n selectedKeys: controlledSelectedKeys,\n stickyHeader,\n sortBy,\n tableActions,\n totalDisabledCount,\n totalPages,\n visibleColumnNames,\n onActiveFiltersChange = () => {},\n onNextPageClick,\n onPageChange,\n onPreviousPageClick,\n onRowClick,\n onSavedViewCreate,\n onSelectedChange,\n onSortChange,\n onVisibleColumnNamesChange,\n savedViewsOptions,\n ...restProps\n}: DataTableElementProps) => {\n const hasRowPressAction = Boolean(onRowClick || getRowLink)\n const rowsAreInteractive = hasRowPressAction || Boolean(selectable)\n const combinedClassName = classNames(\"tds-data-table-grid\", className)\n const sortDescriptor = useSortDescriptor(sortBy)\n const { hasScrollContainer, wrapperRef } = useStickyHeader(\n stickyHeader,\n scrollContainerRef,\n scrollContainerSelector\n )\n const scrollRef = useRef<HTMLDivElement>(null)\n // A `Button` or `Link` in a cell keeps its presses to itself, so activating\n // one doesn't also press the row it's in.\n const cellBoundaryProps = useRowPressBoundary(scrollRef, rowsAreInteractive)\n\n // React Aria only invokes `renderEmptyState` when the collection is empty, so\n // the loading spinner and error message only take over the body while `data`\n // is empty; once rows exist they always render.\n const emptyStateContent = getEmptyStateContent({\n emptyState,\n errorState,\n loadingState,\n })\n const renderEmptyState = emptyStateContent\n ? () => emptyStateContent\n : undefined\n // With rows on screen, loading keeps them in place under a spinner instead.\n const showLoadingOverlay = loadingState === \"loading\" && data.length > 0\n\n // Keyed on column names rather than the `columns` array identity so a fresh\n // `columns` literal each render doesn't rebuild every formatter. `columns` is\n // intentionally omitted from the deps.\n const columnKey = columns.map((c) => `${c.name}/${c.type}`).join(\"|\")\n const preparedColumns = useMemo<PreparedColumn[]>(\n () => columns.map(prepareColumn),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [columnKey]\n )\n\n const {\n hideableColumns,\n isColumnVisible,\n onColumnVisibilityChange,\n visibleHideableColumns,\n } = useColumnVisibility({\n columns,\n onVisibleColumnNamesChange,\n visibleColumnNames,\n })\n\n const applySavedView = (savedView: SavedView) => {\n onActiveFiltersChange(savedView.activeFilters)\n if (savedView.sort) onSortChange?.(savedView.sort)\n if (savedView.hiddenColumnNames) {\n const hiddenNames = new Set(savedView.hiddenColumnNames)\n onColumnVisibilityChange(\n hideableColumns\n .filter(({ name }) => !hiddenNames.has(name))\n .map(({ name }) => name)\n )\n }\n }\n\n const visiblePreparedColumns = useMemo(\n () => preparedColumns.filter(({ column }) => isColumnVisible(column)),\n [preparedColumns, isColumnVisible]\n )\n\n const selectionModel = useDataTableSelection({\n canSelectAllPages,\n data,\n disabledKeys,\n getRowId,\n hasRowPressAction,\n onSelectedChange,\n resultCount,\n selectable,\n selectedKeys: controlledSelectedKeys,\n totalDisabledCount,\n })\n const {\n headerCheckboxProps,\n rowPressSelects,\n selectedCount,\n tableProps: selectionProps,\n totalCount,\n } = selectionModel\n\n // Associate the visible results count with the table so screen readers\n // announce it as a description of the table. `Table` doesn't support a real\n // `<caption>` (its children go through a collection builder), so we link the\n // count via `aria-describedby`, merging with any caller-supplied value.\n const stableId = useId()\n const tableId = id || `tds-data-table-${stableId}`\n const resultsCountId = `${tableId}-results-count`\n const describedBy = hasResultsCount(resultNoun)\n ? [restProps[\"aria-describedby\"], resultsCountId].filter(Boolean).join(\" \")\n : restProps[\"aria-describedby\"]\n\n // A caller-supplied `aria-label` always wins; otherwise the results noun\n // provides the table's accessible name so a label is present whenever a noun\n // is given. Array nouns are transformed to their plural form.\n const resultNounLabel = resolveResultNounLabel(resultNoun)\n const ariaLabel = restProps[\"aria-label\"] || resultNounLabel\n const paginationLabel = resultNounLabel\n ? `${resultNounLabel} table pagination`\n : undefined\n const searchLabel = ariaLabel ? `Search ${ariaLabel}` : \"Search table\"\n\n const hasActions = (tableActions?.length ?? 0) > 0\n const hasFilters = (filters.length ?? 0) > 0\n const hasViewSettingsToggle = hideableColumns.length > 0\n const hasTrailingControls = searchable || hasFilters || hasViewSettingsToggle\n const hasResults = hasResultsCount(resultNoun) || hasActions\n const showHeader = hasResults || Boolean(hasTrailingControls)\n const hasRowActions = (rowActions?.length ?? 0) > 0\n const { pendingFilters } = usePendingFilters()\n const {\n chipFilters,\n clearFilters,\n onChipFiltersChange,\n onSearchChange,\n searchQuery,\n } = useSearchFilter(activeFilters, onActiveFiltersChange)\n const hasEditableFilters = chipFilters.length + pendingFilters.length > 0\n const { filterOpenRequest } = useFilterOpenRequest()\n const [isShelfExpanded, toggleShelf] = useShelfExpanded(\n chipFilters.length + pendingFilters.length,\n pendingFilters.length,\n filterOpenRequest\n )\n // Keeps collapsed shelf content out of tab order/a11y tree. Needs a string,\n // not a boolean — `inert` isn't in `@types/react@18` or recognized by\n // react-dom as a boolean attribute before React 19.\n const shelfInertProps = { inert: isShelfExpanded ? undefined : \"\" } as {\n inert?: string\n }\n // A lone page has nothing to navigate to, so the paged controls stay out of\n // the frame entirely rather than rendering a single inert page marker. The\n // indexed type has no page count to measure against — stepping is the only\n // way through the set — so asking for it always renders the controls, and a\n // set that fits on one page shows both buttons disabled.\n const isIndexedPagination = paginationType === \"indexed\"\n const showPagination =\n isIndexedPagination || (totalPages !== undefined && totalPages > 1)\n\n return (\n <div\n className={classNames(\"tds-data-table\", {\n \"tds-data-table--sticky-header\": hasScrollContainer,\n })}\n >\n {Array.isArray(savedViews) && (\n <SavedViewsBar\n savedViews={savedViews}\n onApply={applySavedView}\n onCreate={\n savedViewsOptions?.creatable === false\n ? undefined\n : onSavedViewCreate\n }\n activeFilters={activeFilters}\n hideableColumns={hideableColumns}\n isColumnVisible={isColumnVisible}\n savedViewsOptions={savedViewsOptions}\n sortBy={sortBy}\n />\n )}\n <div className=\"tds-data-table-frame\">\n <DataTableSelectionContext.Provider value={selectionModel}>\n {showHeader && (\n <div className=\"tds-data-table-frame-header\">\n <div className=\"tds-data-table-frame-header-content\">\n {hasResults && (\n <div className=\"tds-data-table-frame-header-results\">\n <ResultsCount\n id={resultsCountId}\n resultNoun={resultNoun}\n selectable={selectable}\n selectedCount={selectedCount}\n totalCount={totalCount}\n />\n {hasActions && (\n <TableActions\n actions={\n tableActions as TableAction<DataTableSelection>[]\n }\n resultNoun={resultNoun}\n />\n )}\n </div>\n )}\n {hasTrailingControls && (\n <div className=\"tds-data-table-frame-header-controls\">\n {searchable && (\n <TableSearch\n label={searchLabel}\n tableId={tableId}\n value={searchQuery}\n onChange={onSearchChange}\n />\n )}\n {hasFilters && (\n <FilterControls\n activeFilters={chipFilters}\n filters={filters}\n isShelfExpanded={isShelfExpanded}\n onToggleShelf={toggleShelf}\n />\n )}\n {hasViewSettingsToggle && (\n <ViewSettingsToggle\n columns={hideableColumns}\n onColumnVisibilityChange={onColumnVisibilityChange}\n visibleColumnNames={visibleHideableColumns}\n />\n )}\n </div>\n )}\n </div>\n </div>\n )}\n {(hasFilters || hasEditableFilters) && (\n <div\n className={classNames(\"tds-data-table-filters-shelf\", {\n \"tds-data-table-filters-shelf--collapsed\": !isShelfExpanded,\n })}\n {...shelfInertProps}\n >\n <div className=\"tds-data-table-filters\">\n {hasEditableFilters && (\n <ActiveFilters\n activeFilters={chipFilters}\n hasFilters={hasFilters}\n onActiveFiltersChange={onChipFiltersChange}\n onClear={clearFilters}\n />\n )}\n </div>\n </div>\n )}\n <SelectAllBanner resultNoun={resultNoun} />\n </DataTableSelectionContext.Provider>\n <div ref={wrapperRef} className=\"tds-data-table-scroll-wrapper\">\n <div\n ref={scrollRef}\n className=\"tds-data-table-scroll\"\n // Set here because RAC's `Table` doesn't forward `aria-busy`.\n aria-busy={showLoadingOverlay || undefined}\n >\n <Table\n {...restProps}\n {...selectionProps}\n {...(ariaLabel ? { \"aria-label\": ariaLabel } : {})}\n {...(describedBy ? { \"aria-describedby\": describedBy } : {})}\n // RAC's `Table` forwards `id` to the underlying table element at\n // runtime (via `filterDOMProps({ global: true })`) but omits `id`\n // from its prop types, so spread it through a cast.\n {...({ id: tableId } as Partial<AriaTableProps>)}\n className={combinedClassName}\n // Pinned rather than exposed as a prop: `disabledKeys` only ever\n // turns off selection here, leaving the row clickable and\n // focusable. React Aria defaults this to \"all\", which would also\n // disable `onRowClick`/`getRowLink` and drop the row out of the\n // focus order, so it has to be set explicitly.\n disabledBehavior=\"selection\"\n disabledKeys={disabledKeys}\n sortDescriptor={sortDescriptor}\n onSortChange={(sort) => {\n onSortChange?.(serializeSort(sort))\n }}\n >\n <TableHeader className=\"tds-data-table-header\">\n {/*\n Rendered as a sibling before the `preparedColumns.map` below\n (not folded into it) so the map's `index` still starts at 0\n for the first *data* column — that's what keeps\n `isRowHeader={index === 0}` pointing at the first data\n column instead of this selection column.\n */}\n {selectable && (\n <Column className=\"tds-data-table-column tds-data-table-column--selectable\">\n {headerCheckboxProps ? (\n <Checkbox\n {...headerCheckboxProps}\n aria-label=\"Select all\"\n slot={null}\n className=\"tds-data-table-selectable-checkbox\"\n />\n ) : (\n <Checkbox\n slot=\"selection\"\n className=\"tds-data-table-selectable-checkbox\"\n />\n )}\n </Column>\n )}\n {visiblePreparedColumns.map(({ align, column }, index) => (\n <Column\n key={column.name}\n id={column.name}\n isRowHeader={index === 0}\n className={classNames(\"tds-data-table-column\", {\n [`tds-data-table-column--align-${align}`]:\n align !== \"start\",\n })}\n allowsSorting={column.sortable}\n >\n {column.hideLabel ? (\n <span className=\"tds-data-table-column-label--hidden\">\n {column.headerLabel}\n </span>\n ) : (\n column.headerLabel\n )}\n {column.sortable && (\n <Icon\n className=\"tds-data-table-column-icon tds-data-table-column-icon--sort\"\n symbol=\"general#up-caret\"\n aria-hidden={true}\n />\n )}\n </Column>\n ))}\n {hasRowActions && (\n <Column className=\"tds-data-table-column tds-data-table-column--actions\">\n <span className=\"tds-data-table-column-label--hidden\">\n Actions\n </span>\n </Column>\n )}\n </TableHeader>\n <TableBody\n className=\"tds-data-table-body\"\n renderEmptyState={renderEmptyState}\n >\n {data.map((row, rowIndex) => {\n const rowKey = getRowKey(row, rowIndex, getRowId)\n return (\n <Row\n key={rowKey}\n id={rowKey}\n href={getRowLink?.(row)}\n onAction={onRowClick ? () => onRowClick(row) : undefined}\n className={classNames(\"tds-data-table-row\", {\n \"tds-data-table-row--interactive\": rowsAreInteractive,\n \"tds-data-table-row--press-selects\": rowPressSelects,\n })}\n >\n {selectable && (\n <Cell className=\"tds-data-table-cell tds-data-table-cell--selectable\">\n <Checkbox\n slot=\"selection\"\n className=\"tds-data-table-selectable-checkbox\"\n />\n </Cell>\n )}\n {visiblePreparedColumns.map((prepared) => (\n <Cell\n key={prepared.column.name}\n {...cellBoundaryProps}\n data-pii={prepared.column.pii || undefined}\n className={classNames(\"tds-data-table-cell\", {\n [`tds-data-table-cell--align-${prepared.align}`]:\n prepared.align !== \"start\",\n \"tds-data-table-cell--numeric\": prepared.isNumeric,\n })}\n >\n {prepared.renderCell(row)}\n </Cell>\n ))}\n {hasRowActions && (\n <Cell\n {...cellBoundaryProps}\n className=\"tds-data-table-cell tds-data-table-cell--actions\"\n >\n <RowActions\n actions={rowActions!} // Safe to assert non-null here because of `hasRowActions`\n row={row}\n rowKey={rowKey}\n />\n </Cell>\n )}\n </Row>\n )\n })}\n </TableBody>\n </Table>\n </div>\n {showLoadingOverlay && (\n <div className=\"tds-data-table-loading-overlay\" role=\"status\">\n <span className=\"tds-data-table-loading-label--hidden\">\n Loading\n </span>\n <span\n className=\"tds-data-table-loading-spinner\"\n aria-hidden=\"true\"\n >\n <LoadingSpinner />\n </span>\n </div>\n )}\n </div>\n {showPagination && (\n <div className=\"tds-data-table-frame-footer\">\n {/*\n `Pagination`'s two shapes are a discriminated union, so each is\n spelled out in full rather than assembled from one prop bag.\n */}\n {isIndexedPagination ? (\n <Pagination\n aria-label={paginationLabel}\n hasNextPage={hasNextPage}\n hasPreviousPage={hasPreviousPage}\n onNextPageClick={onNextPageClick}\n onPreviousPageClick={onPreviousPageClick}\n type=\"indexed\"\n />\n ) : (\n <Pagination\n aria-label={paginationLabel}\n currentPage={currentPage}\n onPageChange={onPageChange}\n totalPages={totalPages!}\n />\n )}\n </div>\n )}\n </div>\n </div>\n )\n}\n\nDataTable.displayName = \"DataTable\"\n\n/**\n * Resolves the content rendered in the table body's empty-state slot based on\n * `loadingState`, falling back to `emptyState`. Returns `null` when nothing\n * should render (idle with no `emptyState`).\n */\nfunction getEmptyStateContent({\n emptyState,\n errorState,\n loadingState,\n}: {\n emptyState: ReactNode\n errorState: ReactNode\n loadingState: DataTableLoadingState\n}): ReactNode {\n if (loadingState === \"loading\") {\n return (\n <div className=\"tds-data-table-loading\" role=\"status\">\n <span className=\"tds-data-table-cell-label--hidden\">Loading</span>\n <span className=\"tds-data-table-loading-spinner\" aria-hidden=\"true\">\n <LoadingSpinner />\n </span>\n </div>\n )\n }\n\n // Error and empty share the same container; they differ only in content.\n const content =\n loadingState === \"error\" ? (errorState ?? DEFAULT_ERROR_STATE) : emptyState\n if (content == null) return null\n\n return <div className=\"tds-data-table-empty\">{content}</div>\n}\n\nfunction useSortDescriptor(\n sortBy: Sort | undefined\n): SortDescriptor | undefined {\n return useMemo(() => {\n if (!sortBy) return undefined\n return deserializeSort(sortBy)\n }, [sortBy])\n}\n\nfunction deserializeSort(sort: Sort): SortDescriptor {\n if (sort.direction === \"desc\")\n return { column: sort.column, direction: \"descending\" }\n return { column: sort.column, direction: \"ascending\" }\n}\n\nfunction serializeSort(sort: SortDescriptor): Sort {\n if (sort.direction === \"descending\")\n return { column: sort.column as string, direction: \"desc\" }\n return { column: sort.column as string, direction: \"asc\" }\n}\n\nfunction useStickyHeader(\n stickyHeader: boolean | undefined,\n scrollContainerRef: React.RefObject<HTMLElement> | undefined,\n scrollContainerSelector: string | undefined\n) {\n const wrapperRef = useRef<HTMLDivElement>(null)\n const [hasScrollContainer, setHasScrollContainer] = useState(false)\n\n useLayoutEffect(() => {\n setHasScrollContainer(false)\n if (!stickyHeader) return\n if (typeof ResizeObserver === \"undefined\") return\n const wrapper = wrapperRef.current\n if (!wrapper) return\n\n const scrollContainer = getScrollContainer(\n scrollContainerRef,\n scrollContainerSelector,\n wrapper\n )\n if (!scrollContainer) return\n\n setHasScrollContainer(true)\n\n let thead: HTMLElement | null = null\n\n const resizeObserver = new ResizeObserver(() => {\n if (!thead) {\n thead = wrapper.querySelector<HTMLElement>(\".tds-data-table-header\")\n if (!thead) return\n scrollContainer.style.setProperty(\n \"scroll-timeline-name\",\n \"--_sticky-header-scroll\"\n )\n }\n\n const { top: wrapperTop, bottom: wrapperBottom } =\n wrapper.getBoundingClientRect()\n const { top: scrollContainerTop } =\n scrollContainer.getBoundingClientRect()\n // Derive headerTop from the untransformed wrapper to avoid reading the\n // scroll-driven translateY that getBoundingClientRect() includes on thead.\n const headerTop = wrapperTop + wrapper.clientTop\n const start = scrollContainer.scrollTop + (headerTop - scrollContainerTop)\n const max = Math.max(0, wrapperBottom - headerTop - thead.offsetHeight)\n wrapper.style.setProperty(\"--_sticky-header-scroll-start\", `${start}px`)\n wrapper.style.setProperty(\"--_sticky-header-scroll-max\", `${max}px`)\n })\n\n resizeObserver.observe(wrapper)\n // The banner moves the wrapper without changing its size.\n if (wrapper.parentElement) resizeObserver.observe(wrapper.parentElement)\n resizeObserver.observe(scrollContainer)\n\n return () => {\n resizeObserver.disconnect()\n wrapper.style.removeProperty(\"--_sticky-header-scroll-start\")\n wrapper.style.removeProperty(\"--_sticky-header-scroll-max\")\n }\n }, [stickyHeader, scrollContainerRef, scrollContainerSelector])\n\n return { hasScrollContainer, wrapperRef }\n}\n\nfunction getScrollContainer(\n scrollContainerRef: React.RefObject<HTMLElement> | undefined,\n scrollContainerSelector: string | undefined,\n wrapper: HTMLElement\n): HTMLElement | undefined {\n const element =\n scrollContainerRef?.current ??\n getScrollContainerFromSelector(scrollContainerSelector, wrapper)\n if (element instanceof Window) return\n return element\n}\n\nfunction getScrollContainerFromSelector(\n scrollContainerSelector: string | undefined,\n wrapper: HTMLElement\n): HTMLElement | undefined {\n return scrollContainerSelector\n ? (wrapper.parentElement?.closest<HTMLElement>(scrollContainerSelector) ??\n undefined)\n : undefined\n}\n"],"names":["React"],"mappings":"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"}
@@ -8,8 +8,11 @@ export interface SavedViewsBarProps {
8
8
  hideableColumns: DataTableColumn[];
9
9
  isColumnVisible: (column: DataTableColumn) => boolean;
10
10
  onApply: (savedView: SavedView) => void;
11
- /** Omit to hide the new view button and the context menu. */
12
- onCreate?: (savedView: Omit<SavedView, "id">) => void;
11
+ /**
12
+ * Returns the new view's id. Omit to hide the new view button and the
13
+ * context menu.
14
+ */
15
+ onCreate?: (savedView: Omit<SavedView, "id">) => Promise<SavedView["id"]> | SavedView["id"];
13
16
  savedViews: SavedView[];
14
17
  savedViewsOptions?: SavedViewsOptions;
15
18
  sortBy: Sort | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"SavedViewsBar.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/SavedViewsBar.tsx"],"names":[],"mappings":"AAKA,OAAO,KAQN,MAAM,OAAO,CAAA;AAId,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAIjD,OAAO,EAEL,KAAK,SAAS,EACd,KAAK,iBAAiB,EACvB,MAAM,cAAc,CAAA;AAErB,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,YAAY,EAAE,CAAA;IAC7B,eAAe,EAAE,eAAe,EAAE,CAAA;IAClC,eAAe,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,OAAO,CAAA;IACrD,OAAO,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,IAAI,CAAA;IACvC,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,IAAI,CAAA;IACrD,UAAU,EAAE,SAAS,EAAE,CAAA;IACvB,iBAAiB,CAAC,EAAE,iBAAiB,CAAA;IACrC,MAAM,EAAE,IAAI,GAAG,SAAS,CAAA;CACzB;AAED,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EACP,QAAQ,EACR,UAAU,EACV,aAAa,EACb,eAAe,EACf,eAAe,EACf,MAAM,GACP,EAAE,kBAAkB,qBAuHpB;yBA/He,aAAa"}
1
+ {"version":3,"file":"SavedViewsBar.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/SavedViewsBar.tsx"],"names":[],"mappings":"AAKA,OAAO,KAQN,MAAM,OAAO,CAAA;AAId,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAIjD,OAAO,EAEL,KAAK,SAAS,EACd,KAAK,iBAAiB,EACvB,MAAM,cAAc,CAAA;AAGrB,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,YAAY,EAAE,CAAA;IAC7B,eAAe,EAAE,eAAe,EAAE,CAAA;IAClC,eAAe,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,OAAO,CAAA;IACrD,OAAO,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,IAAI,CAAA;IACvC;;;OAGG;IACH,QAAQ,CAAC,EAAE,CACT,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,KAC7B,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAA;IAC/C,UAAU,EAAE,SAAS,EAAE,CAAA;IACvB,iBAAiB,CAAC,EAAE,iBAAiB,CAAA;IACrC,MAAM,EAAE,IAAI,GAAG,SAAS,CAAA;CACzB;AAED,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EACP,QAAQ,EACR,UAAU,EACV,aAAa,EACb,eAAe,EACf,eAAe,EACf,MAAM,GACP,EAAE,kBAAkB,qBA2HpB;yBAnIe,aAAa"}
@@ -7,6 +7,7 @@ import { ManageSavedViewsButton } from './ManageSavedViewsButton.js';
7
7
  import { NewSavedViewButton } from './NewSavedViewButton.js';
8
8
  import { NewSavedViewModal } from './NewSavedViewModal.js';
9
9
  import { findActiveSavedView } from './savedViews.js';
10
+ import { useActiveSavedView } from './useActiveSavedView.js';
10
11
 
11
12
  function SavedViewsBar({ onApply, onCreate, savedViews, activeFilters, hideableColumns, isColumnVisible, sortBy, }) {
12
13
  const closeOpenContextMenuRef = useRef(null);
@@ -18,11 +19,11 @@ function SavedViewsBar({ onApply, onCreate, savedViews, activeFilters, hideableC
18
19
  const hiddenColumnNames = hideableColumns
19
20
  .filter((column) => !isColumnVisible(column))
20
21
  .map(({ name }) => name);
21
- const activeSavedView = findActiveSavedView(savedViews, {
22
+ const { activeSavedView, select, selectWhenSaved } = useActiveSavedView(savedViews, () => findActiveSavedView(savedViews, {
22
23
  activeFilters,
23
24
  hiddenColumnNames,
24
25
  sort: sortBy,
25
- });
26
+ }));
26
27
  const openDraft = (title, view) => {
27
28
  setDraft({ title, view });
28
29
  setIsDraftOpen(true);
@@ -41,9 +42,10 @@ function SavedViewsBar({ onApply, onCreate, savedViews, activeFilters, hideableC
41
42
  openDraft("Duplicate view", { ...view, name: `${view.name} copy` });
42
43
  };
43
44
  const saveDraft = (name) => {
44
- if (draft)
45
- onCreate?.({ ...draft.view, name });
46
45
  setIsDraftOpen(false);
46
+ if (!draft || !onCreate)
47
+ return;
48
+ selectWhenSaved(onCreate({ ...draft.view, name }));
47
49
  };
48
50
  const renderContextMenu = (view) => {
49
51
  if (!onCreate)
@@ -51,27 +53,24 @@ function SavedViewsBar({ onApply, onCreate, savedViews, activeFilters, hideableC
51
53
  return (React__default.createElement(DropdownMenu, null,
52
54
  React__default.createElement(DropdownAction, { id: "duplicate", onAction: () => duplicateSavedView(view) }, "Duplicate")));
53
55
  };
54
- const items = savedViews.map((view, index) => ({
55
- id: view.id ?? `index-${index}`,
56
- view,
57
- }));
58
- const activeItem = items.find(({ view }) => view === activeSavedView);
59
56
  return (React__default.createElement("div", { className: "tds-data-table-saved-views" },
60
57
  React__default.createElement("div", { className: "tds-data-table-saved-views-list" },
61
- items.length > 0 && (React__default.createElement(ReorderableListBox, { items: items, label: "Saved views", selectedKey: activeItem?.id ?? null, onSelectionChange: (key) => {
62
- const item = items.find(({ id }) => id === key);
63
- if (item)
64
- onApply(item.view);
65
- } }, (item) => {
66
- const menu = renderContextMenu(item.view);
67
- return (React__default.createElement(ReorderableListBoxItem, { className: "tds-data-table-saved-view-list-item", id: item.id, render: menu
58
+ savedViews.length > 0 && (React__default.createElement(ReorderableListBox, { items: savedViews, label: "Saved views", selectedKey: activeSavedView?.id ?? null, onSelectionChange: (key) => {
59
+ const view = savedViews.find(({ id }) => id === key);
60
+ if (!view)
61
+ return;
62
+ select(view);
63
+ onApply(view);
64
+ } }, (view) => {
65
+ const menu = renderContextMenu(view);
66
+ return (React__default.createElement(ReorderableListBoxItem, { className: "tds-data-table-saved-view-list-item", id: view.id, render: menu
68
67
  ? (props) => (React__default.createElement(ContextMenuTrigger, { closeOpenContextMenuRef: closeOpenContextMenuRef, menu: menu, optionProps: props }))
69
- : undefined }, item.view.name));
68
+ : undefined }, view.name));
70
69
  })),
71
70
  onCreate && (React__default.createElement(React__default.Fragment, null,
72
71
  React__default.createElement(NewSavedViewButton, { onClick: openNewSavedView }),
73
72
  React__default.createElement(NewSavedViewModal, { defaultName: draft?.view.name, open: isDraftOpen, title: draft?.title, onClose: () => setIsDraftOpen(false), onSave: saveDraft })))),
74
- items.length > 0 && React__default.createElement(ManageSavedViewsButton, null)));
73
+ savedViews.length > 0 && React__default.createElement(ManageSavedViewsButton, null)));
75
74
  }
76
75
  SavedViewsBar.displayName = "SavedViewsBar";
77
76
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"SavedViewsBar.js","sources":["../../../src/components/DataTable/SavedViewsBar.tsx"],"sourcesContent":["import { DropdownAction, DropdownMenu } from \"@components/dropdown\"\nimport {\n ReorderableListBox,\n ReorderableListBoxItem,\n} from \"@components/internal/reorderable-list-box\"\nimport React, {\n type ComponentProps,\n Fragment,\n type MutableRefObject,\n type ReactElement,\n useCallback,\n useRef,\n useState,\n} from \"react\"\nimport { mergeProps } from \"react-aria/mergeProps\"\nimport { MenuTrigger, Pressable } from \"react-aria-components/Menu\"\n\nimport type { Sort } from \"./DataTable\"\nimport type { DataTableColumn } from \"./DataTableColumn\"\nimport type { ActiveFilter } from \"./FilterTypes\"\nimport { ManageSavedViewsButton } from \"./ManageSavedViewsButton\"\nimport { NewSavedViewButton } from \"./NewSavedViewButton\"\nimport { NewSavedViewModal } from \"./NewSavedViewModal\"\nimport {\n findActiveSavedView,\n type SavedView,\n type SavedViewsOptions,\n} from \"./savedViews\"\n\nexport interface SavedViewsBarProps {\n activeFilters: ActiveFilter[]\n hideableColumns: DataTableColumn[]\n isColumnVisible: (column: DataTableColumn) => boolean\n onApply: (savedView: SavedView) => void\n /** Omit to hide the new view button and the context menu. */\n onCreate?: (savedView: Omit<SavedView, \"id\">) => void\n savedViews: SavedView[]\n savedViewsOptions?: SavedViewsOptions\n sortBy: Sort | undefined\n}\n\nexport function SavedViewsBar({\n onApply,\n onCreate,\n savedViews,\n activeFilters,\n hideableColumns,\n isColumnVisible,\n sortBy,\n}: SavedViewsBarProps) {\n const closeOpenContextMenuRef = useRef<(() => void) | null>(null)\n // The view the new view modal will save, under the name entered there. It\n // outlives the modal's open state so the title holds while the modal fades\n // out.\n const [draft, setDraft] = useState<{ title: string; view: SavedView }>()\n const [isDraftOpen, setIsDraftOpen] = useState(false)\n const hiddenColumnNames = hideableColumns\n .filter((column) => !isColumnVisible(column))\n .map(({ name }) => name)\n const activeSavedView = findActiveSavedView(savedViews, {\n activeFilters,\n hiddenColumnNames,\n sort: sortBy,\n })\n\n const openDraft = (title: string, view: SavedView) => {\n setDraft({ title, view })\n setIsDraftOpen(true)\n }\n\n const openNewSavedView = () => {\n openDraft(\"New view\", {\n activeFilters,\n name: \"\",\n ...(hideableColumns.length > 0 && { hiddenColumnNames }),\n ...(sortBy && { sort: sortBy }),\n })\n }\n\n // The copy is a new view, so it doesn't keep the original's id or its\n // per-view permission overrides.\n const duplicateSavedView = ({\n deletable: _deletable,\n editable: _editable,\n id: _id,\n ...view\n }: SavedView) => {\n openDraft(\"Duplicate view\", { ...view, name: `${view.name} copy` })\n }\n\n const saveDraft = (name: string) => {\n if (draft) onCreate?.({ ...draft.view, name })\n setIsDraftOpen(false)\n }\n\n const renderContextMenu = (view: SavedView) => {\n if (!onCreate) return null\n return (\n <DropdownMenu>\n <DropdownAction\n id=\"duplicate\"\n onAction={() => duplicateSavedView(view)}\n >\n Duplicate\n </DropdownAction>\n </DropdownMenu>\n )\n }\n\n const items = savedViews.map((view, index) => ({\n id: view.id ?? `index-${index}`,\n view,\n }))\n const activeItem = items.find(({ view }) => view === activeSavedView)\n\n return (\n <div className=\"tds-data-table-saved-views\">\n <div className=\"tds-data-table-saved-views-list\">\n {items.length > 0 && (\n <ReorderableListBox\n items={items}\n label=\"Saved views\"\n selectedKey={activeItem?.id ?? null}\n onSelectionChange={(key) => {\n const item = items.find(({ id }) => id === key)\n if (item) onApply(item.view)\n }}\n >\n {(item) => {\n const menu = renderContextMenu(item.view)\n return (\n <ReorderableListBoxItem\n className=\"tds-data-table-saved-view-list-item\"\n id={item.id}\n render={\n menu\n ? (props) => (\n <ContextMenuTrigger\n closeOpenContextMenuRef={closeOpenContextMenuRef}\n menu={menu}\n optionProps={props as ComponentProps<\"div\">}\n />\n )\n : undefined\n }\n >\n {item.view.name}\n </ReorderableListBoxItem>\n )\n }}\n </ReorderableListBox>\n )}\n {onCreate && (\n <>\n <NewSavedViewButton onClick={openNewSavedView} />\n <NewSavedViewModal\n defaultName={draft?.view.name}\n open={isDraftOpen}\n title={draft?.title}\n onClose={() => setIsDraftOpen(false)}\n onSave={saveDraft}\n />\n </>\n )}\n </div>\n {items.length > 0 && <ManageSavedViewsButton />}\n </div>\n )\n}\n\nSavedViewsBar.displayName = \"SavedViewsBar\"\n\n/**\n * Makes a saved view's option element itself the context menu trigger, so\n * the menu opens by right click, long press, or the keyboard context menu\n * shortcut (Shift+F10 or the Menu key), is named by the view, and returns\n * focus to it on close. `Pressable` hands the trigger's handlers to the\n * option element, and `data-popup-open` keeps the list from moving its tab\n * stop to the selected view while the menu is open. Opening the menu closes\n * any other view's menu, since a right click elsewhere in the list doesn't\n * count as an outside interaction. The open state stays here rather than in\n * the bar, because re-rendering the bar rebuilds the list's collection and\n * moves its tab stop before focus can return to this view. Each\n * `contextmenu` event remounts the menu, because React Aria only positions\n * an open menu once and would leave it at the first click point.\n */\nfunction ContextMenuTrigger({\n closeOpenContextMenuRef,\n menu,\n optionProps,\n}: {\n closeOpenContextMenuRef: MutableRefObject<(() => void) | null>\n menu: ReactElement\n optionProps: ComponentProps<\"div\">\n}) {\n const [isOpen, setIsOpen] = useState(false)\n const [menuKey, setMenuKey] = useState(0)\n\n const close = useCallback(() => setIsOpen(false), [])\n const handleOpenChange = (nextIsOpen: boolean) => {\n setIsOpen(nextIsOpen)\n if (nextIsOpen) {\n closeOpenContextMenuRef.current?.()\n closeOpenContextMenuRef.current = close\n } else if (closeOpenContextMenuRef.current === close) {\n closeOpenContextMenuRef.current = null\n }\n }\n\n return (\n <MenuTrigger\n isOpen={isOpen}\n onOpenChange={handleOpenChange}\n trigger=\"contextMenu\"\n >\n <Pressable>\n <div\n {...mergeProps(optionProps, {\n \"data-popup-open\": isOpen || undefined,\n onContextMenu: () => setMenuKey((key) => key + 1),\n })}\n />\n </Pressable>\n <Fragment key={menuKey}>{menu}</Fragment>\n </MenuTrigger>\n )\n}\n"],"names":["React"],"mappings":"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"}
1
+ {"version":3,"file":"SavedViewsBar.js","sources":["../../../src/components/DataTable/SavedViewsBar.tsx"],"sourcesContent":["import { DropdownAction, DropdownMenu } from \"@components/dropdown\"\nimport {\n ReorderableListBox,\n ReorderableListBoxItem,\n} from \"@components/internal/reorderable-list-box\"\nimport React, {\n type ComponentProps,\n Fragment,\n type MutableRefObject,\n type ReactElement,\n useCallback,\n useRef,\n useState,\n} from \"react\"\nimport { mergeProps } from \"react-aria/mergeProps\"\nimport { MenuTrigger, Pressable } from \"react-aria-components/Menu\"\n\nimport type { Sort } from \"./DataTable\"\nimport type { DataTableColumn } from \"./DataTableColumn\"\nimport type { ActiveFilter } from \"./FilterTypes\"\nimport { ManageSavedViewsButton } from \"./ManageSavedViewsButton\"\nimport { NewSavedViewButton } from \"./NewSavedViewButton\"\nimport { NewSavedViewModal } from \"./NewSavedViewModal\"\nimport {\n findActiveSavedView,\n type SavedView,\n type SavedViewsOptions,\n} from \"./savedViews\"\nimport { useActiveSavedView } from \"./useActiveSavedView\"\n\nexport interface SavedViewsBarProps {\n activeFilters: ActiveFilter[]\n hideableColumns: DataTableColumn[]\n isColumnVisible: (column: DataTableColumn) => boolean\n onApply: (savedView: SavedView) => void\n /**\n * Returns the new view's id. Omit to hide the new view button and the\n * context menu.\n */\n onCreate?: (\n savedView: Omit<SavedView, \"id\">\n ) => Promise<SavedView[\"id\"]> | SavedView[\"id\"]\n savedViews: SavedView[]\n savedViewsOptions?: SavedViewsOptions\n sortBy: Sort | undefined\n}\n\nexport function SavedViewsBar({\n onApply,\n onCreate,\n savedViews,\n activeFilters,\n hideableColumns,\n isColumnVisible,\n sortBy,\n}: SavedViewsBarProps) {\n const closeOpenContextMenuRef = useRef<(() => void) | null>(null)\n // The view the new view modal will save, under the name entered there. It\n // outlives the modal's open state so the title holds while the modal fades\n // out.\n const [draft, setDraft] = useState<{\n title: string\n view: Omit<SavedView, \"id\">\n }>()\n const [isDraftOpen, setIsDraftOpen] = useState(false)\n const hiddenColumnNames = hideableColumns\n .filter((column) => !isColumnVisible(column))\n .map(({ name }) => name)\n const { activeSavedView, select, selectWhenSaved } = useActiveSavedView(\n savedViews,\n () =>\n findActiveSavedView(savedViews, {\n activeFilters,\n hiddenColumnNames,\n sort: sortBy,\n })\n )\n\n const openDraft = (title: string, view: Omit<SavedView, \"id\">) => {\n setDraft({ title, view })\n setIsDraftOpen(true)\n }\n\n const openNewSavedView = () => {\n openDraft(\"New view\", {\n activeFilters,\n name: \"\",\n ...(hideableColumns.length > 0 && { hiddenColumnNames }),\n ...(sortBy && { sort: sortBy }),\n })\n }\n\n // The copy is a new view, so it doesn't keep the original's id or its\n // per-view permission overrides.\n const duplicateSavedView = ({\n deletable: _deletable,\n editable: _editable,\n id: _id,\n ...view\n }: SavedView) => {\n openDraft(\"Duplicate view\", { ...view, name: `${view.name} copy` })\n }\n\n const saveDraft = (name: string) => {\n setIsDraftOpen(false)\n if (!draft || !onCreate) return\n selectWhenSaved(onCreate({ ...draft.view, name }))\n }\n\n const renderContextMenu = (view: SavedView) => {\n if (!onCreate) return null\n return (\n <DropdownMenu>\n <DropdownAction\n id=\"duplicate\"\n onAction={() => duplicateSavedView(view)}\n >\n Duplicate\n </DropdownAction>\n </DropdownMenu>\n )\n }\n\n return (\n <div className=\"tds-data-table-saved-views\">\n <div className=\"tds-data-table-saved-views-list\">\n {savedViews.length > 0 && (\n <ReorderableListBox\n items={savedViews}\n label=\"Saved views\"\n selectedKey={activeSavedView?.id ?? null}\n onSelectionChange={(key) => {\n const view = savedViews.find(({ id }) => id === key)\n if (!view) return\n select(view)\n onApply(view)\n }}\n >\n {(view) => {\n const menu = renderContextMenu(view)\n return (\n <ReorderableListBoxItem\n className=\"tds-data-table-saved-view-list-item\"\n id={view.id}\n render={\n menu\n ? (props) => (\n <ContextMenuTrigger\n closeOpenContextMenuRef={closeOpenContextMenuRef}\n menu={menu}\n optionProps={props as ComponentProps<\"div\">}\n />\n )\n : undefined\n }\n >\n {view.name}\n </ReorderableListBoxItem>\n )\n }}\n </ReorderableListBox>\n )}\n {onCreate && (\n <>\n <NewSavedViewButton onClick={openNewSavedView} />\n <NewSavedViewModal\n defaultName={draft?.view.name}\n open={isDraftOpen}\n title={draft?.title}\n onClose={() => setIsDraftOpen(false)}\n onSave={saveDraft}\n />\n </>\n )}\n </div>\n {savedViews.length > 0 && <ManageSavedViewsButton />}\n </div>\n )\n}\n\nSavedViewsBar.displayName = \"SavedViewsBar\"\n\n/**\n * Makes a saved view's option element itself the context menu trigger, so\n * the menu opens by right click, long press, or the keyboard context menu\n * shortcut (Shift+F10 or the Menu key), is named by the view, and returns\n * focus to it on close. `Pressable` hands the trigger's handlers to the\n * option element, and `data-popup-open` keeps the list from moving its tab\n * stop to the selected view while the menu is open. Opening the menu closes\n * any other view's menu, since a right click elsewhere in the list doesn't\n * count as an outside interaction. The open state stays here rather than in\n * the bar, because re-rendering the bar rebuilds the list's collection and\n * moves its tab stop before focus can return to this view. Each\n * `contextmenu` event remounts the menu, because React Aria only positions\n * an open menu once and would leave it at the first click point.\n */\nfunction ContextMenuTrigger({\n closeOpenContextMenuRef,\n menu,\n optionProps,\n}: {\n closeOpenContextMenuRef: MutableRefObject<(() => void) | null>\n menu: ReactElement\n optionProps: ComponentProps<\"div\">\n}) {\n const [isOpen, setIsOpen] = useState(false)\n const [menuKey, setMenuKey] = useState(0)\n\n const close = useCallback(() => setIsOpen(false), [])\n const handleOpenChange = (nextIsOpen: boolean) => {\n setIsOpen(nextIsOpen)\n if (nextIsOpen) {\n closeOpenContextMenuRef.current?.()\n closeOpenContextMenuRef.current = close\n } else if (closeOpenContextMenuRef.current === close) {\n closeOpenContextMenuRef.current = null\n }\n }\n\n return (\n <MenuTrigger\n isOpen={isOpen}\n onOpenChange={handleOpenChange}\n trigger=\"contextMenu\"\n >\n <Pressable>\n <div\n {...mergeProps(optionProps, {\n \"data-popup-open\": isOpen || undefined,\n onContextMenu: () => setMenuKey((key) => key + 1),\n })}\n />\n </Pressable>\n <Fragment key={menuKey}>{menu}</Fragment>\n </MenuTrigger>\n )\n}\n"],"names":["React"],"mappings":"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"}
@@ -8,7 +8,7 @@ export interface SavedView {
8
8
  editable?: boolean;
9
9
  /** Omit to leave the current column visibility unchanged when applied. */
10
10
  hiddenColumnNames?: string[];
11
- id?: number | string;
11
+ id: number | string;
12
12
  name: string;
13
13
  /** Omit to leave the current sort unchanged when applied. */
14
14
  sort?: Sort;
@@ -25,9 +25,10 @@ interface SavedViewState {
25
25
  sort: Sort | undefined;
26
26
  }
27
27
  /**
28
- * The first view matching the current state, or undefined. Filters match
29
- * regardless of order, ignoring display-only labels. A view's `sort` and
30
- * `hiddenColumnNames` are only compared when the view sets them.
28
+ * The first view matching the current state, or undefined. Only picks the
29
+ * initially selected view. Filters match regardless of order, ignoring
30
+ * display-only labels. A view's `sort` and `hiddenColumnNames` are only
31
+ * compared when the view sets them.
31
32
  */
32
33
  export declare function findActiveSavedView(savedViews: SavedView[], state: SavedViewState): SavedView | undefined;
33
34
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"savedViews.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/savedViews.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAEjD,MAAM,WAAW,SAAS;IACxB,aAAa,EAAE,YAAY,EAAE,CAAA;IAC7B,6DAA6D;IAC7D,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,0EAA0E;IAC1E,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC5B,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,6DAA6D;IAC7D,IAAI,CAAC,EAAE,IAAI,CAAA;CACZ;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,kFAAkF;IAClF,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,UAAU,cAAc;IACtB,aAAa,EAAE,YAAY,EAAE,CAAA;IAC7B,iBAAiB,EAAE,MAAM,EAAE,CAAA;IAC3B,IAAI,EAAE,IAAI,GAAG,SAAS,CAAA;CACvB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,SAAS,EAAE,EACvB,KAAK,EAAE,cAAc,GACpB,SAAS,GAAG,SAAS,CAEvB"}
1
+ {"version":3,"file":"savedViews.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/savedViews.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAEjD,MAAM,WAAW,SAAS;IACxB,aAAa,EAAE,YAAY,EAAE,CAAA;IAC7B,6DAA6D;IAC7D,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,0EAA0E;IAC1E,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC5B,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,6DAA6D;IAC7D,IAAI,CAAC,EAAE,IAAI,CAAA;CACZ;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,kFAAkF;IAClF,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,UAAU,cAAc;IACtB,aAAa,EAAE,YAAY,EAAE,CAAA;IAC7B,iBAAiB,EAAE,MAAM,EAAE,CAAA;IAC3B,IAAI,EAAE,IAAI,GAAG,SAAS,CAAA;CACvB;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,SAAS,EAAE,EACvB,KAAK,EAAE,cAAc,GACpB,SAAS,GAAG,SAAS,CAEvB"}
@@ -1,7 +1,8 @@
1
1
  /**
2
- * The first view matching the current state, or undefined. Filters match
3
- * regardless of order, ignoring display-only labels. A view's `sort` and
4
- * `hiddenColumnNames` are only compared when the view sets them.
2
+ * The first view matching the current state, or undefined. Only picks the
3
+ * initially selected view. Filters match regardless of order, ignoring
4
+ * display-only labels. A view's `sort` and `hiddenColumnNames` are only
5
+ * compared when the view sets them.
5
6
  */
6
7
  function findActiveSavedView(savedViews, state) {
7
8
  return savedViews.find((view) => savedViewMatches(view, state));
@@ -1 +1 @@
1
- {"version":3,"file":"savedViews.js","sources":["../../../src/components/DataTable/savedViews.ts"],"sourcesContent":["import type { Sort } from \"./DataTable\"\nimport type { ActiveFilter } from \"./FilterTypes\"\n\nexport interface SavedView {\n activeFilters: ActiveFilter[]\n /** Overrides `savedViewsOptions.deletable` for this view. */\n deletable?: boolean\n /** Overrides `savedViewsOptions.editable` for this view. */\n editable?: boolean\n /** Omit to leave the current column visibility unchanged when applied. */\n hiddenColumnNames?: string[]\n id?: number | string\n name: string\n /** Omit to leave the current sort unchanged when applied. */\n sort?: Sort\n}\n\nexport interface SavedViewsOptions {\n creatable?: boolean\n deletable?: boolean\n /** Covers both renaming a view and overwriting its filters, sort, and columns. */\n editable?: boolean\n}\n\ninterface SavedViewState {\n activeFilters: ActiveFilter[]\n hiddenColumnNames: string[]\n sort: Sort | undefined\n}\n\n/**\n * The first view matching the current state, or undefined. Filters match\n * regardless of order, ignoring display-only labels. A view's `sort` and\n * `hiddenColumnNames` are only compared when the view sets them.\n */\nexport function findActiveSavedView(\n savedViews: SavedView[],\n state: SavedViewState\n): SavedView | undefined {\n return savedViews.find((view) => savedViewMatches(view, state))\n}\n\nfunction savedViewMatches(view: SavedView, state: SavedViewState): boolean {\n if (!filtersMatch(view.activeFilters, state.activeFilters)) return false\n if (view.sort && !sortMatches(view.sort, state.sort)) return false\n return (\n !view.hiddenColumnNames ||\n namesMatch(view.hiddenColumnNames, state.hiddenColumnNames)\n )\n}\n\nfunction filtersMatch(a: ActiveFilter[], b: ActiveFilter[]): boolean {\n if (a.length !== b.length) return false\n const unmatched = [...b]\n return a.every((filter) => {\n const index = unmatched.findIndex((other) => filterMatches(filter, other))\n if (index === -1) return false\n unmatched.splice(index, 1)\n return true\n })\n}\n\nfunction filterMatches(a: ActiveFilter, b: ActiveFilter): boolean {\n return (\n a.name === b.name &&\n a.operator === b.operator &&\n a.scope === b.scope &&\n valueMatches(a.value, b.value)\n )\n}\n\nfunction valueMatches(a: unknown, b: unknown): boolean {\n if (Array.isArray(a) && Array.isArray(b)) {\n return a.length === b.length && a.every((item, i) => item === b[i])\n }\n return a === b\n}\n\nfunction sortMatches(a: Sort, b: Sort | undefined): boolean {\n return a.column === b?.column && a.direction === b?.direction\n}\n\nfunction namesMatch(a: string[], b: string[]): boolean {\n const names = new Set(b)\n return new Set(a).size === names.size && a.every((name) => names.has(name))\n}\n"],"names":[],"mappings":"AA8BA;;;;AAIG;AACG,SAAU,mBAAmB,CACjC,UAAuB,EACvB,KAAqB,EAAA;AAErB,IAAA,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,gBAAgB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AACjE;AAEA,SAAS,gBAAgB,CAAC,IAAe,EAAE,KAAqB,EAAA;IAC9D,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC,aAAa,CAAC;AAAE,QAAA,OAAO,KAAK;AACxE,IAAA,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC;AAAE,QAAA,OAAO,KAAK;AAClE,IAAA,QACE,CAAC,IAAI,CAAC,iBAAiB;QACvB,UAAU,CAAC,IAAI,CAAC,iBAAiB,EAAE,KAAK,CAAC,iBAAiB,CAAC;AAE/D;AAEA,SAAS,YAAY,CAAC,CAAiB,EAAE,CAAiB,EAAA;AACxD,IAAA,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;AAAE,QAAA,OAAO,KAAK;AACvC,IAAA,MAAM,SAAS,GAAG,CAAC,GAAG,CAAC,CAAC;AACxB,IAAA,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,KAAI;AACxB,QAAA,MAAM,KAAK,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC,KAAK,KAAK,aAAa,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC1E,IAAI,KAAK,KAAK,EAAE;AAAE,YAAA,OAAO,KAAK;AAC9B,QAAA,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;AAC1B,QAAA,OAAO,IAAI;AACb,IAAA,CAAC,CAAC;AACJ;AAEA,SAAS,aAAa,CAAC,CAAe,EAAE,CAAe,EAAA;AACrD,IAAA,QACE,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI;AACjB,QAAA,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,QAAQ;AACzB,QAAA,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK;QACnB,YAAY,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC;AAElC;AAEA,SAAS,YAAY,CAAC,CAAU,EAAE,CAAU,EAAA;AAC1C,IAAA,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;QACxC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACrE;IACA,OAAO,CAAC,KAAK,CAAC;AAChB;AAEA,SAAS,WAAW,CAAC,CAAO,EAAE,CAAmB,EAAA;AAC/C,IAAA,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC,SAAS,KAAK,CAAC,EAAE,SAAS;AAC/D;AAEA,SAAS,UAAU,CAAC,CAAW,EAAE,CAAW,EAAA;AAC1C,IAAA,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC;AACxB,IAAA,OAAO,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC7E;;;;"}
1
+ {"version":3,"file":"savedViews.js","sources":["../../../src/components/DataTable/savedViews.ts"],"sourcesContent":["import type { Sort } from \"./DataTable\"\nimport type { ActiveFilter } from \"./FilterTypes\"\n\nexport interface SavedView {\n activeFilters: ActiveFilter[]\n /** Overrides `savedViewsOptions.deletable` for this view. */\n deletable?: boolean\n /** Overrides `savedViewsOptions.editable` for this view. */\n editable?: boolean\n /** Omit to leave the current column visibility unchanged when applied. */\n hiddenColumnNames?: string[]\n id: number | string\n name: string\n /** Omit to leave the current sort unchanged when applied. */\n sort?: Sort\n}\n\nexport interface SavedViewsOptions {\n creatable?: boolean\n deletable?: boolean\n /** Covers both renaming a view and overwriting its filters, sort, and columns. */\n editable?: boolean\n}\n\ninterface SavedViewState {\n activeFilters: ActiveFilter[]\n hiddenColumnNames: string[]\n sort: Sort | undefined\n}\n\n/**\n * The first view matching the current state, or undefined. Only picks the\n * initially selected view. Filters match regardless of order, ignoring\n * display-only labels. A view's `sort` and `hiddenColumnNames` are only\n * compared when the view sets them.\n */\nexport function findActiveSavedView(\n savedViews: SavedView[],\n state: SavedViewState\n): SavedView | undefined {\n return savedViews.find((view) => savedViewMatches(view, state))\n}\n\nfunction savedViewMatches(view: SavedView, state: SavedViewState): boolean {\n if (!filtersMatch(view.activeFilters, state.activeFilters)) return false\n if (view.sort && !sortMatches(view.sort, state.sort)) return false\n return (\n !view.hiddenColumnNames ||\n namesMatch(view.hiddenColumnNames, state.hiddenColumnNames)\n )\n}\n\nfunction filtersMatch(a: ActiveFilter[], b: ActiveFilter[]): boolean {\n if (a.length !== b.length) return false\n const unmatched = [...b]\n return a.every((filter) => {\n const index = unmatched.findIndex((other) => filterMatches(filter, other))\n if (index === -1) return false\n unmatched.splice(index, 1)\n return true\n })\n}\n\nfunction filterMatches(a: ActiveFilter, b: ActiveFilter): boolean {\n return (\n a.name === b.name &&\n a.operator === b.operator &&\n a.scope === b.scope &&\n valueMatches(a.value, b.value)\n )\n}\n\nfunction valueMatches(a: unknown, b: unknown): boolean {\n if (Array.isArray(a) && Array.isArray(b)) {\n return a.length === b.length && a.every((item, i) => item === b[i])\n }\n return a === b\n}\n\nfunction sortMatches(a: Sort, b: Sort | undefined): boolean {\n return a.column === b?.column && a.direction === b?.direction\n}\n\nfunction namesMatch(a: string[], b: string[]): boolean {\n const names = new Set(b)\n return new Set(a).size === names.size && a.every((name) => names.has(name))\n}\n"],"names":[],"mappings":"AA8BA;;;;;AAKG;AACG,SAAU,mBAAmB,CACjC,UAAuB,EACvB,KAAqB,EAAA;AAErB,IAAA,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,gBAAgB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AACjE;AAEA,SAAS,gBAAgB,CAAC,IAAe,EAAE,KAAqB,EAAA;IAC9D,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC,aAAa,CAAC;AAAE,QAAA,OAAO,KAAK;AACxE,IAAA,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC;AAAE,QAAA,OAAO,KAAK;AAClE,IAAA,QACE,CAAC,IAAI,CAAC,iBAAiB;QACvB,UAAU,CAAC,IAAI,CAAC,iBAAiB,EAAE,KAAK,CAAC,iBAAiB,CAAC;AAE/D;AAEA,SAAS,YAAY,CAAC,CAAiB,EAAE,CAAiB,EAAA;AACxD,IAAA,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;AAAE,QAAA,OAAO,KAAK;AACvC,IAAA,MAAM,SAAS,GAAG,CAAC,GAAG,CAAC,CAAC;AACxB,IAAA,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,KAAI;AACxB,QAAA,MAAM,KAAK,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC,KAAK,KAAK,aAAa,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC1E,IAAI,KAAK,KAAK,EAAE;AAAE,YAAA,OAAO,KAAK;AAC9B,QAAA,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;AAC1B,QAAA,OAAO,IAAI;AACb,IAAA,CAAC,CAAC;AACJ;AAEA,SAAS,aAAa,CAAC,CAAe,EAAE,CAAe,EAAA;AACrD,IAAA,QACE,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI;AACjB,QAAA,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,QAAQ;AACzB,QAAA,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK;QACnB,YAAY,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC;AAElC;AAEA,SAAS,YAAY,CAAC,CAAU,EAAE,CAAU,EAAA;AAC1C,IAAA,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;QACxC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACrE;IACA,OAAO,CAAC,KAAK,CAAC;AAChB;AAEA,SAAS,WAAW,CAAC,CAAO,EAAE,CAAmB,EAAA;AAC/C,IAAA,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC,SAAS,KAAK,CAAC,EAAE,SAAS;AAC/D;AAEA,SAAS,UAAU,CAAC,CAAW,EAAE,CAAW,EAAA;AAC1C,IAAA,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC;AACxB,IAAA,OAAO,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC7E;;;;"}
@@ -0,0 +1,7 @@
1
+ import type { SavedView } from "./savedViews";
2
+ export declare function useActiveSavedView(savedViews: SavedView[], getInitialView: () => SavedView | undefined): {
3
+ activeSavedView: SavedView | undefined;
4
+ select: (view: SavedView) => void;
5
+ selectWhenSaved: (savedId: Promise<SavedView["id"]> | SavedView["id"]) => Promise<void>;
6
+ };
7
+ //# sourceMappingURL=useActiveSavedView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useActiveSavedView.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/useActiveSavedView.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAE7C,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,SAAS,EAAE,EACvB,cAAc,EAAE,MAAM,SAAS,GAAG,SAAS;;mBAQ1B,SAAS;+BAKb,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC;EAOxD"}
@@ -0,0 +1,23 @@
1
+ import { useState, useRef } from 'react';
2
+
3
+ function useActiveSavedView(savedViews, getInitialView) {
4
+ const [activeId, setActiveId] = useState(() => getInitialView()?.id);
5
+ // Lets a slow save skip selecting its view if the user picked another.
6
+ const selectionCount = useRef(0);
7
+ return {
8
+ activeSavedView: savedViews.find(({ id }) => id === activeId),
9
+ select: (view) => {
10
+ selectionCount.current++;
11
+ setActiveId(view.id);
12
+ },
13
+ selectWhenSaved: async (savedId) => {
14
+ const selection = ++selectionCount.current;
15
+ const id = await savedId;
16
+ if (selection === selectionCount.current)
17
+ setActiveId(id);
18
+ },
19
+ };
20
+ }
21
+
22
+ export { useActiveSavedView };
23
+ //# sourceMappingURL=useActiveSavedView.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useActiveSavedView.js","sources":["../../../src/components/DataTable/useActiveSavedView.ts"],"sourcesContent":["import { useRef, useState } from \"react\"\n\nimport type { SavedView } from \"./savedViews\"\n\nexport function useActiveSavedView(\n savedViews: SavedView[],\n getInitialView: () => SavedView | undefined\n) {\n const [activeId, setActiveId] = useState(() => getInitialView()?.id)\n // Lets a slow save skip selecting its view if the user picked another.\n const selectionCount = useRef(0)\n\n return {\n activeSavedView: savedViews.find(({ id }) => id === activeId),\n select: (view: SavedView) => {\n selectionCount.current++\n setActiveId(view.id)\n },\n selectWhenSaved: async (\n savedId: Promise<SavedView[\"id\"]> | SavedView[\"id\"]\n ) => {\n const selection = ++selectionCount.current\n const id = await savedId\n if (selection === selectionCount.current) setActiveId(id)\n },\n }\n}\n"],"names":[],"mappings":";;AAIM,SAAU,kBAAkB,CAChC,UAAuB,EACvB,cAA2C,EAAA;AAE3C,IAAA,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,MAAM,cAAc,EAAE,EAAE,EAAE,CAAC;;AAEpE,IAAA,MAAM,cAAc,GAAG,MAAM,CAAC,CAAC,CAAC;IAEhC,OAAO;AACL,QAAA,eAAe,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,QAAQ,CAAC;AAC7D,QAAA,MAAM,EAAE,CAAC,IAAe,KAAI;YAC1B,cAAc,CAAC,OAAO,EAAE;AACxB,YAAA,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,CAAC;AACD,QAAA,eAAe,EAAE,OACf,OAAmD,KACjD;AACF,YAAA,MAAM,SAAS,GAAG,EAAE,cAAc,CAAC,OAAO;AAC1C,YAAA,MAAM,EAAE,GAAG,MAAM,OAAO;AACxB,YAAA,IAAI,SAAS,KAAK,cAAc,CAAC,OAAO;gBAAE,WAAW,CAAC,EAAE,CAAC;QAC3D,CAAC;KACF;AACH;;;;"}