@planningcenter/tapestry 4.12.0 → 4.13.0-rc.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 (134) hide show
  1. package/dist/componentRegistrars.d.ts +1 -0
  2. package/dist/componentRegistrars.d.ts.map +1 -1
  3. package/dist/componentRegistrars.js +6 -2
  4. package/dist/componentRegistrars.js.map +1 -1
  5. package/dist/components/DataTable/ActiveFilters.d.ts +23 -1
  6. package/dist/components/DataTable/ActiveFilters.d.ts.map +1 -1
  7. package/dist/components/DataTable/ActiveFilters.js +49 -4
  8. package/dist/components/DataTable/ActiveFilters.js.map +1 -1
  9. package/dist/components/DataTable/CollectionEditorsLazy.d.ts.map +1 -1
  10. package/dist/components/DataTable/CollectionEditorsLazy.js +20 -18
  11. package/dist/components/DataTable/CollectionEditorsLazy.js.map +1 -1
  12. package/dist/components/DataTable/DataTable.d.ts +66 -50
  13. package/dist/components/DataTable/DataTable.d.ts.map +1 -1
  14. package/dist/components/DataTable/DataTable.js +78 -17
  15. package/dist/components/DataTable/DataTable.js.map +1 -1
  16. package/dist/components/DataTable/ManageSavedViewsModal.d.ts +18 -7
  17. package/dist/components/DataTable/ManageSavedViewsModal.d.ts.map +1 -1
  18. package/dist/components/DataTable/ManageSavedViewsModal.js +120 -104
  19. package/dist/components/DataTable/ManageSavedViewsModal.js.map +1 -1
  20. package/dist/components/DataTable/ManageSavedViewsModal.module.css.js +1 -1
  21. package/dist/components/DataTable/NewSavedViewButton.d.ts.map +1 -1
  22. package/dist/components/DataTable/NewSavedViewButton.js +1 -1
  23. package/dist/components/DataTable/NewSavedViewButton.js.map +1 -1
  24. package/dist/components/DataTable/SavedViewActions.d.ts +19 -0
  25. package/dist/components/DataTable/SavedViewActions.d.ts.map +1 -0
  26. package/dist/components/DataTable/SavedViewActions.js +34 -0
  27. package/dist/components/DataTable/SavedViewActions.js.map +1 -0
  28. package/dist/components/DataTable/SavedViewMenu.d.ts +18 -0
  29. package/dist/components/DataTable/SavedViewMenu.d.ts.map +1 -0
  30. package/dist/components/DataTable/SavedViewMenu.js +25 -0
  31. package/dist/components/DataTable/SavedViewMenu.js.map +1 -0
  32. package/dist/components/DataTable/SavedViewsBar.d.ts +25 -13
  33. package/dist/components/DataTable/SavedViewsBar.d.ts.map +1 -1
  34. package/dist/components/DataTable/SavedViewsBar.js +43 -83
  35. package/dist/components/DataTable/SavedViewsBar.js.map +1 -1
  36. package/dist/components/DataTable/TableActions.d.ts +4 -2
  37. package/dist/components/DataTable/TableActions.d.ts.map +1 -1
  38. package/dist/components/DataTable/TableActions.js +11 -14
  39. package/dist/components/DataTable/TableActions.js.map +1 -1
  40. package/dist/components/DataTable/index.d.ts +2 -0
  41. package/dist/components/DataTable/index.d.ts.map +1 -1
  42. package/dist/components/DataTable/saveErrorMessage.d.ts +3 -0
  43. package/dist/components/DataTable/saveErrorMessage.d.ts.map +1 -0
  44. package/dist/components/DataTable/saveErrorMessage.js +9 -0
  45. package/dist/components/DataTable/saveErrorMessage.js.map +1 -0
  46. package/dist/components/DataTable/savedViews.d.ts +15 -30
  47. package/dist/components/DataTable/savedViews.d.ts.map +1 -1
  48. package/dist/components/DataTable/savedViews.js +51 -98
  49. package/dist/components/DataTable/savedViews.js.map +1 -1
  50. package/dist/components/DataTable/useActiveSavedView.d.ts +1 -1
  51. package/dist/components/DataTable/useActiveSavedView.d.ts.map +1 -1
  52. package/dist/components/DataTable/useActiveSavedView.js +5 -4
  53. package/dist/components/DataTable/useActiveSavedView.js.map +1 -1
  54. package/dist/components/DataTable/useColumnVisibility.d.ts +7 -7
  55. package/dist/components/DataTable/useColumnVisibility.d.ts.map +1 -1
  56. package/dist/components/DataTable/useColumnVisibility.js +14 -14
  57. package/dist/components/DataTable/useColumnVisibility.js.map +1 -1
  58. package/dist/components/DataTable/useResultsAnnouncement.d.ts +26 -0
  59. package/dist/components/DataTable/useResultsAnnouncement.d.ts.map +1 -0
  60. package/dist/components/DataTable/{useFilterAnnouncement.js → useResultsAnnouncement.js} +16 -12
  61. package/dist/components/DataTable/useResultsAnnouncement.js.map +1 -0
  62. package/dist/components/DataTable/useSaveStatus.d.ts +32 -0
  63. package/dist/components/DataTable/useSaveStatus.d.ts.map +1 -0
  64. package/dist/components/DataTable/useSaveStatus.js +80 -0
  65. package/dist/components/DataTable/useSaveStatus.js.map +1 -0
  66. package/dist/components/DataTable/useSavedViewNameModal.d.ts +14 -0
  67. package/dist/components/DataTable/useSavedViewNameModal.d.ts.map +1 -0
  68. package/dist/components/DataTable/useSavedViewNameModal.js +43 -0
  69. package/dist/components/DataTable/useSavedViewNameModal.js.map +1 -0
  70. package/dist/components/DataTable/useSavedViewsClient.d.ts +58 -0
  71. package/dist/components/DataTable/useSavedViewsClient.d.ts.map +1 -0
  72. package/dist/components/DataTable/useSavedViewsClient.js +87 -0
  73. package/dist/components/DataTable/useSavedViewsClient.js.map +1 -0
  74. package/dist/components/DataTable/useSavedViewsState.d.ts +35 -0
  75. package/dist/components/DataTable/useSavedViewsState.d.ts.map +1 -0
  76. package/dist/components/DataTable/useSavedViewsState.js +192 -0
  77. package/dist/components/DataTable/useSavedViewsState.js.map +1 -0
  78. package/dist/components/DataTable/useUpdateSavedViewName.d.ts +2 -3
  79. package/dist/components/DataTable/useUpdateSavedViewName.d.ts.map +1 -1
  80. package/dist/components/DataTable/useUpdateSavedViewName.js +1 -2
  81. package/dist/components/DataTable/useUpdateSavedViewName.js.map +1 -1
  82. package/dist/components/button/BaseButton.d.ts +2 -0
  83. package/dist/components/button/BaseButton.d.ts.map +1 -1
  84. package/dist/components/button/BaseButton.js +8 -17
  85. package/dist/components/button/BaseButton.js.map +1 -1
  86. package/dist/components/internal/LoadingAnnouncement.d.ts +6 -0
  87. package/dist/components/internal/LoadingAnnouncement.d.ts.map +1 -1
  88. package/dist/components/internal/LoadingAnnouncement.js +12 -3
  89. package/dist/components/internal/LoadingAnnouncement.js.map +1 -1
  90. package/dist/components/internal/index.d.ts +1 -1
  91. package/dist/components/internal/index.d.ts.map +1 -1
  92. package/dist/components/internal/tooltip/useTooltipTriggerProps.d.ts +13 -0
  93. package/dist/components/internal/tooltip/useTooltipTriggerProps.d.ts.map +1 -0
  94. package/dist/components/internal/tooltip/useTooltipTriggerProps.js +24 -0
  95. package/dist/components/internal/tooltip/useTooltipTriggerProps.js.map +1 -0
  96. package/dist/components/link/BaseLink.d.ts.map +1 -1
  97. package/dist/components/link/BaseLink.js +3 -13
  98. package/dist/components/link/BaseLink.js.map +1 -1
  99. package/dist/components/segmented-control/IconSegment.d.ts +30 -8
  100. package/dist/components/segmented-control/IconSegment.d.ts.map +1 -1
  101. package/dist/components/segmented-control/IconSegment.js +10 -3
  102. package/dist/components/segmented-control/IconSegment.js.map +1 -1
  103. package/dist/components/segmented-control/SegmentBase.d.ts.map +1 -1
  104. package/dist/components/segmented-control/SegmentBase.js +4 -2
  105. package/dist/components/segmented-control/SegmentBase.js.map +1 -1
  106. package/dist/components/segmented-control/SegmentedControl.d.ts.map +1 -1
  107. package/dist/components/segmented-control/SegmentedControl.js +10 -3
  108. package/dist/components/segmented-control/SegmentedControl.js.map +1 -1
  109. package/dist/index.css +20 -5
  110. package/dist/index.css.map +1 -1
  111. package/dist/reactRender.css +1409 -1319
  112. package/dist/reactRender.css.map +1 -1
  113. package/dist/reactRender.js +1 -1
  114. package/dist/reactRenderLegacy.css +1409 -1319
  115. package/dist/reactRenderLegacy.css.map +1 -1
  116. package/dist/reactRenderLegacy.js +1 -1
  117. package/dist/tapestryMount.css +1409 -1319
  118. package/dist/tapestryMount.css.map +1 -1
  119. package/dist/tapestryMount.js +1 -1
  120. package/dist/tapestryMountLegacy.css +1409 -1319
  121. package/dist/tapestryMountLegacy.css.map +1 -1
  122. package/dist/tapestryMountLegacy.js +1 -1
  123. package/dist/tokens-dark.css +2 -2
  124. package/dist/tokens-dark.css.map +1 -1
  125. package/dist/tokens.css +3 -3
  126. package/dist/tokens.css.map +1 -1
  127. package/dist/unstable.css +385 -295
  128. package/dist/unstable.css.map +1 -1
  129. package/dist/unstable.js +1 -0
  130. package/dist/unstable.js.map +1 -1
  131. package/package.json +6 -7
  132. package/dist/components/DataTable/useFilterAnnouncement.d.ts +0 -24
  133. package/dist/components/DataTable/useFilterAnnouncement.d.ts.map +0 -1
  134. package/dist/components/DataTable/useFilterAnnouncement.js.map +0 -1
@@ -31,12 +31,6 @@ interface DataTableBaseProps {
31
31
  currentPage?: number;
32
32
  /** The array of rows to display. */
33
33
  data: unknown[];
34
- /**
35
- * The id of the view the table opens with. Defaults to `"initial"`. The
36
- * table doesn't apply it on mount; set the initial `activeFilters`, sort,
37
- * and visible columns from it.
38
- */
39
- defaultViewId?: NonNullable<SavedView["id"]>;
40
34
  /**
41
35
  * Row keys that can't be selected. Keys are the values returned by `getRowId`
42
36
  * (or `row.id`, or the row's index) — the same keys used by `selectedKeys`.
@@ -52,6 +46,7 @@ interface DataTableBaseProps {
52
46
  /**
53
47
  * The filter tree shown in the "Add filter" popover. Renders the filter
54
48
  * controls in the header when set; omit to leave filtering off entirely.
49
+ * `q` is reserved for the search, so no filter can use it as its name.
55
50
  */
56
51
  filters?: FilterNode[];
57
52
  /** Returns a stable identity for each row. Defaults to `row.id`. */
@@ -74,19 +69,42 @@ interface DataTableBaseProps {
74
69
  * `false` (the default) disables the Previous button.
75
70
  */
76
71
  hasPreviousPage?: boolean;
72
+ /**
73
+ * The names of the columns currently hidden. Only columns marked `hideable`
74
+ * can be hidden — every other column stays visible. Omitting this (or
75
+ * passing `[]`) leaves all columns visible, and unknown names are ignored.
76
+ * Columns added later stay visible until hidden, so a stored value never
77
+ * hides them by accident.
78
+ */
79
+ hiddenColumnNames?: string[];
77
80
  /**
78
81
  * An `id` for the table element. When omitted, a stable generated id is used
79
82
  * so the results count can be linked to the table via `aria-describedby`.
80
83
  */
81
84
  id?: string;
85
+ /**
86
+ * The id of the view the table opens with, selected on mount. Defaults to
87
+ * `"initial"`. The table doesn't apply it; the initial `activeFilters`
88
+ * (apart from the search), sort, and visible columns must match it. Later
89
+ * changes are ignored.
90
+ */
91
+ initialDefaultViewId?: NonNullable<SavedView["id"]>;
92
+ /**
93
+ * Named sets of filters, sort, and hidden columns the user can apply, shown
94
+ * in array order. Can't use the id `"initial"`, which is reserved for the
95
+ * initial view. Later changes are ignored; remount with a new `key` to start
96
+ * from fresh views.
97
+ */
98
+ initialSavedViews?: SavedView[];
82
99
  /**
83
100
  * Async loading state for the table body.
84
101
  * - `"loading"`: While `data` is empty, replaces the empty state with a
85
102
  * centered spinner. While `data` has rows, keeps them on screen with a
86
103
  * spinner over them until new `data` arrives, so a search doesn't blank
87
104
  * the table. When requests can overlap, apply only the latest response.
88
- * Set it while a filter or search request is in flight, so the count
89
- * announced to screen reader users is the new one.
105
+ * Set it while any request is in flight, so screen reader users hear
106
+ * the new count when it ends. Keep `"idle"` for a refresh the user did
107
+ * not start, such as polling, or the count is announced again.
90
108
  * - `"error"`: While `data` is empty, replaces the empty state with
91
109
  * `errorState` (or a default error message).
92
110
  * - `"idle"` (default): Normal rendering.
@@ -99,11 +117,21 @@ interface DataTableBaseProps {
99
117
  onActiveFiltersChange?: (activeFilters: ActiveFilter[]) => void;
100
118
  /**
101
119
  * Called with the id of the view the user sets as the default, or
102
- * `"initial"` when they delete the default view. Without it, the Set as
120
+ * `"initial"` once the default view is deleted. Without it, the Set as
103
121
  * default action is hidden; on the default view it's disabled and reads
104
- * "Default view". Pass the id back in as `defaultViewId`.
122
+ * "Default view". The table shows the new default right away, and puts the
123
+ * previous one back if the promise rejects, unless the user has set another
124
+ * default since.
125
+ */
126
+ onDefaultViewIdChange?: (id: NonNullable<SavedView["id"]>) => Promise<void> | void;
127
+ /**
128
+ * Called with the hidden column names, in `columns` order, when the
129
+ * visibility toggle changes or a saved view is applied. Only `hideable`
130
+ * columns are included, so the value can be passed straight back as
131
+ * `hiddenColumnNames`. Column visibility is controlled, so the table only
132
+ * updates once `hiddenColumnNames` changes.
105
133
  */
106
- onDefaultViewIdChange?: (id: NonNullable<SavedView["id"]>) => void;
134
+ onHiddenColumnNamesChange?: (hiddenColumnNames: string[]) => void;
107
135
  /**
108
136
  * Called when the Next button is activated. Only used by
109
137
  * `paginationType="indexed"`; load the following page's rows and pass them
@@ -131,35 +159,38 @@ interface DataTableBaseProps {
131
159
  onRowClick?: (row: unknown) => void;
132
160
  /**
133
161
  * Called with the new view when the user saves the current filters, sort,
134
- * and columns as a view. Without it, the new view button is hidden. Return
135
- * the saved view with its new id, or a promise of it; that view is selected
136
- * once it's passed back in `savedViews`. A callback that returns nothing
137
- * doesn't type check, so resolve to the view after refetching, e.g.
162
+ * and columns as a view, or duplicates a view. Without it, views can't be
163
+ * created or duplicated. Return the saved view with its new id, or a promise
164
+ * of it; that view is selected once it's passed back in `savedViews`, unless
165
+ * it was duplicated from the manage views modal. A callback that returns
166
+ * nothing doesn't type check, so resolve to the view after refetching, e.g.
138
167
  * `(view) => api.create(view).then(async (saved) => { await refetch(); return saved })`.
139
168
  */
140
169
  onSavedViewCreate?: (savedView: Omit<SavedView, "id">) => Promise<SavedView> | SavedView;
141
170
  /**
142
171
  * Called with the view once the user confirms deleting it, from the context
143
- * menu or the manage views modal. Without it, views can't be deleted. Remove
144
- * the view from `savedViews` to finish.
172
+ * menu or the manage views modal. Without it, views can't be deleted. The
173
+ * table removes the view right away, and puts it back in its place if the
174
+ * promise rejects. Deleting the default view resets the default to
175
+ * `"initial"`, which is restored too.
176
+ */
177
+ onSavedViewDelete?: (savedView: SavedView) => Promise<void> | void;
178
+ /**
179
+ * Called when the user moves a saved view, with the saved view it now comes
180
+ * after, or `null` when it's first. Save the new position and return a
181
+ * promise. The table moves the view right away, and moves it back if the
182
+ * promise rejects. Without it, the manage views modal has no drag handles.
145
183
  */
146
- onSavedViewDelete?: (savedView: SavedView) => void;
184
+ onSavedViewReorder?: (savedView: SavedView, after: SavedView | null) => Promise<void> | void;
147
185
  /**
148
186
  * Called with the updated view, matched by `id`. Return the saved view, or a
149
- * promise of it; like `onSavedViewCreate`, a callback that returns nothing
150
- * doesn't type check. Without it, view names are read only.
187
+ * promise of it. The table shows the change right away, then swaps in the
188
+ * returned view, or puts the old one back if the promise rejects, unless
189
+ * the view has changed again since. Without it, view names are read only.
151
190
  */
152
191
  onSavedViewUpdate?: (savedView: SavedView) => Promise<SavedView> | SavedView;
153
192
  /** Callback invoked when the sort state changes. */
154
193
  onSortChange?: (sort: Sort) => void;
155
- /**
156
- * Called with the full ordered list of visible column names when the
157
- * visibility toggle changes. Always-visible columns are included, so the
158
- * value can be passed straight back as `visibleColumnNames`. Column
159
- * visibility is controlled, so the table only updates once
160
- * `visibleColumnNames` changes.
161
- */
162
- onVisibleColumnNamesChange?: (visibleColumnNames: string[]) => void;
163
194
  /**
164
195
  * Which shape the page controls take, forwarded to the `Pagination` control's
165
196
  * `type`.
@@ -184,7 +215,7 @@ interface DataTableBaseProps {
184
215
  * the select-all banner. Without a result count, the banner isn't offered
185
216
  * because the table can't accurately describe the all-pages selection.
186
217
  * It also sets the count announced to screen reader users after a filter
187
- * change. Without it, a paginated table announces only the current page,
218
+ * change or a load. Without it, a paginated table announces only the current page,
188
219
  * e.g. `"25 results on this page"`.
189
220
  */
190
221
  resultCount?: number;
@@ -217,15 +248,6 @@ interface DataTableBaseProps {
217
248
  * action's `onAction` or `getHref` receives the row.
218
249
  */
219
250
  rowActions?: RowAction[];
220
- /**
221
- * Named sets of filters, sort, and hidden columns the user can apply, shown
222
- * by `sortKey`, then in array order. The first view matching the state on
223
- * mount starts selected; after that, the selection follows the view the
224
- * user last applied or created, even once the filters, sort, or columns
225
- * change. Can't use the id `"initial"`, which is reserved for the initial
226
- * view.
227
- */
228
- savedViews?: SavedView[];
229
251
  /** Ref to the scroll container the sticky header should track. Takes priority over `scrollContainerSelector`. Only used when `stickyHeader` is true. */
230
252
  scrollContainerRef?: React.RefObject<HTMLElement>;
231
253
  /** CSS selector for the scroll container the sticky header should track. Only used when `stickyHeader` is true. Defaults to ".content-wrap" */
@@ -233,7 +255,8 @@ interface DataTableBaseProps {
233
255
  /**
234
256
  * Displays a search input above the table. The query is kept in
235
257
  * `activeFilters` as a `q` filter and reported through
236
- * `onActiveFiltersChange` once typing pauses.
258
+ * `onActiveFiltersChange` once typing pauses. It isn't saved with
259
+ * views, and applying a saved view leaves it alone.
237
260
  */
238
261
  searchable?: boolean;
239
262
  /**
@@ -245,10 +268,10 @@ interface DataTableBaseProps {
245
268
  /** The current sort state for the table. */
246
269
  sortBy?: Sort;
247
270
  /**
248
- * Read-only views from the app, listed before `savedViews`. Ids must not
249
- * overlap with `savedViews`. Unless one has the id `"initial"`, an "All"
250
- * view is added first. Omit both `staticViews` and `savedViews` to hide the
251
- * views bar.
271
+ * Read-only views from the app, listed before the saved views. Ids must not
272
+ * overlap with `initialSavedViews`. Unless one has the id `"initial"`, an
273
+ * "All" view is added first. Omit both `staticViews` and `initialSavedViews`
274
+ * to hide the views bar.
252
275
  */
253
276
  staticViews?: StaticView[];
254
277
  /** 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. */
@@ -273,13 +296,6 @@ interface DataTableBaseProps {
273
296
  * the whole result set, and `onPageChange` should load the next page.
274
297
  */
275
298
  totalPages?: number;
276
- /**
277
- * The names of the columns currently visible. Only columns marked `hideable`
278
- * are affected — every other column stays visible. Omitting this leaves all
279
- * columns visible. Unknown names are ignored and display order always
280
- * follows `columns`.
281
- */
282
- visibleColumnNames?: string[];
283
299
  }
284
300
  interface DataTableExplicitSelectionProps {
285
301
  /** Keeps selection values as arrays of row keys. */
@@ -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,11 +1,11 @@
1
1
  import LoadingSpinner from '../internal/LoadingSpinner.js';
2
- import React__default, { useRef, useMemo, useState, useLayoutEffect } from 'react';
3
- import 'react-aria/private/live-announcer/LiveAnnouncer';
2
+ import { LoadingAnnouncement } from '../internal/LoadingAnnouncement.js';
4
3
  import '../internal/tooltip/Tooltip.js';
5
4
  import { Pagination } from '../internal/pagination/Pagination.js';
6
5
  import Icon from '../../utilities/Icon.js';
7
6
  import { useId } from '../../utilities/useId.js';
8
7
  import classNames from 'classnames';
8
+ import React__default, { useRef, useMemo, useState, useLayoutEffect } from 'react';
9
9
  import { Table, TableHeader, Column, Checkbox, TableBody, Row, Cell } from 'react-aria-components/Table';
10
10
  import { ActiveFilters } from './ActiveFilters.js';
11
11
  import { prepareColumn } from './DataTableColumnTypes.js';
@@ -16,15 +16,18 @@ import { useFilterOpenRequest } from './FilterOpenRequest.js';
16
16
  import { usePendingFilters } from './PendingFilterContext.js';
17
17
  import { hasResultsCount, resolveResultNounLabel, ResultsCount } from './ResultsCount.js';
18
18
  import { RowActions } from './RowActions.js';
19
- import { sortSavedViews } from './savedViews.js';
19
+ import { withoutSearch, initialView, isSavedViewModified, isSavedViewEditable } from './savedViews.js';
20
20
  import { SavedViewsBar } from './SavedViewsBar.js';
21
21
  import { SelectAllBanner } from './SelectAllBanner.js';
22
22
  import { TableActions } from './TableActions.js';
23
23
  import { TableSearch } from './TableSearch.js';
24
+ import { useActiveSavedView } from './useActiveSavedView.js';
24
25
  import { useColumnVisibility } from './useColumnVisibility.js';
25
26
  import { useDataTableSelection, DataTableSelectionContext } from './useDataTableSelection.js';
26
- import { useFilterAnnouncement } from './useFilterAnnouncement.js';
27
+ import { useResultsAnnouncement } from './useResultsAnnouncement.js';
27
28
  import { useRowPressBoundary } from './useRowPressBoundary.js';
29
+ import { useSavedViewsState } from './useSavedViewsState.js';
30
+ import { useSaveStatus } from './useSaveStatus.js';
28
31
  import { useSearchFilter } from './useSearchFilter.js';
29
32
  import { useShelfExpanded } from './useShelfExpanded.js';
30
33
  import { ViewSettingsToggle } from './ViewSettingsToggle.js';
@@ -49,7 +52,7 @@ const DEFAULT_ERROR_STATE = "Something went wrong.";
49
52
  */
50
53
  const DataTable = ({ activeFilters = [], filters = [], ...props }) => (React__default.createElement(FiltersProvider, { activeFilters: activeFilters, filters: filters },
51
54
  React__default.createElement(DataTableInner, { ...props, activeFilters: activeFilters, filters: filters })));
52
- const DataTableInner = ({ activeFilters = [], className, canSelectAllPages, columns, currentPage = 1, data, defaultViewId = "initial", disabledKeys, emptyState, errorState, filters = [], getRowId, getRowLink, hasNextPage = false, hasPreviousPage = false, id, loadingState = "idle", paginationType = "paged", resultCount, resultNoun, scrollContainerRef, scrollContainerSelector = ".content-wrap", rowActions, savedViews, searchable, selectable, selectedKeys: controlledSelectedKeys, staticViews, stickyHeader, sortBy, tableActions, totalDisabledCount, totalPages, visibleColumnNames, onActiveFiltersChange = () => { }, onDefaultViewIdChange, onNextPageClick, onPageChange, onPreviousPageClick, onRowClick, onSavedViewCreate, onSavedViewDelete, onSavedViewUpdate, onSelectedChange, onSortChange, onVisibleColumnNamesChange, ...restProps }) => {
55
+ const DataTableInner = ({ activeFilters = [], className, canSelectAllPages, columns, currentPage = 1, data, disabledKeys, emptyState, errorState, filters = [], getRowId, getRowLink, hasNextPage = false, hasPreviousPage = false, hiddenColumnNames, id, initialDefaultViewId = "initial", initialSavedViews, loadingState = "idle", paginationType = "paged", resultCount, resultNoun, scrollContainerRef, scrollContainerSelector = ".content-wrap", rowActions, searchable, selectable, selectedKeys: controlledSelectedKeys, staticViews: staticViewsProp, stickyHeader, sortBy, tableActions, totalDisabledCount, totalPages, onActiveFiltersChange = () => { }, onDefaultViewIdChange: onDefaultViewIdChangeProp, onHiddenColumnNamesChange, onNextPageClick, onPageChange, onPreviousPageClick, onRowClick, onSavedViewCreate: onSavedViewCreateProp, onSavedViewDelete: onSavedViewDeleteProp, onSavedViewReorder, onSavedViewUpdate: onSavedViewUpdateProp, onSelectedChange, onSortChange, ...restProps }) => {
53
56
  const hasRowPressAction = Boolean(onRowClick || getRowLink);
54
57
  const rowsAreInteractive = hasRowPressAction || Boolean(selectable);
55
58
  const combinedClassName = classNames("tds-data-table-grid", className);
@@ -81,9 +84,25 @@ const DataTableInner = ({ activeFilters = [], className, canSelectAllPages, colu
81
84
  [columnKey]);
82
85
  const { hideableColumns, isColumnVisible, onColumnVisibilityChange, visibleHideableColumns, } = useColumnVisibility({
83
86
  columns,
84
- onVisibleColumnNamesChange,
85
- visibleColumnNames,
87
+ hiddenColumnNames,
88
+ onHiddenColumnNamesChange,
86
89
  });
90
+ const staticViews = useMemo(() => staticViewsProp?.map(withoutSearch), [staticViewsProp]);
91
+ const { defaultViewId, isReordering: isSavedViewReordering, onCreate: onSavedViewCreate, onDelete: onSavedViewDelete, onReorder: onSavedViewMove, onSetDefault: onDefaultViewIdChange, onUpdate: onSavedViewUpdate, savedViews, } = useSavedViewsState({
92
+ initialDefaultViewId,
93
+ initialSavedViews,
94
+ onCreate: onSavedViewCreateProp,
95
+ onDelete: onSavedViewDeleteProp,
96
+ onReorder: onSavedViewReorder,
97
+ onSetDefault: onDefaultViewIdChangeProp,
98
+ onUpdate: onSavedViewUpdateProp,
99
+ });
100
+ const hasInitialView = staticViews?.some(({ id }) => id === initialView.id);
101
+ const staticViewsWithInitial = hasInitialView
102
+ ? (staticViews ?? [])
103
+ : [initialView, ...(staticViews ?? [])];
104
+ const views = [...staticViewsWithInitial, ...(savedViews ?? [])];
105
+ const { activeSavedView, select, selectWhenSaved } = useActiveSavedView(views, () => views.find(({ id }) => id === defaultViewId));
87
106
  const visiblePreparedColumns = useMemo(() => preparedColumns.filter(({ column }) => isColumnVisible(column)), [preparedColumns, isColumnVisible]);
88
107
  const selectionModel = useDataTableSelection({
89
108
  canSelectAllPages,
@@ -105,15 +124,24 @@ const DataTableInner = ({ activeFilters = [], className, canSelectAllPages, colu
105
124
  // set that fits on one page shows both buttons disabled.
106
125
  const isIndexedPagination = paginationType === "indexed";
107
126
  const showPagination = isIndexedPagination || (totalPages !== undefined && totalPages > 1);
108
- const announcedActiveFiltersChange = useFilterAnnouncement({
127
+ const announcedActiveFiltersChange = useResultsAnnouncement({
109
128
  isPageCount: showPagination && resultCount === undefined,
110
129
  loadingState,
111
130
  onActiveFiltersChange,
112
131
  resultNoun,
113
132
  totalCount,
114
133
  });
134
+ const { chipFilters, clearFilters, onChipFiltersChange, onSearchChange, searchQuery, } = useSearchFilter(activeFilters, announcedActiveFiltersChange);
135
+ // Shared by the saved views bar and the filters shelf, so a save from the
136
+ // shelf shows its status in the bar.
137
+ const saveStatus = useSaveStatus();
138
+ // The view being applied, until the table's state matches it, so its actions
139
+ // don't flash in before the app passes the view's filters back.
140
+ const [applyingView, setApplyingView] = useState();
141
+ // Search isn't part of a view, so applying one keeps the current search.
115
142
  const applySavedView = (savedView) => {
116
- announcedActiveFiltersChange(savedView.activeFilters);
143
+ setApplyingView(savedView);
144
+ onChipFiltersChange(savedView.activeFilters);
117
145
  if (savedView.sort)
118
146
  onSortChange?.(savedView.sort);
119
147
  if (savedView.hiddenColumnNames) {
@@ -123,6 +151,37 @@ const DataTableInner = ({ activeFilters = [], className, canSelectAllPages, colu
123
151
  .map(({ name }) => name));
124
152
  }
125
153
  };
154
+ // What a view saves from the table. Hidden columns are left out when no
155
+ // column can be hidden, and sort when there isn't one.
156
+ const currentState = {
157
+ activeFilters: chipFilters,
158
+ ...(hideableColumns.length > 0 && {
159
+ hiddenColumnNames: hideableColumns
160
+ .filter((column) => !isColumnVisible(column))
161
+ .map(({ name }) => name),
162
+ }),
163
+ ...(sortBy && { sort: sortBy }),
164
+ };
165
+ if (applyingView && !isSavedViewModified(applyingView, currentState))
166
+ setApplyingView(undefined);
167
+ // A filter, sort, or column edit also ends applying, so the actions still
168
+ // show when the table can't match a view, such as an app that doesn't apply
169
+ // its sort or a view that hides a column that's gone.
170
+ const changeChipFilters = (filters) => {
171
+ setApplyingView(undefined);
172
+ onChipFiltersChange(filters);
173
+ };
174
+ const changeColumnVisibility = (visibleColumnNames) => {
175
+ setApplyingView(undefined);
176
+ onColumnVisibilityChange(visibleColumnNames);
177
+ };
178
+ // Only a user-created view with filters can be saved over. Pending filters
179
+ // aren't applied yet, so they don't count as changes.
180
+ const isActiveSavedViewModified = activeSavedView !== undefined &&
181
+ activeSavedView.id !== applyingView?.id &&
182
+ isSavedViewEditable(activeSavedView, savedViews ?? []) &&
183
+ chipFilters.length > 0 &&
184
+ isSavedViewModified(activeSavedView, currentState);
126
185
  // Associate the visible results count with the table so screen readers
127
186
  // announce it as a description of the table. `Table` doesn't support a real
128
187
  // `<caption>` (its children go through a collection builder), so we link the
@@ -150,7 +209,6 @@ const DataTableInner = ({ activeFilters = [], className, canSelectAllPages, colu
150
209
  const showHeader = hasResults || Boolean(hasTrailingControls);
151
210
  const hasRowActions = (rowActions?.length ?? 0) > 0;
152
211
  const { pendingFilters } = usePendingFilters();
153
- const { chipFilters, clearFilters, onChipFiltersChange, onSearchChange, searchQuery, } = useSearchFilter(activeFilters, announcedActiveFiltersChange);
154
212
  const hasEditableFilters = chipFilters.length + pendingFilters.length > 0;
155
213
  const { filterOpenRequest } = useFilterOpenRequest();
156
214
  const [isShelfExpanded, toggleShelf] = useShelfExpanded(chipFilters.length + pendingFilters.length, pendingFilters.length, filterOpenRequest);
@@ -161,7 +219,7 @@ const DataTableInner = ({ activeFilters = [], className, canSelectAllPages, colu
161
219
  return (React__default.createElement("div", { className: classNames("tds-data-table", {
162
220
  "tds-data-table--sticky-header": hasScrollContainer,
163
221
  }) },
164
- (Array.isArray(staticViews) || Array.isArray(savedViews)) && (React__default.createElement(SavedViewsBar, { defaultViewId: defaultViewId, savedViews: sortSavedViews(savedViews ?? []), staticViews: staticViews ?? [], onApply: applySavedView, onCreate: onSavedViewCreate, onDelete: onSavedViewDelete, onSetDefault: onDefaultViewIdChange, onUpdate: onSavedViewUpdate, activeFilters: activeFilters, hideableColumns: hideableColumns, isColumnVisible: isColumnVisible, sortBy: sortBy })),
222
+ (Array.isArray(staticViews) || Array.isArray(savedViews)) && (React__default.createElement(SavedViewsBar, { activeSavedView: activeSavedView, currentState: currentState, defaultViewId: defaultViewId, isReordering: isSavedViewReordering, saveStatus: saveStatus, savedViews: savedViews ?? [], select: select, selectWhenSaved: selectWhenSaved, staticViews: staticViewsWithInitial, onApply: applySavedView, onCreate: onSavedViewCreate, onDelete: onSavedViewDelete, onReorder: onSavedViewMove, onSetDefault: onDefaultViewIdChange, onUpdate: onSavedViewUpdate })),
165
223
  React__default.createElement("div", { className: "tds-data-table-frame" },
166
224
  React__default.createElement(DataTableSelectionContext.Provider, { value: selectionModel },
167
225
  showHeader && (React__default.createElement("div", { className: "tds-data-table-frame-header" },
@@ -172,11 +230,11 @@ const DataTableInner = ({ activeFilters = [], className, canSelectAllPages, colu
172
230
  hasTrailingControls && (React__default.createElement("div", { className: "tds-data-table-frame-header-controls" },
173
231
  searchable && (React__default.createElement(TableSearch, { label: searchLabel, tableId: tableId, value: searchQuery, onChange: onSearchChange })),
174
232
  hasFilters && (React__default.createElement(FilterControls, { activeFilters: chipFilters, filters: filters, isShelfExpanded: isShelfExpanded, onToggleShelf: toggleShelf })),
175
- hasViewSettingsToggle && (React__default.createElement(ViewSettingsToggle, { columns: hideableColumns, onColumnVisibilityChange: onColumnVisibilityChange, visibleColumnNames: visibleHideableColumns }))))))),
233
+ hasViewSettingsToggle && (React__default.createElement(ViewSettingsToggle, { columns: hideableColumns, onColumnVisibilityChange: changeColumnVisibility, visibleColumnNames: visibleHideableColumns }))))))),
176
234
  (hasFilters || hasEditableFilters) && (React__default.createElement("div", { className: classNames("tds-data-table-filters-shelf", {
177
235
  "tds-data-table-filters-shelf--collapsed": !isShelfExpanded,
178
236
  }), ...shelfInertProps },
179
- React__default.createElement("div", { className: "tds-data-table-filters" }, hasEditableFilters && (React__default.createElement(ActiveFilters, { activeFilters: chipFilters, hasFilters: hasFilters, onActiveFiltersChange: onChipFiltersChange, onClear: clearFilters }))))),
237
+ React__default.createElement("div", { className: "tds-data-table-filters" }, hasEditableFilters && (React__default.createElement(ActiveFilters, { activeFilters: chipFilters, activeSavedView: isActiveSavedViewModified ? activeSavedView : undefined, currentState: currentState, hasFilters: hasFilters, saveStatus: saveStatus, selectSavedViewWhenSaved: selectWhenSaved, onActiveFiltersChange: changeChipFilters, onClear: clearFilters, onSavedViewApply: applySavedView, onSavedViewCreate: onSavedViewCreate, onSavedViewUpdate: onSavedViewUpdate }))))),
180
238
  React__default.createElement(SelectAllBanner, { resultNoun: resultNoun })),
181
239
  React__default.createElement("div", { ref: wrapperRef, className: "tds-data-table-scroll-wrapper" },
182
240
  React__default.createElement("div", { ref: scrollRef, className: "tds-data-table-scroll", "aria-busy": showLoadingOverlay || undefined },
@@ -187,6 +245,7 @@ const DataTableInner = ({ activeFilters = [], className, canSelectAllPages, colu
187
245
  // disable `onRowClick`/`getRowLink` and drop the row out of the
188
246
  // focus order, so it has to be set explicitly.
189
247
  disabledBehavior: "selection", disabledKeys: disabledKeys, sortDescriptor: sortDescriptor, onSortChange: (sort) => {
248
+ setApplyingView(undefined);
190
249
  onSortChange?.(serializeSort(sort));
191
250
  } },
192
251
  React__default.createElement(TableHeader, { className: "tds-data-table-header" },
@@ -213,10 +272,11 @@ const DataTableInner = ({ activeFilters = [], className, canSelectAllPages, colu
213
272
  hasRowActions && (React__default.createElement(Cell, { ...cellBoundaryProps, className: "tds-data-table-cell tds-data-table-cell--actions" },
214
273
  React__default.createElement(RowActions, { actions: rowActions, row: row, rowKey: rowKey })))));
215
274
  })))),
216
- showLoadingOverlay && (React__default.createElement("div", { className: "tds-data-table-loading-overlay", role: "status" },
275
+ showLoadingOverlay && (React__default.createElement("div", { className: "tds-data-table-loading-overlay" },
217
276
  React__default.createElement("span", { className: "tds-data-table-loading-label--hidden" }, "Loading"),
218
277
  React__default.createElement("span", { className: "tds-data-table-loading-spinner", "aria-hidden": "true" },
219
- React__default.createElement(LoadingSpinner, null))))),
278
+ React__default.createElement(LoadingSpinner, null)),
279
+ React__default.createElement(LoadingAnnouncement, { message: "Loading" })))),
220
280
  showPagination && (React__default.createElement("div", { className: "tds-data-table-frame-footer" }, isIndexedPagination ? (React__default.createElement(Pagination, { "aria-label": paginationLabel, hasNextPage: hasNextPage, hasPreviousPage: hasPreviousPage, onNextPageClick: onNextPageClick, onPreviousPageClick: onPreviousPageClick, type: "indexed" })) : (React__default.createElement(Pagination, { "aria-label": paginationLabel, currentPage: currentPage, onPageChange: onPageChange, totalPages: totalPages })))))));
221
281
  };
222
282
  DataTable.displayName = "DataTable";
@@ -227,10 +287,11 @@ DataTable.displayName = "DataTable";
227
287
  */
228
288
  function getEmptyStateContent({ emptyState, errorState, loadingState, }) {
229
289
  if (loadingState === "loading") {
230
- return (React__default.createElement("div", { className: "tds-data-table-loading", role: "status" },
290
+ return (React__default.createElement("div", { className: "tds-data-table-loading" },
231
291
  React__default.createElement("span", { className: "tds-data-table-cell-label--hidden" }, "Loading"),
232
292
  React__default.createElement("span", { className: "tds-data-table-loading-spinner", "aria-hidden": "true" },
233
- React__default.createElement(LoadingSpinner, null))));
293
+ React__default.createElement(LoadingSpinner, null)),
294
+ React__default.createElement(LoadingAnnouncement, { message: "Loading" })));
234
295
  }
235
296
  // Error and empty share the same container; they differ only in content.
236
297
  const content = loadingState === "error" ? (errorState ?? DEFAULT_ERROR_STATE) : emptyState;