@planningcenter/tapestry 4.12.0 → 4.13.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 (150) 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 +81 -93
  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/DataTable/useVisibleSavedViews.d.ts +31 -0
  83. package/dist/components/DataTable/useVisibleSavedViews.d.ts.map +1 -0
  84. package/dist/components/DataTable/useVisibleSavedViews.js +178 -0
  85. package/dist/components/DataTable/useVisibleSavedViews.js.map +1 -0
  86. package/dist/components/button/BaseButton.d.ts +2 -0
  87. package/dist/components/button/BaseButton.d.ts.map +1 -1
  88. package/dist/components/button/BaseButton.js +8 -17
  89. package/dist/components/button/BaseButton.js.map +1 -1
  90. package/dist/components/internal/LoadingAnnouncement.d.ts +6 -0
  91. package/dist/components/internal/LoadingAnnouncement.d.ts.map +1 -1
  92. package/dist/components/internal/LoadingAnnouncement.js +12 -3
  93. package/dist/components/internal/LoadingAnnouncement.js.map +1 -1
  94. package/dist/components/internal/index.d.ts +1 -1
  95. package/dist/components/internal/index.d.ts.map +1 -1
  96. package/dist/components/internal/reorderable-list-box/ReorderableListBox.d.ts +6 -0
  97. package/dist/components/internal/reorderable-list-box/ReorderableListBox.d.ts.map +1 -1
  98. package/dist/components/internal/reorderable-list-box/ReorderableListBox.js +9 -2
  99. package/dist/components/internal/reorderable-list-box/ReorderableListBox.js.map +1 -1
  100. package/dist/components/internal/tooltip/useTooltipTriggerProps.d.ts +13 -0
  101. package/dist/components/internal/tooltip/useTooltipTriggerProps.d.ts.map +1 -0
  102. package/dist/components/internal/tooltip/useTooltipTriggerProps.js +24 -0
  103. package/dist/components/internal/tooltip/useTooltipTriggerProps.js.map +1 -0
  104. package/dist/components/link/BaseLink.d.ts.map +1 -1
  105. package/dist/components/link/BaseLink.js +3 -13
  106. package/dist/components/link/BaseLink.js.map +1 -1
  107. package/dist/components/segmented-control/IconSegment.d.ts +30 -8
  108. package/dist/components/segmented-control/IconSegment.d.ts.map +1 -1
  109. package/dist/components/segmented-control/IconSegment.js +10 -3
  110. package/dist/components/segmented-control/IconSegment.js.map +1 -1
  111. package/dist/components/segmented-control/SegmentBase.d.ts.map +1 -1
  112. package/dist/components/segmented-control/SegmentBase.js +4 -2
  113. package/dist/components/segmented-control/SegmentBase.js.map +1 -1
  114. package/dist/components/segmented-control/SegmentedControl.d.ts.map +1 -1
  115. package/dist/components/segmented-control/SegmentedControl.js +10 -3
  116. package/dist/components/segmented-control/SegmentedControl.js.map +1 -1
  117. package/dist/index.css +28 -12
  118. package/dist/index.css.map +1 -1
  119. package/dist/packages/tapestry-render/dist/{buildComponent-C5PfOgH9.js → buildComponent-DzY2PDMT.js} +23 -23
  120. package/dist/packages/tapestry-render/dist/buildComponent-DzY2PDMT.js.map +1 -0
  121. package/dist/packages/tapestry-render/dist/index.js +2 -2
  122. package/dist/packages/tapestry-render/dist/index.js.map +1 -1
  123. package/dist/packages/tapestry-render/dist/legacy.js +2 -2
  124. package/dist/packages/tapestry-render/dist/legacy.js.map +1 -1
  125. package/dist/product-tokens/giving.css +1 -0
  126. package/dist/reactRender.css +773 -658
  127. package/dist/reactRender.css.map +1 -1
  128. package/dist/reactRender.js +1 -1
  129. package/dist/reactRenderLegacy.css +773 -658
  130. package/dist/reactRenderLegacy.css.map +1 -1
  131. package/dist/reactRenderLegacy.js +1 -1
  132. package/dist/tapestryMount.css +773 -658
  133. package/dist/tapestryMount.css.map +1 -1
  134. package/dist/tapestryMount.js +1 -1
  135. package/dist/tapestryMountLegacy.css +773 -658
  136. package/dist/tapestryMountLegacy.css.map +1 -1
  137. package/dist/tapestryMountLegacy.js +1 -1
  138. package/dist/tokens-dark.css +2 -2
  139. package/dist/tokens-dark.css.map +1 -1
  140. package/dist/tokens.css +11 -10
  141. package/dist/tokens.css.map +1 -1
  142. package/dist/unstable.css +418 -303
  143. package/dist/unstable.css.map +1 -1
  144. package/dist/unstable.js +1 -0
  145. package/dist/unstable.js.map +1 -1
  146. package/package.json +8 -9
  147. package/dist/components/DataTable/useFilterAnnouncement.d.ts +0 -24
  148. package/dist/components/DataTable/useFilterAnnouncement.d.ts.map +0 -1
  149. package/dist/components/DataTable/useFilterAnnouncement.js.map +0 -1
  150. package/dist/packages/tapestry-render/dist/buildComponent-C5PfOgH9.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SavedViewActions.js","sources":["../../../src/components/DataTable/SavedViewActions.tsx"],"sourcesContent":["import { Button, IconButton } from \"@components/button\"\nimport { ButtonGroup } from \"@components/button-group\"\nimport {\n Dropdown,\n DropdownAction,\n DropdownMenu,\n DropdownTrigger,\n} from \"@components/dropdown\"\nimport Icon from \"@utilities/Icon\"\nimport React, { useState } from \"react\"\n\nimport { NewSavedViewModal } from \"./NewSavedViewModal\"\n\nexport interface SavedViewActionsProps {\n onDiscard: () => void\n /** Omit to hide \"Save as new view\". */\n onSaveAsNew?: (name: string) => void\n /** Omit to disable \"Update view\". */\n onUpdate?: () => void\n /** The view whose filters have changed. */\n savedViewName: string\n}\n\n/**\n * Actions for a modified saved view. The host owns focus afterward, since it\n * decides whether these stay mounted.\n */\nexport function SavedViewActions({\n onDiscard,\n onSaveAsNew,\n onUpdate,\n savedViewName,\n}: SavedViewActionsProps) {\n const [isNewViewModalOpen, setIsNewViewModalOpen] = useState(false)\n\n return (\n <>\n <ButtonGroup aria-label={`Changes to ${savedViewName}`}>\n <Button\n disabled={!onUpdate}\n kind=\"secondary\"\n label=\"Update view\"\n size=\"sm\"\n onClick={onUpdate}\n />\n <Dropdown>\n <DropdownTrigger>\n <IconButton\n aria-label=\"More view actions\"\n icon={<Icon aria-hidden symbol=\"general#down-caret\" />}\n kind=\"secondary\"\n size=\"sm\"\n />\n </DropdownTrigger>\n <DropdownMenu placement=\"bottom end\">\n {onSaveAsNew && (\n <DropdownAction\n id=\"save-as-new\"\n onAction={() =>\n queueMicrotask(() => setIsNewViewModalOpen(true))\n }\n >\n Save as new view\n </DropdownAction>\n )}\n <DropdownAction id=\"discard\" onAction={onDiscard}>\n Discard changes\n </DropdownAction>\n </DropdownMenu>\n </Dropdown>\n </ButtonGroup>\n {onSaveAsNew && (\n <NewSavedViewModal\n open={isNewViewModalOpen}\n onClose={() => setIsNewViewModalOpen(false)}\n onSave={onSaveAsNew}\n />\n )}\n </>\n )\n}\n\nSavedViewActions.displayName = \"SavedViewActions\"\n"],"names":["React"],"mappings":";;;;;;;;;;;;;AAuBA;;;AAGG;AACG,SAAU,gBAAgB,CAAC,EAC/B,SAAS,EACT,WAAW,EACX,QAAQ,EACR,aAAa,GACS,EAAA;IACtB,MAAM,CAAC,kBAAkB,EAAE,qBAAqB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;AAEnE,IAAA,QACEA,cAAA,CAAA,aAAA,CAAAA,cAAA,CAAA,QAAA,EAAA,IAAA;AACE,QAAAA,cAAA,CAAA,aAAA,CAAC,WAAW,EAAA,EAAA,YAAA,EAAa,CAAA,WAAA,EAAc,aAAa,CAAA,CAAE,EAAA;YACpDA,cAAA,CAAA,aAAA,CAAC,MAAM,IACL,QAAQ,EAAE,CAAC,QAAQ,EACnB,IAAI,EAAC,WAAW,EAChB,KAAK,EAAC,aAAa,EACnB,IAAI,EAAC,IAAI,EACT,OAAO,EAAE,QAAQ,EAAA,CACjB;AACF,YAAAA,cAAA,CAAA,aAAA,CAAC,QAAQ,EAAA,IAAA;AACP,gBAAAA,cAAA,CAAA,aAAA,CAAC,eAAe,EAAA,IAAA;oBACdA,cAAA,CAAA,aAAA,CAAC,UAAU,kBACE,mBAAmB,EAC9B,IAAI,EAAEA,cAAA,CAAA,aAAA,CAAC,IAAI,EAAA,EAAA,aAAA,EAAA,IAAA,EAAa,MAAM,EAAC,oBAAoB,EAAA,CAAG,EACtD,IAAI,EAAC,WAAW,EAChB,IAAI,EAAC,IAAI,EAAA,CACT,CACc;AAClB,gBAAAA,cAAA,CAAA,aAAA,CAAC,YAAY,EAAA,EAAC,SAAS,EAAC,YAAY,EAAA;oBACjC,WAAW,KACVA,cAAA,CAAA,aAAA,CAAC,cAAc,EAAA,EACb,EAAE,EAAC,aAAa,EAChB,QAAQ,EAAE,MACR,cAAc,CAAC,MAAM,qBAAqB,CAAC,IAAI,CAAC,CAAC,EAAA,EAAA,kBAAA,CAIpC,CAClB;AACD,oBAAAA,cAAA,CAAA,aAAA,CAAC,cAAc,EAAA,EAAC,EAAE,EAAC,SAAS,EAAC,QAAQ,EAAE,SAAS,EAAA,EAAA,iBAAA,CAE/B,CACJ,CACN,CACC;QACb,WAAW,KACVA,cAAA,CAAA,aAAA,CAAC,iBAAiB,EAAA,EAChB,IAAI,EAAE,kBAAkB,EACxB,OAAO,EAAE,MAAM,qBAAqB,CAAC,KAAK,CAAC,EAC3C,MAAM,EAAE,WAAW,EAAA,CACnB,CACH,CACA;AAEP;AAEA,gBAAgB,CAAC,WAAW,GAAG,kBAAkB;;;;"}
@@ -0,0 +1,18 @@
1
+ import { type DropdownPlacement } from "../dropdown";
2
+ import React from "react";
3
+ export interface SavedViewMenuProps {
4
+ isDefault: boolean;
5
+ /** Omit to leave out each action. */
6
+ onDelete?: () => void;
7
+ onDuplicate?: () => void;
8
+ onRename?: () => void;
9
+ onSetDefault?: () => void;
10
+ placement?: DropdownPlacement;
11
+ }
12
+ /**
13
+ * A view's actions, shared by its context menu in the bar and its actions
14
+ * menu in Manage views. Render it only when `hasSavedViewMenuActions`.
15
+ */
16
+ export declare function SavedViewMenu({ isDefault, onDelete, onDuplicate, onRename, onSetDefault, placement, }: SavedViewMenuProps): React.JSX.Element;
17
+ export declare function hasSavedViewMenuActions({ onDelete, onDuplicate, onRename, onSetDefault, }: SavedViewMenuProps): boolean;
18
+ //# sourceMappingURL=SavedViewMenu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SavedViewMenu.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/SavedViewMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,iBAAiB,EAEvB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,OAAO,CAAA;IAClB,qCAAqC;IACrC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,WAAW,CAAC,EAAE,MAAM,IAAI,CAAA;IACxB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAA;IACzB,SAAS,CAAC,EAAE,iBAAiB,CAAA;CAC9B;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,EAC5B,SAAS,EACT,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,YAAY,EACZ,SAAS,GACV,EAAE,kBAAkB,qBAkCpB;AAED,wBAAgB,uBAAuB,CAAC,EACtC,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,YAAY,GACb,EAAE,kBAAkB,WAEpB"}
@@ -0,0 +1,25 @@
1
+ import { DropdownMenu, DropdownAction, DropdownSeparator } from '../dropdown/Dropdown.js';
2
+ import React__default from 'react';
3
+
4
+ /**
5
+ * A view's actions, shared by its context menu in the bar and its actions
6
+ * menu in Manage views. Render it only when `hasSavedViewMenuActions`.
7
+ */
8
+ function SavedViewMenu({ isDefault, onDelete, onDuplicate, onRename, onSetDefault, placement, }) {
9
+ const hasActions = Boolean(onRename || onDuplicate || onSetDefault);
10
+ return (React__default.createElement(DropdownMenu, { placement: placement },
11
+ onRename && (React__default.createElement(DropdownAction, { id: "rename", onAction: onRename }, "Rename")),
12
+ onDuplicate && (React__default.createElement(DropdownAction, { id: "duplicate", onAction: onDuplicate }, "Duplicate")),
13
+ onSetDefault && (
14
+ // Stays in the menu for the default view, disabled, so the user can
15
+ // see which view is the default.
16
+ React__default.createElement(DropdownAction, { disabled: isDefault, id: "set-default", onAction: onSetDefault }, isDefault ? "Default view" : "Set as default")),
17
+ hasActions && onDelete && React__default.createElement(DropdownSeparator, null),
18
+ onDelete && (React__default.createElement(DropdownAction, { destructive: true, id: "delete", onAction: onDelete }, "Delete"))));
19
+ }
20
+ function hasSavedViewMenuActions({ onDelete, onDuplicate, onRename, onSetDefault, }) {
21
+ return Boolean(onDelete || onDuplicate || onRename || onSetDefault);
22
+ }
23
+
24
+ export { SavedViewMenu, hasSavedViewMenuActions };
25
+ //# sourceMappingURL=SavedViewMenu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SavedViewMenu.js","sources":["../../../src/components/DataTable/SavedViewMenu.tsx"],"sourcesContent":["import {\n DropdownAction,\n DropdownMenu,\n type DropdownPlacement,\n DropdownSeparator,\n} from \"@components/dropdown\"\nimport React from \"react\"\n\nexport interface SavedViewMenuProps {\n isDefault: boolean\n /** Omit to leave out each action. */\n onDelete?: () => void\n onDuplicate?: () => void\n onRename?: () => void\n onSetDefault?: () => void\n placement?: DropdownPlacement\n}\n\n/**\n * A view's actions, shared by its context menu in the bar and its actions\n * menu in Manage views. Render it only when `hasSavedViewMenuActions`.\n */\nexport function SavedViewMenu({\n isDefault,\n onDelete,\n onDuplicate,\n onRename,\n onSetDefault,\n placement,\n}: SavedViewMenuProps) {\n const hasActions = Boolean(onRename || onDuplicate || onSetDefault)\n\n return (\n <DropdownMenu placement={placement}>\n {onRename && (\n <DropdownAction id=\"rename\" onAction={onRename}>\n Rename\n </DropdownAction>\n )}\n {onDuplicate && (\n <DropdownAction id=\"duplicate\" onAction={onDuplicate}>\n Duplicate\n </DropdownAction>\n )}\n {onSetDefault && (\n // Stays in the menu for the default view, disabled, so the user can\n // see which view is the default.\n <DropdownAction\n disabled={isDefault}\n id=\"set-default\"\n onAction={onSetDefault}\n >\n {isDefault ? \"Default view\" : \"Set as default\"}\n </DropdownAction>\n )}\n {hasActions && onDelete && <DropdownSeparator />}\n {onDelete && (\n <DropdownAction destructive id=\"delete\" onAction={onDelete}>\n Delete\n </DropdownAction>\n )}\n </DropdownMenu>\n )\n}\n\nexport function hasSavedViewMenuActions({\n onDelete,\n onDuplicate,\n onRename,\n onSetDefault,\n}: SavedViewMenuProps) {\n return Boolean(onDelete || onDuplicate || onRename || onSetDefault)\n}\n"],"names":["React"],"mappings":";;;AAkBA;;;AAGG;AACG,SAAU,aAAa,CAAC,EAC5B,SAAS,EACT,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,YAAY,EACZ,SAAS,GACU,EAAA;IACnB,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,IAAI,WAAW,IAAI,YAAY,CAAC;AAEnE,IAAA,QACEA,cAAA,CAAA,aAAA,CAAC,YAAY,EAAA,EAAC,SAAS,EAAE,SAAS,EAAA;AAC/B,QAAA,QAAQ,KACPA,cAAA,CAAA,aAAA,CAAC,cAAc,EAAA,EAAC,EAAE,EAAC,QAAQ,EAAC,QAAQ,EAAE,QAAQ,aAE7B,CAClB;AACA,QAAA,WAAW,KACVA,cAAA,CAAA,aAAA,CAAC,cAAc,EAAA,EAAC,EAAE,EAAC,WAAW,EAAC,QAAQ,EAAE,WAAW,gBAEnC,CAClB;AACA,QAAA,YAAY;;;QAGXA,cAAA,CAAA,aAAA,CAAC,cAAc,EAAA,EACb,QAAQ,EAAE,SAAS,EACnB,EAAE,EAAC,aAAa,EAChB,QAAQ,EAAE,YAAY,EAAA,EAErB,SAAS,GAAG,cAAc,GAAG,gBAAgB,CAC/B,CAClB;AACA,QAAA,UAAU,IAAI,QAAQ,IAAIA,cAAA,CAAA,aAAA,CAAC,iBAAiB,EAAA,IAAA,CAAG;AAC/C,QAAA,QAAQ,KACPA,cAAA,CAAA,aAAA,CAAC,cAAc,EAAA,EAAC,WAAW,QAAC,EAAE,EAAC,QAAQ,EAAC,QAAQ,EAAE,QAAQ,aAEzC,CAClB,CACY;AAEnB;AAEM,SAAU,uBAAuB,CAAC,EACtC,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,YAAY,GACO,EAAA;IACnB,OAAO,OAAO,CAAC,QAAQ,IAAI,WAAW,IAAI,QAAQ,IAAI,YAAY,CAAC;AACrE;;;;"}
@@ -1,31 +1,43 @@
1
1
  import React from "react";
2
- import type { Sort } from "./DataTable";
3
- import type { DataTableColumn } from "./DataTableColumn";
4
- import type { ActiveFilter } from "./FilterTypes";
5
2
  import { type SavedView, type StaticView } from "./savedViews";
3
+ import type { ReorderTarget } from "./useSavedViewsState";
4
+ import { type useSaveStatus } from "./useSaveStatus";
6
5
  export interface SavedViewsBarProps {
7
- activeFilters: ActiveFilter[];
6
+ /** The selected view, if any. */
7
+ activeSavedView: SavedView | undefined;
8
+ /** What New view saves. Its filters leave out the search. */
9
+ currentState: Omit<SavedView, "id" | "name">;
8
10
  defaultViewId: NonNullable<SavedView["id"]>;
9
- hideableColumns: DataTableColumn[];
10
- isColumnVisible: (column: DataTableColumn) => boolean;
11
+ /** Disables the drag handles while a reorder saves. */
12
+ isReordering?: boolean;
11
13
  onApply: (savedView: SavedView) => void;
12
14
  /**
13
15
  * Returns the saved view with its new id. Omit to hide the new view button
14
16
  * and the Duplicate action.
15
17
  */
16
- onCreate?: (savedView: Omit<SavedView, "id">) => Promise<SavedView> | SavedView;
18
+ onCreate?: (savedView: Omit<SavedView, "id">) => Promise<SavedView | undefined> | SavedView;
17
19
  /** Called once the user confirms. Omit to leave out the Delete action. */
18
- onDelete?: (savedView: SavedView) => void;
20
+ onDelete?: (savedView: SavedView) => Promise<void>;
21
+ /** Omit to leave out the drag handles in the manage views modal. */
22
+ onReorder?: (savedView: SavedView, target: ReorderTarget) => Promise<void>;
19
23
  /** Omit to leave out the Set as default action. */
20
- onSetDefault?: (id: NonNullable<SavedView["id"]>) => void;
24
+ onSetDefault?: (id: NonNullable<SavedView["id"]>) => Promise<void>;
21
25
  /** Omit to leave out the Rename action. */
22
- onUpdate?: (savedView: SavedView) => Promise<SavedView> | SavedView;
26
+ onUpdate?: (savedView: SavedView) => Promise<SavedView | undefined> | SavedView;
27
+ /** Tracks saves, shared with the filters shelf's saved view actions. */
28
+ saveStatus: ReturnType<typeof useSaveStatus>;
23
29
  savedViews: SavedView[];
24
- sortBy: Sort | undefined;
25
- /** Listed before `savedViews` and can't be edited. */
30
+ /** Selects the view the user picked. */
31
+ select: (savedView: SavedView) => void;
32
+ /** Selects a created view once it's saved, resolving to it if selected. */
33
+ selectWhenSaved: (savedView: Promise<SavedView | undefined> | SavedView) => Promise<SavedView | undefined>;
34
+ /**
35
+ * Listed before `savedViews` and can't be edited. Starts with the initial
36
+ * view unless one replaces it.
37
+ */
26
38
  staticViews: StaticView[];
27
39
  }
28
- export declare function SavedViewsBar({ defaultViewId, onApply, onCreate, onDelete, onSetDefault, onUpdate, savedViews, staticViews, activeFilters, hideableColumns, isColumnVisible, sortBy, }: SavedViewsBarProps): React.JSX.Element;
40
+ export declare function SavedViewsBar({ activeSavedView, currentState, defaultViewId, isReordering, onApply, onCreate, onDelete, onReorder, onSetDefault, onUpdate, saveStatus, savedViews, select, selectWhenSaved, staticViews, }: SavedViewsBarProps): React.JSX.Element;
29
41
  export declare namespace SavedViewsBar {
30
42
  var displayName: string;
31
43
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SavedViewsBar.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/SavedViewsBar.tsx"],"names":[],"mappings":"AAWA,OAAO,KAaN,MAAM,OAAO,CAAA;AAId,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAExD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAKjD,OAAO,EAGL,KAAK,SAAS,EAEd,KAAK,UAAU,EAChB,MAAM,cAAc,CAAA;AAUrB,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,YAAY,EAAE,CAAA;IAC7B,aAAa,EAAE,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAA;IAC3C,eAAe,EAAE,eAAe,EAAE,CAAA;IAClC,eAAe,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,OAAO,CAAA;IACrD,OAAO,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,IAAI,CAAA;IACvC;;;OAGG;IACH,QAAQ,CAAC,EAAE,CACT,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,KAC7B,OAAO,CAAC,SAAS,CAAC,GAAG,SAAS,CAAA;IACnC,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,IAAI,CAAA;IACzC,mDAAmD;IACnD,YAAY,CAAC,EAAE,CAAC,EAAE,EAAE,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,CAAA;IACzD,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,OAAO,CAAC,SAAS,CAAC,GAAG,SAAS,CAAA;IACnE,UAAU,EAAE,SAAS,EAAE,CAAA;IACvB,MAAM,EAAE,IAAI,GAAG,SAAS,CAAA;IACxB,sDAAsD;IACtD,WAAW,EAAE,UAAU,EAAE,CAAA;CAC1B;AAED,wBAAgB,aAAa,CAAC,EAC5B,aAAa,EACb,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,YAAY,EACZ,QAAQ,EACR,UAAU,EACV,WAAW,EACX,aAAa,EACb,eAAe,EACf,eAAe,EACf,MAAM,GACP,EAAE,kBAAkB,qBAiSpB;yBA9Se,aAAa"}
1
+ {"version":3,"file":"SavedViewsBar.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/SavedViewsBar.tsx"],"names":[],"mappings":"AAaA,OAAO,KAaN,MAAM,OAAO,CAAA;AAWd,OAAO,EAEL,KAAK,SAAS,EACd,KAAK,UAAU,EAChB,MAAM,cAAc,CAAA;AAErB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,EAA4B,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAS9E,MAAM,WAAW,kBAAkB;IACjC,iCAAiC;IACjC,eAAe,EAAE,SAAS,GAAG,SAAS,CAAA;IACtC,6DAA6D;IAC7D,YAAY,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,GAAG,MAAM,CAAC,CAAA;IAC5C,aAAa,EAAE,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAA;IAC3C,uDAAuD;IACvD,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,OAAO,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,IAAI,CAAA;IACvC;;;OAGG;IACH,QAAQ,CAAC,EAAE,CACT,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,KAC7B,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,GAAG,SAAS,CAAA;IAC/C,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAClD,oEAAoE;IACpE,SAAS,CAAC,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1E,mDAAmD;IACnD,YAAY,CAAC,EAAE,CAAC,EAAE,EAAE,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAClE,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,CACT,SAAS,EAAE,SAAS,KACjB,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,GAAG,SAAS,CAAA;IAC/C,wEAAwE;IACxE,UAAU,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAA;IAC5C,UAAU,EAAE,SAAS,EAAE,CAAA;IACvB,wCAAwC;IACxC,MAAM,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,IAAI,CAAA;IACtC,2EAA2E;IAC3E,eAAe,EAAE,CACf,SAAS,EAAE,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,GAAG,SAAS,KAClD,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAAA;IACnC;;;OAGG;IACH,WAAW,EAAE,UAAU,EAAE,CAAA;CAC1B;AAED,wBAAgB,aAAa,CAAC,EAC5B,eAAe,EACf,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,QAAQ,EACR,UAAU,EACV,UAAU,EACV,MAAM,EACN,eAAe,EACf,WAAW,GACZ,EAAE,kBAAkB,qBA2QpB;yBA3Re,aAAa"}
@@ -1,4 +1,11 @@
1
- import { DropdownMenu, DropdownAction, DropdownSeparator } from '../dropdown/Dropdown.js';
1
+ import '../button/ActionsDropdownIconButton.js';
2
+ import '../button/Button.js';
3
+ import { DropdownButton } from '../button/DropdownButton.js';
4
+ import '../button/DropdownIconButton.js';
5
+ import '../button/IconButton.js';
6
+ import '../button/LoadingButton.js';
7
+ import '../button/PageHeaderActionsDropdownButton.js';
8
+ import { Dropdown, DropdownTrigger, DropdownMenu, DropdownAction } from '../dropdown/Dropdown.js';
2
9
  import { ReorderableListBox, ReorderableListBoxItem } from '../internal/reorderable-list-box/ReorderableListBox.js';
3
10
  import Icon from '../../utilities/Icon.js';
4
11
  import classNames from 'classnames';
@@ -10,85 +17,67 @@ import { ManageSavedViewsButton } from './ManageSavedViewsButton.js';
10
17
  import { ManageSavedViewsModal } from './ManageSavedViewsModal.js';
11
18
  import { NewSavedViewButton } from './NewSavedViewButton.js';
12
19
  import { NewSavedViewModal } from './NewSavedViewModal.js';
13
- import { initialView, findActiveSavedView, sortKeyAfter } from './savedViews.js';
14
- import { useActiveSavedView } from './useActiveSavedView.js';
15
- import { useUpdateSavedViewName } from './useUpdateSavedViewName.js';
20
+ import { hasSavedViewMenuActions, SavedViewMenu } from './SavedViewMenu.js';
21
+ import { isSavedViewEditable } from './savedViews.js';
22
+ import { useSavedViewNameModal } from './useSavedViewNameModal.js';
23
+ import { SaveStatusIcon, NEW_VIEW } from './useSaveStatus.js';
24
+ import { useVisibleSavedViews } from './useVisibleSavedViews.js';
16
25
 
17
26
  /**
18
27
  * The id of the view the delete alert returns focus to. Read through context
19
28
  * so the list's cached items see it without rebuilding the collection.
20
29
  */
21
30
  const ReturningFocusViewIdContext = createContext(null);
22
- function SavedViewsBar({ defaultViewId, onApply, onCreate, onDelete, onSetDefault, onUpdate, savedViews, staticViews, activeFilters, hideableColumns, isColumnVisible, sortBy, }) {
31
+ function SavedViewsBar({ activeSavedView, currentState, defaultViewId, isReordering, onApply, onCreate, onDelete, onReorder, onSetDefault, onUpdate, saveStatus, savedViews, select, selectWhenSaved, staticViews, }) {
23
32
  const closeOpenContextMenuRef = useRef(null);
24
- const hasInitialView = staticViews.some(({ id }) => id === initialView.id);
25
- const staticViewsWithInitial = hasInitialView
26
- ? staticViews
27
- : [initialView, ...staticViews];
28
- const views = [...staticViewsWithInitial, ...savedViews];
33
+ const views = [...staticViews, ...savedViews];
29
34
  // The list needs a key for every view, including ones not yet saved.
30
35
  const items = views.map((view, index) => ({
31
36
  id: view.id ?? `unsaved-view-${index}`,
32
37
  view,
33
38
  }));
34
- // What the name modal saves, under the name entered there: a new view, a
35
- // duplicate, or a rename. It outlives the modal's open state so the title
36
- // holds while the modal fades out.
37
- const [draft, setDraft] = useState();
38
- const [isDraftOpen, setIsDraftOpen] = useState(false);
39
39
  const [isManageOpen, setIsManageOpen] = useState(false);
40
40
  const barRef = useRef(null);
41
+ const listRef = useRef(null);
42
+ const newViewRef = useRef(null);
41
43
  // Kept after the alert closes, so its text holds during the exit animation,
42
44
  // and its view keeps the tab stop until focus returns to it on cancel.
43
45
  const [viewToDelete, setViewToDelete] = useState(null);
44
46
  const [isDeleteAlertOpen, setIsDeleteAlertOpen] = useState(false);
45
47
  const [isReturningFocus, setIsReturningFocus] = useState(false);
46
- const hiddenColumnNames = hideableColumns
47
- .filter((column) => !isColumnVisible(column))
48
- .map(({ name }) => name);
49
- // Static views come first, so they win ties with saved views.
50
- const { activeSavedView, select, selectWhenSaved } = useActiveSavedView(views, () => findActiveSavedView(views, {
51
- activeFilters,
52
- hiddenColumnNames,
53
- sort: sortBy,
54
- }));
55
- const updateSavedViewName = useUpdateSavedViewName(onUpdate);
56
- const openDraft = (title, defaultName, save) => {
57
- setDraft({ defaultName, save, title });
58
- setIsDraftOpen(true);
48
+ const { isCollapsed, isMeasuring, measure, overflowItems, visibleItems } = useVisibleSavedViews({
49
+ activeKey: activeSavedView?.id ?? null,
50
+ items,
51
+ listRef,
52
+ newViewRef,
53
+ });
54
+ // While measuring, the most it can hold, for its widest width.
55
+ const overflowCount = isMeasuring ? items.length : overflowItems.length;
56
+ const applyView = (view) => {
57
+ select(view);
58
+ onApply(view);
59
59
  };
60
+ // The first view is the default unless another is marked.
61
+ const renderLabel = (id, view) => (React__default.createElement(React__default.Fragment, null,
62
+ React__default.createElement("span", { className: "tds-data-table-saved-view-name" }, view.name),
63
+ view.id === defaultViewId && id !== items[0].id && (React__default.createElement(Icon, { "aria-hidden": true, className: "tds-data-table-saved-view-default-indicator", symbol: "general#pin" })),
64
+ React__default.createElement(SaveStatusIcon, { status: saveStatus.statusFor(view.id) })));
65
+ const nameModal = useSavedViewNameModal(onUpdate);
66
+ // Not in the list until it saves, so its status shows by the new view
67
+ // button.
60
68
  const createSavedView = (view) => {
61
- const sortKey = sortKeyAfter(savedViews);
62
- if (onCreate) {
63
- selectWhenSaved(onCreate({ ...view, ...(sortKey && { sortKey }) }));
64
- }
65
- };
66
- const openNewSavedView = () => {
67
- openDraft("New view", "", (name) => createSavedView({
68
- activeFilters,
69
- name,
70
- ...(hideableColumns.length > 0 && { hiddenColumnNames }),
71
- ...(sortBy && { sort: sortBy }),
72
- }));
69
+ if (onCreate)
70
+ saveStatus.track(NEW_VIEW, selectWhenSaved(onCreate(view)), view.name);
73
71
  };
74
- // The copy is a new view, so it doesn't keep the original's id or place in
75
- // the order.
76
- const duplicateSavedView = ({ id: _id, sortKey: _sortKey, ...view }) => {
77
- openDraft("Duplicate view", `${view.name} copy`, (name) => createSavedView({ ...view, name }));
72
+ // A duplicate of another view has other settings than the table, so it's
73
+ // applied once it's selected.
74
+ const duplicateSavedView = (view) => {
75
+ if (onCreate)
76
+ saveStatus.track(NEW_VIEW, selectWhenSaved(onCreate(view)).then((selected) => selected && onApply(selected)), view.name);
78
77
  };
79
- const renameSavedView = (view) => {
80
- openDraft("Rename view", view.name, (name) => {
81
- if (name !== view.name)
82
- updateSavedViewName(view, name);
83
- });
84
- };
85
- const saveDraft = (name) => {
86
- setIsDraftOpen(false);
87
- draft?.save(name);
78
+ const openNewSavedView = () => {
79
+ nameModal.open("New view", "", (name) => createSavedView({ ...currentState, name }));
88
80
  };
89
- // Updates and deletes are matched by id, so an unsaved view can't be
90
- // renamed or deleted. Static views can't be edited at all.
91
- const isEditable = (view) => view.id !== undefined && savedViews.includes(view);
92
81
  // The menu item Delete was chosen from is gone by now, so the view takes
93
82
  // focus first for the alert to return it to on cancel.
94
83
  const requestDelete = (view) => {
@@ -99,14 +88,11 @@ function SavedViewsBar({ defaultViewId, onApply, onCreate, onDelete, onSetDefaul
99
88
  setIsDeleteAlertOpen(true);
100
89
  setIsReturningFocus(true);
101
90
  };
102
- // Lets the tab stop go back to the selected view, where focus lands.
103
- // Deleting the default view hands the default back to "initial".
91
+ // Lets the tab stop go back to the selected view, where focus lands. A
92
+ // failed delete puts the view back, showing its status.
104
93
  const confirmDelete = () => {
105
- if (viewToDelete) {
106
- onDelete?.(viewToDelete);
107
- if (viewToDelete.id === defaultViewId)
108
- onSetDefault?.("initial");
109
- }
94
+ if (viewToDelete && onDelete)
95
+ saveStatus.track(viewToDelete.id, onDelete(viewToDelete), viewToDelete.name);
110
96
  setIsDeleteAlertOpen(false);
111
97
  setIsReturningFocus(false);
112
98
  };
@@ -123,39 +109,37 @@ function SavedViewsBar({ defaultViewId, onApply, onCreate, onDelete, onSetDefaul
123
109
  setIsReturningFocus(false);
124
110
  };
125
111
  const renderContextMenu = (view) => {
126
- const canRename = onUpdate && isEditable(view);
127
- const canDelete = onDelete && isEditable(view);
128
112
  // The default is matched by id, so an unsaved view can't be made the
129
113
  // default. Static views can.
130
114
  const { id } = view;
131
- const canSetDefault = onSetDefault && id !== undefined;
132
- const isDefault = id === defaultViewId;
133
- const hasActions = canRename || onCreate || canSetDefault;
134
- if (!hasActions && !canDelete)
135
- return null;
136
- return (React__default.createElement(DropdownMenu, null,
137
- canRename && (React__default.createElement(DropdownAction, { id: "rename", onAction: () => renameSavedView(view) }, "Rename")),
138
- onCreate && (React__default.createElement(DropdownAction, { id: "duplicate", onAction: () => duplicateSavedView(view) }, "Duplicate")),
139
- canSetDefault && (
140
- // Stays in the menu for the default view, disabled, so the user can
141
- // see which view is the default.
142
- React__default.createElement(DropdownAction, { disabled: isDefault, id: "set-default", onAction: () => onSetDefault(id) }, isDefault ? "Default view" : "Set as default")),
143
- hasActions && canDelete && React__default.createElement(DropdownSeparator, null),
144
- canDelete && (React__default.createElement(DropdownAction, { destructive: true, id: "delete", onAction: () => queueMicrotask(() => requestDelete(view)) }, "Delete"))));
115
+ const menuProps = {
116
+ isDefault: id === defaultViewId,
117
+ onDelete: onDelete && isSavedViewEditable(view, savedViews)
118
+ ? () => queueMicrotask(() => requestDelete(view))
119
+ : undefined,
120
+ onDuplicate: onCreate
121
+ ? () => nameModal.openDuplicate(view, duplicateSavedView)
122
+ : undefined,
123
+ onRename: onUpdate && isSavedViewEditable(view, savedViews)
124
+ ? () => nameModal.openRename(view, (saving) => saveStatus.track(view.id, saving, view.name))
125
+ : undefined,
126
+ onSetDefault: onSetDefault && id !== undefined
127
+ ? () => saveStatus.track(id, onSetDefault(id), view.name)
128
+ : undefined,
129
+ };
130
+ return hasSavedViewMenuActions(menuProps) ? (React__default.createElement(SavedViewMenu, { ...menuProps })) : null;
145
131
  };
146
132
  return (React__default.createElement("div", { ref: barRef, className: "tds-data-table-saved-views", onFocus: isReturningFocus ? handleFocus : undefined },
147
- React__default.createElement("div", { className: "tds-data-table-saved-views-list" },
133
+ React__default.createElement("div", { ref: listRef, className: classNames("tds-data-table-saved-views-list", {
134
+ "tds-data-table-saved-views-list--collapsed": isCollapsed,
135
+ }) },
148
136
  React__default.createElement(ReturningFocusViewIdContext.Provider, { value: isReturningFocus ? (viewToDelete?.id ?? null) : null },
149
- React__default.createElement(ReorderableListBox, { items: items, label: "Views", selectedKey: activeSavedView?.id ?? null, onSelectionChange: (key) => {
137
+ React__default.createElement(ReorderableListBox, { items: visibleItems, label: "Views", selectedKey: activeSavedView?.id ?? null, onItemsRendered: measure, onSelectionChange: (key) => {
150
138
  const view = items.find(({ id }) => id === key)?.view;
151
- if (!view)
152
- return;
153
- select(view);
154
- onApply(view);
139
+ if (view)
140
+ applyView(view);
155
141
  } }, ({ id, view }) => {
156
142
  const menu = renderContextMenu(view);
157
- // The first view is the default unless another is marked.
158
- const pin = view.id === defaultViewId && id !== items[0].id && (React__default.createElement(Icon, { "aria-hidden": true, className: "tds-data-table-saved-view-default-indicator", symbol: "general#pin" }));
159
143
  return (React__default.createElement(ReorderableListBoxItem, { className: classNames("tds-data-table-saved-view-list-item", {
160
144
  "tds-data-table-saved-view-list-item--default": view.id === defaultViewId,
161
145
  }), id: id,
@@ -163,17 +147,21 @@ function SavedViewsBar({ defaultViewId, onApply, onCreate, onDelete, onSetDefaul
163
147
  render: (props) => {
164
148
  const optionProps = {
165
149
  ...props,
166
- children: (React__default.createElement(React__default.Fragment, null,
167
- view.name,
168
- pin)),
150
+ children: renderLabel(id, view),
169
151
  };
170
152
  return menu ? (React__default.createElement(ContextMenuTrigger, { id: view.id, closeOpenContextMenuRef: closeOpenContextMenuRef, menu: menu, optionProps: optionProps })) : (React__default.createElement("div", { ...optionProps }));
171
153
  } }, view.name));
172
154
  })),
173
- onCreate && React__default.createElement(NewSavedViewButton, { onClick: openNewSavedView }),
174
- React__default.createElement(NewSavedViewModal, { defaultName: draft?.defaultName, open: isDraftOpen, title: draft?.title, onClose: () => setIsDraftOpen(false), onSave: saveDraft })),
155
+ (isMeasuring || overflowItems.length > 0) && (React__default.createElement(Dropdown, null,
156
+ React__default.createElement(DropdownTrigger, null,
157
+ React__default.createElement(DropdownButton, { "aria-label": `${overflowCount} more views`, className: "tds-btn--data-table-saved-views-overflow", kind: "pill", label: `${overflowCount} more` })),
158
+ React__default.createElement(DropdownMenu, null, overflowItems.map(({ id, view }) => (React__default.createElement(DropdownAction, { key: id, id: id, textValue: view.name, onAction: () => applyView(view) }, renderLabel(id, view))))))),
159
+ React__default.createElement("div", { ref: newViewRef, className: "tds-data-table-saved-views-new-view" },
160
+ onCreate && React__default.createElement(NewSavedViewButton, { onClick: openNewSavedView }),
161
+ React__default.createElement(SaveStatusIcon, { label: "View not saved", status: saveStatus.statusFor(NEW_VIEW) })),
162
+ React__default.createElement(NewSavedViewModal, { ...nameModal.modalProps })),
175
163
  views.length > 1 && (React__default.createElement(ManageSavedViewsButton, { onClick: () => setIsManageOpen(true) })),
176
- React__default.createElement(ManageSavedViewsModal, { defaultViewId: defaultViewId, open: isManageOpen, savedViews: savedViews, staticViews: staticViewsWithInitial, onClose: closeManageViews, onDelete: onDelete, onSetDefault: onSetDefault, onUpdate: onUpdate }),
164
+ React__default.createElement(ManageSavedViewsModal, { defaultViewId: defaultViewId, isReordering: isReordering, open: isManageOpen, savedViews: savedViews, staticViews: staticViews, onClose: closeManageViews, onCreate: onCreate, onDelete: onDelete, onReorder: onReorder, onSetDefault: onSetDefault, onUpdate: onUpdate }),
177
165
  onDelete && (React__default.createElement(DeleteSavedViewAlertDialog, { open: isDeleteAlertOpen, view: viewToDelete, onCancel: () => setIsDeleteAlertOpen(false), onConfirm: confirmDelete }))));
178
166
  }
179
167
  SavedViewsBar.displayName = "SavedViewsBar";
@@ -1 +1 @@
1
- {"version":3,"file":"SavedViewsBar.js","sources":["../../../src/components/DataTable/SavedViewsBar.tsx"],"sourcesContent":["import {\n DropdownAction,\n DropdownMenu,\n DropdownSeparator,\n} from \"@components/dropdown\"\nimport {\n ReorderableListBox,\n ReorderableListBoxItem,\n} from \"@components/internal/reorderable-list-box\"\nimport Icon from \"@utilities/Icon\"\nimport classNames from \"classnames\"\nimport React, {\n type ComponentProps,\n createContext,\n Fragment,\n type KeyboardEvent,\n type MutableRefObject,\n type ReactElement,\n type RefObject,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n} from \"react\"\nimport { mergeProps } from \"react-aria/mergeProps\"\nimport { MenuTrigger, Pressable } from \"react-aria-components/Menu\"\n\nimport type { Sort } from \"./DataTable\"\nimport type { DataTableColumn } from \"./DataTableColumn\"\nimport { DeleteSavedViewAlertDialog } from \"./DeleteSavedViewAlertDialog\"\nimport type { ActiveFilter } from \"./FilterTypes\"\nimport { ManageSavedViewsButton } from \"./ManageSavedViewsButton\"\nimport { ManageSavedViewsModal } from \"./ManageSavedViewsModal\"\nimport { NewSavedViewButton } from \"./NewSavedViewButton\"\nimport { NewSavedViewModal } from \"./NewSavedViewModal\"\nimport {\n findActiveSavedView,\n initialView,\n type SavedView,\n sortKeyAfter,\n type StaticView,\n} from \"./savedViews\"\nimport { useActiveSavedView } from \"./useActiveSavedView\"\nimport { useUpdateSavedViewName } from \"./useUpdateSavedViewName\"\n\n/**\n * The id of the view the delete alert returns focus to. Read through context\n * so the list's cached items see it without rebuilding the collection.\n */\nconst ReturningFocusViewIdContext = createContext<SavedView[\"id\"] | null>(null)\n\nexport interface SavedViewsBarProps {\n activeFilters: ActiveFilter[]\n defaultViewId: NonNullable<SavedView[\"id\"]>\n hideableColumns: DataTableColumn[]\n isColumnVisible: (column: DataTableColumn) => boolean\n onApply: (savedView: SavedView) => void\n /**\n * Returns the saved view with its new id. Omit to hide the new view button\n * and the Duplicate action.\n */\n onCreate?: (\n savedView: Omit<SavedView, \"id\">\n ) => Promise<SavedView> | SavedView\n /** Called once the user confirms. Omit to leave out the Delete action. */\n onDelete?: (savedView: SavedView) => void\n /** Omit to leave out the Set as default action. */\n onSetDefault?: (id: NonNullable<SavedView[\"id\"]>) => void\n /** Omit to leave out the Rename action. */\n onUpdate?: (savedView: SavedView) => Promise<SavedView> | SavedView\n savedViews: SavedView[]\n sortBy: Sort | undefined\n /** Listed before `savedViews` and can't be edited. */\n staticViews: StaticView[]\n}\n\nexport function SavedViewsBar({\n defaultViewId,\n onApply,\n onCreate,\n onDelete,\n onSetDefault,\n onUpdate,\n savedViews,\n staticViews,\n activeFilters,\n hideableColumns,\n isColumnVisible,\n sortBy,\n}: SavedViewsBarProps) {\n const closeOpenContextMenuRef = useRef<(() => void) | null>(null)\n const hasInitialView = staticViews.some(({ id }) => id === initialView.id)\n const staticViewsWithInitial = hasInitialView\n ? staticViews\n : [initialView, ...staticViews]\n const views = [...staticViewsWithInitial, ...savedViews]\n // The list needs a key for every view, including ones not yet saved.\n const items = views.map((view, index) => ({\n id: view.id ?? `unsaved-view-${index}`,\n view,\n }))\n // What the name modal saves, under the name entered there: a new view, a\n // duplicate, or a rename. It outlives the modal's open state so the title\n // holds while the modal fades out.\n const [draft, setDraft] = useState<{\n defaultName: string\n save: (name: string) => void\n title: string\n }>()\n const [isDraftOpen, setIsDraftOpen] = useState(false)\n const [isManageOpen, setIsManageOpen] = useState(false)\n const barRef = useRef<HTMLDivElement>(null)\n // Kept after the alert closes, so its text holds during the exit animation,\n // and its view keeps the tab stop until focus returns to it on cancel.\n const [viewToDelete, setViewToDelete] = useState<SavedView | null>(null)\n const [isDeleteAlertOpen, setIsDeleteAlertOpen] = useState(false)\n const [isReturningFocus, setIsReturningFocus] = useState(false)\n const hiddenColumnNames = hideableColumns\n .filter((column) => !isColumnVisible(column))\n .map(({ name }) => name)\n // Static views come first, so they win ties with saved views.\n const { activeSavedView, select, selectWhenSaved } = useActiveSavedView(\n views,\n () =>\n findActiveSavedView(views, {\n activeFilters,\n hiddenColumnNames,\n sort: sortBy,\n })\n )\n\n const updateSavedViewName = useUpdateSavedViewName(onUpdate)\n\n const openDraft = (\n title: string,\n defaultName: string,\n save: (name: string) => void\n ) => {\n setDraft({ defaultName, save, title })\n setIsDraftOpen(true)\n }\n\n const createSavedView = (view: Omit<SavedView, \"id\">) => {\n const sortKey = sortKeyAfter(savedViews)\n if (onCreate) {\n selectWhenSaved(onCreate({ ...view, ...(sortKey && { sortKey }) }))\n }\n }\n\n const openNewSavedView = () => {\n openDraft(\"New view\", \"\", (name) =>\n createSavedView({\n activeFilters,\n name,\n ...(hideableColumns.length > 0 && { hiddenColumnNames }),\n ...(sortBy && { sort: sortBy }),\n })\n )\n }\n\n // The copy is a new view, so it doesn't keep the original's id or place in\n // the order.\n const duplicateSavedView = ({\n id: _id,\n sortKey: _sortKey,\n ...view\n }: SavedView) => {\n openDraft(\"Duplicate view\", `${view.name} copy`, (name) =>\n createSavedView({ ...view, name })\n )\n }\n\n const renameSavedView = (view: SavedView) => {\n openDraft(\"Rename view\", view.name, (name) => {\n if (name !== view.name) updateSavedViewName(view, name)\n })\n }\n\n const saveDraft = (name: string) => {\n setIsDraftOpen(false)\n draft?.save(name)\n }\n\n // Updates and deletes are matched by id, so an unsaved view can't be\n // renamed or deleted. Static views can't be edited at all.\n const isEditable = (view: SavedView) =>\n view.id !== undefined && savedViews.includes(view)\n\n // The menu item Delete was chosen from is gone by now, so the view takes\n // focus first for the alert to return it to on cancel.\n const requestDelete = (view: SavedView) => {\n barRef.current\n ?.querySelector<HTMLElement>(\n `[role=\"option\"][data-key=\"${CSS.escape(String(view.id))}\"]`\n )\n ?.focus()\n setViewToDelete(view)\n setIsDeleteAlertOpen(true)\n setIsReturningFocus(true)\n }\n\n // Lets the tab stop go back to the selected view, where focus lands.\n // Deleting the default view hands the default back to \"initial\".\n const confirmDelete = () => {\n if (viewToDelete) {\n onDelete?.(viewToDelete)\n if (viewToDelete.id === defaultViewId) onSetDefault?.(\"initial\")\n }\n setIsDeleteAlertOpen(false)\n setIsReturningFocus(false)\n }\n\n const focusSelectedViewAfterClose = useFocusSelectedViewAfterClose(\n barRef,\n isManageOpen\n )\n\n // Deleting down to one view hides the button the modal returns focus to.\n const closeManageViews = () => {\n if (views.length <= 1) focusSelectedViewAfterClose()\n setIsManageOpen(false)\n }\n\n // Focus from inside the open alert reaches here too, through the portal.\n const handleFocus = () => {\n if (!isDeleteAlertOpen) setIsReturningFocus(false)\n }\n\n const renderContextMenu = (view: SavedView) => {\n const canRename = onUpdate && isEditable(view)\n const canDelete = onDelete && isEditable(view)\n // The default is matched by id, so an unsaved view can't be made the\n // default. Static views can.\n const { id } = view\n const canSetDefault = onSetDefault && id !== undefined\n const isDefault = id === defaultViewId\n const hasActions = canRename || onCreate || canSetDefault\n if (!hasActions && !canDelete) return null\n return (\n <DropdownMenu>\n {canRename && (\n <DropdownAction id=\"rename\" onAction={() => renameSavedView(view)}>\n Rename\n </DropdownAction>\n )}\n {onCreate && (\n <DropdownAction\n id=\"duplicate\"\n onAction={() => duplicateSavedView(view)}\n >\n Duplicate\n </DropdownAction>\n )}\n {canSetDefault && (\n // Stays in the menu for the default view, disabled, so the user can\n // see which view is the default.\n <DropdownAction\n disabled={isDefault}\n id=\"set-default\"\n onAction={() => onSetDefault(id)}\n >\n {isDefault ? \"Default view\" : \"Set as default\"}\n </DropdownAction>\n )}\n {hasActions && canDelete && <DropdownSeparator />}\n {canDelete && (\n <DropdownAction\n destructive\n id=\"delete\"\n onAction={() => queueMicrotask(() => requestDelete(view))}\n >\n Delete\n </DropdownAction>\n )}\n </DropdownMenu>\n )\n }\n\n return (\n <div\n ref={barRef}\n className=\"tds-data-table-saved-views\"\n onFocus={isReturningFocus ? handleFocus : undefined}\n >\n <div className=\"tds-data-table-saved-views-list\">\n <ReturningFocusViewIdContext.Provider\n value={isReturningFocus ? (viewToDelete?.id ?? null) : null}\n >\n <ReorderableListBox\n items={items}\n label=\"Views\"\n selectedKey={activeSavedView?.id ?? null}\n onSelectionChange={(key) => {\n const view = items.find(({ id }) => id === key)?.view\n if (!view) return\n select(view)\n onApply(view)\n }}\n >\n {({ id, view }) => {\n const menu = renderContextMenu(view)\n // The first view is the default unless another is marked.\n const pin = view.id === defaultViewId && id !== items[0].id && (\n <Icon\n aria-hidden\n className=\"tds-data-table-saved-view-default-indicator\"\n symbol=\"general#pin\"\n />\n )\n return (\n <ReorderableListBoxItem\n className={classNames(\"tds-data-table-saved-view-list-item\", {\n \"tds-data-table-saved-view-list-item--default\":\n view.id === defaultViewId,\n })}\n id={id}\n // The list item only takes text, so the pin goes in here.\n render={(props) => {\n const optionProps = {\n ...(props as ComponentProps<\"div\">),\n children: (\n <>\n {view.name}\n {pin}\n </>\n ),\n }\n return menu ? (\n <ContextMenuTrigger\n id={view.id}\n closeOpenContextMenuRef={closeOpenContextMenuRef}\n menu={menu}\n optionProps={optionProps}\n />\n ) : (\n <div {...optionProps} />\n )\n }}\n >\n {view.name}\n </ReorderableListBoxItem>\n )\n }}\n </ReorderableListBox>\n </ReturningFocusViewIdContext.Provider>\n {onCreate && <NewSavedViewButton onClick={openNewSavedView} />}\n <NewSavedViewModal\n defaultName={draft?.defaultName}\n open={isDraftOpen}\n title={draft?.title}\n onClose={() => setIsDraftOpen(false)}\n onSave={saveDraft}\n />\n </div>\n {views.length > 1 && (\n <ManageSavedViewsButton onClick={() => setIsManageOpen(true)} />\n )}\n {/* Rendered apart from the button, so a delete that hides the button doesn't remove the open modal. */}\n <ManageSavedViewsModal\n defaultViewId={defaultViewId}\n open={isManageOpen}\n savedViews={savedViews}\n staticViews={staticViewsWithInitial}\n onClose={closeManageViews}\n onDelete={onDelete}\n onSetDefault={onSetDefault}\n onUpdate={onUpdate}\n />\n {onDelete && (\n <DeleteSavedViewAlertDialog\n open={isDeleteAlertOpen}\n view={viewToDelete}\n onCancel={() => setIsDeleteAlertOpen(false)}\n onConfirm={confirmDelete}\n />\n )}\n </div>\n )\n}\n\nSavedViewsBar.displayName = \"SavedViewsBar\"\n\n/**\n * Once the manage views modal starts closing, focuses the selected view, or\n * the first one.\n */\nfunction useFocusSelectedViewAfterClose(\n barRef: RefObject<HTMLDivElement>,\n isManageOpen: boolean\n) {\n const shouldFocusRef = useRef(false)\n\n useEffect(() => {\n if (isManageOpen || !shouldFocusRef.current) return\n shouldFocusRef.current = false\n const bar = barRef.current\n ;(\n bar?.querySelector<HTMLElement>(\n '[role=\"option\"][aria-selected=\"true\"]'\n ) ?? bar?.querySelector<HTMLElement>('[role=\"option\"]')\n )?.focus()\n }, [barRef, isManageOpen])\n\n return () => {\n shouldFocusRef.current = true\n }\n}\n\n/**\n * Makes a saved view's option element itself the context menu trigger, so\n * the menu opens by right click, long press, or the keyboard context menu\n * shortcut (Shift+F10, the Menu key, or Ctrl+Enter on macOS), is named by\n * the view, and returns focus to it on close. `Pressable` hands the trigger's\n * handlers to the option element. The option ignores Ctrl+Enter, so the\n * macOS shortcut opens the menu without also selecting the view. The\n * `data-popup-open` attribute keeps the list from moving its tab\n * stop to the selected view while the menu is open. Opening the menu closes\n * any other view's menu, since a right click elsewhere in the list doesn't\n * count as an outside interaction. The open state stays here rather than in\n * the bar, because re-rendering the bar rebuilds the list's collection and\n * moves its tab stop before focus can return to this view. Each\n * `contextmenu` event remounts the menu, because React Aria only positions\n * an open menu once and would leave it at the first click point.\n */\nfunction ContextMenuTrigger({\n closeOpenContextMenuRef,\n id,\n menu,\n optionProps,\n}: {\n closeOpenContextMenuRef: MutableRefObject<(() => void) | null>\n id: SavedView[\"id\"]\n menu: ReactElement\n optionProps: ComponentProps<\"div\">\n}) {\n const { onKeyDown, ...restOptionProps } = optionProps\n const [isOpen, setIsOpen] = useState(false)\n // Such as the delete alert, which returns focus to this view on cancel.\n const hasOtherPopup = useContext(ReturningFocusViewIdContext) === id\n const [menuKey, setMenuKey] = useState(0)\n\n const close = useCallback(() => setIsOpen(false), [])\n const handleOpenChange = (nextIsOpen: boolean) => {\n setIsOpen(nextIsOpen)\n if (nextIsOpen) {\n closeOpenContextMenuRef.current?.()\n closeOpenContextMenuRef.current = close\n } else if (closeOpenContextMenuRef.current === close) {\n closeOpenContextMenuRef.current = null\n }\n }\n\n return (\n <MenuTrigger\n isOpen={isOpen}\n onOpenChange={handleOpenChange}\n trigger=\"contextMenu\"\n >\n <Pressable>\n <div\n {...mergeProps(restOptionProps, {\n \"data-popup-open\": isOpen || hasOtherPopup || undefined,\n onContextMenu: () => setMenuKey((key) => key + 1),\n onKeyDown: (event: KeyboardEvent<HTMLDivElement>) => {\n if (event.ctrlKey && event.key === \"Enter\") return\n onKeyDown?.(event)\n },\n })}\n />\n </Pressable>\n <Fragment key={menuKey}>{menu}</Fragment>\n </MenuTrigger>\n )\n}\n"],"names":["React"],"mappings":";;;;;;;;;;;;;;;;AA8CA;;;AAGG;AACH,MAAM,2BAA2B,GAAG,aAAa,CAAyB,IAAI,CAAC;AA2BzE,SAAU,aAAa,CAAC,EAC5B,aAAa,EACb,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,YAAY,EACZ,QAAQ,EACR,UAAU,EACV,WAAW,EACX,aAAa,EACb,eAAe,EACf,eAAe,EACf,MAAM,GACa,EAAA;AACnB,IAAA,MAAM,uBAAuB,GAAG,MAAM,CAAsB,IAAI,CAAC;AACjE,IAAA,MAAM,cAAc,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,WAAW,CAAC,EAAE,CAAC;IAC1E,MAAM,sBAAsB,GAAG;AAC7B,UAAE;AACF,UAAE,CAAC,WAAW,EAAE,GAAG,WAAW,CAAC;IACjC,MAAM,KAAK,GAAG,CAAC,GAAG,sBAAsB,EAAE,GAAG,UAAU,CAAC;;AAExD,IAAA,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,MAAM;AACxC,QAAA,EAAE,EAAE,IAAI,CAAC,EAAE,IAAI,CAAA,aAAA,EAAgB,KAAK,CAAA,CAAE;QACtC,IAAI;AACL,KAAA,CAAC,CAAC;;;;IAIH,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,EAI9B;IACJ,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;IACrD,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;AACvD,IAAA,MAAM,MAAM,GAAG,MAAM,CAAiB,IAAI,CAAC;;;IAG3C,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAmB,IAAI,CAAC;IACxE,MAAM,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;IACjE,MAAM,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;IAC/D,MAAM,iBAAiB,GAAG;SACvB,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,eAAe,CAAC,MAAM,CAAC;SAC3C,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;;AAE1B,IAAA,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,eAAe,EAAE,GAAG,kBAAkB,CACrE,KAAK,EACL,MACE,mBAAmB,CAAC,KAAK,EAAE;QACzB,aAAa;QACb,iBAAiB;AACjB,QAAA,IAAI,EAAE,MAAM;AACb,KAAA,CAAC,CACL;AAED,IAAA,MAAM,mBAAmB,GAAG,sBAAsB,CAAC,QAAQ,CAAC;IAE5D,MAAM,SAAS,GAAG,CAChB,KAAa,EACb,WAAmB,EACnB,IAA4B,KAC1B;QACF,QAAQ,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;QACtC,cAAc,CAAC,IAAI,CAAC;AACtB,IAAA,CAAC;AAED,IAAA,MAAM,eAAe,GAAG,CAAC,IAA2B,KAAI;AACtD,QAAA,MAAM,OAAO,GAAG,YAAY,CAAC,UAAU,CAAC;QACxC,IAAI,QAAQ,EAAE;AACZ,YAAA,eAAe,CAAC,QAAQ,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,OAAO,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;QACrE;AACF,IAAA,CAAC;IAED,MAAM,gBAAgB,GAAG,MAAK;QAC5B,SAAS,CAAC,UAAU,EAAE,EAAE,EAAE,CAAC,IAAI,KAC7B,eAAe,CAAC;YACd,aAAa;YACb,IAAI;YACJ,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,iBAAiB,EAAE,CAAC;YACxD,IAAI,MAAM,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAChC,SAAA,CAAC,CACH;AACH,IAAA,CAAC;;;AAID,IAAA,MAAM,kBAAkB,GAAG,CAAC,EAC1B,EAAE,EAAE,GAAG,EACP,OAAO,EAAE,QAAQ,EACjB,GAAG,IAAI,EACG,KAAI;QACd,SAAS,CAAC,gBAAgB,EAAE,CAAA,EAAG,IAAI,CAAC,IAAI,CAAA,KAAA,CAAO,EAAE,CAAC,IAAI,KACpD,eAAe,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,CAAC,CACnC;AACH,IAAA,CAAC;AAED,IAAA,MAAM,eAAe,GAAG,CAAC,IAAe,KAAI;QAC1C,SAAS,CAAC,aAAa,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI,KAAI;AAC3C,YAAA,IAAI,IAAI,KAAK,IAAI,CAAC,IAAI;AAAE,gBAAA,mBAAmB,CAAC,IAAI,EAAE,IAAI,CAAC;AACzD,QAAA,CAAC,CAAC;AACJ,IAAA,CAAC;AAED,IAAA,MAAM,SAAS,GAAG,CAAC,IAAY,KAAI;QACjC,cAAc,CAAC,KAAK,CAAC;AACrB,QAAA,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC;AACnB,IAAA,CAAC;;;AAID,IAAA,MAAM,UAAU,GAAG,CAAC,IAAe,KACjC,IAAI,CAAC,EAAE,KAAK,SAAS,IAAI,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC;;;AAIpD,IAAA,MAAM,aAAa,GAAG,CAAC,IAAe,KAAI;AACxC,QAAA,MAAM,CAAC;AACL,cAAE,aAAa,CACb,CAAA,0BAAA,EAA6B,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI;cAE5D,KAAK,EAAE;QACX,eAAe,CAAC,IAAI,CAAC;QACrB,oBAAoB,CAAC,IAAI,CAAC;QAC1B,mBAAmB,CAAC,IAAI,CAAC;AAC3B,IAAA,CAAC;;;IAID,MAAM,aAAa,GAAG,MAAK;QACzB,IAAI,YAAY,EAAE;AAChB,YAAA,QAAQ,GAAG,YAAY,CAAC;AACxB,YAAA,IAAI,YAAY,CAAC,EAAE,KAAK,aAAa;AAAE,gBAAA,YAAY,GAAG,SAAS,CAAC;QAClE;QACA,oBAAoB,CAAC,KAAK,CAAC;QAC3B,mBAAmB,CAAC,KAAK,CAAC;AAC5B,IAAA,CAAC;IAED,MAAM,2BAA2B,GAAG,8BAA8B,CAChE,MAAM,EACN,YAAY,CACb;;IAGD,MAAM,gBAAgB,GAAG,MAAK;AAC5B,QAAA,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC;AAAE,YAAA,2BAA2B,EAAE;QACpD,eAAe,CAAC,KAAK,CAAC;AACxB,IAAA,CAAC;;IAGD,MAAM,WAAW,GAAG,MAAK;AACvB,QAAA,IAAI,CAAC,iBAAiB;YAAE,mBAAmB,CAAC,KAAK,CAAC;AACpD,IAAA,CAAC;AAED,IAAA,MAAM,iBAAiB,GAAG,CAAC,IAAe,KAAI;QAC5C,MAAM,SAAS,GAAG,QAAQ,IAAI,UAAU,CAAC,IAAI,CAAC;QAC9C,MAAM,SAAS,GAAG,QAAQ,IAAI,UAAU,CAAC,IAAI,CAAC;;;AAG9C,QAAA,MAAM,EAAE,EAAE,EAAE,GAAG,IAAI;AACnB,QAAA,MAAM,aAAa,GAAG,YAAY,IAAI,EAAE,KAAK,SAAS;AACtD,QAAA,MAAM,SAAS,GAAG,EAAE,KAAK,aAAa;AACtC,QAAA,MAAM,UAAU,GAAG,SAAS,IAAI,QAAQ,IAAI,aAAa;AACzD,QAAA,IAAI,CAAC,UAAU,IAAI,CAAC,SAAS;AAAE,YAAA,OAAO,IAAI;QAC1C,QACEA,6BAAC,YAAY,EAAA,IAAA;AACV,YAAA,SAAS,KACRA,cAAA,CAAA,aAAA,CAAC,cAAc,EAAA,EAAC,EAAE,EAAC,QAAQ,EAAC,QAAQ,EAAE,MAAM,eAAe,CAAC,IAAI,CAAC,aAEhD,CAClB;AACA,YAAA,QAAQ,KACPA,cAAA,CAAA,aAAA,CAAC,cAAc,EAAA,EACb,EAAE,EAAC,WAAW,EACd,QAAQ,EAAE,MAAM,kBAAkB,CAAC,IAAI,CAAC,gBAGzB,CAClB;AACA,YAAA,aAAa;;;AAGZ,YAAAA,cAAA,CAAA,aAAA,CAAC,cAAc,EAAA,EACb,QAAQ,EAAE,SAAS,EACnB,EAAE,EAAC,aAAa,EAChB,QAAQ,EAAE,MAAM,YAAY,CAAC,EAAE,CAAC,EAAA,EAE/B,SAAS,GAAG,cAAc,GAAG,gBAAgB,CAC/B,CAClB;AACA,YAAA,UAAU,IAAI,SAAS,IAAIA,cAAA,CAAA,aAAA,CAAC,iBAAiB,EAAA,IAAA,CAAG;AAChD,YAAA,SAAS,KACRA,cAAA,CAAA,aAAA,CAAC,cAAc,EAAA,EACb,WAAW,EAAA,IAAA,EACX,EAAE,EAAC,QAAQ,EACX,QAAQ,EAAE,MAAM,cAAc,CAAC,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC,EAAA,EAAA,QAAA,CAG1C,CAClB,CACY;AAEnB,IAAA,CAAC;IAED,QACEA,sCACE,GAAG,EAAE,MAAM,EACX,SAAS,EAAC,4BAA4B,EACtC,OAAO,EAAE,gBAAgB,GAAG,WAAW,GAAG,SAAS,EAAA;QAEnDA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,iCAAiC,EAAA;YAC9CA,cAAA,CAAA,aAAA,CAAC,2BAA2B,CAAC,QAAQ,EAAA,EACnC,KAAK,EAAE,gBAAgB,IAAI,YAAY,EAAE,EAAE,IAAI,IAAI,IAAI,IAAI,EAAA;gBAE3DA,cAAA,CAAA,aAAA,CAAC,kBAAkB,IACjB,KAAK,EAAE,KAAK,EACZ,KAAK,EAAC,OAAO,EACb,WAAW,EAAE,eAAe,EAAE,EAAE,IAAI,IAAI,EACxC,iBAAiB,EAAE,CAAC,GAAG,KAAI;AACzB,wBAAA,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC,EAAE,IAAI;AACrD,wBAAA,IAAI,CAAC,IAAI;4BAAE;wBACX,MAAM,CAAC,IAAI,CAAC;wBACZ,OAAO,CAAC,IAAI,CAAC;oBACf,CAAC,EAAA,EAEA,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,KAAI;AAChB,oBAAA,MAAM,IAAI,GAAG,iBAAiB,CAAC,IAAI,CAAC;;AAEpC,oBAAA,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,KAAK,aAAa,IAAI,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,KACzDA,cAAA,CAAA,aAAA,CAAC,IAAI,EAAA,EAAA,aAAA,EAAA,IAAA,EAEH,SAAS,EAAC,6CAA6C,EACvD,MAAM,EAAC,aAAa,EAAA,CACpB,CACH;oBACD,QACEA,6BAAC,sBAAsB,EAAA,EACrB,SAAS,EAAE,UAAU,CAAC,qCAAqC,EAAE;AAC3D,4BAAA,8CAA8C,EAC5C,IAAI,CAAC,EAAE,KAAK,aAAa;yBAC5B,CAAC,EACF,EAAE,EAAE,EAAE;;AAEN,wBAAA,MAAM,EAAE,CAAC,KAAK,KAAI;AAChB,4BAAA,MAAM,WAAW,GAAG;AAClB,gCAAA,GAAI,KAA+B;AACnC,gCAAA,QAAQ,GACNA,cAAA,CAAA,aAAA,CAAAA,cAAA,CAAA,QAAA,EAAA,IAAA;AACG,oCAAA,IAAI,CAAC,IAAI;AACT,oCAAA,GAAG,CACH,CACJ;6BACF;AACD,4BAAA,OAAO,IAAI,IACTA,cAAA,CAAA,aAAA,CAAC,kBAAkB,EAAA,EACjB,EAAE,EAAE,IAAI,CAAC,EAAE,EACX,uBAAuB,EAAE,uBAAuB,EAChD,IAAI,EAAE,IAAI,EACV,WAAW,EAAE,WAAW,EAAA,CACxB,KAEFA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAA,GAAS,WAAW,EAAA,CAAI,CACzB;AACH,wBAAA,CAAC,IAEA,IAAI,CAAC,IAAI,CACa;AAE7B,gBAAA,CAAC,CACkB,CACgB;AACtC,YAAA,QAAQ,IAAIA,cAAA,CAAA,aAAA,CAAC,kBAAkB,IAAC,OAAO,EAAE,gBAAgB,EAAA,CAAI;AAC9D,YAAAA,cAAA,CAAA,aAAA,CAAC,iBAAiB,EAAA,EAChB,WAAW,EAAE,KAAK,EAAE,WAAW,EAC/B,IAAI,EAAE,WAAW,EACjB,KAAK,EAAE,KAAK,EAAE,KAAK,EACnB,OAAO,EAAE,MAAM,cAAc,CAAC,KAAK,CAAC,EACpC,MAAM,EAAE,SAAS,GACjB,CACE;AACL,QAAA,KAAK,CAAC,MAAM,GAAG,CAAC,KACfA,6BAAC,sBAAsB,EAAA,EAAC,OAAO,EAAE,MAAM,eAAe,CAAC,IAAI,CAAC,GAAI,CACjE;AAED,QAAAA,cAAA,CAAA,aAAA,CAAC,qBAAqB,EAAA,EACpB,aAAa,EAAE,aAAa,EAC5B,IAAI,EAAE,YAAY,EAClB,UAAU,EAAE,UAAU,EACtB,WAAW,EAAE,sBAAsB,EACnC,OAAO,EAAE,gBAAgB,EACzB,QAAQ,EAAE,QAAQ,EAClB,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,QAAQ,EAAA,CAClB;AACD,QAAA,QAAQ,KACPA,cAAA,CAAA,aAAA,CAAC,0BAA0B,EAAA,EACzB,IAAI,EAAE,iBAAiB,EACvB,IAAI,EAAE,YAAY,EAClB,QAAQ,EAAE,MAAM,oBAAoB,CAAC,KAAK,CAAC,EAC3C,SAAS,EAAE,aAAa,EAAA,CACxB,CACH,CACG;AAEV;AAEA,aAAa,CAAC,WAAW,GAAG,eAAe;AAE3C;;;AAGG;AACH,SAAS,8BAA8B,CACrC,MAAiC,EACjC,YAAqB,EAAA;AAErB,IAAA,MAAM,cAAc,GAAG,MAAM,CAAC,KAAK,CAAC;IAEpC,SAAS,CAAC,MAAK;AACb,QAAA,IAAI,YAAY,IAAI,CAAC,cAAc,CAAC,OAAO;YAAE;AAC7C,QAAA,cAAc,CAAC,OAAO,GAAG,KAAK;AAC9B,QAAA,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO;AACzB,QAAA,CACC,GAAG,EAAE,aAAa,CAChB,uCAAuC,CACxC,IAAI,GAAG,EAAE,aAAa,CAAc,iBAAiB,CAAC,GACtD,KAAK,EAAE;AACZ,IAAA,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;AAE1B,IAAA,OAAO,MAAK;AACV,QAAA,cAAc,CAAC,OAAO,GAAG,IAAI;AAC/B,IAAA,CAAC;AACH;AAEA;;;;;;;;;;;;;;;AAeG;AACH,SAAS,kBAAkB,CAAC,EAC1B,uBAAuB,EACvB,EAAE,EACF,IAAI,EACJ,WAAW,GAMZ,EAAA;IACC,MAAM,EAAE,SAAS,EAAE,GAAG,eAAe,EAAE,GAAG,WAAW;IACrD,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;;IAE3C,MAAM,aAAa,GAAG,UAAU,CAAC,2BAA2B,CAAC,KAAK,EAAE;IACpE,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC;AAEzC,IAAA,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,SAAS,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;AACrD,IAAA,MAAM,gBAAgB,GAAG,CAAC,UAAmB,KAAI;QAC/C,SAAS,CAAC,UAAU,CAAC;QACrB,IAAI,UAAU,EAAE;AACd,YAAA,uBAAuB,CAAC,OAAO,IAAI;AACnC,YAAA,uBAAuB,CAAC,OAAO,GAAG,KAAK;QACzC;AAAO,aAAA,IAAI,uBAAuB,CAAC,OAAO,KAAK,KAAK,EAAE;AACpD,YAAA,uBAAuB,CAAC,OAAO,GAAG,IAAI;QACxC;AACF,IAAA,CAAC;AAED,IAAA,QACEA,cAAA,CAAA,aAAA,CAAC,WAAW,EAAA,EACV,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,gBAAgB,EAC9B,OAAO,EAAC,aAAa,EAAA;AAErB,QAAAA,cAAA,CAAA,aAAA,CAAC,SAAS,EAAA,IAAA;YACRA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAA,GACM,UAAU,CAAC,eAAe,EAAE;AAC9B,oBAAA,iBAAiB,EAAE,MAAM,IAAI,aAAa,IAAI,SAAS;AACvD,oBAAA,aAAa,EAAE,MAAM,UAAU,CAAC,CAAC,GAAG,KAAK,GAAG,GAAG,CAAC,CAAC;AACjD,oBAAA,SAAS,EAAE,CAAC,KAAoC,KAAI;wBAClD,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,GAAG,KAAK,OAAO;4BAAE;AAC5C,wBAAA,SAAS,GAAG,KAAK,CAAC;oBACpB,CAAC;AACF,iBAAA,CAAC,GACF,CACQ;QACZA,cAAA,CAAA,aAAA,CAAC,QAAQ,EAAA,EAAC,GAAG,EAAE,OAAO,IAAG,IAAI,CAAY,CAC7B;AAElB;;;;"}
1
+ {"version":3,"file":"SavedViewsBar.js","sources":["../../../src/components/DataTable/SavedViewsBar.tsx"],"sourcesContent":["import { DropdownButton } from \"@components/button\"\nimport {\n Dropdown,\n DropdownAction,\n DropdownMenu,\n DropdownTrigger,\n} from \"@components/dropdown\"\nimport {\n ReorderableListBox,\n ReorderableListBoxItem,\n} from \"@components/internal/reorderable-list-box\"\nimport Icon from \"@utilities/Icon\"\nimport classNames from \"classnames\"\nimport React, {\n type ComponentProps,\n createContext,\n Fragment,\n type KeyboardEvent,\n type MutableRefObject,\n type ReactElement,\n type RefObject,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n} from \"react\"\nimport { mergeProps } from \"react-aria/mergeProps\"\nimport type { Key } from \"react-aria-components/ListBox\"\nimport { MenuTrigger, Pressable } from \"react-aria-components/Menu\"\n\nimport { DeleteSavedViewAlertDialog } from \"./DeleteSavedViewAlertDialog\"\nimport { ManageSavedViewsButton } from \"./ManageSavedViewsButton\"\nimport { ManageSavedViewsModal } from \"./ManageSavedViewsModal\"\nimport { NewSavedViewButton } from \"./NewSavedViewButton\"\nimport { NewSavedViewModal } from \"./NewSavedViewModal\"\nimport { hasSavedViewMenuActions, SavedViewMenu } from \"./SavedViewMenu\"\nimport {\n isSavedViewEditable,\n type SavedView,\n type StaticView,\n} from \"./savedViews\"\nimport { useSavedViewNameModal } from \"./useSavedViewNameModal\"\nimport type { ReorderTarget } from \"./useSavedViewsState\"\nimport { NEW_VIEW, SaveStatusIcon, type useSaveStatus } from \"./useSaveStatus\"\nimport { useVisibleSavedViews } from \"./useVisibleSavedViews\"\n\n/**\n * The id of the view the delete alert returns focus to. Read through context\n * so the list's cached items see it without rebuilding the collection.\n */\nconst ReturningFocusViewIdContext = createContext<SavedView[\"id\"] | null>(null)\n\nexport interface SavedViewsBarProps {\n /** The selected view, if any. */\n activeSavedView: SavedView | undefined\n /** What New view saves. Its filters leave out the search. */\n currentState: Omit<SavedView, \"id\" | \"name\">\n defaultViewId: NonNullable<SavedView[\"id\"]>\n /** Disables the drag handles while a reorder saves. */\n isReordering?: boolean\n onApply: (savedView: SavedView) => void\n /**\n * Returns the saved view with its new id. Omit to hide the new view button\n * and the Duplicate action.\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 action. */\n onDelete?: (savedView: SavedView) => Promise<void>\n /** Omit to leave out the drag handles in the manage views modal. */\n onReorder?: (savedView: SavedView, target: ReorderTarget) => Promise<void>\n /** Omit to leave out the Set as default action. */\n onSetDefault?: (id: NonNullable<SavedView[\"id\"]>) => Promise<void>\n /** Omit to leave out the Rename action. */\n onUpdate?: (\n savedView: SavedView\n ) => Promise<SavedView | undefined> | SavedView\n /** Tracks saves, shared with the filters shelf's saved view actions. */\n saveStatus: ReturnType<typeof useSaveStatus>\n savedViews: SavedView[]\n /** Selects the view the user picked. */\n select: (savedView: SavedView) => void\n /** Selects a created view once it's saved, resolving to it if selected. */\n selectWhenSaved: (\n savedView: Promise<SavedView | undefined> | SavedView\n ) => Promise<SavedView | undefined>\n /**\n * Listed before `savedViews` and can't be edited. Starts with the initial\n * view unless one replaces it.\n */\n staticViews: StaticView[]\n}\n\nexport function SavedViewsBar({\n activeSavedView,\n currentState,\n defaultViewId,\n isReordering,\n onApply,\n onCreate,\n onDelete,\n onReorder,\n onSetDefault,\n onUpdate,\n saveStatus,\n savedViews,\n select,\n selectWhenSaved,\n staticViews,\n}: SavedViewsBarProps) {\n const closeOpenContextMenuRef = useRef<(() => void) | null>(null)\n const views = [...staticViews, ...savedViews]\n // The list needs a key for every view, including ones not yet saved.\n const items = views.map((view, index) => ({\n id: view.id ?? `unsaved-view-${index}`,\n view,\n }))\n const [isManageOpen, setIsManageOpen] = useState(false)\n const barRef = useRef<HTMLDivElement>(null)\n const listRef = useRef<HTMLDivElement>(null)\n const newViewRef = useRef<HTMLDivElement>(null)\n // Kept after the alert closes, so its text holds during the exit animation,\n // and its view keeps the tab stop until focus returns to it on cancel.\n const [viewToDelete, setViewToDelete] = useState<SavedView | null>(null)\n const [isDeleteAlertOpen, setIsDeleteAlertOpen] = useState(false)\n const [isReturningFocus, setIsReturningFocus] = useState(false)\n\n const { isCollapsed, isMeasuring, measure, overflowItems, visibleItems } =\n useVisibleSavedViews({\n activeKey: activeSavedView?.id ?? null,\n items,\n listRef,\n newViewRef,\n })\n // While measuring, the most it can hold, for its widest width.\n const overflowCount = isMeasuring ? items.length : overflowItems.length\n\n const applyView = (view: SavedView) => {\n select(view)\n onApply(view)\n }\n\n // The first view is the default unless another is marked.\n const renderLabel = (id: Key, view: SavedView) => (\n <>\n <span className=\"tds-data-table-saved-view-name\">{view.name}</span>\n {view.id === defaultViewId && id !== items[0].id && (\n <Icon\n aria-hidden\n className=\"tds-data-table-saved-view-default-indicator\"\n symbol=\"general#pin\"\n />\n )}\n <SaveStatusIcon status={saveStatus.statusFor(view.id)} />\n </>\n )\n\n const nameModal = useSavedViewNameModal(onUpdate)\n\n // Not in the list until it saves, so its status shows by the new view\n // button.\n const createSavedView = (view: Omit<SavedView, \"id\">) => {\n if (onCreate)\n saveStatus.track(NEW_VIEW, selectWhenSaved(onCreate(view)), view.name)\n }\n\n // A duplicate of another view has other settings than the table, so it's\n // applied once it's selected.\n const duplicateSavedView = (view: Omit<SavedView, \"id\">) => {\n if (onCreate)\n saveStatus.track(\n NEW_VIEW,\n selectWhenSaved(onCreate(view)).then(\n (selected) => selected && onApply(selected)\n ),\n view.name\n )\n }\n\n const openNewSavedView = () => {\n nameModal.open(\"New view\", \"\", (name) =>\n createSavedView({ ...currentState, name })\n )\n }\n\n // The menu item Delete was chosen from is gone by now, so the view takes\n // focus first for the alert to return it to on cancel.\n const requestDelete = (view: SavedView) => {\n barRef.current\n ?.querySelector<HTMLElement>(\n `[role=\"option\"][data-key=\"${CSS.escape(String(view.id))}\"]`\n )\n ?.focus()\n setViewToDelete(view)\n setIsDeleteAlertOpen(true)\n setIsReturningFocus(true)\n }\n\n // Lets the tab stop go back to the selected view, where focus lands. A\n // failed delete puts the view back, showing its status.\n const confirmDelete = () => {\n if (viewToDelete && onDelete)\n saveStatus.track(\n viewToDelete.id,\n onDelete(viewToDelete),\n viewToDelete.name\n )\n setIsDeleteAlertOpen(false)\n setIsReturningFocus(false)\n }\n\n const focusSelectedViewAfterClose = useFocusSelectedViewAfterClose(\n barRef,\n isManageOpen\n )\n\n // Deleting down to one view hides the button the modal returns focus to.\n const closeManageViews = () => {\n if (views.length <= 1) focusSelectedViewAfterClose()\n setIsManageOpen(false)\n }\n\n // Focus from inside the open alert reaches here too, through the portal.\n const handleFocus = () => {\n if (!isDeleteAlertOpen) setIsReturningFocus(false)\n }\n\n const renderContextMenu = (view: SavedView) => {\n // The default is matched by id, so an unsaved view can't be made the\n // default. Static views can.\n const { id } = view\n const menuProps = {\n isDefault: id === defaultViewId,\n onDelete:\n onDelete && isSavedViewEditable(view, savedViews)\n ? () => queueMicrotask(() => requestDelete(view))\n : undefined,\n onDuplicate: onCreate\n ? () => nameModal.openDuplicate(view, duplicateSavedView)\n : undefined,\n onRename:\n onUpdate && isSavedViewEditable(view, savedViews)\n ? () =>\n nameModal.openRename(view, (saving) =>\n saveStatus.track(view.id, saving, view.name)\n )\n : undefined,\n onSetDefault:\n onSetDefault && id !== undefined\n ? () => saveStatus.track(id, onSetDefault(id), view.name)\n : undefined,\n }\n return hasSavedViewMenuActions(menuProps) ? (\n <SavedViewMenu {...menuProps} />\n ) : null\n }\n\n return (\n <div\n ref={barRef}\n className=\"tds-data-table-saved-views\"\n onFocus={isReturningFocus ? handleFocus : undefined}\n >\n <div\n ref={listRef}\n className={classNames(\"tds-data-table-saved-views-list\", {\n \"tds-data-table-saved-views-list--collapsed\": isCollapsed,\n })}\n >\n <ReturningFocusViewIdContext.Provider\n value={isReturningFocus ? (viewToDelete?.id ?? null) : null}\n >\n <ReorderableListBox\n items={visibleItems}\n label=\"Views\"\n selectedKey={activeSavedView?.id ?? null}\n onItemsRendered={measure}\n onSelectionChange={(key) => {\n const view = items.find(({ id }) => id === key)?.view\n if (view) applyView(view)\n }}\n >\n {({ id, view }) => {\n const menu = renderContextMenu(view)\n return (\n <ReorderableListBoxItem\n className={classNames(\"tds-data-table-saved-view-list-item\", {\n \"tds-data-table-saved-view-list-item--default\":\n view.id === defaultViewId,\n })}\n id={id}\n // The list item only takes text, so the pin goes in here.\n render={(props) => {\n const optionProps = {\n ...(props as ComponentProps<\"div\">),\n children: renderLabel(id, view),\n }\n return menu ? (\n <ContextMenuTrigger\n id={view.id}\n closeOpenContextMenuRef={closeOpenContextMenuRef}\n menu={menu}\n optionProps={optionProps}\n />\n ) : (\n <div {...optionProps} />\n )\n }}\n >\n {view.name}\n </ReorderableListBoxItem>\n )\n }}\n </ReorderableListBox>\n </ReturningFocusViewIdContext.Provider>\n {(isMeasuring || overflowItems.length > 0) && (\n <Dropdown>\n <DropdownTrigger>\n <DropdownButton\n aria-label={`${overflowCount} more views`}\n className=\"tds-btn--data-table-saved-views-overflow\"\n kind=\"pill\"\n label={`${overflowCount} more`}\n />\n </DropdownTrigger>\n <DropdownMenu>\n {overflowItems.map(({ id, view }) => (\n <DropdownAction\n key={id}\n id={id}\n textValue={view.name}\n onAction={() => applyView(view)}\n >\n {renderLabel(id, view)}\n </DropdownAction>\n ))}\n </DropdownMenu>\n </Dropdown>\n )}\n {/* Kept beside the views, so its width comes off theirs. */}\n <div ref={newViewRef} className=\"tds-data-table-saved-views-new-view\">\n {onCreate && <NewSavedViewButton onClick={openNewSavedView} />}\n <SaveStatusIcon\n label=\"View not saved\"\n status={saveStatus.statusFor(NEW_VIEW)}\n />\n </div>\n <NewSavedViewModal {...nameModal.modalProps} />\n </div>\n {views.length > 1 && (\n <ManageSavedViewsButton onClick={() => setIsManageOpen(true)} />\n )}\n {/* Rendered apart from the button, so a delete that hides the button doesn't remove the open modal. */}\n <ManageSavedViewsModal\n defaultViewId={defaultViewId}\n isReordering={isReordering}\n open={isManageOpen}\n savedViews={savedViews}\n staticViews={staticViews}\n onClose={closeManageViews}\n onCreate={onCreate}\n onDelete={onDelete}\n onReorder={onReorder}\n onSetDefault={onSetDefault}\n onUpdate={onUpdate}\n />\n {onDelete && (\n <DeleteSavedViewAlertDialog\n open={isDeleteAlertOpen}\n view={viewToDelete}\n onCancel={() => setIsDeleteAlertOpen(false)}\n onConfirm={confirmDelete}\n />\n )}\n </div>\n )\n}\n\nSavedViewsBar.displayName = \"SavedViewsBar\"\n\n/**\n * Once the manage views modal starts closing, focuses the selected view, or\n * the first one.\n */\nfunction useFocusSelectedViewAfterClose(\n barRef: RefObject<HTMLDivElement>,\n isManageOpen: boolean\n) {\n const shouldFocusRef = useRef(false)\n\n useEffect(() => {\n if (isManageOpen || !shouldFocusRef.current) return\n shouldFocusRef.current = false\n const bar = barRef.current\n ;(\n bar?.querySelector<HTMLElement>(\n '[role=\"option\"][aria-selected=\"true\"]'\n ) ?? bar?.querySelector<HTMLElement>('[role=\"option\"]')\n )?.focus()\n }, [barRef, isManageOpen])\n\n return () => {\n shouldFocusRef.current = true\n }\n}\n\n/**\n * Makes a saved view's option element itself the context menu trigger, so\n * the menu opens by right click, long press, or the keyboard context menu\n * shortcut (Shift+F10, the Menu key, or Ctrl+Enter on macOS), is named by\n * the view, and returns focus to it on close. `Pressable` hands the trigger's\n * handlers to the option element. The option ignores Ctrl+Enter, so the\n * macOS shortcut opens the menu without also selecting the view. The\n * `data-popup-open` attribute keeps the list from moving its tab\n * stop to the selected view while the menu is open. Opening the menu closes\n * any other view's menu, since a right click elsewhere in the list doesn't\n * count as an outside interaction. The open state stays here rather than in\n * the bar, because re-rendering the bar rebuilds the list's collection and\n * moves its tab stop before focus can return to this view. Each\n * `contextmenu` event remounts the menu, because React Aria only positions\n * an open menu once and would leave it at the first click point.\n */\nfunction ContextMenuTrigger({\n closeOpenContextMenuRef,\n id,\n menu,\n optionProps,\n}: {\n closeOpenContextMenuRef: MutableRefObject<(() => void) | null>\n id: SavedView[\"id\"]\n menu: ReactElement\n optionProps: ComponentProps<\"div\">\n}) {\n const { onKeyDown, ...restOptionProps } = optionProps\n const [isOpen, setIsOpen] = useState(false)\n // Such as the delete alert, which returns focus to this view on cancel.\n const hasOtherPopup = useContext(ReturningFocusViewIdContext) === id\n const [menuKey, setMenuKey] = useState(0)\n\n const close = useCallback(() => setIsOpen(false), [])\n const handleOpenChange = (nextIsOpen: boolean) => {\n setIsOpen(nextIsOpen)\n if (nextIsOpen) {\n closeOpenContextMenuRef.current?.()\n closeOpenContextMenuRef.current = close\n } else if (closeOpenContextMenuRef.current === close) {\n closeOpenContextMenuRef.current = null\n }\n }\n\n return (\n <MenuTrigger\n isOpen={isOpen}\n onOpenChange={handleOpenChange}\n trigger=\"contextMenu\"\n >\n <Pressable>\n <div\n {...mergeProps(restOptionProps, {\n \"data-popup-open\": isOpen || hasOtherPopup || undefined,\n onContextMenu: () => setMenuKey((key) => key + 1),\n onKeyDown: (event: KeyboardEvent<HTMLDivElement>) => {\n if (event.ctrlKey && event.key === \"Enter\") return\n onKeyDown?.(event)\n },\n })}\n />\n </Pressable>\n <Fragment key={menuKey}>{menu}</Fragment>\n </MenuTrigger>\n )\n}\n"],"names":["React"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA+CA;;;AAGG;AACH,MAAM,2BAA2B,GAAG,aAAa,CAAyB,IAAI,CAAC;AA4CzE,SAAU,aAAa,CAAC,EAC5B,eAAe,EACf,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,QAAQ,EACR,UAAU,EACV,UAAU,EACV,MAAM,EACN,eAAe,EACf,WAAW,GACQ,EAAA;AACnB,IAAA,MAAM,uBAAuB,GAAG,MAAM,CAAsB,IAAI,CAAC;IACjE,MAAM,KAAK,GAAG,CAAC,GAAG,WAAW,EAAE,GAAG,UAAU,CAAC;;AAE7C,IAAA,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,MAAM;AACxC,QAAA,EAAE,EAAE,IAAI,CAAC,EAAE,IAAI,CAAA,aAAA,EAAgB,KAAK,CAAA,CAAE;QACtC,IAAI;AACL,KAAA,CAAC,CAAC;IACH,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;AACvD,IAAA,MAAM,MAAM,GAAG,MAAM,CAAiB,IAAI,CAAC;AAC3C,IAAA,MAAM,OAAO,GAAG,MAAM,CAAiB,IAAI,CAAC;AAC5C,IAAA,MAAM,UAAU,GAAG,MAAM,CAAiB,IAAI,CAAC;;;IAG/C,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAmB,IAAI,CAAC;IACxE,MAAM,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;IACjE,MAAM,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;AAE/D,IAAA,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,GACtE,oBAAoB,CAAC;AACnB,QAAA,SAAS,EAAE,eAAe,EAAE,EAAE,IAAI,IAAI;QACtC,KAAK;QACL,OAAO;QACP,UAAU;AACX,KAAA,CAAC;;AAEJ,IAAA,MAAM,aAAa,GAAG,WAAW,GAAG,KAAK,CAAC,MAAM,GAAG,aAAa,CAAC,MAAM;AAEvE,IAAA,MAAM,SAAS,GAAG,CAAC,IAAe,KAAI;QACpC,MAAM,CAAC,IAAI,CAAC;QACZ,OAAO,CAAC,IAAI,CAAC;AACf,IAAA,CAAC;;IAGD,MAAM,WAAW,GAAG,CAAC,EAAO,EAAE,IAAe,MAC3CA,cAAA,CAAA,aAAA,CAAAA,cAAA,CAAA,QAAA,EAAA,IAAA;AACE,QAAAA,cAAA,CAAA,aAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAC,gCAAgC,IAAE,IAAI,CAAC,IAAI,CAAQ;QAClE,IAAI,CAAC,EAAE,KAAK,aAAa,IAAI,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,KAC9CA,cAAA,CAAA,aAAA,CAAC,IAAI,EAAA,EAAA,aAAA,EAAA,IAAA,EAEH,SAAS,EAAC,6CAA6C,EACvD,MAAM,EAAC,aAAa,EAAA,CACpB,CACH;AACD,QAAAA,cAAA,CAAA,aAAA,CAAC,cAAc,EAAA,EAAC,MAAM,EAAE,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,EAAA,CAAI,CACxD,CACJ;AAED,IAAA,MAAM,SAAS,GAAG,qBAAqB,CAAC,QAAQ,CAAC;;;AAIjD,IAAA,MAAM,eAAe,GAAG,CAAC,IAA2B,KAAI;AACtD,QAAA,IAAI,QAAQ;AACV,YAAA,UAAU,CAAC,KAAK,CAAC,QAAQ,EAAE,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC;AAC1E,IAAA,CAAC;;;AAID,IAAA,MAAM,kBAAkB,GAAG,CAAC,IAA2B,KAAI;AACzD,QAAA,IAAI,QAAQ;AACV,YAAA,UAAU,CAAC,KAAK,CACd,QAAQ,EACR,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAClC,CAAC,QAAQ,KAAK,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC,CAC5C,EACD,IAAI,CAAC,IAAI,CACV;AACL,IAAA,CAAC;IAED,MAAM,gBAAgB,GAAG,MAAK;QAC5B,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,EAAE,CAAC,IAAI,KAClC,eAAe,CAAC,EAAE,GAAG,YAAY,EAAE,IAAI,EAAE,CAAC,CAC3C;AACH,IAAA,CAAC;;;AAID,IAAA,MAAM,aAAa,GAAG,CAAC,IAAe,KAAI;AACxC,QAAA,MAAM,CAAC;AACL,cAAE,aAAa,CACb,CAAA,0BAAA,EAA6B,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI;cAE5D,KAAK,EAAE;QACX,eAAe,CAAC,IAAI,CAAC;QACrB,oBAAoB,CAAC,IAAI,CAAC;QAC1B,mBAAmB,CAAC,IAAI,CAAC;AAC3B,IAAA,CAAC;;;IAID,MAAM,aAAa,GAAG,MAAK;QACzB,IAAI,YAAY,IAAI,QAAQ;AAC1B,YAAA,UAAU,CAAC,KAAK,CACd,YAAY,CAAC,EAAE,EACf,QAAQ,CAAC,YAAY,CAAC,EACtB,YAAY,CAAC,IAAI,CAClB;QACH,oBAAoB,CAAC,KAAK,CAAC;QAC3B,mBAAmB,CAAC,KAAK,CAAC;AAC5B,IAAA,CAAC;IAED,MAAM,2BAA2B,GAAG,8BAA8B,CAChE,MAAM,EACN,YAAY,CACb;;IAGD,MAAM,gBAAgB,GAAG,MAAK;AAC5B,QAAA,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC;AAAE,YAAA,2BAA2B,EAAE;QACpD,eAAe,CAAC,KAAK,CAAC;AACxB,IAAA,CAAC;;IAGD,MAAM,WAAW,GAAG,MAAK;AACvB,QAAA,IAAI,CAAC,iBAAiB;YAAE,mBAAmB,CAAC,KAAK,CAAC;AACpD,IAAA,CAAC;AAED,IAAA,MAAM,iBAAiB,GAAG,CAAC,IAAe,KAAI;;;AAG5C,QAAA,MAAM,EAAE,EAAE,EAAE,GAAG,IAAI;AACnB,QAAA,MAAM,SAAS,GAAG;YAChB,SAAS,EAAE,EAAE,KAAK,aAAa;YAC/B,QAAQ,EACN,QAAQ,IAAI,mBAAmB,CAAC,IAAI,EAAE,UAAU;AAC9C,kBAAE,MAAM,cAAc,CAAC,MAAM,aAAa,CAAC,IAAI,CAAC;AAChD,kBAAE,SAAS;AACf,YAAA,WAAW,EAAE;kBACT,MAAM,SAAS,CAAC,aAAa,CAAC,IAAI,EAAE,kBAAkB;AACxD,kBAAE,SAAS;YACb,QAAQ,EACN,QAAQ,IAAI,mBAAmB,CAAC,IAAI,EAAE,UAAU;AAC9C,kBAAE,MACE,SAAS,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,MAAM,KAChC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC;AAElD,kBAAE,SAAS;AACf,YAAA,YAAY,EACV,YAAY,IAAI,EAAE,KAAK;AACrB,kBAAE,MAAM,UAAU,CAAC,KAAK,CAAC,EAAE,EAAE,YAAY,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,IAAI;AACxD,kBAAE,SAAS;SAChB;AACD,QAAA,OAAO,uBAAuB,CAAC,SAAS,CAAC,IACvCA,cAAA,CAAA,aAAA,CAAC,aAAa,EAAA,EAAA,GAAK,SAAS,EAAA,CAAI,IAC9B,IAAI;AACV,IAAA,CAAC;IAED,QACEA,sCACE,GAAG,EAAE,MAAM,EACX,SAAS,EAAC,4BAA4B,EACtC,OAAO,EAAE,gBAAgB,GAAG,WAAW,GAAG,SAAS,EAAA;QAEnDA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EACE,GAAG,EAAE,OAAO,EACZ,SAAS,EAAE,UAAU,CAAC,iCAAiC,EAAE;AACvD,gBAAA,4CAA4C,EAAE,WAAW;aAC1D,CAAC,EAAA;YAEFA,cAAA,CAAA,aAAA,CAAC,2BAA2B,CAAC,QAAQ,EAAA,EACnC,KAAK,EAAE,gBAAgB,IAAI,YAAY,EAAE,EAAE,IAAI,IAAI,IAAI,IAAI,EAAA;gBAE3DA,cAAA,CAAA,aAAA,CAAC,kBAAkB,EAAA,EACjB,KAAK,EAAE,YAAY,EACnB,KAAK,EAAC,OAAO,EACb,WAAW,EAAE,eAAe,EAAE,EAAE,IAAI,IAAI,EACxC,eAAe,EAAE,OAAO,EACxB,iBAAiB,EAAE,CAAC,GAAG,KAAI;AACzB,wBAAA,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC,EAAE,IAAI;AACrD,wBAAA,IAAI,IAAI;4BAAE,SAAS,CAAC,IAAI,CAAC;oBAC3B,CAAC,EAAA,EAEA,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,KAAI;AAChB,oBAAA,MAAM,IAAI,GAAG,iBAAiB,CAAC,IAAI,CAAC;oBACpC,QACEA,6BAAC,sBAAsB,EAAA,EACrB,SAAS,EAAE,UAAU,CAAC,qCAAqC,EAAE;AAC3D,4BAAA,8CAA8C,EAC5C,IAAI,CAAC,EAAE,KAAK,aAAa;yBAC5B,CAAC,EACF,EAAE,EAAE,EAAE;;AAEN,wBAAA,MAAM,EAAE,CAAC,KAAK,KAAI;AAChB,4BAAA,MAAM,WAAW,GAAG;AAClB,gCAAA,GAAI,KAA+B;AACnC,gCAAA,QAAQ,EAAE,WAAW,CAAC,EAAE,EAAE,IAAI,CAAC;6BAChC;AACD,4BAAA,OAAO,IAAI,IACTA,cAAA,CAAA,aAAA,CAAC,kBAAkB,EAAA,EACjB,EAAE,EAAE,IAAI,CAAC,EAAE,EACX,uBAAuB,EAAE,uBAAuB,EAChD,IAAI,EAAE,IAAI,EACV,WAAW,EAAE,WAAW,EAAA,CACxB,KAEFA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAA,GAAS,WAAW,EAAA,CAAI,CACzB;AACH,wBAAA,CAAC,IAEA,IAAI,CAAC,IAAI,CACa;AAE7B,gBAAA,CAAC,CACkB,CACgB;YACtC,CAAC,WAAW,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,MACvCA,cAAA,CAAA,aAAA,CAAC,QAAQ,EAAA,IAAA;AACP,gBAAAA,cAAA,CAAA,aAAA,CAAC,eAAe,EAAA,IAAA;oBACdA,cAAA,CAAA,aAAA,CAAC,cAAc,kBACD,CAAA,EAAG,aAAa,aAAa,EACzC,SAAS,EAAC,0CAA0C,EACpD,IAAI,EAAC,MAAM,EACX,KAAK,EAAE,GAAG,aAAa,CAAA,KAAA,CAAO,GAC9B,CACc;gBAClBA,cAAA,CAAA,aAAA,CAAC,YAAY,EAAA,IAAA,EACV,aAAa,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,MAC9BA,cAAA,CAAA,aAAA,CAAC,cAAc,EAAA,EACb,GAAG,EAAE,EAAE,EACP,EAAE,EAAE,EAAE,EACN,SAAS,EAAE,IAAI,CAAC,IAAI,EACpB,QAAQ,EAAE,MAAM,SAAS,CAAC,IAAI,CAAC,EAAA,EAE9B,WAAW,CAAC,EAAE,EAAE,IAAI,CAAC,CACP,CAClB,CAAC,CACW,CACN,CACZ;AAED,YAAAA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAK,GAAG,EAAE,UAAU,EAAE,SAAS,EAAC,qCAAqC,EAAA;AAClE,gBAAA,QAAQ,IAAIA,cAAA,CAAA,aAAA,CAAC,kBAAkB,IAAC,OAAO,EAAE,gBAAgB,EAAA,CAAI;AAC9D,gBAAAA,cAAA,CAAA,aAAA,CAAC,cAAc,EAAA,EACb,KAAK,EAAC,gBAAgB,EACtB,MAAM,EAAE,UAAU,CAAC,SAAS,CAAC,QAAQ,CAAC,GACtC,CACE;AACN,YAAAA,cAAA,CAAA,aAAA,CAAC,iBAAiB,EAAA,EAAA,GAAK,SAAS,CAAC,UAAU,GAAI,CAC3C;AACL,QAAA,KAAK,CAAC,MAAM,GAAG,CAAC,KACfA,6BAAC,sBAAsB,EAAA,EAAC,OAAO,EAAE,MAAM,eAAe,CAAC,IAAI,CAAC,GAAI,CACjE;QAEDA,cAAA,CAAA,aAAA,CAAC,qBAAqB,IACpB,aAAa,EAAE,aAAa,EAC5B,YAAY,EAAE,YAAY,EAC1B,IAAI,EAAE,YAAY,EAClB,UAAU,EAAE,UAAU,EACtB,WAAW,EAAE,WAAW,EACxB,OAAO,EAAE,gBAAgB,EACzB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,QAAQ,EAAA,CAClB;AACD,QAAA,QAAQ,KACPA,cAAA,CAAA,aAAA,CAAC,0BAA0B,EAAA,EACzB,IAAI,EAAE,iBAAiB,EACvB,IAAI,EAAE,YAAY,EAClB,QAAQ,EAAE,MAAM,oBAAoB,CAAC,KAAK,CAAC,EAC3C,SAAS,EAAE,aAAa,EAAA,CACxB,CACH,CACG;AAEV;AAEA,aAAa,CAAC,WAAW,GAAG,eAAe;AAE3C;;;AAGG;AACH,SAAS,8BAA8B,CACrC,MAAiC,EACjC,YAAqB,EAAA;AAErB,IAAA,MAAM,cAAc,GAAG,MAAM,CAAC,KAAK,CAAC;IAEpC,SAAS,CAAC,MAAK;AACb,QAAA,IAAI,YAAY,IAAI,CAAC,cAAc,CAAC,OAAO;YAAE;AAC7C,QAAA,cAAc,CAAC,OAAO,GAAG,KAAK;AAC9B,QAAA,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO;AACzB,QAAA,CACC,GAAG,EAAE,aAAa,CAChB,uCAAuC,CACxC,IAAI,GAAG,EAAE,aAAa,CAAc,iBAAiB,CAAC,GACtD,KAAK,EAAE;AACZ,IAAA,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;AAE1B,IAAA,OAAO,MAAK;AACV,QAAA,cAAc,CAAC,OAAO,GAAG,IAAI;AAC/B,IAAA,CAAC;AACH;AAEA;;;;;;;;;;;;;;;AAeG;AACH,SAAS,kBAAkB,CAAC,EAC1B,uBAAuB,EACvB,EAAE,EACF,IAAI,EACJ,WAAW,GAMZ,EAAA;IACC,MAAM,EAAE,SAAS,EAAE,GAAG,eAAe,EAAE,GAAG,WAAW;IACrD,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;;IAE3C,MAAM,aAAa,GAAG,UAAU,CAAC,2BAA2B,CAAC,KAAK,EAAE;IACpE,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC;AAEzC,IAAA,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,SAAS,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;AACrD,IAAA,MAAM,gBAAgB,GAAG,CAAC,UAAmB,KAAI;QAC/C,SAAS,CAAC,UAAU,CAAC;QACrB,IAAI,UAAU,EAAE;AACd,YAAA,uBAAuB,CAAC,OAAO,IAAI;AACnC,YAAA,uBAAuB,CAAC,OAAO,GAAG,KAAK;QACzC;AAAO,aAAA,IAAI,uBAAuB,CAAC,OAAO,KAAK,KAAK,EAAE;AACpD,YAAA,uBAAuB,CAAC,OAAO,GAAG,IAAI;QACxC;AACF,IAAA,CAAC;AAED,IAAA,QACEA,cAAA,CAAA,aAAA,CAAC,WAAW,EAAA,EACV,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,gBAAgB,EAC9B,OAAO,EAAC,aAAa,EAAA;AAErB,QAAAA,cAAA,CAAA,aAAA,CAAC,SAAS,EAAA,IAAA;YACRA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAA,GACM,UAAU,CAAC,eAAe,EAAE;AAC9B,oBAAA,iBAAiB,EAAE,MAAM,IAAI,aAAa,IAAI,SAAS;AACvD,oBAAA,aAAa,EAAE,MAAM,UAAU,CAAC,CAAC,GAAG,KAAK,GAAG,GAAG,CAAC,CAAC;AACjD,oBAAA,SAAS,EAAE,CAAC,KAAoC,KAAI;wBAClD,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,GAAG,KAAK,OAAO;4BAAE;AAC5C,wBAAA,SAAS,GAAG,KAAK,CAAC;oBACpB,CAAC;AACF,iBAAA,CAAC,GACF,CACQ;QACZA,cAAA,CAAA,aAAA,CAAC,QAAQ,EAAA,EAAC,GAAG,EAAE,OAAO,IAAG,IAAI,CAAY,CAC7B;AAElB;;;;"}
@@ -23,7 +23,7 @@ export interface TableActionsProps {
23
23
  /** The table actions to render as an `IconButton` group. */
24
24
  actions: TableAction<DataTableSelection>[];
25
25
  /**
26
- * The noun used to describe the selection in each action's `aria-label`.
26
+ * The noun used to describe the selection in the group's `aria-label`.
27
27
  * See {@link ResultNoun}.
28
28
  */
29
29
  resultNoun?: ResultNoun;
@@ -31,7 +31,9 @@ export interface TableActionsProps {
31
31
  /**
32
32
  * Renders the table actions as an `IconButton` group displayed directly after
33
33
  * the results count, above the table. Each entry becomes an icon button whose
34
- * `callback` receives the current selection.
34
+ * `callback` receives the current selection. The group's label carries the
35
+ * selected count, so screen readers announce it once on entering the group
36
+ * rather than on every button.
35
37
  */
36
38
  export declare const TableActions: {
37
39
  ({ actions, resultNoun }: TableActionsProps): React.JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"TableActions.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/TableActions.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAE7C,OAAO,EAA4B,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAC1E,OAAO,EACL,KAAK,kBAAkB,EAExB,MAAM,yBAAyB,CAAA;AAEhC;;;;;GAKG;AACH,MAAM,MAAM,WAAW,CACrB,cAAc,SAAS,kBAAkB,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,IAC7D;IACF,sEAAsE;IACtE,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,cAAc,KAAK,IAAI,CAAA;IAC9C,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,yDAAyD;IACzD,IAAI,EAAE,SAAS,CAAA;IACf,wDAAwD;IACxD,KAAK,EAAE,MAAM,CAAA;IACb,8EAA8E;IAC9E,OAAO,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAAA;CACrD,CAAA;AAED,MAAM,WAAW,iBAAiB;IAChC,4DAA4D;IAC5D,OAAO,EAAE,WAAW,CAAC,kBAAkB,CAAC,EAAE,CAAA;IAC1C;;;OAGG;IACH,UAAU,CAAC,EAAE,UAAU,CAAA;CACxB;AAED;;;;GAIG;AACH,eAAO,MAAM,YAAY;8BAA6B,iBAAiB;;CAwBtE,CAAA"}
1
+ {"version":3,"file":"TableActions.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/TableActions.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAE7C,OAAO,EAA4B,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAC1E,OAAO,EACL,KAAK,kBAAkB,EAExB,MAAM,yBAAyB,CAAA;AAEhC;;;;;GAKG;AACH,MAAM,MAAM,WAAW,CACrB,cAAc,SAAS,kBAAkB,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,IAC7D;IACF,sEAAsE;IACtE,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,cAAc,KAAK,IAAI,CAAA;IAC9C,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,yDAAyD;IACzD,IAAI,EAAE,SAAS,CAAA;IACf,wDAAwD;IACxD,KAAK,EAAE,MAAM,CAAA;IACb,8EAA8E;IAC9E,OAAO,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAAA;CACrD,CAAA;AAED,MAAM,WAAW,iBAAiB;IAChC,4DAA4D;IAC5D,OAAO,EAAE,WAAW,CAAC,kBAAkB,CAAC,EAAE,CAAA;IAC1C;;;OAGG;IACH,UAAU,CAAC,EAAE,UAAU,CAAA;CACxB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,YAAY;8BAA6B,iBAAiB;;CAuBtE,CAAA"}
@@ -13,32 +13,29 @@ import { useDataTableSelectionContext } from './useDataTableSelection.js';
13
13
  /**
14
14
  * Renders the table actions as an `IconButton` group displayed directly after
15
15
  * the results count, above the table. Each entry becomes an icon button whose
16
- * `callback` receives the current selection.
16
+ * `callback` receives the current selection. The group's label carries the
17
+ * selected count, so screen readers announce it once on entering the group
18
+ * rather than on every button.
17
19
  */
18
20
  const TableActions = ({ actions, resultNoun }) => {
19
21
  const { selectedCount, selection } = useDataTableSelectionContext();
20
- // The count/noun suffix is the same for every table action, so compute it once
21
- // here rather than per-button inside the map below.
22
- const countSuffix = getTableActionCountSuffix(selectedCount, resultNoun);
23
- return (React__default.createElement(ButtonGroup, { "aria-label": "Table actions" }, actions.map(({ callback, disabled, icon, label, onClick }) => (React__default.createElement(IconButton, { key: label, "aria-label": `${label}${countSuffix}`, disabled: disabled, icon: icon, onClick: (event) => {
22
+ return (React__default.createElement(ButtonGroup, { "aria-label": getTableActionsGroupLabel(selectedCount, resultNoun) }, actions.map(({ callback, disabled, icon, label, onClick }) => (React__default.createElement(IconButton, { key: label, "aria-label": label, disabled: disabled, icon: icon, onClick: (event) => {
24
23
  onClick?.(event);
25
24
  callback?.(selection);
26
25
  }, tooltip: label, tooltipPlacement: "bottom" })))));
27
26
  };
28
27
  TableActions.displayName = "TableActions";
29
28
  /**
30
- * The count/noun suffix appended to each table action's `aria-label` when rows
31
- * are selected, e.g. `" (2 selected people)"` — so `"Email"` reads as
32
- * `"Email (2 selected people)"`. Empty when nothing is selected. Falls back to
33
- * the default `"result"` noun when `resultNoun` isn't provided. Shared across
34
- * every action, so it's computed once rather than per-button.
29
+ * The table actions group's `aria-label`, e.g. `"Actions for 2 selected
30
+ * people"` when rows are selected, or `"Table actions"` when nothing is
31
+ * selected. Falls back to the default `"result"` noun when `resultNoun` isn't
32
+ * provided.
35
33
  */
36
- function getTableActionCountSuffix(count, resultNoun) {
34
+ function getTableActionsGroupLabel(count, resultNoun) {
37
35
  if (!count)
38
- return "";
39
- // An absent or `true` noun both default to `"result"`/`"results"`.
36
+ return "Table actions";
40
37
  const noun = resolveNoun(count, resultNoun || true);
41
- return ` (${formatCount(count)} selected ${noun})`;
38
+ return `Actions for ${formatCount(count)} selected ${noun}`;
42
39
  }
43
40
 
44
41
  export { TableActions };