@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
@@ -1,18 +1,19 @@
1
- import '../button/ActionsDropdownIconButton.js';
1
+ import { ActionsDropdownIconButton } from '../button/ActionsDropdownIconButton.js';
2
2
  import { Button } from '../button/Button.js';
3
3
  import '../button/DropdownButton.js';
4
4
  import '../button/DropdownIconButton.js';
5
5
  import { IconButton } from '../button/IconButton.js';
6
6
  import '../button/LoadingButton.js';
7
7
  import '../button/PageHeaderActionsDropdownButton.js';
8
- import { ToggleIconButton } from '../button/ToggleIconButton.js';
9
- import { Input } from '../input/Input.js';
8
+ import { Dropdown, DropdownTrigger } from '../dropdown/Dropdown.js';
9
+ import { Tooltip } from '../internal/tooltip/Tooltip.js';
10
+ import { TooltipTriggerContext } from '../internal/tooltip/TooltipTriggerContext.js';
10
11
  import { Modal } from '../modal/Modal.js';
11
12
  import { ModalBody } from '../modal/ModalBody.js';
12
13
  import { ModalFooter } from '../modal/ModalFooter.js';
13
14
  import { ModalHeader } from '../modal/ModalHeader.js';
14
15
  import Icon from '../../utilities/Icon.js';
15
- import React__default, { useState, useRef, useEffect } from 'react';
16
+ import React__default, { useState, useRef, useEffect, useContext } from 'react';
16
17
  import { ListDropTargetDelegate } from 'react-aria/ListDropTargetDelegate';
17
18
  import { ListKeyboardDelegate } from 'react-aria/ListKeyboardDelegate';
18
19
  import { mergeProps } from 'react-aria/mergeProps';
@@ -26,48 +27,75 @@ import { useDroppableCollectionState } from 'react-stately/useDroppableCollectio
26
27
  import { useListState } from 'react-stately/useListState';
27
28
  import { DeleteSavedViewAlertDialog } from './DeleteSavedViewAlertDialog.js';
28
29
  import styles from './ManageSavedViewsModal.module.css.js';
29
- import { savedViewUpdatesForReorder } from './savedViews.js';
30
- import { useUpdateSavedViewName } from './useUpdateSavedViewName.js';
30
+ import { NewSavedViewModal } from './NewSavedViewModal.js';
31
+ import { hasSavedViewMenuActions, SavedViewMenu } from './SavedViewMenu.js';
32
+ import { useSavedViewNameModal } from './useSavedViewNameModal.js';
33
+ import { useSaveStatus, SaveStatusIcon } from './useSaveStatus.js';
31
34
 
32
- function ManageSavedViewsModal({ defaultViewId, onClose, onDelete, onSetDefault, onUpdate, open, savedViews, staticViews, }) {
33
- const updateSavedViewName = useUpdateSavedViewName(onUpdate);
35
+ function ManageSavedViewsModal({ defaultViewId, isReordering = false, onClose, onCreate, onDelete, onReorder, onSetDefault, onUpdate, open, savedViews, staticViews, }) {
34
36
  // Kept after the alert closes, so its text holds during the exit animation.
35
37
  const [viewToDelete, setViewToDelete] = useState(null);
36
38
  const [isDeleteAlertOpen, setIsDeleteAlertOpen] = useState(false);
37
39
  // Without this, focus would go to the modal's close button, since the
38
- // alert returns it to the delete button, which is gone with its row.
40
+ // alert returns it to the actions button, which is gone with its row.
39
41
  const { doneButtonRef, focusAfterDelete, listRef } = useFocusAfterDelete(savedViews, isDeleteAlertOpen);
42
+ const nameModal = useSavedViewNameModal(onUpdate);
43
+ const saveStatus = useSaveStatus();
44
+ // Listed after the other saved views. Managing views leaves the selection
45
+ // alone, so unlike the context menu's Duplicate, it doesn't select the
46
+ // duplicate. Its status shows on the view it was duplicated from, since
47
+ // it isn't listed until it saves.
48
+ const createDuplicate = (view, duplicate) => {
49
+ if (onCreate)
50
+ saveStatus.track(view.id, onCreate(duplicate), duplicate.name);
51
+ };
40
52
  const requestDelete = (view) => {
41
53
  setViewToDelete(view);
42
54
  setIsDeleteAlertOpen(true);
43
55
  };
44
- // Deleting the default view hands the default back to "initial".
45
56
  const confirmDelete = () => {
46
- if (viewToDelete) {
57
+ if (viewToDelete && onDelete) {
47
58
  focusAfterDelete(viewToDelete);
48
- onDelete?.(viewToDelete);
49
- if (viewToDelete.id === defaultViewId)
50
- onSetDefault?.("initial");
59
+ saveStatus.track(viewToDelete.id, onDelete(viewToDelete), viewToDelete.name);
51
60
  }
52
61
  setIsDeleteAlertOpen(false);
53
62
  };
54
- // The default is matched by id, so an unsaved view can't be made the
55
- // default. Unsetting the default hands it back to "initial".
56
- const renderDefaultViewToggle = ({ id, name }) => onSetDefault && id !== undefined ? (React__default.createElement(DefaultViewToggle, { isDefault: id === defaultViewId, name: name, onChange: (isDefault) => onSetDefault(isDefault ? id : "initial") })) : null;
57
- return (React__default.createElement(Modal, { dismissible: true, open: open, onClose: onClose },
63
+ // Every row gets an actions button, disabled without actions, so the
64
+ // buttons line up.
65
+ const hasViewActions = Boolean(onCreate || onDelete || onSetDefault || onUpdate);
66
+ // The actions static views share with saved views. The default is matched
67
+ // by id, so an unsaved view can't be made the default.
68
+ const viewActions = (view) => {
69
+ const { id } = view;
70
+ return {
71
+ isDefault: id === defaultViewId,
72
+ onDuplicate: onCreate
73
+ ? () => nameModal.openDuplicate(view, (duplicate) => createDuplicate(view, duplicate))
74
+ : undefined,
75
+ onSetDefault: onSetDefault && id !== undefined
76
+ ? () => saveStatus.track(id, onSetDefault(id), view.name)
77
+ : undefined,
78
+ };
79
+ };
80
+ return (React__default.createElement(Modal, { dismissible: true, open: open, size: "sm", onClose: onClose },
58
81
  React__default.createElement(ModalHeader, { title: "Manage views" }),
59
82
  React__default.createElement(ModalBody, null,
60
- React__default.createElement(SavedViewsList, { listRef: listRef, renderStaticViewActions: (view) => (React__default.createElement(React__default.Fragment, null,
61
- renderDefaultViewToggle(view),
62
- onDelete && React__default.createElement(DeleteViewButton, { disabled: true, name: view.name }))), savedViews: savedViews, staticViews: staticViews, onUpdate: onUpdate }, (view) => (React__default.createElement(SavedViewRow, { defaultViewToggle: renderDefaultViewToggle(view), hasDeleteButton: Boolean(onDelete),
83
+ React__default.createElement(SavedViewsList, { isReordering: isReordering, listRef: listRef, renderStaticViewActions: (view) => (React__default.createElement(React__default.Fragment, null,
84
+ React__default.createElement(SaveStatusIcon, { status: saveStatus.statusFor(view.id) }),
85
+ view.id === defaultViewId && React__default.createElement(DefaultViewIcon, null),
86
+ hasViewActions && (React__default.createElement(ViewActionsMenu, { name: view.name, ...viewActions(view) })))), savedViews: savedViews, staticViews: staticViews, onReorder: onReorder &&
87
+ ((view, target) => saveStatus.track(view.id, onReorder(view, target), view.name)) }, (view) => (React__default.createElement(SavedViewRow, { hasActionsMenu: hasViewActions, view: view, ...viewActions(view), saveStatus: React__default.createElement(SaveStatusIcon, { status: saveStatus.statusFor(view.id) }),
63
88
  // Updates and deletes are matched by id, so an unsaved view
64
89
  // can't be renamed or deleted.
65
- readOnly: !onUpdate || view.id === undefined, view: view, onDelete: onDelete && view.id !== undefined
66
- ? (name) => requestDelete({ ...view, name })
67
- : undefined, onRename: (name) => updateSavedViewName(view, name) })))),
90
+ onDelete: onDelete && view.id !== undefined
91
+ ? () => requestDelete(view)
92
+ : undefined, onRename: onUpdate && view.id !== undefined
93
+ ? () => nameModal.openRename(view, (saving) => saveStatus.track(view.id, saving, view.name))
94
+ : undefined })))),
68
95
  React__default.createElement(ModalFooter, null,
69
96
  React__default.createElement(Button, { ref: doneButtonRef, kind: "primary", label: "Done", onClick: onClose })),
70
- onDelete && (React__default.createElement(DeleteSavedViewAlertDialog, { open: isDeleteAlertOpen, view: viewToDelete, onCancel: () => setIsDeleteAlertOpen(false), onConfirm: confirmDelete }))));
97
+ onDelete && (React__default.createElement(DeleteSavedViewAlertDialog, { open: isDeleteAlertOpen, view: viewToDelete, onCancel: () => setIsDeleteAlertOpen(false), onConfirm: confirmDelete })),
98
+ (onCreate || onUpdate) && (React__default.createElement(NewSavedViewModal, { ...nameModal.modalProps }))));
71
99
  }
72
100
  ManageSavedViewsModal.displayName = "ManageSavedViewsModal";
73
101
  /**
@@ -75,17 +103,17 @@ ManageSavedViewsModal.displayName = "ManageSavedViewsModal";
75
103
  * modal's content, since React Aria registers the list as a drop target when
76
104
  * its hooks mount, and the modal stays mounted while closed.
77
105
  */
78
- function SavedViewsList({ children, listRef, onUpdate, renderStaticViewActions, savedViews, staticViews, }) {
79
- const { collectionProps, dragState, dropState } = useSavedViewsDragAndDrop(savedViews, listRef, onUpdate);
106
+ function SavedViewsList({ children, isReordering, listRef, onReorder, renderStaticViewActions, savedViews, staticViews, }) {
107
+ const { collectionProps, dragState, dropState } = useSavedViewsDragAndDrop(savedViews, listRef, isReordering, onReorder);
80
108
  return (React__default.createElement("ol", { ref: listRef, ...collectionProps, className: styles["views-list"] },
81
109
  staticViews.map((view) => (React__default.createElement("li", { key: view.id, className: styles["views-list-item--static"] },
82
- React__default.createElement("span", { className: styles["view-list-item-static-name"] }, view.name),
110
+ React__default.createElement("span", { className: styles["view-list-item-name"] }, view.name),
83
111
  renderStaticViewActions(view)))),
84
112
  savedViews.map((view, index) => {
85
113
  const key = savedViewKey(view, index);
86
114
  return (React__default.createElement("li", { key: key, className: styles["views-list-item"], "data-dragging": dragState.isDragging(key) || undefined, "data-key": key },
87
115
  React__default.createElement(SavedViewDropIndicator, { dropState: dropState, target: { dropPosition: "before", key, type: "item" } }),
88
- savedViews.length > 1 && onUpdate && view.id !== undefined && (React__default.createElement(SavedViewDragHandle, { dragState: dragState, itemKey: key, name: view.name })),
116
+ savedViews.length > 1 && onReorder && view.id !== undefined && (React__default.createElement(SavedViewDragHandle, { dragState: dragState, itemKey: key, name: view.name })),
89
117
  children(view),
90
118
  index === savedViews.length - 1 && (React__default.createElement(SavedViewDropIndicator, { dropState: dropState, target: { dropPosition: "after", key, type: "item" } }))));
91
119
  })));
@@ -96,22 +124,27 @@ function savedViewKey(view, index) {
96
124
  }
97
125
  /**
98
126
  * Drag and drop for the saved views' rows, which React Aria finds by their
99
- * `data-key`. A drop sends the views with new sort keys to `onUpdate`, and
100
- * the row moves once they're passed back in.
127
+ * `data-key`. A drop sends the dragged view and where it landed to
128
+ * `onReorder`.
101
129
  */
102
- function useSavedViewsDragAndDrop(savedViews, listRef, onUpdate) {
130
+ function useSavedViewsDragAndDrop(savedViews, listRef, isReordering, onReorder) {
103
131
  const { collection, selectionManager } = useListState({
104
132
  children: savedViews.map((view, index) => (React__default.createElement(Item, { key: savedViewKey(view, index), textValue: view.name }, view.name))),
105
133
  selectionMode: "none",
106
134
  });
135
+ const [isDragging, setIsDragging] = useState(false);
107
136
  const dragState = useDraggableCollectionState({
108
137
  collection,
109
138
  getItems: (keys) => [...keys].map((key) => ({
110
139
  "text/plain": collection.getItem(key)?.textValue ?? String(key),
111
140
  })),
141
+ // Reorders save one at a time. A pointer drop starts the save before the
142
+ // drag ends, and a disabled handle drops the listener that ends it.
143
+ isDisabled: isReordering && !isDragging,
112
144
  // A drop removes the drop target that had focus, and rows can't take
113
145
  // focus, so it goes back to the handle that started the drag.
114
146
  onDragEnd: ({ keys }) => {
147
+ setIsDragging(false);
115
148
  const [key] = keys;
116
149
  listRef.current
117
150
  ?.querySelector(`[data-key="${CSS.escape(String(key))}"] .${styles["view-list-item-drag-handle"]}`)
@@ -120,36 +153,37 @@ function useSavedViewsDragAndDrop(savedViews, listRef, onUpdate) {
120
153
  // A keyboard drag starts after the focused row, which the rows can't
121
154
  // set themselves, since they can't take focus.
122
155
  onDragStart: ({ keys }) => {
156
+ setIsDragging(true);
123
157
  const [key] = keys;
124
158
  selectionManager.setFocusedKey(key);
125
159
  },
126
160
  selectionManager,
127
161
  });
128
162
  useDraggableCollection({}, dragState, listRef);
129
- const onReorder = ({ keys, target }) => {
130
- const indexOf = (key) => savedViews.findIndex((view, index) => savedViewKey(view, index) === key);
163
+ const reorder = ({ keys, target }) => {
164
+ const viewFor = (key) => savedViews.find((view, index) => savedViewKey(view, index) === key);
131
165
  // Rows only offer drop targets between them, not on them.
132
166
  if (target.dropPosition === "on")
133
167
  return;
134
168
  const [key] = keys;
135
- const updates = savedViewUpdatesForReorder(savedViews, indexOf(key), indexOf(target.key), target.dropPosition);
136
- // Updates are matched by id, so a reorder that needs to update an unsaved
137
- // view can't be saved in full. Saving part of it would leave the order
138
- // unchanged anyway.
139
- if (updates.some((view) => view.id === undefined))
140
- return;
141
- for (const view of updates)
142
- onUpdate?.(view);
169
+ const view = viewFor(key);
170
+ const targetView = viewFor(target.key);
171
+ if (view && targetView) {
172
+ onReorder?.(view, {
173
+ dropPosition: target.dropPosition,
174
+ view: targetView,
175
+ });
176
+ }
143
177
  };
144
178
  const dropState = useDroppableCollectionState({
145
179
  collection,
146
- onReorder,
180
+ onReorder: reorder,
147
181
  selectionManager,
148
182
  });
149
183
  const { collectionProps } = useDroppableCollection({
150
184
  dropTargetDelegate: new ListDropTargetDelegate(collection, listRef),
151
185
  keyboardDelegate: new ListKeyboardDelegate({ collection, ref: listRef }),
152
- onReorder,
186
+ onReorder: reorder,
153
187
  }, dropState, listRef);
154
188
  return { collectionProps, dragState, dropState };
155
189
  }
@@ -174,7 +208,9 @@ function SavedViewDragHandle({ dragState, itemKey, name, }) {
174
208
  requestAnimationFrame(() => row.classList.remove(className));
175
209
  event.dataTransfer.setDragImage(row, event.clientX - left, event.clientY - top);
176
210
  },
177
- }), "aria-label": `Reorder ${name}`, className: styles["view-list-item-drag-handle"], icon: React__default.createElement(Icon, { "aria-hidden": true, symbol: "general#drag-handle" }), kind: "ghost" }));
211
+ }), "aria-label": `Reorder ${name}`, className: styles["view-list-item-drag-handle"],
212
+ // Stays focusable, since focus returns here after a keyboard drop.
213
+ disabled: dragState.isDisabled, focusableWhenDisabled: true, icon: React__default.createElement(Icon, { "aria-hidden": true, symbol: "general#drag-handle" }), kind: "ghost" }));
178
214
  }
179
215
  /**
180
216
  * A line at a row's edge while dragging. Screen readers reach the hidden
@@ -198,17 +234,15 @@ function useFocusAfterDelete(savedViews, isDeleteAlertOpen) {
198
234
  const listRef = useRef(null);
199
235
  const doneButtonRef = useRef(null);
200
236
  const focusTargetRef = useRef(null);
201
- // Step 1: the next view's row, or the previous one's if the deleted view is
202
- // last, or Done if it's the only one.
237
+ // Step 1: the actions button on the next view's row, or the previous one's
238
+ // if the deleted view is last, or Done if that row's actions are disabled or
239
+ // it's the only one.
203
240
  const focusAfterDelete = (view) => {
204
241
  const rows = listRef.current?.querySelectorAll(`.${styles["views-list-item"]}`) ?? [];
205
242
  const index = savedViews.findIndex(({ id }) => id === view.id);
206
243
  const row = rows[index + 1] ?? rows[index - 1];
207
- // The row's last enabled button is its delete button, when it has one.
208
- const buttons = row?.querySelectorAll(`button:not(.${styles["view-list-item-drag-handle"]}, :disabled)`);
209
244
  focusTargetRef.current =
210
- buttons?.[buttons.length - 1] ??
211
- row?.querySelector("input") ??
245
+ row?.querySelector("button[data-view-actions]:enabled") ??
212
246
  doneButtonRef.current;
213
247
  };
214
248
  // Step 2: a closing alert no longer holds focus, and doesn't take it back
@@ -221,63 +255,45 @@ function useFocusAfterDelete(savedViews, isDeleteAlertOpen) {
221
255
  }, [isDeleteAlertOpen]);
222
256
  return { doneButtonRef, focusAfterDelete, listRef };
223
257
  }
258
+ /** A saved view's name and actions menu. */
259
+ function SavedViewRow({ hasActionsMenu, saveStatus, view, ...menuProps }) {
260
+ return (React__default.createElement(React__default.Fragment, null,
261
+ React__default.createElement("span", { className: styles["view-list-item-name"] }, view.name),
262
+ saveStatus,
263
+ menuProps.isDefault && React__default.createElement(DefaultViewIcon, null),
264
+ hasActionsMenu && React__default.createElement(ViewActionsMenu, { name: view.name, ...menuProps })));
265
+ }
224
266
  /**
225
- * A saved view's name field, default view toggle, and delete button. Renames on blur or Enter. An
226
- * empty name reverts to the current one. Tracks the last name it sent, so
227
- * Enter followed by blur renames once. Deleting sends a pending rename first,
228
- * then passes along the name, so the alert shows what the field does.
267
+ * Marks the default view. Set the default from its actions menu. Its tooltip
268
+ * shows on hover only, since the icon can't take focus, and screen readers get
269
+ * the same text from the icon's name.
229
270
  */
230
- function SavedViewRow({ defaultViewToggle, hasDeleteButton, onDelete, onRename, readOnly, view, }) {
231
- const [name, setName] = useState(view.name);
232
- const committedName = useRef(view.name);
233
- // Picks up names changed outside this field, including once a rename saves,
234
- // unless the field has newer edits, which its next blur or Enter sends.
235
- useEffect(() => {
236
- const previousName = committedName.current;
237
- committedName.current = view.name;
238
- setName((currentName) => currentName === previousName ? view.name : currentName);
239
- }, [view.name]);
240
- const commit = () => {
241
- const trimmedName = name.trim();
242
- if (!trimmedName) {
243
- setName(committedName.current);
244
- return;
245
- }
246
- setName(trimmedName);
247
- if (trimmedName === committedName.current)
248
- return;
249
- committedName.current = trimmedName;
250
- onRename(trimmedName);
251
- };
252
- return (React__default.createElement(React__default.Fragment, null,
253
- React__default.createElement(Input, { autoComplete: "off", className: styles["view-list-item-input"], hideLabel: true, label: `Name for ${view.name}`, readOnly: readOnly, required: !readOnly, value: name, onBlur: readOnly ? undefined : commit, onChange: (event) => setName(event.target.value), onKeyDown: (event) => {
254
- if (!readOnly &&
255
- event.key === "Enter" &&
256
- !event.repeat &&
257
- !event.nativeEvent.isComposing) {
258
- commit();
259
- }
260
- } }),
261
- defaultViewToggle,
262
- hasDeleteButton && (React__default.createElement(DeleteViewButton, { disabled: !onDelete, name: view.name, onClick: (event) => {
263
- // Safari doesn't focus a button on click, and the alert returns
264
- // focus to whatever had it when it opened. Focusing also blurs
265
- // the field, which sends a pending rename.
266
- event.currentTarget.focus();
267
- onDelete?.(committedName.current);
268
- } }))));
271
+ function DefaultViewIcon() {
272
+ return (React__default.createElement(Tooltip, { content: "Default view", placement: "bottom", visualOnly: true },
273
+ React__default.createElement(DefaultViewIconTrigger, null)));
269
274
  }
270
- function DeleteViewButton({ disabled, name, onClick, }) {
271
- return (React__default.createElement(IconButton, { "aria-label": `Delete ${name}`, disabled: disabled, icon: React__default.createElement(Icon, { "aria-hidden": true, symbol: "general#trash" }), kind: "ghost", tooltip: "Delete", onClick: onClick }));
275
+ /** Takes the tooltip's trigger wiring, which only buttons and links read. */
276
+ function DefaultViewIconTrigger() {
277
+ const tooltip = useContext(TooltipTriggerContext);
278
+ return (React__default.createElement("span", { ref: tooltip?.ref, ...tooltip?.triggerProps, className: styles["view-list-item-default-icon"] },
279
+ React__default.createElement(Icon, { "aria-label": "Default view", role: "img", symbol: "general#pin" })));
272
280
  }
273
- /** Makes a view the default, or hands the default back to "initial". */
274
- function DefaultViewToggle({ isDefault, name, onChange, }) {
275
- return (React__default.createElement(ToggleIconButton
276
- // Only one view is the default, so its label doesn't need the view's
277
- // name to be unique.
278
- , { "aria-label": isDefault ? "Default view" : `Set ${name} as default`, icon: React__default.createElement(Icon, { "aria-hidden": true, symbol: isDefault ? "general#pin" : "general#outlined-pin" }),
279
- // Only the default's pin is blue.
280
- kind: isDefault ? "ghost-interaction" : "ghost", pressed: isDefault, tooltip: isDefault ? "Default view" : "Set as default", onChange: onChange }));
281
+ /** A view's actions menu. Disabled without any actions. */
282
+ function ViewActionsMenu({ name, ...menuProps }) {
283
+ const triggerRef = useRef(null);
284
+ const { onDelete, onDuplicate, onRename } = menuProps;
285
+ // The name modal and alert return focus to whatever had it when they
286
+ // opened. The menu hasn't returned focus to its button yet by then, so
287
+ // this does it first.
288
+ const withFocusOnTrigger = (open) => open &&
289
+ (() => queueMicrotask(() => {
290
+ triggerRef.current?.focus();
291
+ open();
292
+ }));
293
+ return (React__default.createElement(Dropdown, null,
294
+ React__default.createElement(DropdownTrigger, { disabled: !hasSavedViewMenuActions(menuProps) },
295
+ React__default.createElement(ActionsDropdownIconButton, { ref: triggerRef, "aria-label": `Actions for ${name}`, className: styles["view-list-item-actions"], "data-view-actions": true })),
296
+ React__default.createElement(SavedViewMenu, { ...menuProps, placement: "bottom end", onDelete: withFocusOnTrigger(onDelete), onDuplicate: withFocusOnTrigger(onDuplicate), onRename: withFocusOnTrigger(onRename) })));
281
297
  }
282
298
 
283
299
  export { ManageSavedViewsModal };
@@ -1 +1 @@
1
- {"version":3,"file":"ManageSavedViewsModal.js","sources":["../../../src/components/DataTable/ManageSavedViewsModal.tsx"],"sourcesContent":["import { Button, IconButton } from \"@components/button\"\nimport { ToggleIconButton } from \"@components/button/ToggleIconButton\"\nimport { Input } from \"@components/input\"\nimport { Modal, ModalBody, ModalFooter, ModalHeader } from \"@components/modal\"\nimport Icon from \"@utilities/Icon\"\nimport React, { type ReactNode, useEffect, useRef, useState } from \"react\"\nimport { ListDropTargetDelegate } from \"react-aria/ListDropTargetDelegate\"\nimport { ListKeyboardDelegate } from \"react-aria/ListKeyboardDelegate\"\nimport { mergeProps } from \"react-aria/mergeProps\"\nimport { useButton } from \"react-aria/useButton\"\nimport {\n useDraggableCollection,\n useDraggableItem,\n} from \"react-aria/useDraggableCollection\"\nimport {\n type DroppableCollectionReorderEvent,\n type DropTarget,\n useDropIndicator,\n useDroppableCollection,\n} from \"react-aria/useDroppableCollection\"\nimport { useVisuallyHidden } from \"react-aria/VisuallyHidden\"\nimport type { Key } from \"react-aria-components/ListBox\"\nimport { Item } from \"react-stately/Item\"\nimport {\n type DraggableCollectionState,\n useDraggableCollectionState,\n} from \"react-stately/useDraggableCollectionState\"\nimport {\n type DroppableCollectionState,\n useDroppableCollectionState,\n} from \"react-stately/useDroppableCollectionState\"\nimport { useListState } from \"react-stately/useListState\"\n\nimport { DeleteSavedViewAlertDialog } from \"./DeleteSavedViewAlertDialog\"\nimport styles from \"./ManageSavedViewsModal.module.css\"\nimport {\n type SavedView,\n savedViewUpdatesForReorder,\n type StaticView,\n} from \"./savedViews\"\nimport { useUpdateSavedViewName } from \"./useUpdateSavedViewName\"\n\nexport interface ManageSavedViewsModalProps {\n defaultViewId: NonNullable<SavedView[\"id\"]>\n onClose: () => void\n /** Called once the user confirms. Omit to leave out the delete buttons. */\n onDelete?: (savedView: SavedView) => void\n /** Omit to leave out the default view buttons. */\n onSetDefault?: (id: NonNullable<SavedView[\"id\"]>) => void\n onUpdate?: (savedView: SavedView) => Promise<SavedView> | SavedView\n open: boolean\n savedViews: SavedView[]\n /** Listed by name before `savedViews`, since they can't be renamed. */\n staticViews: StaticView[]\n}\n\nexport function ManageSavedViewsModal({\n defaultViewId,\n onClose,\n onDelete,\n onSetDefault,\n onUpdate,\n open,\n savedViews,\n staticViews,\n}: ManageSavedViewsModalProps) {\n const updateSavedViewName = useUpdateSavedViewName(onUpdate)\n // Kept after the alert closes, so its text holds during the exit animation.\n const [viewToDelete, setViewToDelete] = useState<SavedView | null>(null)\n const [isDeleteAlertOpen, setIsDeleteAlertOpen] = useState(false)\n // Without this, focus would go to the modal's close button, since the\n // alert returns it to the delete button, which is gone with its row.\n const { doneButtonRef, focusAfterDelete, listRef } = useFocusAfterDelete(\n savedViews,\n isDeleteAlertOpen\n )\n\n const requestDelete = (view: SavedView) => {\n setViewToDelete(view)\n setIsDeleteAlertOpen(true)\n }\n\n // Deleting the default view hands the default back to \"initial\".\n const confirmDelete = () => {\n if (viewToDelete) {\n focusAfterDelete(viewToDelete)\n onDelete?.(viewToDelete)\n if (viewToDelete.id === defaultViewId) onSetDefault?.(\"initial\")\n }\n setIsDeleteAlertOpen(false)\n }\n\n // The default is matched by id, so an unsaved view can't be made the\n // default. Unsetting the default hands it back to \"initial\".\n const renderDefaultViewToggle = ({ id, name }: SavedView) =>\n onSetDefault && id !== undefined ? (\n <DefaultViewToggle\n isDefault={id === defaultViewId}\n name={name}\n onChange={(isDefault) => onSetDefault(isDefault ? id : \"initial\")}\n />\n ) : null\n\n return (\n <Modal dismissible open={open} onClose={onClose}>\n <ModalHeader title=\"Manage views\" />\n <ModalBody>\n <SavedViewsList\n listRef={listRef}\n renderStaticViewActions={(view) => (\n <>\n {renderDefaultViewToggle(view)}\n {/* Static views can't be deleted, but keep the column lined up. */}\n {onDelete && <DeleteViewButton disabled name={view.name} />}\n </>\n )}\n savedViews={savedViews}\n staticViews={staticViews}\n onUpdate={onUpdate}\n >\n {(view) => (\n <SavedViewRow\n defaultViewToggle={renderDefaultViewToggle(view)}\n hasDeleteButton={Boolean(onDelete)}\n // Updates and deletes are matched by id, so an unsaved view\n // can't be renamed or deleted.\n readOnly={!onUpdate || view.id === undefined}\n view={view}\n onDelete={\n onDelete && view.id !== undefined\n ? (name) => requestDelete({ ...view, name })\n : undefined\n }\n onRename={(name) => updateSavedViewName(view, name)}\n />\n )}\n </SavedViewsList>\n </ModalBody>\n <ModalFooter>\n <Button\n ref={doneButtonRef}\n kind=\"primary\"\n label=\"Done\"\n onClick={onClose}\n />\n </ModalFooter>\n {onDelete && (\n <DeleteSavedViewAlertDialog\n open={isDeleteAlertOpen}\n view={viewToDelete}\n onCancel={() => setIsDeleteAlertOpen(false)}\n onConfirm={confirmDelete}\n />\n )}\n </Modal>\n )\n}\n\nManageSavedViewsModal.displayName = \"ManageSavedViewsModal\"\n\n/**\n * The static views, then the saved views with drag handles. Mounts with the\n * modal's content, since React Aria registers the list as a drop target when\n * its hooks mount, and the modal stays mounted while closed.\n */\nfunction SavedViewsList({\n children,\n listRef,\n onUpdate,\n renderStaticViewActions,\n savedViews,\n staticViews,\n}: {\n children: (view: SavedView) => ReactNode\n listRef: React.RefObject<HTMLOListElement>\n onUpdate?: ManageSavedViewsModalProps[\"onUpdate\"]\n renderStaticViewActions: (view: StaticView) => ReactNode\n savedViews: SavedView[]\n staticViews: StaticView[]\n}) {\n const { collectionProps, dragState, dropState } = useSavedViewsDragAndDrop(\n savedViews,\n listRef,\n onUpdate\n )\n\n return (\n <ol ref={listRef} {...collectionProps} className={styles[\"views-list\"]}>\n {staticViews.map((view) => (\n <li key={view.id} className={styles[\"views-list-item--static\"]}>\n <span className={styles[\"view-list-item-static-name\"]}>\n {view.name}\n </span>\n {renderStaticViewActions(view)}\n </li>\n ))}\n {savedViews.map((view, index) => {\n const key = savedViewKey(view, index)\n return (\n <li\n key={key}\n className={styles[\"views-list-item\"]}\n data-dragging={dragState.isDragging(key) || undefined}\n data-key={key}\n >\n <SavedViewDropIndicator\n dropState={dropState}\n target={{ dropPosition: \"before\", key, type: \"item\" }}\n />\n {/* A single view has no order to change, and updates are matched\n by id, so an unsaved view can't be reordered. */}\n {savedViews.length > 1 && onUpdate && view.id !== undefined && (\n <SavedViewDragHandle\n dragState={dragState}\n itemKey={key}\n name={view.name}\n />\n )}\n {children(view)}\n {index === savedViews.length - 1 && (\n <SavedViewDropIndicator\n dropState={dropState}\n target={{ dropPosition: \"after\", key, type: \"item\" }}\n />\n )}\n </li>\n )\n })}\n </ol>\n )\n}\n\n/** A string, since React Aria's collection keys an `Item` by its React key. */\nfunction savedViewKey(view: SavedView, index: number): Key {\n return String(view.id ?? `unsaved-view-${index}`)\n}\n\n/**\n * Drag and drop for the saved views' rows, which React Aria finds by their\n * `data-key`. A drop sends the views with new sort keys to `onUpdate`, and\n * the row moves once they're passed back in.\n */\nfunction useSavedViewsDragAndDrop(\n savedViews: SavedView[],\n listRef: React.RefObject<HTMLOListElement | null>,\n onUpdate?: ManageSavedViewsModalProps[\"onUpdate\"]\n) {\n const { collection, selectionManager } = useListState({\n children: savedViews.map((view, index) => (\n <Item key={savedViewKey(view, index)} textValue={view.name}>\n {view.name}\n </Item>\n )),\n selectionMode: \"none\",\n })\n\n const dragState = useDraggableCollectionState({\n collection,\n getItems: (keys) =>\n [...keys].map((key) => ({\n \"text/plain\": collection.getItem(key)?.textValue ?? String(key),\n })),\n\n // A drop removes the drop target that had focus, and rows can't take\n // focus, so it goes back to the handle that started the drag.\n onDragEnd: ({ keys }) => {\n const [key] = keys\n listRef.current\n ?.querySelector<HTMLElement>(\n `[data-key=\"${CSS.escape(String(key))}\"] .${styles[\"view-list-item-drag-handle\"]}`\n )\n ?.focus()\n },\n\n // A keyboard drag starts after the focused row, which the rows can't\n // set themselves, since they can't take focus.\n onDragStart: ({ keys }) => {\n const [key] = keys\n selectionManager.setFocusedKey(key)\n },\n selectionManager,\n })\n useDraggableCollection({}, dragState, listRef)\n\n const onReorder = ({ keys, target }: DroppableCollectionReorderEvent) => {\n const indexOf = (key: Key) =>\n savedViews.findIndex((view, index) => savedViewKey(view, index) === key)\n // Rows only offer drop targets between them, not on them.\n if (target.dropPosition === \"on\") return\n const [key] = keys\n const updates = savedViewUpdatesForReorder(\n savedViews,\n indexOf(key),\n indexOf(target.key),\n target.dropPosition\n )\n // Updates are matched by id, so a reorder that needs to update an unsaved\n // view can't be saved in full. Saving part of it would leave the order\n // unchanged anyway.\n if (updates.some((view) => view.id === undefined)) return\n for (const view of updates) onUpdate?.(view)\n }\n const dropState = useDroppableCollectionState({\n collection,\n onReorder,\n selectionManager,\n })\n const { collectionProps } = useDroppableCollection(\n {\n dropTargetDelegate: new ListDropTargetDelegate(collection, listRef),\n keyboardDelegate: new ListKeyboardDelegate({ collection, ref: listRef }),\n onReorder,\n },\n dropState,\n listRef\n )\n\n return { collectionProps, dragState, dropState }\n}\n\n/**\n * Starts a drag with a pointer, or with Enter or Space. A pointer drag shows\n * the whole row, held where the pointer grabbed it, rather than the handle.\n */\nfunction SavedViewDragHandle({\n dragState,\n itemKey,\n name,\n}: {\n dragState: DraggableCollectionState\n itemKey: Key\n name: string\n}) {\n const ref = useRef<HTMLButtonElement>(null)\n const { dragButtonProps, dragProps } = useDraggableItem(\n { hasDragButton: true, key: itemKey },\n dragState\n )\n const { buttonProps } = useButton(dragButtonProps, ref)\n\n return (\n <IconButton\n ref={ref}\n {...mergeProps(buttonProps, dragProps, {\n onDragStart: (event: React.DragEvent<HTMLButtonElement>) => {\n const row = event.currentTarget.closest(\"li\")\n if (!row) return\n const { left, top } = row.getBoundingClientRect()\n // The browser snapshots the row once this handler returns, so the\n // ghost styles apply only to the snapshot.\n const className = styles[\"views-list-item--drag-ghost\"]\n row.classList.add(className)\n requestAnimationFrame(() => row.classList.remove(className))\n event.dataTransfer.setDragImage(\n row,\n event.clientX - left,\n event.clientY - top\n )\n },\n })}\n aria-label={`Reorder ${name}`}\n className={styles[\"view-list-item-drag-handle\"]}\n icon={<Icon aria-hidden symbol=\"general#drag-handle\" />}\n kind=\"ghost\"\n />\n )\n}\n\n/**\n * A line at a row's edge while dragging. Screen readers reach the hidden\n * button inside it as a drop target.\n */\nfunction SavedViewDropIndicator({\n dropState,\n target,\n}: {\n dropState: DroppableCollectionState\n target: DropTarget\n}) {\n const ref = useRef<HTMLDivElement>(null)\n const { dropIndicatorProps, isDropTarget, isHidden } = useDropIndicator(\n { target },\n dropState,\n ref\n )\n const { visuallyHiddenProps } = useVisuallyHidden()\n if (isHidden) return null\n\n return (\n <div\n className={styles[\"view-list-drop-indicator\"]}\n data-drop-position={\n target.type === \"item\" ? target.dropPosition : undefined\n }\n data-drop-target={isDropTarget || undefined}\n >\n <div\n {...visuallyHiddenProps}\n role=\"button\"\n {...dropIndicatorProps}\n ref={ref}\n />\n </div>\n )\n}\n\n/**\n * Moves focus off a deleted view's row in two steps: `focusAfterDelete` picks\n * the target while the row is still there, and focus moves to it once the\n * alert starts closing.\n */\nfunction useFocusAfterDelete(\n savedViews: SavedView[],\n isDeleteAlertOpen: boolean\n) {\n const listRef = useRef<HTMLOListElement>(null)\n const doneButtonRef = useRef<HTMLButtonElement>(null)\n const focusTargetRef = useRef<HTMLElement | null>(null)\n\n // Step 1: the next view's row, or the previous one's if the deleted view is\n // last, or Done if it's the only one.\n const focusAfterDelete = (view: SavedView) => {\n const rows =\n listRef.current?.querySelectorAll(`.${styles[\"views-list-item\"]}`) ?? []\n const index = savedViews.findIndex(({ id }) => id === view.id)\n const row = rows[index + 1] ?? rows[index - 1]\n // The row's last enabled button is its delete button, when it has one.\n const buttons = row?.querySelectorAll<HTMLElement>(\n `button:not(.${styles[\"view-list-item-drag-handle\"]}, :disabled)`\n )\n focusTargetRef.current =\n buttons?.[buttons.length - 1] ??\n row?.querySelector(\"input\") ??\n doneButtonRef.current\n }\n\n // Step 2: a closing alert no longer holds focus, and doesn't take it back\n // once focus is outside it.\n useEffect(() => {\n if (isDeleteAlertOpen) return\n focusTargetRef.current?.focus()\n focusTargetRef.current = null\n }, [isDeleteAlertOpen])\n\n return { doneButtonRef, focusAfterDelete, listRef }\n}\n\n/**\n * A saved view's name field, default view toggle, and delete button. Renames on blur or Enter. An\n * empty name reverts to the current one. Tracks the last name it sent, so\n * Enter followed by blur renames once. Deleting sends a pending rename first,\n * then passes along the name, so the alert shows what the field does.\n */\nfunction SavedViewRow({\n defaultViewToggle,\n hasDeleteButton,\n onDelete,\n onRename,\n readOnly,\n view,\n}: {\n defaultViewToggle: ReactNode\n /** Shows the delete button, disabled without `onDelete`. */\n hasDeleteButton: boolean\n onDelete?: (name: string) => void\n onRename: (name: string) => void\n readOnly: boolean\n view: SavedView\n}) {\n const [name, setName] = useState(view.name)\n const committedName = useRef(view.name)\n\n // Picks up names changed outside this field, including once a rename saves,\n // unless the field has newer edits, which its next blur or Enter sends.\n useEffect(() => {\n const previousName = committedName.current\n committedName.current = view.name\n setName((currentName) =>\n currentName === previousName ? view.name : currentName\n )\n }, [view.name])\n\n const commit = () => {\n const trimmedName = name.trim()\n if (!trimmedName) {\n setName(committedName.current)\n return\n }\n setName(trimmedName)\n if (trimmedName === committedName.current) return\n committedName.current = trimmedName\n onRename(trimmedName)\n }\n\n return (\n <>\n <Input\n autoComplete=\"off\"\n className={styles[\"view-list-item-input\"]}\n hideLabel\n label={`Name for ${view.name}`}\n readOnly={readOnly}\n required={!readOnly}\n value={name}\n onBlur={readOnly ? undefined : commit}\n onChange={(event) => setName(event.target.value)}\n onKeyDown={(event) => {\n if (\n !readOnly &&\n event.key === \"Enter\" &&\n !event.repeat &&\n !event.nativeEvent.isComposing\n ) {\n commit()\n }\n }}\n />\n {defaultViewToggle}\n {hasDeleteButton && (\n <DeleteViewButton\n disabled={!onDelete}\n name={view.name}\n onClick={(event) => {\n // Safari doesn't focus a button on click, and the alert returns\n // focus to whatever had it when it opened. Focusing also blurs\n // the field, which sends a pending rename.\n event.currentTarget.focus()\n onDelete?.(committedName.current)\n }}\n />\n )}\n </>\n )\n}\n\nfunction DeleteViewButton({\n disabled,\n name,\n onClick,\n}: {\n disabled?: boolean\n name: string\n onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void\n}) {\n return (\n <IconButton\n aria-label={`Delete ${name}`}\n disabled={disabled}\n icon={<Icon aria-hidden symbol=\"general#trash\" />}\n kind=\"ghost\"\n tooltip=\"Delete\"\n onClick={onClick}\n />\n )\n}\n\n/** Makes a view the default, or hands the default back to \"initial\". */\nfunction DefaultViewToggle({\n isDefault,\n name,\n onChange,\n}: {\n isDefault: boolean\n name: string\n onChange: (isDefault: boolean) => void\n}) {\n return (\n <ToggleIconButton\n // Only one view is the default, so its label doesn't need the view's\n // name to be unique.\n aria-label={isDefault ? \"Default view\" : `Set ${name} as default`}\n icon={\n <Icon\n aria-hidden\n symbol={isDefault ? \"general#pin\" : \"general#outlined-pin\"}\n />\n }\n // Only the default's pin is blue.\n kind={isDefault ? \"ghost-interaction\" : \"ghost\"}\n pressed={isDefault}\n tooltip={isDefault ? \"Default view\" : \"Set as default\"}\n onChange={onChange}\n />\n )\n}\n"],"names":["React"],"mappings":"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"}
1
+ {"version":3,"file":"ManageSavedViewsModal.js","sources":["../../../src/components/DataTable/ManageSavedViewsModal.tsx"],"sourcesContent":["import {\n ActionsDropdownIconButton,\n Button,\n IconButton,\n} from \"@components/button\"\nimport { Dropdown, DropdownTrigger } from \"@components/dropdown\"\nimport { Tooltip } from \"@components/internal/tooltip\"\nimport { TooltipTriggerContext } from \"@components/internal/tooltip/TooltipTriggerContext\"\nimport { Modal, ModalBody, ModalFooter, ModalHeader } from \"@components/modal\"\nimport Icon from \"@utilities/Icon\"\nimport React, {\n type ReactNode,\n useContext,\n useEffect,\n useRef,\n useState,\n} from \"react\"\nimport { ListDropTargetDelegate } from \"react-aria/ListDropTargetDelegate\"\nimport { ListKeyboardDelegate } from \"react-aria/ListKeyboardDelegate\"\nimport { mergeProps } from \"react-aria/mergeProps\"\nimport { useButton } from \"react-aria/useButton\"\nimport {\n useDraggableCollection,\n useDraggableItem,\n} from \"react-aria/useDraggableCollection\"\nimport {\n type DroppableCollectionReorderEvent,\n type DropTarget,\n useDropIndicator,\n useDroppableCollection,\n} from \"react-aria/useDroppableCollection\"\nimport { useVisuallyHidden } from \"react-aria/VisuallyHidden\"\nimport type { Key } from \"react-aria-components/ListBox\"\nimport { Item } from \"react-stately/Item\"\nimport {\n type DraggableCollectionState,\n useDraggableCollectionState,\n} from \"react-stately/useDraggableCollectionState\"\nimport {\n type DroppableCollectionState,\n useDroppableCollectionState,\n} from \"react-stately/useDroppableCollectionState\"\nimport { useListState } from \"react-stately/useListState\"\n\nimport { DeleteSavedViewAlertDialog } from \"./DeleteSavedViewAlertDialog\"\nimport styles from \"./ManageSavedViewsModal.module.css\"\nimport { NewSavedViewModal } from \"./NewSavedViewModal\"\nimport {\n hasSavedViewMenuActions,\n SavedViewMenu,\n type SavedViewMenuProps,\n} from \"./SavedViewMenu\"\nimport { type SavedView, type StaticView } from \"./savedViews\"\nimport { useSavedViewNameModal } from \"./useSavedViewNameModal\"\nimport type { ReorderTarget } from \"./useSavedViewsState\"\nimport { SaveStatusIcon, useSaveStatus } from \"./useSaveStatus\"\n\nexport interface ManageSavedViewsModalProps {\n defaultViewId: NonNullable<SavedView[\"id\"]>\n /** Disables the drag handles while a reorder saves. */\n isReordering?: boolean\n onClose: () => void\n /**\n * Called with a view's duplicate once the user names it. Omit to leave out\n * the Duplicate actions.\n */\n onCreate?: (\n savedView: Omit<SavedView, \"id\">\n ) => Promise<SavedView | undefined> | SavedView\n /** Called once the user confirms. Omit to leave out the Delete actions. */\n onDelete?: (savedView: SavedView) => Promise<void>\n /** Omit to leave out the drag handles. */\n onReorder?: (savedView: SavedView, target: ReorderTarget) => Promise<void>\n /** Omit to leave out the Set as default actions. */\n onSetDefault?: (id: NonNullable<SavedView[\"id\"]>) => Promise<void>\n /** Omit to leave out the Rename actions. */\n onUpdate?: (\n savedView: SavedView\n ) => Promise<SavedView | undefined> | SavedView\n open: boolean\n savedViews: SavedView[]\n /** Listed before `savedViews`, and can't be renamed, reordered, or deleted. */\n staticViews: StaticView[]\n}\n\nexport function ManageSavedViewsModal({\n defaultViewId,\n isReordering = false,\n onClose,\n onCreate,\n onDelete,\n onReorder,\n onSetDefault,\n onUpdate,\n open,\n savedViews,\n staticViews,\n}: ManageSavedViewsModalProps) {\n // Kept after the alert closes, so its text holds during the exit animation.\n const [viewToDelete, setViewToDelete] = useState<SavedView | null>(null)\n const [isDeleteAlertOpen, setIsDeleteAlertOpen] = useState(false)\n // Without this, focus would go to the modal's close button, since the\n // alert returns it to the actions button, which is gone with its row.\n const { doneButtonRef, focusAfterDelete, listRef } = useFocusAfterDelete(\n savedViews,\n isDeleteAlertOpen\n )\n const nameModal = useSavedViewNameModal(onUpdate)\n const saveStatus = useSaveStatus()\n\n // Listed after the other saved views. Managing views leaves the selection\n // alone, so unlike the context menu's Duplicate, it doesn't select the\n // duplicate. Its status shows on the view it was duplicated from, since\n // it isn't listed until it saves.\n const createDuplicate = (\n view: SavedView,\n duplicate: Omit<SavedView, \"id\">\n ) => {\n if (onCreate) saveStatus.track(view.id, onCreate(duplicate), duplicate.name)\n }\n\n const requestDelete = (view: SavedView) => {\n setViewToDelete(view)\n setIsDeleteAlertOpen(true)\n }\n\n const confirmDelete = () => {\n if (viewToDelete && onDelete) {\n focusAfterDelete(viewToDelete)\n saveStatus.track(\n viewToDelete.id,\n onDelete(viewToDelete),\n viewToDelete.name\n )\n }\n setIsDeleteAlertOpen(false)\n }\n\n // Every row gets an actions button, disabled without actions, so the\n // buttons line up.\n const hasViewActions = Boolean(\n onCreate || onDelete || onSetDefault || onUpdate\n )\n\n // The actions static views share with saved views. The default is matched\n // by id, so an unsaved view can't be made the default.\n const viewActions = (view: SavedView) => {\n const { id } = view\n return {\n isDefault: id === defaultViewId,\n onDuplicate: onCreate\n ? () =>\n nameModal.openDuplicate(view, (duplicate) =>\n createDuplicate(view, duplicate)\n )\n : undefined,\n onSetDefault:\n onSetDefault && id !== undefined\n ? () => saveStatus.track(id, onSetDefault(id), view.name)\n : undefined,\n }\n }\n\n return (\n <Modal dismissible open={open} size=\"sm\" onClose={onClose}>\n <ModalHeader title=\"Manage views\" />\n <ModalBody>\n <SavedViewsList\n isReordering={isReordering}\n listRef={listRef}\n renderStaticViewActions={(view) => (\n <>\n <SaveStatusIcon status={saveStatus.statusFor(view.id)} />\n {view.id === defaultViewId && <DefaultViewIcon />}\n {hasViewActions && (\n <ViewActionsMenu name={view.name} {...viewActions(view)} />\n )}\n </>\n )}\n savedViews={savedViews}\n staticViews={staticViews}\n onReorder={\n onReorder &&\n ((view, target) =>\n saveStatus.track(view.id, onReorder(view, target), view.name))\n }\n >\n {(view) => (\n <SavedViewRow\n hasActionsMenu={hasViewActions}\n view={view}\n {...viewActions(view)}\n saveStatus={\n <SaveStatusIcon status={saveStatus.statusFor(view.id)} />\n }\n // Updates and deletes are matched by id, so an unsaved view\n // can't be renamed or deleted.\n onDelete={\n onDelete && view.id !== undefined\n ? () => requestDelete(view)\n : undefined\n }\n onRename={\n onUpdate && view.id !== undefined\n ? () =>\n nameModal.openRename(view, (saving) =>\n saveStatus.track(view.id, saving, view.name)\n )\n : undefined\n }\n />\n )}\n </SavedViewsList>\n </ModalBody>\n <ModalFooter>\n <Button\n ref={doneButtonRef}\n kind=\"primary\"\n label=\"Done\"\n onClick={onClose}\n />\n </ModalFooter>\n {onDelete && (\n <DeleteSavedViewAlertDialog\n open={isDeleteAlertOpen}\n view={viewToDelete}\n onCancel={() => setIsDeleteAlertOpen(false)}\n onConfirm={confirmDelete}\n />\n )}\n {(onCreate || onUpdate) && (\n <NewSavedViewModal {...nameModal.modalProps} />\n )}\n </Modal>\n )\n}\n\nManageSavedViewsModal.displayName = \"ManageSavedViewsModal\"\n\n/**\n * The static views, then the saved views with drag handles. Mounts with the\n * modal's content, since React Aria registers the list as a drop target when\n * its hooks mount, and the modal stays mounted while closed.\n */\nfunction SavedViewsList({\n children,\n isReordering,\n listRef,\n onReorder,\n renderStaticViewActions,\n savedViews,\n staticViews,\n}: {\n children: (view: SavedView) => ReactNode\n isReordering: boolean\n listRef: React.RefObject<HTMLOListElement>\n onReorder?: ManageSavedViewsModalProps[\"onReorder\"]\n renderStaticViewActions: (view: StaticView) => ReactNode\n savedViews: SavedView[]\n staticViews: StaticView[]\n}) {\n const { collectionProps, dragState, dropState } = useSavedViewsDragAndDrop(\n savedViews,\n listRef,\n isReordering,\n onReorder\n )\n\n return (\n <ol ref={listRef} {...collectionProps} className={styles[\"views-list\"]}>\n {staticViews.map((view) => (\n <li key={view.id} className={styles[\"views-list-item--static\"]}>\n <span className={styles[\"view-list-item-name\"]}>{view.name}</span>\n {renderStaticViewActions(view)}\n </li>\n ))}\n {savedViews.map((view, index) => {\n const key = savedViewKey(view, index)\n return (\n <li\n key={key}\n className={styles[\"views-list-item\"]}\n data-dragging={dragState.isDragging(key) || undefined}\n data-key={key}\n >\n <SavedViewDropIndicator\n dropState={dropState}\n target={{ dropPosition: \"before\", key, type: \"item\" }}\n />\n {/* A single view has no order to change, and the new position is\n saved by id, so an unsaved view can't be reordered. */}\n {savedViews.length > 1 && onReorder && view.id !== undefined && (\n <SavedViewDragHandle\n dragState={dragState}\n itemKey={key}\n name={view.name}\n />\n )}\n {children(view)}\n {index === savedViews.length - 1 && (\n <SavedViewDropIndicator\n dropState={dropState}\n target={{ dropPosition: \"after\", key, type: \"item\" }}\n />\n )}\n </li>\n )\n })}\n </ol>\n )\n}\n\n/** A string, since React Aria's collection keys an `Item` by its React key. */\nfunction savedViewKey(view: SavedView, index: number): Key {\n return String(view.id ?? `unsaved-view-${index}`)\n}\n\n/**\n * Drag and drop for the saved views' rows, which React Aria finds by their\n * `data-key`. A drop sends the dragged view and where it landed to\n * `onReorder`.\n */\nfunction useSavedViewsDragAndDrop(\n savedViews: SavedView[],\n listRef: React.RefObject<HTMLOListElement | null>,\n isReordering: boolean,\n onReorder?: ManageSavedViewsModalProps[\"onReorder\"]\n) {\n const { collection, selectionManager } = useListState({\n children: savedViews.map((view, index) => (\n <Item key={savedViewKey(view, index)} textValue={view.name}>\n {view.name}\n </Item>\n )),\n selectionMode: \"none\",\n })\n const [isDragging, setIsDragging] = useState(false)\n\n const dragState = useDraggableCollectionState({\n collection,\n getItems: (keys) =>\n [...keys].map((key) => ({\n \"text/plain\": collection.getItem(key)?.textValue ?? String(key),\n })),\n\n // Reorders save one at a time. A pointer drop starts the save before the\n // drag ends, and a disabled handle drops the listener that ends it.\n isDisabled: isReordering && !isDragging,\n\n // A drop removes the drop target that had focus, and rows can't take\n // focus, so it goes back to the handle that started the drag.\n onDragEnd: ({ keys }) => {\n setIsDragging(false)\n const [key] = keys\n listRef.current\n ?.querySelector<HTMLElement>(\n `[data-key=\"${CSS.escape(String(key))}\"] .${styles[\"view-list-item-drag-handle\"]}`\n )\n ?.focus()\n },\n\n // A keyboard drag starts after the focused row, which the rows can't\n // set themselves, since they can't take focus.\n onDragStart: ({ keys }) => {\n setIsDragging(true)\n const [key] = keys\n selectionManager.setFocusedKey(key)\n },\n selectionManager,\n })\n useDraggableCollection({}, dragState, listRef)\n\n const reorder = ({ keys, target }: DroppableCollectionReorderEvent) => {\n const viewFor = (key: Key) =>\n savedViews.find((view, index) => savedViewKey(view, index) === key)\n // Rows only offer drop targets between them, not on them.\n if (target.dropPosition === \"on\") return\n const [key] = keys\n const view = viewFor(key)\n const targetView = viewFor(target.key)\n if (view && targetView) {\n onReorder?.(view, {\n dropPosition: target.dropPosition,\n view: targetView,\n })\n }\n }\n const dropState = useDroppableCollectionState({\n collection,\n onReorder: reorder,\n selectionManager,\n })\n const { collectionProps } = useDroppableCollection(\n {\n dropTargetDelegate: new ListDropTargetDelegate(collection, listRef),\n keyboardDelegate: new ListKeyboardDelegate({ collection, ref: listRef }),\n onReorder: reorder,\n },\n dropState,\n listRef\n )\n\n return { collectionProps, dragState, dropState }\n}\n\n/**\n * Starts a drag with a pointer, or with Enter or Space. A pointer drag shows\n * the whole row, held where the pointer grabbed it, rather than the handle.\n */\nfunction SavedViewDragHandle({\n dragState,\n itemKey,\n name,\n}: {\n dragState: DraggableCollectionState\n itemKey: Key\n name: string\n}) {\n const ref = useRef<HTMLButtonElement>(null)\n const { dragButtonProps, dragProps } = useDraggableItem(\n { hasDragButton: true, key: itemKey },\n dragState\n )\n const { buttonProps } = useButton(dragButtonProps, ref)\n\n return (\n <IconButton\n ref={ref}\n {...mergeProps(buttonProps, dragProps, {\n onDragStart: (event: React.DragEvent<HTMLButtonElement>) => {\n const row = event.currentTarget.closest(\"li\")\n if (!row) return\n const { left, top } = row.getBoundingClientRect()\n // The browser snapshots the row once this handler returns, so the\n // ghost styles apply only to the snapshot.\n const className = styles[\"views-list-item--drag-ghost\"]\n row.classList.add(className)\n requestAnimationFrame(() => row.classList.remove(className))\n event.dataTransfer.setDragImage(\n row,\n event.clientX - left,\n event.clientY - top\n )\n },\n })}\n aria-label={`Reorder ${name}`}\n className={styles[\"view-list-item-drag-handle\"]}\n // Stays focusable, since focus returns here after a keyboard drop.\n disabled={dragState.isDisabled}\n focusableWhenDisabled\n icon={<Icon aria-hidden symbol=\"general#drag-handle\" />}\n kind=\"ghost\"\n />\n )\n}\n\n/**\n * A line at a row's edge while dragging. Screen readers reach the hidden\n * button inside it as a drop target.\n */\nfunction SavedViewDropIndicator({\n dropState,\n target,\n}: {\n dropState: DroppableCollectionState\n target: DropTarget\n}) {\n const ref = useRef<HTMLDivElement>(null)\n const { dropIndicatorProps, isDropTarget, isHidden } = useDropIndicator(\n { target },\n dropState,\n ref\n )\n const { visuallyHiddenProps } = useVisuallyHidden()\n if (isHidden) return null\n\n return (\n <div\n className={styles[\"view-list-drop-indicator\"]}\n data-drop-position={\n target.type === \"item\" ? target.dropPosition : undefined\n }\n data-drop-target={isDropTarget || undefined}\n >\n <div\n {...visuallyHiddenProps}\n role=\"button\"\n {...dropIndicatorProps}\n ref={ref}\n />\n </div>\n )\n}\n\n/**\n * Moves focus off a deleted view's row in two steps: `focusAfterDelete` picks\n * the target while the row is still there, and focus moves to it once the\n * alert starts closing.\n */\nfunction useFocusAfterDelete(\n savedViews: SavedView[],\n isDeleteAlertOpen: boolean\n) {\n const listRef = useRef<HTMLOListElement>(null)\n const doneButtonRef = useRef<HTMLButtonElement>(null)\n const focusTargetRef = useRef<HTMLElement | null>(null)\n\n // Step 1: the actions button on the next view's row, or the previous one's\n // if the deleted view is last, or Done if that row's actions are disabled or\n // it's the only one.\n const focusAfterDelete = (view: SavedView) => {\n const rows =\n listRef.current?.querySelectorAll(`.${styles[\"views-list-item\"]}`) ?? []\n const index = savedViews.findIndex(({ id }) => id === view.id)\n const row = rows[index + 1] ?? rows[index - 1]\n focusTargetRef.current =\n row?.querySelector<HTMLElement>(\"button[data-view-actions]:enabled\") ??\n doneButtonRef.current\n }\n\n // Step 2: a closing alert no longer holds focus, and doesn't take it back\n // once focus is outside it.\n useEffect(() => {\n if (isDeleteAlertOpen) return\n focusTargetRef.current?.focus()\n focusTargetRef.current = null\n }, [isDeleteAlertOpen])\n\n return { doneButtonRef, focusAfterDelete, listRef }\n}\n\n/** A saved view's name and actions menu. */\nfunction SavedViewRow({\n hasActionsMenu,\n saveStatus,\n view,\n ...menuProps\n}: SavedViewMenuProps & {\n /** Shows the actions menu, disabled without any actions. */\n hasActionsMenu: boolean\n saveStatus: ReactNode\n view: SavedView\n}) {\n return (\n <>\n <span className={styles[\"view-list-item-name\"]}>{view.name}</span>\n {saveStatus}\n {menuProps.isDefault && <DefaultViewIcon />}\n {hasActionsMenu && <ViewActionsMenu name={view.name} {...menuProps} />}\n </>\n )\n}\n\n/**\n * Marks the default view. Set the default from its actions menu. Its tooltip\n * shows on hover only, since the icon can't take focus, and screen readers get\n * the same text from the icon's name.\n */\nfunction DefaultViewIcon() {\n return (\n <Tooltip content=\"Default view\" placement=\"bottom\" visualOnly>\n <DefaultViewIconTrigger />\n </Tooltip>\n )\n}\n\n/** Takes the tooltip's trigger wiring, which only buttons and links read. */\nfunction DefaultViewIconTrigger() {\n const tooltip = useContext(TooltipTriggerContext)\n\n return (\n <span\n ref={tooltip?.ref}\n {...tooltip?.triggerProps}\n className={styles[\"view-list-item-default-icon\"]}\n >\n <Icon aria-label=\"Default view\" role=\"img\" symbol=\"general#pin\" />\n </span>\n )\n}\n\n/** A view's actions menu. Disabled without any actions. */\nfunction ViewActionsMenu({\n name,\n ...menuProps\n}: SavedViewMenuProps & { name: string }) {\n const triggerRef = useRef<HTMLButtonElement>(null)\n const { onDelete, onDuplicate, onRename } = menuProps\n\n // The name modal and alert return focus to whatever had it when they\n // opened. The menu hasn't returned focus to its button yet by then, so\n // this does it first.\n const withFocusOnTrigger = (open?: () => void) =>\n open &&\n (() =>\n queueMicrotask(() => {\n triggerRef.current?.focus()\n open()\n }))\n\n return (\n <Dropdown>\n <DropdownTrigger disabled={!hasSavedViewMenuActions(menuProps)}>\n <ActionsDropdownIconButton\n ref={triggerRef}\n aria-label={`Actions for ${name}`}\n className={styles[\"view-list-item-actions\"]}\n // Lets `useFocusAfterDelete` find a neighboring row's actions.\n data-view-actions\n />\n </DropdownTrigger>\n <SavedViewMenu\n {...menuProps}\n placement=\"bottom end\"\n onDelete={withFocusOnTrigger(onDelete)}\n onDuplicate={withFocusOnTrigger(onDuplicate)}\n onRename={withFocusOnTrigger(onRename)}\n />\n </Dropdown>\n )\n}\n"],"names":["React"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- var styles = {"views-list":"views-list-3AMVI","views-list-item":"views-list-item-cWGsC","view-list-drop-indicator":"view-list-drop-indicator-zyDIt","view-list-item-drag-handle":"view-list-item-drag-handle-fiO5Z","views-list-item--drag-ghost":"views-list-item--drag-ghost-zEVbL","view-list-item-input":"view-list-item-input-dowHY","views-list-item--static":"views-list-item--static-9zGpJ","view-list-item-static-name":"view-list-item-static-name-nxBiG"};
1
+ var styles = {"views-list":"views-list-3AMVI","views-list-item":"views-list-item-cWGsC","views-list-item--static":"views-list-item--static-9zGpJ","view-list-drop-indicator":"view-list-drop-indicator-zyDIt","view-list-item-default-icon":"view-list-item-default-icon-d-QS1","view-list-item-actions":"view-list-item-actions-NFBUU","view-list-item-drag-handle":"view-list-item-drag-handle-fiO5Z","views-list-item--drag-ghost":"views-list-item--drag-ghost-zEVbL","view-list-item-name":"view-list-item-name-VRsyM"};
2
2
 
3
3
  export { styles as default };
4
4
  //# sourceMappingURL=ManageSavedViewsModal.module.css.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"NewSavedViewButton.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/NewSavedViewButton.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,OAAO,EAAE,EAAE,uBAAuB,qBAStE;yBATe,kBAAkB"}
1
+ {"version":3,"file":"NewSavedViewButton.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/NewSavedViewButton.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,OAAO,EAAE,EAAE,uBAAuB,qBAUtE;yBAVe,kBAAkB"}
@@ -9,7 +9,7 @@ import Icon from '../../utilities/Icon.js';
9
9
  import React__default from 'react';
10
10
 
11
11
  function NewSavedViewButton({ onClick }) {
12
- return (React__default.createElement(IconButton, { "aria-label": "New view", icon: React__default.createElement(Icon, { "aria-hidden": true, symbol: "general#plus" }), kind: "pill", onClick: onClick }));
12
+ return (React__default.createElement(IconButton, { className: "tds-btn--data-table-saved-views-new-view", icon: React__default.createElement(Icon, { "aria-hidden": true, symbol: "general#plus" }), kind: "pill", tooltip: "Add new view", onClick: onClick }));
13
13
  }
14
14
  NewSavedViewButton.displayName = "NewSavedViewButton";
15
15
 
@@ -1 +1 @@
1
- {"version":3,"file":"NewSavedViewButton.js","sources":["../../../src/components/DataTable/NewSavedViewButton.tsx"],"sourcesContent":["import { IconButton } from \"@components/button\"\nimport Icon from \"@utilities/Icon\"\nimport React from \"react\"\n\nexport interface NewSavedViewButtonProps {\n onClick: () => void\n}\n\nexport function NewSavedViewButton({ onClick }: NewSavedViewButtonProps) {\n return (\n <IconButton\n aria-label=\"New view\"\n icon={<Icon aria-hidden symbol=\"general#plus\" />}\n kind=\"pill\"\n onClick={onClick}\n />\n )\n}\n\nNewSavedViewButton.displayName = \"NewSavedViewButton\"\n"],"names":["React"],"mappings":";;;;;;;;;;AAQM,SAAU,kBAAkB,CAAC,EAAE,OAAO,EAA2B,EAAA;IACrE,QACEA,cAAA,CAAA,aAAA,CAAC,UAAU,EAAA,EAAA,YAAA,EACE,UAAU,EACrB,IAAI,EAAEA,cAAA,CAAA,aAAA,CAAC,IAAI,EAAA,EAAA,aAAA,EAAA,IAAA,EAAa,MAAM,EAAC,cAAc,EAAA,CAAG,EAChD,IAAI,EAAC,MAAM,EACX,OAAO,EAAE,OAAO,EAAA,CAChB;AAEN;AAEA,kBAAkB,CAAC,WAAW,GAAG,oBAAoB;;;;"}
1
+ {"version":3,"file":"NewSavedViewButton.js","sources":["../../../src/components/DataTable/NewSavedViewButton.tsx"],"sourcesContent":["import { IconButton } from \"@components/button\"\nimport Icon from \"@utilities/Icon\"\nimport React from \"react\"\n\nexport interface NewSavedViewButtonProps {\n onClick: () => void\n}\n\nexport function NewSavedViewButton({ onClick }: NewSavedViewButtonProps) {\n return (\n <IconButton\n className=\"tds-btn--data-table-saved-views-new-view\"\n icon={<Icon aria-hidden symbol=\"general#plus\" />}\n kind=\"pill\"\n tooltip=\"Add new view\"\n onClick={onClick}\n />\n )\n}\n\nNewSavedViewButton.displayName = \"NewSavedViewButton\"\n"],"names":["React"],"mappings":";;;;;;;;;;AAQM,SAAU,kBAAkB,CAAC,EAAE,OAAO,EAA2B,EAAA;AACrE,IAAA,QACEA,cAAA,CAAA,aAAA,CAAC,UAAU,EAAA,EACT,SAAS,EAAC,0CAA0C,EACpD,IAAI,EAAEA,cAAA,CAAA,aAAA,CAAC,IAAI,yBAAa,MAAM,EAAC,cAAc,EAAA,CAAG,EAChD,IAAI,EAAC,MAAM,EACX,OAAO,EAAC,cAAc,EACtB,OAAO,EAAE,OAAO,EAAA,CAChB;AAEN;AAEA,kBAAkB,CAAC,WAAW,GAAG,oBAAoB;;;;"}
@@ -0,0 +1,19 @@
1
+ import React from "react";
2
+ export interface SavedViewActionsProps {
3
+ onDiscard: () => void;
4
+ /** Omit to hide "Save as new view". */
5
+ onSaveAsNew?: (name: string) => void;
6
+ /** Omit to disable "Update view". */
7
+ onUpdate?: () => void;
8
+ /** The view whose filters have changed. */
9
+ savedViewName: string;
10
+ }
11
+ /**
12
+ * Actions for a modified saved view. The host owns focus afterward, since it
13
+ * decides whether these stay mounted.
14
+ */
15
+ export declare function SavedViewActions({ onDiscard, onSaveAsNew, onUpdate, savedViewName, }: SavedViewActionsProps): React.JSX.Element;
16
+ export declare namespace SavedViewActions {
17
+ var displayName: string;
18
+ }
19
+ //# sourceMappingURL=SavedViewActions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SavedViewActions.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/SavedViewActions.tsx"],"names":[],"mappings":"AASA,OAAO,KAAmB,MAAM,OAAO,CAAA;AAIvC,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,IAAI,CAAA;IACrB,uCAAuC;IACvC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IACpC,qCAAqC;IACrC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,2CAA2C;IAC3C,aAAa,EAAE,MAAM,CAAA;CACtB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,SAAS,EACT,WAAW,EACX,QAAQ,EACR,aAAa,GACd,EAAE,qBAAqB,qBAgDvB;yBArDe,gBAAgB"}
@@ -0,0 +1,34 @@
1
+ import '../button/ActionsDropdownIconButton.js';
2
+ import { Button } from '../button/Button.js';
3
+ import '../button/DropdownButton.js';
4
+ import '../button/DropdownIconButton.js';
5
+ import { IconButton } from '../button/IconButton.js';
6
+ import '../button/LoadingButton.js';
7
+ import '../button/PageHeaderActionsDropdownButton.js';
8
+ import { ButtonGroup } from '../button-group/ButtonGroup.js';
9
+ import { Dropdown, DropdownTrigger, DropdownMenu, DropdownAction } from '../dropdown/Dropdown.js';
10
+ import Icon from '../../utilities/Icon.js';
11
+ import React__default, { useState } from 'react';
12
+ import { NewSavedViewModal } from './NewSavedViewModal.js';
13
+
14
+ /**
15
+ * Actions for a modified saved view. The host owns focus afterward, since it
16
+ * decides whether these stay mounted.
17
+ */
18
+ function SavedViewActions({ onDiscard, onSaveAsNew, onUpdate, savedViewName, }) {
19
+ const [isNewViewModalOpen, setIsNewViewModalOpen] = useState(false);
20
+ return (React__default.createElement(React__default.Fragment, null,
21
+ React__default.createElement(ButtonGroup, { "aria-label": `Changes to ${savedViewName}` },
22
+ React__default.createElement(Button, { disabled: !onUpdate, kind: "secondary", label: "Update view", size: "sm", onClick: onUpdate }),
23
+ React__default.createElement(Dropdown, null,
24
+ React__default.createElement(DropdownTrigger, null,
25
+ React__default.createElement(IconButton, { "aria-label": "More view actions", icon: React__default.createElement(Icon, { "aria-hidden": true, symbol: "general#down-caret" }), kind: "secondary", size: "sm" })),
26
+ React__default.createElement(DropdownMenu, { placement: "bottom end" },
27
+ onSaveAsNew && (React__default.createElement(DropdownAction, { id: "save-as-new", onAction: () => queueMicrotask(() => setIsNewViewModalOpen(true)) }, "Save as new view")),
28
+ React__default.createElement(DropdownAction, { id: "discard", onAction: onDiscard }, "Discard changes")))),
29
+ onSaveAsNew && (React__default.createElement(NewSavedViewModal, { open: isNewViewModalOpen, onClose: () => setIsNewViewModalOpen(false), onSave: onSaveAsNew }))));
30
+ }
31
+ SavedViewActions.displayName = "SavedViewActions";
32
+
33
+ export { SavedViewActions };
34
+ //# sourceMappingURL=SavedViewActions.js.map