@planningcenter/tapestry 4.12.0 → 4.13.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/componentRegistrars.d.ts +1 -0
- package/dist/componentRegistrars.d.ts.map +1 -1
- package/dist/componentRegistrars.js +6 -2
- package/dist/componentRegistrars.js.map +1 -1
- package/dist/components/DataTable/ActiveFilters.d.ts +23 -1
- package/dist/components/DataTable/ActiveFilters.d.ts.map +1 -1
- package/dist/components/DataTable/ActiveFilters.js +49 -4
- package/dist/components/DataTable/ActiveFilters.js.map +1 -1
- package/dist/components/DataTable/CollectionEditorsLazy.d.ts.map +1 -1
- package/dist/components/DataTable/CollectionEditorsLazy.js +20 -18
- package/dist/components/DataTable/CollectionEditorsLazy.js.map +1 -1
- package/dist/components/DataTable/DataTable.d.ts +66 -50
- package/dist/components/DataTable/DataTable.d.ts.map +1 -1
- package/dist/components/DataTable/DataTable.js +78 -17
- package/dist/components/DataTable/DataTable.js.map +1 -1
- package/dist/components/DataTable/ManageSavedViewsModal.d.ts +18 -7
- package/dist/components/DataTable/ManageSavedViewsModal.d.ts.map +1 -1
- package/dist/components/DataTable/ManageSavedViewsModal.js +120 -104
- package/dist/components/DataTable/ManageSavedViewsModal.js.map +1 -1
- package/dist/components/DataTable/ManageSavedViewsModal.module.css.js +1 -1
- package/dist/components/DataTable/NewSavedViewButton.d.ts.map +1 -1
- package/dist/components/DataTable/NewSavedViewButton.js +1 -1
- package/dist/components/DataTable/NewSavedViewButton.js.map +1 -1
- package/dist/components/DataTable/SavedViewActions.d.ts +19 -0
- package/dist/components/DataTable/SavedViewActions.d.ts.map +1 -0
- package/dist/components/DataTable/SavedViewActions.js +34 -0
- package/dist/components/DataTable/SavedViewActions.js.map +1 -0
- package/dist/components/DataTable/SavedViewMenu.d.ts +18 -0
- package/dist/components/DataTable/SavedViewMenu.d.ts.map +1 -0
- package/dist/components/DataTable/SavedViewMenu.js +25 -0
- package/dist/components/DataTable/SavedViewMenu.js.map +1 -0
- package/dist/components/DataTable/SavedViewsBar.d.ts +25 -13
- package/dist/components/DataTable/SavedViewsBar.d.ts.map +1 -1
- package/dist/components/DataTable/SavedViewsBar.js +43 -83
- package/dist/components/DataTable/SavedViewsBar.js.map +1 -1
- package/dist/components/DataTable/TableActions.d.ts +4 -2
- package/dist/components/DataTable/TableActions.d.ts.map +1 -1
- package/dist/components/DataTable/TableActions.js +11 -14
- package/dist/components/DataTable/TableActions.js.map +1 -1
- package/dist/components/DataTable/index.d.ts +2 -0
- package/dist/components/DataTable/index.d.ts.map +1 -1
- package/dist/components/DataTable/saveErrorMessage.d.ts +3 -0
- package/dist/components/DataTable/saveErrorMessage.d.ts.map +1 -0
- package/dist/components/DataTable/saveErrorMessage.js +9 -0
- package/dist/components/DataTable/saveErrorMessage.js.map +1 -0
- package/dist/components/DataTable/savedViews.d.ts +15 -30
- package/dist/components/DataTable/savedViews.d.ts.map +1 -1
- package/dist/components/DataTable/savedViews.js +51 -98
- package/dist/components/DataTable/savedViews.js.map +1 -1
- package/dist/components/DataTable/useActiveSavedView.d.ts +1 -1
- package/dist/components/DataTable/useActiveSavedView.d.ts.map +1 -1
- package/dist/components/DataTable/useActiveSavedView.js +5 -4
- package/dist/components/DataTable/useActiveSavedView.js.map +1 -1
- package/dist/components/DataTable/useColumnVisibility.d.ts +7 -7
- package/dist/components/DataTable/useColumnVisibility.d.ts.map +1 -1
- package/dist/components/DataTable/useColumnVisibility.js +14 -14
- package/dist/components/DataTable/useColumnVisibility.js.map +1 -1
- package/dist/components/DataTable/useResultsAnnouncement.d.ts +26 -0
- package/dist/components/DataTable/useResultsAnnouncement.d.ts.map +1 -0
- package/dist/components/DataTable/{useFilterAnnouncement.js → useResultsAnnouncement.js} +16 -12
- package/dist/components/DataTable/useResultsAnnouncement.js.map +1 -0
- package/dist/components/DataTable/useSaveStatus.d.ts +32 -0
- package/dist/components/DataTable/useSaveStatus.d.ts.map +1 -0
- package/dist/components/DataTable/useSaveStatus.js +80 -0
- package/dist/components/DataTable/useSaveStatus.js.map +1 -0
- package/dist/components/DataTable/useSavedViewNameModal.d.ts +14 -0
- package/dist/components/DataTable/useSavedViewNameModal.d.ts.map +1 -0
- package/dist/components/DataTable/useSavedViewNameModal.js +43 -0
- package/dist/components/DataTable/useSavedViewNameModal.js.map +1 -0
- package/dist/components/DataTable/useSavedViewsClient.d.ts +58 -0
- package/dist/components/DataTable/useSavedViewsClient.d.ts.map +1 -0
- package/dist/components/DataTable/useSavedViewsClient.js +87 -0
- package/dist/components/DataTable/useSavedViewsClient.js.map +1 -0
- package/dist/components/DataTable/useSavedViewsState.d.ts +35 -0
- package/dist/components/DataTable/useSavedViewsState.d.ts.map +1 -0
- package/dist/components/DataTable/useSavedViewsState.js +192 -0
- package/dist/components/DataTable/useSavedViewsState.js.map +1 -0
- package/dist/components/DataTable/useUpdateSavedViewName.d.ts +2 -3
- package/dist/components/DataTable/useUpdateSavedViewName.d.ts.map +1 -1
- package/dist/components/DataTable/useUpdateSavedViewName.js +1 -2
- package/dist/components/DataTable/useUpdateSavedViewName.js.map +1 -1
- package/dist/components/button/BaseButton.d.ts +2 -0
- package/dist/components/button/BaseButton.d.ts.map +1 -1
- package/dist/components/button/BaseButton.js +8 -17
- package/dist/components/button/BaseButton.js.map +1 -1
- package/dist/components/internal/LoadingAnnouncement.d.ts +6 -0
- package/dist/components/internal/LoadingAnnouncement.d.ts.map +1 -1
- package/dist/components/internal/LoadingAnnouncement.js +12 -3
- package/dist/components/internal/LoadingAnnouncement.js.map +1 -1
- package/dist/components/internal/index.d.ts +1 -1
- package/dist/components/internal/index.d.ts.map +1 -1
- package/dist/components/internal/tooltip/useTooltipTriggerProps.d.ts +13 -0
- package/dist/components/internal/tooltip/useTooltipTriggerProps.d.ts.map +1 -0
- package/dist/components/internal/tooltip/useTooltipTriggerProps.js +24 -0
- package/dist/components/internal/tooltip/useTooltipTriggerProps.js.map +1 -0
- package/dist/components/link/BaseLink.d.ts.map +1 -1
- package/dist/components/link/BaseLink.js +3 -13
- package/dist/components/link/BaseLink.js.map +1 -1
- package/dist/components/segmented-control/IconSegment.d.ts +30 -8
- package/dist/components/segmented-control/IconSegment.d.ts.map +1 -1
- package/dist/components/segmented-control/IconSegment.js +10 -3
- package/dist/components/segmented-control/IconSegment.js.map +1 -1
- package/dist/components/segmented-control/SegmentBase.d.ts.map +1 -1
- package/dist/components/segmented-control/SegmentBase.js +4 -2
- package/dist/components/segmented-control/SegmentBase.js.map +1 -1
- package/dist/components/segmented-control/SegmentedControl.d.ts.map +1 -1
- package/dist/components/segmented-control/SegmentedControl.js +10 -3
- package/dist/components/segmented-control/SegmentedControl.js.map +1 -1
- package/dist/index.css +20 -5
- package/dist/index.css.map +1 -1
- package/dist/reactRender.css +1409 -1319
- package/dist/reactRender.css.map +1 -1
- package/dist/reactRender.js +1 -1
- package/dist/reactRenderLegacy.css +1409 -1319
- package/dist/reactRenderLegacy.css.map +1 -1
- package/dist/reactRenderLegacy.js +1 -1
- package/dist/tapestryMount.css +1409 -1319
- package/dist/tapestryMount.css.map +1 -1
- package/dist/tapestryMount.js +1 -1
- package/dist/tapestryMountLegacy.css +1409 -1319
- package/dist/tapestryMountLegacy.css.map +1 -1
- package/dist/tapestryMountLegacy.js +1 -1
- package/dist/tokens-dark.css +2 -2
- package/dist/tokens-dark.css.map +1 -1
- package/dist/tokens.css +3 -3
- package/dist/tokens.css.map +1 -1
- package/dist/unstable.css +385 -295
- package/dist/unstable.css.map +1 -1
- package/dist/unstable.js +1 -0
- package/dist/unstable.js.map +1 -1
- package/package.json +6 -7
- package/dist/components/DataTable/useFilterAnnouncement.d.ts +0 -24
- package/dist/components/DataTable/useFilterAnnouncement.d.ts.map +0 -1
- package/dist/components/DataTable/useFilterAnnouncement.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
|
-
|
|
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
|
-
|
|
10
|
-
|
|
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
|
-
|
|
25
|
-
|
|
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,
|
|
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":"
|
|
1
|
+
{"version":3,"file":"SavedViewsBar.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/SavedViewsBar.tsx"],"names":[],"mappings":"AAMA,OAAO,KAaN,MAAM,OAAO,CAAA;AAUd,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;AAQ9E,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,qBA4NpB;yBA5Oe,aAAa"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { DropdownMenu, DropdownAction, DropdownSeparator } from '../dropdown/Dropdown.js';
|
|
2
1
|
import { ReorderableListBox, ReorderableListBoxItem } from '../internal/reorderable-list-box/ReorderableListBox.js';
|
|
3
2
|
import Icon from '../../utilities/Icon.js';
|
|
4
3
|
import classNames from 'classnames';
|
|
@@ -10,32 +9,24 @@ import { ManageSavedViewsButton } from './ManageSavedViewsButton.js';
|
|
|
10
9
|
import { ManageSavedViewsModal } from './ManageSavedViewsModal.js';
|
|
11
10
|
import { NewSavedViewButton } from './NewSavedViewButton.js';
|
|
12
11
|
import { NewSavedViewModal } from './NewSavedViewModal.js';
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
12
|
+
import { hasSavedViewMenuActions, SavedViewMenu } from './SavedViewMenu.js';
|
|
13
|
+
import { isSavedViewEditable } from './savedViews.js';
|
|
14
|
+
import { useSavedViewNameModal } from './useSavedViewNameModal.js';
|
|
15
|
+
import { SaveStatusIcon, NEW_VIEW } from './useSaveStatus.js';
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* The id of the view the delete alert returns focus to. Read through context
|
|
19
19
|
* so the list's cached items see it without rebuilding the collection.
|
|
20
20
|
*/
|
|
21
21
|
const ReturningFocusViewIdContext = createContext(null);
|
|
22
|
-
function SavedViewsBar({ defaultViewId, onApply, onCreate, onDelete, onSetDefault, onUpdate,
|
|
22
|
+
function SavedViewsBar({ activeSavedView, currentState, defaultViewId, isReordering, onApply, onCreate, onDelete, onReorder, onSetDefault, onUpdate, saveStatus, savedViews, select, selectWhenSaved, staticViews, }) {
|
|
23
23
|
const closeOpenContextMenuRef = useRef(null);
|
|
24
|
-
const
|
|
25
|
-
const staticViewsWithInitial = hasInitialView
|
|
26
|
-
? staticViews
|
|
27
|
-
: [initialView, ...staticViews];
|
|
28
|
-
const views = [...staticViewsWithInitial, ...savedViews];
|
|
24
|
+
const views = [...staticViews, ...savedViews];
|
|
29
25
|
// The list needs a key for every view, including ones not yet saved.
|
|
30
26
|
const items = views.map((view, index) => ({
|
|
31
27
|
id: view.id ?? `unsaved-view-${index}`,
|
|
32
28
|
view,
|
|
33
29
|
}));
|
|
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
30
|
const [isManageOpen, setIsManageOpen] = useState(false);
|
|
40
31
|
const barRef = useRef(null);
|
|
41
32
|
// Kept after the alert closes, so its text holds during the exit animation,
|
|
@@ -43,52 +34,22 @@ function SavedViewsBar({ defaultViewId, onApply, onCreate, onDelete, onSetDefaul
|
|
|
43
34
|
const [viewToDelete, setViewToDelete] = useState(null);
|
|
44
35
|
const [isDeleteAlertOpen, setIsDeleteAlertOpen] = useState(false);
|
|
45
36
|
const [isReturningFocus, setIsReturningFocus] = useState(false);
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
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);
|
|
59
|
-
};
|
|
37
|
+
const nameModal = useSavedViewNameModal(onUpdate);
|
|
38
|
+
// Not in the list until it saves, so its status shows by the new view
|
|
39
|
+
// button.
|
|
60
40
|
const createSavedView = (view) => {
|
|
61
|
-
|
|
62
|
-
|
|
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
|
-
}));
|
|
73
|
-
};
|
|
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 }));
|
|
41
|
+
if (onCreate)
|
|
42
|
+
saveStatus.track(NEW_VIEW, selectWhenSaved(onCreate(view)), view.name);
|
|
78
43
|
};
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
44
|
+
// A duplicate of another view has other settings than the table, so it's
|
|
45
|
+
// applied once it's selected.
|
|
46
|
+
const duplicateSavedView = (view) => {
|
|
47
|
+
if (onCreate)
|
|
48
|
+
saveStatus.track(NEW_VIEW, selectWhenSaved(onCreate(view)).then((selected) => selected && onApply(selected)), view.name);
|
|
84
49
|
};
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
draft?.save(name);
|
|
50
|
+
const openNewSavedView = () => {
|
|
51
|
+
nameModal.open("New view", "", (name) => createSavedView({ ...currentState, name }));
|
|
88
52
|
};
|
|
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
53
|
// The menu item Delete was chosen from is gone by now, so the view takes
|
|
93
54
|
// focus first for the alert to return it to on cancel.
|
|
94
55
|
const requestDelete = (view) => {
|
|
@@ -99,14 +60,11 @@ function SavedViewsBar({ defaultViewId, onApply, onCreate, onDelete, onSetDefaul
|
|
|
99
60
|
setIsDeleteAlertOpen(true);
|
|
100
61
|
setIsReturningFocus(true);
|
|
101
62
|
};
|
|
102
|
-
// Lets the tab stop go back to the selected view, where focus lands.
|
|
103
|
-
//
|
|
63
|
+
// Lets the tab stop go back to the selected view, where focus lands. A
|
|
64
|
+
// failed delete puts the view back, showing its status.
|
|
104
65
|
const confirmDelete = () => {
|
|
105
|
-
if (viewToDelete)
|
|
106
|
-
onDelete
|
|
107
|
-
if (viewToDelete.id === defaultViewId)
|
|
108
|
-
onSetDefault?.("initial");
|
|
109
|
-
}
|
|
66
|
+
if (viewToDelete && onDelete)
|
|
67
|
+
saveStatus.track(viewToDelete.id, onDelete(viewToDelete), viewToDelete.name);
|
|
110
68
|
setIsDeleteAlertOpen(false);
|
|
111
69
|
setIsReturningFocus(false);
|
|
112
70
|
};
|
|
@@ -123,25 +81,25 @@ function SavedViewsBar({ defaultViewId, onApply, onCreate, onDelete, onSetDefaul
|
|
|
123
81
|
setIsReturningFocus(false);
|
|
124
82
|
};
|
|
125
83
|
const renderContextMenu = (view) => {
|
|
126
|
-
const canRename = onUpdate && isEditable(view);
|
|
127
|
-
const canDelete = onDelete && isEditable(view);
|
|
128
84
|
// The default is matched by id, so an unsaved view can't be made the
|
|
129
85
|
// default. Static views can.
|
|
130
86
|
const { id } = view;
|
|
131
|
-
const
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
87
|
+
const menuProps = {
|
|
88
|
+
isDefault: id === defaultViewId,
|
|
89
|
+
onDelete: onDelete && isSavedViewEditable(view, savedViews)
|
|
90
|
+
? () => queueMicrotask(() => requestDelete(view))
|
|
91
|
+
: undefined,
|
|
92
|
+
onDuplicate: onCreate
|
|
93
|
+
? () => nameModal.openDuplicate(view, duplicateSavedView)
|
|
94
|
+
: undefined,
|
|
95
|
+
onRename: onUpdate && isSavedViewEditable(view, savedViews)
|
|
96
|
+
? () => nameModal.openRename(view, (saving) => saveStatus.track(view.id, saving, view.name))
|
|
97
|
+
: undefined,
|
|
98
|
+
onSetDefault: onSetDefault && id !== undefined
|
|
99
|
+
? () => saveStatus.track(id, onSetDefault(id), view.name)
|
|
100
|
+
: undefined,
|
|
101
|
+
};
|
|
102
|
+
return hasSavedViewMenuActions(menuProps) ? (React__default.createElement(SavedViewMenu, { ...menuProps })) : null;
|
|
145
103
|
};
|
|
146
104
|
return (React__default.createElement("div", { ref: barRef, className: "tds-data-table-saved-views", onFocus: isReturningFocus ? handleFocus : undefined },
|
|
147
105
|
React__default.createElement("div", { className: "tds-data-table-saved-views-list" },
|
|
@@ -165,15 +123,17 @@ function SavedViewsBar({ defaultViewId, onApply, onCreate, onDelete, onSetDefaul
|
|
|
165
123
|
...props,
|
|
166
124
|
children: (React__default.createElement(React__default.Fragment, null,
|
|
167
125
|
view.name,
|
|
168
|
-
pin
|
|
126
|
+
pin,
|
|
127
|
+
React__default.createElement(SaveStatusIcon, { status: saveStatus.statusFor(view.id) }))),
|
|
169
128
|
};
|
|
170
129
|
return menu ? (React__default.createElement(ContextMenuTrigger, { id: view.id, closeOpenContextMenuRef: closeOpenContextMenuRef, menu: menu, optionProps: optionProps })) : (React__default.createElement("div", { ...optionProps }));
|
|
171
130
|
} }, view.name));
|
|
172
131
|
})),
|
|
173
132
|
onCreate && React__default.createElement(NewSavedViewButton, { onClick: openNewSavedView }),
|
|
174
|
-
React__default.createElement(
|
|
133
|
+
React__default.createElement(SaveStatusIcon, { label: "View not saved", status: saveStatus.statusFor(NEW_VIEW) }),
|
|
134
|
+
React__default.createElement(NewSavedViewModal, { ...nameModal.modalProps })),
|
|
175
135
|
views.length > 1 && (React__default.createElement(ManageSavedViewsButton, { onClick: () => setIsManageOpen(true) })),
|
|
176
|
-
React__default.createElement(ManageSavedViewsModal, { defaultViewId: defaultViewId, open: isManageOpen, savedViews: savedViews, staticViews:
|
|
136
|
+
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
137
|
onDelete && (React__default.createElement(DeleteSavedViewAlertDialog, { open: isDeleteAlertOpen, view: viewToDelete, onCancel: () => setIsDeleteAlertOpen(false), onConfirm: confirmDelete }))));
|
|
178
138
|
}
|
|
179
139
|
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":"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"}
|
|
1
|
+
{"version":3,"file":"SavedViewsBar.js","sources":["../../../src/components/DataTable/SavedViewsBar.tsx"],"sourcesContent":["import {\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 { 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\"\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 // 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 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 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 <SaveStatusIcon\n status={saveStatus.statusFor(view.id)}\n />\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 <SaveStatusIcon\n label=\"View not saved\"\n status={saveStatus.statusFor(NEW_VIEW)}\n />\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":"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"}
|
|
@@ -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
|
|
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
|
|
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
|
-
|
|
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
|
|
31
|
-
* are selected,
|
|
32
|
-
*
|
|
33
|
-
*
|
|
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
|
|
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 `
|
|
38
|
+
return `Actions for ${formatCount(count)} selected ${noun}`;
|
|
42
39
|
}
|
|
43
40
|
|
|
44
41
|
export { TableActions };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TableActions.js","sources":["../../../src/components/DataTable/TableActions.tsx"],"sourcesContent":["import { IconButton } from \"@components/button\"\nimport { ButtonGroup } from \"@components/button-group\"\nimport React, { type ReactNode } from \"react\"\n\nimport { formatCount, resolveNoun, type ResultNoun } from \"./ResultsCount\"\nimport {\n type DataTableSelection,\n useDataTableSelectionContext,\n} from \"./useDataTableSelection\"\n\n/**\n * A table action rendered as an `IconButton` in the button group above the\n * table. Replaces the original RFC's `{ buttonProps; callback }` shape with a\n * narrower, more controllable API so the design can evolve without exposing the\n * full button surface.\n */\nexport type TableAction<\n SelectionValue extends DataTableSelection = (number | string)[],\n> = {\n /** Called with the current selection when the action is triggered. */\n callback?: (selection: SelectionValue) => void\n /** Whether the action's button is disabled. */\n disabled?: boolean\n /** The icon rendered inside the action's icon button. */\n icon: ReactNode\n /** Accessible label for the icon-only action button. */\n label: string\n /** Standard click handler, invoked with the click event before `callback`. */\n onClick?: React.MouseEventHandler<HTMLButtonElement>\n}\n\nexport interface TableActionsProps {\n /** The table actions to render as an `IconButton` group. */\n actions: TableAction<DataTableSelection>[]\n /**\n * The noun used to describe the selection in
|
|
1
|
+
{"version":3,"file":"TableActions.js","sources":["../../../src/components/DataTable/TableActions.tsx"],"sourcesContent":["import { IconButton } from \"@components/button\"\nimport { ButtonGroup } from \"@components/button-group\"\nimport React, { type ReactNode } from \"react\"\n\nimport { formatCount, resolveNoun, type ResultNoun } from \"./ResultsCount\"\nimport {\n type DataTableSelection,\n useDataTableSelectionContext,\n} from \"./useDataTableSelection\"\n\n/**\n * A table action rendered as an `IconButton` in the button group above the\n * table. Replaces the original RFC's `{ buttonProps; callback }` shape with a\n * narrower, more controllable API so the design can evolve without exposing the\n * full button surface.\n */\nexport type TableAction<\n SelectionValue extends DataTableSelection = (number | string)[],\n> = {\n /** Called with the current selection when the action is triggered. */\n callback?: (selection: SelectionValue) => void\n /** Whether the action's button is disabled. */\n disabled?: boolean\n /** The icon rendered inside the action's icon button. */\n icon: ReactNode\n /** Accessible label for the icon-only action button. */\n label: string\n /** Standard click handler, invoked with the click event before `callback`. */\n onClick?: React.MouseEventHandler<HTMLButtonElement>\n}\n\nexport interface TableActionsProps {\n /** The table actions to render as an `IconButton` group. */\n actions: TableAction<DataTableSelection>[]\n /**\n * The noun used to describe the selection in the group's `aria-label`.\n * See {@link ResultNoun}.\n */\n resultNoun?: ResultNoun\n}\n\n/**\n * Renders the table actions as an `IconButton` group displayed directly after\n * the results count, above the table. Each entry becomes an icon button whose\n * `callback` receives the current selection. The group's label carries the\n * selected count, so screen readers announce it once on entering the group\n * rather than on every button.\n */\nexport const TableActions = ({ actions, resultNoun }: TableActionsProps) => {\n const { selectedCount, selection } = useDataTableSelectionContext()\n\n return (\n <ButtonGroup\n aria-label={getTableActionsGroupLabel(selectedCount, resultNoun)}\n >\n {actions.map(({ callback, disabled, icon, label, onClick }) => (\n <IconButton\n key={label}\n aria-label={label}\n disabled={disabled}\n icon={icon}\n onClick={(event) => {\n onClick?.(event)\n callback?.(selection)\n }}\n tooltip={label}\n tooltipPlacement=\"bottom\"\n />\n ))}\n </ButtonGroup>\n )\n}\n\nTableActions.displayName = \"TableActions\"\n\n/**\n * The table actions group's `aria-label`, e.g. `\"Actions for 2 selected\n * people\"` when rows are selected, or `\"Table actions\"` when nothing is\n * selected. Falls back to the default `\"result\"` noun when `resultNoun` isn't\n * provided.\n */\nfunction getTableActionsGroupLabel(\n count: number,\n resultNoun: ResultNoun | undefined\n): string {\n if (!count) return \"Table actions\"\n const noun = resolveNoun(count, resultNoun || true)\n return `Actions for ${formatCount(count)} selected ${noun}`\n}\n"],"names":["React"],"mappings":";;;;;;;;;;;;AAyCA;;;;;;AAMG;AACI,MAAM,YAAY,GAAG,CAAC,EAAE,OAAO,EAAE,UAAU,EAAqB,KAAI;IACzE,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,GAAG,4BAA4B,EAAE;IAEnE,QACEA,cAAA,CAAA,aAAA,CAAC,WAAW,EAAA,EAAA,YAAA,EACE,yBAAyB,CAAC,aAAa,EAAE,UAAU,CAAC,EAAA,EAE/D,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,MACxDA,cAAA,CAAA,aAAA,CAAC,UAAU,IACT,GAAG,EAAE,KAAK,EAAA,YAAA,EACE,KAAK,EACjB,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,CAAC,KAAK,KAAI;AACjB,YAAA,OAAO,GAAG,KAAK,CAAC;AAChB,YAAA,QAAQ,GAAG,SAAS,CAAC;AACvB,QAAA,CAAC,EACD,OAAO,EAAE,KAAK,EACd,gBAAgB,EAAC,QAAQ,EAAA,CACzB,CACH,CAAC,CACU;AAElB;AAEA,YAAY,CAAC,WAAW,GAAG,cAAc;AAEzC;;;;;AAKG;AACH,SAAS,yBAAyB,CAChC,KAAa,EACb,UAAkC,EAAA;AAElC,IAAA,IAAI,CAAC,KAAK;AAAE,QAAA,OAAO,eAAe;IAClC,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,EAAE,UAAU,IAAI,IAAI,CAAC;IACnD,OAAO,CAAA,YAAA,EAAe,WAAW,CAAC,KAAK,CAAC,CAAA,UAAA,EAAa,IAAI,EAAE;AAC7D;;;;"}
|
|
@@ -14,4 +14,6 @@ export type { PresenceActiveFilter, PresenceFilterConfig, PresenceFilterValue, P
|
|
|
14
14
|
export type { SavedView, StaticView } from "./savedViews";
|
|
15
15
|
export type { ScopedFilterConfig, ScopedFilterOptions } from "./scopedFilter";
|
|
16
16
|
export type { TextActiveFilter, TextFilterValue, TextOperatorName, } from "./textFilter";
|
|
17
|
+
export type { ApiClient, UseSavedViewsClientOptions, } from "./useSavedViewsClient";
|
|
18
|
+
export { useSavedViewsClient } from "./useSavedViewsClient";
|
|
17
19
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/index.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAA;AACpB,OAAO,eAAe,CAAA;AAEtB,YAAY,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAA;AACtE,YAAY,EACV,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,oBAAoB,CAAA;AAC3B,YAAY,EACV,qBAAqB,EACrB,qBAAqB,EACrB,cAAc,EACd,kBAAkB,EAClB,IAAI,GACL,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,YAAY,EACV,aAAa,EACb,cAAc,EACd,YAAY,EACZ,eAAe,EACf,oBAAoB,EACpB,mBAAmB,EACnB,UAAU,EACV,cAAc,EACd,UAAU,EACV,YAAY,EACZ,YAAY,GACb,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EACV,gBAAgB,EAChB,eAAe,EACf,gBAAgB,GACjB,MAAM,cAAc,CAAA;AACrB,YAAY,EACV,eAAe,EACf,cAAc,EACd,eAAe,GAChB,MAAM,aAAa,CAAA;AACpB,cAAc,WAAW,CAAA;AACzB,YAAY,EACV,YAAY,EACZ,iBAAiB,EACjB,gBAAgB,EAChB,UAAU,EACV,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,QAAQ,GACT,MAAM,eAAe,CAAA;AACtB,YAAY,EACV,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,gBAAgB,CAAA;AACvB,YAAY,EACV,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,kBAAkB,CAAA;AACzB,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzD,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAC7E,YAAY,EACV,gBAAgB,EAChB,eAAe,EACf,gBAAgB,GACjB,MAAM,cAAc,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/index.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAA;AACpB,OAAO,eAAe,CAAA;AAEtB,YAAY,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAA;AACtE,YAAY,EACV,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,oBAAoB,CAAA;AAC3B,YAAY,EACV,qBAAqB,EACrB,qBAAqB,EACrB,cAAc,EACd,kBAAkB,EAClB,IAAI,GACL,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,YAAY,EACV,aAAa,EACb,cAAc,EACd,YAAY,EACZ,eAAe,EACf,oBAAoB,EACpB,mBAAmB,EACnB,UAAU,EACV,cAAc,EACd,UAAU,EACV,YAAY,EACZ,YAAY,GACb,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EACV,gBAAgB,EAChB,eAAe,EACf,gBAAgB,GACjB,MAAM,cAAc,CAAA;AACrB,YAAY,EACV,eAAe,EACf,cAAc,EACd,eAAe,GAChB,MAAM,aAAa,CAAA;AACpB,cAAc,WAAW,CAAA;AACzB,YAAY,EACV,YAAY,EACZ,iBAAiB,EACjB,gBAAgB,EAChB,UAAU,EACV,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,QAAQ,GACT,MAAM,eAAe,CAAA;AACtB,YAAY,EACV,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,gBAAgB,CAAA;AACvB,YAAY,EACV,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,kBAAkB,CAAA;AACzB,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzD,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAC7E,YAAY,EACV,gBAAgB,EAChB,eAAe,EACf,gBAAgB,GACjB,MAAM,cAAc,CAAA;AACrB,YAAY,EACV,SAAS,EACT,0BAA0B,GAC3B,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"saveErrorMessage.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/saveErrorMessage.ts"],"names":[],"mappings":"AAEA,mDAAmD;AACnD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,UAG9C"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
const DEFAULT_MESSAGE = "Your change couldn't be saved. Try again.";
|
|
2
|
+
/** The rejection's message, else a generic one. */
|
|
3
|
+
function saveErrorMessage(error) {
|
|
4
|
+
const message = error?.message;
|
|
5
|
+
return typeof message === "string" && message ? message : DEFAULT_MESSAGE;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export { saveErrorMessage };
|
|
9
|
+
//# sourceMappingURL=saveErrorMessage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"saveErrorMessage.js","sources":["../../../src/components/DataTable/saveErrorMessage.ts"],"sourcesContent":["const DEFAULT_MESSAGE = \"Your change couldn't be saved. Try again.\"\n\n/** The rejection's message, else a generic one. */\nexport function saveErrorMessage(error: unknown) {\n const message = (error as { message?: unknown } | null)?.message\n return typeof message === \"string\" && message ? message : DEFAULT_MESSAGE\n}\n"],"names":[],"mappings":"AAAA,MAAM,eAAe,GAAG,2CAA2C;AAEnE;AACM,SAAU,gBAAgB,CAAC,KAAc,EAAA;AAC7C,IAAA,MAAM,OAAO,GAAI,KAAsC,EAAE,OAAO;AAChE,IAAA,OAAO,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,GAAG,OAAO,GAAG,eAAe;AAC3E;;;;"}
|