@planningcenter/tapestry 4.7.0 → 4.8.0-rc.1

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 (89) hide show
  1. package/dist/components/DataTable/ActiveFilterInstance.d.ts +2 -2
  2. package/dist/components/DataTable/ActiveFilterInstance.d.ts.map +1 -1
  3. package/dist/components/DataTable/ActiveFilterInstance.js +4 -1
  4. package/dist/components/DataTable/ActiveFilterInstance.js.map +1 -1
  5. package/dist/components/DataTable/ActiveFilters.d.ts +7 -4
  6. package/dist/components/DataTable/ActiveFilters.d.ts.map +1 -1
  7. package/dist/components/DataTable/ActiveFilters.js +43 -15
  8. package/dist/components/DataTable/ActiveFilters.js.map +1 -1
  9. package/dist/components/DataTable/DataTable.d.ts +1 -1
  10. package/dist/components/DataTable/DataTable.d.ts.map +1 -1
  11. package/dist/components/DataTable/DataTable.js +59 -56
  12. package/dist/components/DataTable/DataTable.js.map +1 -1
  13. package/dist/components/DataTable/FilterChip.d.ts.map +1 -1
  14. package/dist/components/DataTable/FilterChip.js +25 -1
  15. package/dist/components/DataTable/FilterChip.js.map +1 -1
  16. package/dist/components/DataTable/FilterContext.d.ts +10 -1
  17. package/dist/components/DataTable/FilterContext.d.ts.map +1 -1
  18. package/dist/components/DataTable/FilterContext.js +52 -9
  19. package/dist/components/DataTable/FilterContext.js.map +1 -1
  20. package/dist/components/DataTable/FilterControls.d.ts.map +1 -1
  21. package/dist/components/DataTable/FilterControls.js +81 -23
  22. package/dist/components/DataTable/FilterControls.js.map +1 -1
  23. package/dist/components/DataTable/FilterControls.module.css.js +4 -0
  24. package/dist/components/DataTable/FilterControls.module.css.js.map +1 -0
  25. package/dist/components/DataTable/FilterTypes.d.ts +34 -0
  26. package/dist/components/DataTable/FilterTypes.d.ts.map +1 -1
  27. package/dist/components/DataTable/FilterTypes.js +7 -0
  28. package/dist/components/DataTable/FilterTypes.js.map +1 -0
  29. package/dist/components/DataTable/PendingFilterContext.d.ts +12 -0
  30. package/dist/components/DataTable/PendingFilterContext.d.ts.map +1 -0
  31. package/dist/components/DataTable/PendingFilterContext.js +33 -0
  32. package/dist/components/DataTable/PendingFilterContext.js.map +1 -0
  33. package/dist/components/DataTable/PendingFilterQueue.d.ts +13 -0
  34. package/dist/components/DataTable/PendingFilterQueue.d.ts.map +1 -0
  35. package/dist/components/DataTable/PendingFilterQueue.js +42 -0
  36. package/dist/components/DataTable/PendingFilterQueue.js.map +1 -0
  37. package/dist/components/DataTable/SearchableFilters.d.ts +2 -0
  38. package/dist/components/DataTable/SearchableFilters.d.ts.map +1 -1
  39. package/dist/components/DataTable/SearchableFilters.js +3 -0
  40. package/dist/components/DataTable/SearchableFilters.js.map +1 -1
  41. package/dist/components/DataTable/collectionFilter.d.ts.map +1 -1
  42. package/dist/components/DataTable/collectionFilter.js +20 -6
  43. package/dist/components/DataTable/collectionFilter.js.map +1 -1
  44. package/dist/components/DataTable/dateFilter.d.ts.map +1 -1
  45. package/dist/components/DataTable/dateFilter.js +23 -7
  46. package/dist/components/DataTable/dateFilter.js.map +1 -1
  47. package/dist/components/DataTable/filters.d.ts +1 -0
  48. package/dist/components/DataTable/filters.d.ts.map +1 -1
  49. package/dist/components/DataTable/index.d.ts +2 -1
  50. package/dist/components/DataTable/index.d.ts.map +1 -1
  51. package/dist/components/DataTable/numberFilter.d.ts.map +1 -1
  52. package/dist/components/DataTable/numberFilter.js +15 -4
  53. package/dist/components/DataTable/numberFilter.js.map +1 -1
  54. package/dist/components/DataTable/scopedFilter.d.ts +13 -0
  55. package/dist/components/DataTable/scopedFilter.d.ts.map +1 -0
  56. package/dist/components/DataTable/scopedFilter.js +114 -0
  57. package/dist/components/DataTable/scopedFilter.js.map +1 -0
  58. package/dist/components/DataTable/textFilter.d.ts.map +1 -1
  59. package/dist/components/DataTable/textFilter.js +8 -3
  60. package/dist/components/DataTable/textFilter.js.map +1 -1
  61. package/dist/components/DataTable/useShelfExpanded.d.ts +4 -3
  62. package/dist/components/DataTable/useShelfExpanded.d.ts.map +1 -1
  63. package/dist/components/DataTable/useShelfExpanded.js +16 -8
  64. package/dist/components/DataTable/useShelfExpanded.js.map +1 -1
  65. package/dist/components/DataTable/utils.d.ts +4 -0
  66. package/dist/components/DataTable/utils.d.ts.map +1 -0
  67. package/dist/components/DataTable/utils.js +13 -0
  68. package/dist/components/DataTable/utils.js.map +1 -0
  69. package/dist/components/currency-input/CurrencyInput.d.ts +51 -0
  70. package/dist/components/currency-input/CurrencyInput.d.ts.map +1 -0
  71. package/dist/components/currency-input/CurrencyInput.js +64 -0
  72. package/dist/components/currency-input/CurrencyInput.js.map +1 -0
  73. package/dist/components/currency-input/index.d.ts +4 -0
  74. package/dist/components/currency-input/index.d.ts.map +1 -0
  75. package/dist/components/popover/Popover.d.ts +12 -7
  76. package/dist/components/popover/Popover.d.ts.map +1 -1
  77. package/dist/components/popover/Popover.js +26 -4
  78. package/dist/components/popover/Popover.js.map +1 -1
  79. package/dist/reactRender.css +1800 -1585
  80. package/dist/reactRender.css.map +1 -1
  81. package/dist/reactRenderLegacy.css +1800 -1585
  82. package/dist/reactRenderLegacy.css.map +1 -1
  83. package/dist/unstable.css +442 -227
  84. package/dist/unstable.css.map +1 -1
  85. package/dist/unstable.d.ts +1 -0
  86. package/dist/unstable.d.ts.map +1 -1
  87. package/dist/unstable.js +2 -0
  88. package/dist/unstable.js.map +1 -1
  89. package/package.json +3 -3
@@ -2,7 +2,7 @@ import '../button/ActionsDropdownIconButton.js';
2
2
  import { Button } from '../button/Button.js';
3
3
  import '../button/DropdownButton.js';
4
4
  import '../button/DropdownIconButton.js';
5
- import '../button/IconButton.js';
5
+ import { IconButton } from '../button/IconButton.js';
6
6
  import '../button/LoadingButton.js';
7
7
  import '../button/PageHeaderActionsDropdownButton.js';
8
8
  import { ButtonGroup } from '../button-group/ButtonGroup.js';
@@ -10,63 +10,121 @@ import { DropdownSection, DropdownAction } from '../dropdown/Dropdown.js';
10
10
  import { Popover, PopoverTrigger, PopoverContent } from '../popover/Popover.js';
11
11
  import Icon from '../../utilities/Icon.js';
12
12
  import { useId } from '../../utilities/useId.js';
13
- import React__default, { useState, useMemo } from 'react';
13
+ import classNames from 'classnames';
14
+ import React__default, { useState, useRef, useMemo } from 'react';
14
15
  import { Autocomplete, SearchField } from 'react-aria-components';
15
16
  import { Input } from 'react-aria-components/Input';
16
17
  import { Label } from 'react-aria-components/Label';
17
18
  import { Menu, SubmenuTrigger, Popover as Popover$1 } from 'react-aria-components/Menu';
19
+ import { useAddFilterButtonRef } from './FilterContext.js';
20
+ import styles from './FilterControls.module.css.js';
21
+ import { PendingFilterQueue, useQueuePendingFilter, useIsFilterTaken } from './PendingFilterQueue.js';
18
22
  import { useSearchableFilters } from './SearchableFilters.js';
23
+ import { getDefaultOperatorName } from './utils.js';
19
24
 
20
25
  const NOOP_ACTION = () => { };
26
+ const useVisibleChildren = (group) => {
27
+ const isFilterTaken = useIsFilterTaken();
28
+ return group.children.filter((child) => isFilterNodeVisible(child, isFilterTaken));
29
+ };
30
+ function isFilterNodeVisible(node, isFilterTaken) {
31
+ if (node.children) {
32
+ return node.children.some((child) => isFilterNodeVisible(child, isFilterTaken));
33
+ }
34
+ return node.allowMultiple || !isFilterTaken(node.name);
35
+ }
21
36
  // Must be a dedicated component, not returned inline from `renderFilterItem`.
22
37
  // RAC clones an `id` onto whatever that function returns, and an inline
23
38
  // `SubmenuTrigger` has none of its own — the clone falls back to `item.id`,
24
39
  // colliding with the trigger child's own `id` and silently breaking it.
25
40
  function FilterSubmenu({ group }) {
41
+ const visibleChildren = useVisibleChildren(group);
42
+ if (visibleChildren.length === 0)
43
+ return null;
26
44
  return (React__default.createElement(SubmenuTrigger, null,
27
45
  React__default.createElement(DropdownAction, { className: "tds-data-table-filter-controls-submenu-trigger", id: group.label, onAction: NOOP_ACTION, textValue: group.label },
28
46
  React__default.createElement("span", { slot: "label" }, group.label),
29
47
  React__default.createElement(Icon, { "aria-hidden": true, className: "tds-data-table-filter-controls-submenu-chevron", slot: "suffix", symbol: "general#right-chevron" })),
30
48
  React__default.createElement(Popover$1, { className: "tds-dropdown-popover tds-data-table-filter-controls-submenu-popover", placement: "right top" },
31
- React__default.createElement(Menu, { "aria-label": group.label, className: "tds-data-table-filter-controls-submenu-list", items: group.children }, renderFilterItem))));
49
+ React__default.createElement(Menu, { "aria-label": group.label, className: "tds-data-table-filter-controls-submenu-list", items: visibleChildren }, renderFilterItem))));
50
+ }
51
+ function FilterItem({ node }) {
52
+ const queuePendingFilter = useQueuePendingFilter();
53
+ const isFilterTaken = useIsFilterTaken();
54
+ const hide = !node.allowMultiple && isFilterTaken(node.name);
55
+ if (hide)
56
+ return null;
57
+ return (React__default.createElement(DropdownAction, { key: node.name, id: node.name, onAction: () => queuePendingFilter({
58
+ name: node.name,
59
+ operator: getDefaultOperatorName(node),
60
+ value: undefined,
61
+ }), textValue: node.label },
62
+ React__default.createElement("span", { slot: "label" }, node.label)));
63
+ }
64
+ function FilterGroupSection({ group }) {
65
+ const visibleChildren = useVisibleChildren(group);
66
+ if (visibleChildren.length === 0)
67
+ return null;
68
+ return (React__default.createElement(DropdownSection, { id: group.label, title: group.label }, visibleChildren.map(renderFilterItem)));
32
69
  }
33
70
  function renderFilterItem(node) {
34
71
  if (node.children) {
35
72
  if (node.renderChildrenInSubmenu) {
36
73
  return React__default.createElement(FilterSubmenu, { key: node.label, group: node });
37
74
  }
38
- return (React__default.createElement(DropdownSection, { key: node.label, id: node.label, title: node.label }, node.children.map(renderFilterItem)));
75
+ return React__default.createElement(FilterGroupSection, { key: node.label, group: node });
39
76
  }
40
- return (React__default.createElement(DropdownAction, { key: node.name, id: node.name, onAction: NOOP_ACTION, textValue: node.label },
41
- React__default.createElement("span", { slot: "label" }, node.label)));
77
+ return React__default.createElement(FilterItem, { key: node.name, node: node });
42
78
  }
43
79
  /** Skeleton for the DataTable filters cluster — grows incrementally. */
44
80
  function FilterControls({ activeFilters = [], filters, isShelfExpanded = false, onToggleShelf = () => { }, }) {
45
81
  const searchInputId = `tds-data-table-filter-controls-search-${useId()}`;
46
82
  const [searchQuery, setSearchQuery] = useState("");
83
+ const addFilterButtonRef = useAddFilterButtonRef();
84
+ const searchInputRef = useRef(null);
47
85
  return (React__default.createElement(ButtonGroup, { "aria-label": "Filters", className: "tds-data-table-filter-controls" },
48
- React__default.createElement(Popover, null,
86
+ React__default.createElement(Popover, { onOpenChange: (open) => {
87
+ if (open)
88
+ setSearchQuery("");
89
+ } },
49
90
  React__default.createElement(PopoverTrigger, null,
50
- React__default.createElement(Button, { label: "Add filter", prefix: React__default.createElement(Icon, { "aria-hidden": true, symbol: "general#three-reducing-horizontal-bars" }) })),
91
+ React__default.createElement(Button, { ref: addFilterButtonRef, label: "Add filter", prefix: React__default.createElement(Icon, { "aria-hidden": true, symbol: "general#three-reducing-horizontal-bars" }) })),
51
92
  React__default.createElement(PopoverContent, { className: "tds-data-table-popover", placement: "bottom" },
52
- React__default.createElement(Autocomplete, { filter: prefixSearch },
53
- React__default.createElement(SearchField, null,
54
- React__default.createElement(Label, { className: "tds-data-table-filter-controls-label--hidden", htmlFor: searchInputId }, "Search filters"),
55
- React__default.createElement("div", { className: "tds-data-table-filter-controls-search-input-sticky" },
56
- React__default.createElement(Input, { id: searchInputId, placeholder: "Search filters", className: "tds-data-table-filter-controls-search-input", value: searchQuery, onChange: (e) => {
57
- setSearchQuery(e.target.value);
58
- } }))),
59
- React__default.createElement(Menu, { "aria-label": "Filters", items: filters, className: "tds-data-table-filter-controls-list", renderEmptyState: () => "No filters match" }, searchQuery.length ? React__default.createElement(SearchResults, null) : renderFilterItem)))),
93
+ React__default.createElement(PendingFilterQueue, null,
94
+ React__default.createElement(Autocomplete, { filter: prefixSearch, inputValue: searchQuery, onInputChange: setSearchQuery },
95
+ React__default.createElement(SearchField, { className: "tds-data-table-filter-controls-search-input-sticky" },
96
+ React__default.createElement(Label, { className: "tds-data-table-filter-controls-label--hidden", htmlFor: searchInputId }, "Search filters"),
97
+ React__default.createElement("div", { className: classNames("tds-data-table-filter-controls-search-input-control", {
98
+ "tds-data-table-filter-controls-search-input-control--has-value": searchQuery.length > 0,
99
+ }) },
100
+ React__default.createElement(Icon, { "aria-hidden": true, className: "tds-data-table-filter-controls-search-input-icon", symbol: "general#search" }),
101
+ React__default.createElement(Input, { id: searchInputId, placeholder: "Search filters", className: "tds-data-table-filter-controls-search-input", ref: searchInputRef,
102
+ // eslint-disable-next-line jsx-a11y/no-autofocus
103
+ autoFocus: true }),
104
+ React__default.createElement(IconButton, { "aria-label": "Clear", icon: React__default.createElement(Icon, { "aria-hidden": true, className: "tds-data-table-filter-controls-search-input-clear-icon", symbol: "general#x" }), kind: "neutral-inline", onClick: () => {
105
+ setSearchQuery("");
106
+ searchInputRef.current?.focus();
107
+ }, tabIndex: -1 }))),
108
+ React__default.createElement(Menu, { "aria-label": "Filters", items: filters, className: "tds-data-table-filter-controls-list", renderEmptyState: () => (React__default.createElement("span", { className: "tds-dropdown-item" }, "No filters match")) }, searchQuery.length ? React__default.createElement(SearchResults, null) : renderFilterItem))))),
60
109
  activeFilters.length > 0 && (React__default.createElement(Button, { "aria-expanded": isShelfExpanded, "aria-label": `${activeFilters.length} active filter${activeFilters.length === 1 ? "" : "s"}`, label: React__default.createElement("span", { className: "tds-data-table-filter-controls-badge" }, activeFilters.length), onClick: onToggleShelf }))));
61
110
  }
62
111
  FilterControls.displayName = "FilterControls";
63
- function renderSearchResultItem(filter) {
112
+ function SearchResultItem({ filter }) {
113
+ const queuePendingFilter = useQueuePendingFilter();
114
+ const isFilterTaken = useIsFilterTaken();
115
+ const hide = !filter.allowMultiple && isFilterTaken(filter.name);
116
+ if (hide)
117
+ return null;
64
118
  const [, ...remainingGrouping] = filter.grouping;
65
- return (React__default.createElement(DropdownAction, { key: filter.name, textValue: filter.searchable, id: `filter-search-${filter.name}`, onAction: NOOP_ACTION },
119
+ return (React__default.createElement(DropdownAction, { key: filter.name, textValue: filter.searchable, id: `filter-search-${filter.name}`, onAction: () => queuePendingFilter({
120
+ name: filter.name,
121
+ operator: filter.operator,
122
+ value: undefined,
123
+ }) },
66
124
  React__default.createElement("span", { slot: "label" },
67
- remainingGrouping.length > 0 && (React__default.createElement("span", { className: "tds-data-table-filter-controls-grouping", style: { color: "crimson" } },
68
- remainingGrouping.join(" > "),
69
- " > ")),
125
+ remainingGrouping.length > 0 && (React__default.createElement("span", { className: styles["search-result-grouping"] }, remainingGrouping.map((grouping, index) => (React__default.createElement("span", { className: styles["search-result-grouping-chevron"], key: `${grouping}-${index}` },
126
+ grouping,
127
+ React__default.createElement("span", { className: styles["search-result-grouping-separator"] }, ", ")))))),
70
128
  filter.label)));
71
129
  }
72
130
  function SearchResults() {
@@ -83,8 +141,8 @@ function SearchResults() {
83
141
  return { groups: groupedItems, ungrouped: ungroupedItems };
84
142
  }, [filters]);
85
143
  return (React__default.createElement(React__default.Fragment, null,
86
- ungrouped.map(renderSearchResultItem),
87
- Array.from(groups, ([groupLabel, items]) => (React__default.createElement(DropdownSection, { key: groupLabel, id: groupLabel, title: groupLabel }, items.map(renderSearchResultItem))))));
144
+ ungrouped.map((filter) => (React__default.createElement(SearchResultItem, { key: filter.name, filter: filter }))),
145
+ Array.from(groups, ([groupLabel, items]) => (React__default.createElement(DropdownSection, { key: groupLabel, id: groupLabel, title: groupLabel }, items.map((filter) => (React__default.createElement(SearchResultItem, { key: filter.name, filter: filter }))))))));
88
146
  }
89
147
  function prefixSearch(string, query) {
90
148
  if (query.length === 0) {
@@ -1 +1 @@
1
- {"version":3,"file":"FilterControls.js","sources":["../../../src/components/DataTable/FilterControls.tsx"],"sourcesContent":["import { Button } from \"@components/button\"\nimport { ButtonGroup } from \"@components/button-group\"\nimport { DropdownAction, DropdownSection } from \"@components/dropdown\"\nimport { Popover, PopoverContent, PopoverTrigger } from \"@components/popover\"\nimport Icon from \"@utilities/Icon\"\nimport { useId } from \"@utilities/useId\"\nimport React, { type ReactElement, useMemo, useState } from \"react\"\nimport { Autocomplete, SearchField } from \"react-aria-components\"\nimport { Input } from \"react-aria-components/Input\"\nimport { Label } from \"react-aria-components/Label\"\nimport {\n Menu,\n Popover as AriaPopover,\n SubmenuTrigger,\n} from \"react-aria-components/Menu\"\n\nimport type { ActiveFilter, FilterNode, FilterNodeGroup } from \"./FilterTypes\"\nimport type { SearchableSimpleFilterItem } from \"./SearchableFilters\"\nimport { useSearchableFilters } from \"./SearchableFilters\"\n\nconst NOOP_ACTION = () => {}\n\n// Must be a dedicated component, not returned inline from `renderFilterItem`.\n// RAC clones an `id` onto whatever that function returns, and an inline\n// `SubmenuTrigger` has none of its own — the clone falls back to `item.id`,\n// colliding with the trigger child's own `id` and silently breaking it.\nfunction FilterSubmenu({ group }: { group: FilterNodeGroup }) {\n return (\n <SubmenuTrigger>\n <DropdownAction\n className=\"tds-data-table-filter-controls-submenu-trigger\"\n id={group.label}\n onAction={NOOP_ACTION}\n textValue={group.label}\n >\n <span slot=\"label\">{group.label}</span>\n <Icon\n aria-hidden\n className=\"tds-data-table-filter-controls-submenu-chevron\"\n slot=\"suffix\"\n symbol=\"general#right-chevron\"\n />\n </DropdownAction>\n <AriaPopover\n className=\"tds-dropdown-popover tds-data-table-filter-controls-submenu-popover\"\n placement=\"right top\"\n >\n <Menu\n aria-label={group.label}\n className=\"tds-data-table-filter-controls-submenu-list\"\n items={group.children}\n >\n {renderFilterItem}\n </Menu>\n </AriaPopover>\n </SubmenuTrigger>\n )\n}\n\nfunction renderFilterItem(node: FilterNode): ReactElement {\n if (node.children) {\n if (node.renderChildrenInSubmenu) {\n return <FilterSubmenu key={node.label} group={node} />\n }\n\n return (\n <DropdownSection key={node.label} id={node.label} title={node.label}>\n {node.children.map(renderFilterItem)}\n </DropdownSection>\n )\n }\n\n return (\n <DropdownAction\n key={node.name}\n id={node.name}\n onAction={NOOP_ACTION}\n textValue={node.label}\n >\n <span slot=\"label\">{node.label}</span>\n </DropdownAction>\n )\n}\n\nexport interface FilterControlsProps {\n /** The currently active filters. The toggle button only renders when this is non-empty. */\n activeFilters?: ActiveFilter[]\n filters: FilterNode[]\n /** Whether the filters shelf is currently expanded. */\n isShelfExpanded?: boolean\n /** Called when the toggle button is pressed. */\n onToggleShelf?: () => void\n}\n\n/** Skeleton for the DataTable filters cluster — grows incrementally. */\nexport function FilterControls({\n activeFilters = [],\n filters,\n isShelfExpanded = false,\n onToggleShelf = () => {},\n}: FilterControlsProps) {\n const searchInputId = `tds-data-table-filter-controls-search-${useId()}`\n const [searchQuery, setSearchQuery] = useState(\"\")\n\n return (\n <ButtonGroup\n aria-label=\"Filters\"\n className=\"tds-data-table-filter-controls\"\n >\n <Popover>\n <PopoverTrigger>\n <Button\n label=\"Add filter\"\n prefix={\n <Icon\n aria-hidden\n symbol=\"general#three-reducing-horizontal-bars\"\n />\n }\n />\n </PopoverTrigger>\n <PopoverContent className=\"tds-data-table-popover\" placement=\"bottom\">\n <Autocomplete filter={prefixSearch}>\n <SearchField>\n <Label\n className=\"tds-data-table-filter-controls-label--hidden\"\n htmlFor={searchInputId}\n >\n Search filters\n </Label>\n <div className=\"tds-data-table-filter-controls-search-input-sticky\">\n <Input\n id={searchInputId}\n placeholder=\"Search filters\"\n className=\"tds-data-table-filter-controls-search-input\"\n value={searchQuery}\n onChange={(e) => {\n setSearchQuery(e.target.value)\n }}\n />\n </div>\n </SearchField>\n <Menu\n aria-label=\"Filters\"\n items={filters}\n className=\"tds-data-table-filter-controls-list\"\n renderEmptyState={() => \"No filters match\"}\n >\n {searchQuery.length ? <SearchResults /> : renderFilterItem}\n </Menu>\n </Autocomplete>\n </PopoverContent>\n </Popover>\n {activeFilters.length > 0 && (\n <Button\n aria-expanded={isShelfExpanded}\n aria-label={`${activeFilters.length} active filter${\n activeFilters.length === 1 ? \"\" : \"s\"\n }`}\n label={\n <span className=\"tds-data-table-filter-controls-badge\">\n {activeFilters.length}\n </span>\n }\n onClick={onToggleShelf}\n />\n )}\n </ButtonGroup>\n )\n}\n\nFilterControls.displayName = \"FilterControls\"\n\nfunction renderSearchResultItem(filter: SearchableSimpleFilterItem) {\n const [, ...remainingGrouping] = filter.grouping\n\n return (\n <DropdownAction\n key={filter.name}\n textValue={filter.searchable}\n id={`filter-search-${filter.name}`}\n onAction={NOOP_ACTION}\n >\n <span slot=\"label\">\n {remainingGrouping.length > 0 && (\n <span\n className=\"tds-data-table-filter-controls-grouping\"\n style={{ color: \"crimson\" }}\n >\n {remainingGrouping.join(\" > \")}\n {\" > \"}\n </span>\n )}\n {filter.label}\n </span>\n </DropdownAction>\n )\n}\n\nfunction SearchResults() {\n const filters = useSearchableFilters()\n\n const { groups, ungrouped } = useMemo(() => {\n const ungroupedItems = filters.filter((f) => f.grouping.length === 0)\n const groupedItems = new Map<string, SearchableSimpleFilterItem[]>()\n filters.forEach((filter) => {\n const [heading] = filter.grouping\n if (!heading) return\n groupedItems.set(heading, [...(groupedItems.get(heading) ?? []), filter])\n })\n return { groups: groupedItems, ungrouped: ungroupedItems }\n }, [filters])\n\n return (\n <>\n {ungrouped.map(renderSearchResultItem)}\n {Array.from(groups, ([groupLabel, items]) => (\n <DropdownSection key={groupLabel} id={groupLabel} title={groupLabel}>\n {items.map(renderSearchResultItem)}\n </DropdownSection>\n ))}\n </>\n )\n}\n\nfunction prefixSearch(string: string, query: string): boolean {\n if (query.length === 0) {\n return true\n }\n\n const segments = query.normalize(\"NFC\").toLowerCase().split(/\\s+/)\n return segments.every((segment) => string.includes(segment))\n}\n"],"names":["React","AriaPopover"],"mappings":"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"}
1
+ {"version":3,"file":"FilterControls.js","sources":["../../../src/components/DataTable/FilterControls.tsx"],"sourcesContent":["import { Button, IconButton } from \"@components/button\"\nimport { ButtonGroup } from \"@components/button-group\"\nimport { DropdownAction, DropdownSection } from \"@components/dropdown\"\nimport { Popover, PopoverContent, PopoverTrigger } from \"@components/popover\"\nimport Icon from \"@utilities/Icon\"\nimport { useId } from \"@utilities/useId\"\nimport classNames from \"classnames\"\nimport React, { type ReactElement, useMemo, useRef, useState } from \"react\"\nimport { Autocomplete, SearchField } from \"react-aria-components\"\nimport { Input } from \"react-aria-components/Input\"\nimport { Label } from \"react-aria-components/Label\"\nimport {\n Menu,\n Popover as AriaPopover,\n SubmenuTrigger,\n} from \"react-aria-components/Menu\"\n\nimport { useAddFilterButtonRef } from \"./FilterContext\"\nimport styles from \"./FilterControls.module.css\"\nimport type {\n ActiveFilter,\n FilterNode,\n FilterNodeGroup,\n FilterNodeItem,\n} from \"./FilterTypes\"\nimport {\n PendingFilterQueue,\n useIsFilterTaken,\n useQueuePendingFilter,\n} from \"./PendingFilterQueue\"\nimport type { SearchableSimpleFilterItem } from \"./SearchableFilters\"\nimport { useSearchableFilters } from \"./SearchableFilters\"\nimport { getDefaultOperatorName } from \"./utils\"\n\nconst NOOP_ACTION = () => {}\n\nconst useVisibleChildren = (group: FilterNodeGroup) => {\n const isFilterTaken = useIsFilterTaken()\n return group.children.filter((child) =>\n isFilterNodeVisible(child, isFilterTaken)\n )\n}\n\nfunction isFilterNodeVisible(\n node: FilterNode,\n isFilterTaken: (name: string) => boolean\n): boolean {\n if (node.children) {\n return node.children.some((child) =>\n isFilterNodeVisible(child, isFilterTaken)\n )\n }\n\n return node.allowMultiple || !isFilterTaken(node.name)\n}\n\n// Must be a dedicated component, not returned inline from `renderFilterItem`.\n// RAC clones an `id` onto whatever that function returns, and an inline\n// `SubmenuTrigger` has none of its own — the clone falls back to `item.id`,\n// colliding with the trigger child's own `id` and silently breaking it.\nfunction FilterSubmenu({ group }: { group: FilterNodeGroup }) {\n const visibleChildren = useVisibleChildren(group)\n\n if (visibleChildren.length === 0) return null\n\n return (\n <SubmenuTrigger>\n <DropdownAction\n className=\"tds-data-table-filter-controls-submenu-trigger\"\n id={group.label}\n onAction={NOOP_ACTION}\n textValue={group.label}\n >\n <span slot=\"label\">{group.label}</span>\n <Icon\n aria-hidden\n className=\"tds-data-table-filter-controls-submenu-chevron\"\n slot=\"suffix\"\n symbol=\"general#right-chevron\"\n />\n </DropdownAction>\n <AriaPopover\n className=\"tds-dropdown-popover tds-data-table-filter-controls-submenu-popover\"\n placement=\"right top\"\n >\n <Menu\n aria-label={group.label}\n className=\"tds-data-table-filter-controls-submenu-list\"\n items={visibleChildren}\n >\n {renderFilterItem}\n </Menu>\n </AriaPopover>\n </SubmenuTrigger>\n )\n}\n\nfunction FilterItem({ node }: { node: FilterNodeItem }) {\n const queuePendingFilter = useQueuePendingFilter()\n const isFilterTaken = useIsFilterTaken()\n const hide = !node.allowMultiple && isFilterTaken(node.name)\n\n if (hide) return null\n\n return (\n <DropdownAction\n key={node.name}\n id={node.name}\n onAction={() =>\n queuePendingFilter({\n name: node.name,\n operator: getDefaultOperatorName(node),\n value: undefined,\n })\n }\n textValue={node.label}\n >\n <span slot=\"label\">{node.label}</span>\n </DropdownAction>\n )\n}\n\nfunction FilterGroupSection({ group }: { group: FilterNodeGroup }) {\n const visibleChildren = useVisibleChildren(group)\n\n if (visibleChildren.length === 0) return null\n\n return (\n <DropdownSection id={group.label} title={group.label}>\n {visibleChildren.map(renderFilterItem)}\n </DropdownSection>\n )\n}\n\nfunction renderFilterItem(node: FilterNode): ReactElement {\n if (node.children) {\n if (node.renderChildrenInSubmenu) {\n return <FilterSubmenu key={node.label} group={node} />\n }\n\n return <FilterGroupSection key={node.label} group={node} />\n }\n\n return <FilterItem key={node.name} node={node} />\n}\n\nexport interface FilterControlsProps {\n /** The currently active filters. The toggle button only renders when this is non-empty. */\n activeFilters?: ActiveFilter[]\n filters: FilterNode[]\n /** Whether the filters shelf is currently expanded. */\n isShelfExpanded?: boolean\n /** Called when the toggle button is pressed. */\n onToggleShelf?: () => void\n}\n\n/** Skeleton for the DataTable filters cluster — grows incrementally. */\nexport function FilterControls({\n activeFilters = [],\n filters,\n isShelfExpanded = false,\n onToggleShelf = () => {},\n}: FilterControlsProps) {\n const searchInputId = `tds-data-table-filter-controls-search-${useId()}`\n const [searchQuery, setSearchQuery] = useState(\"\")\n const addFilterButtonRef = useAddFilterButtonRef()\n const searchInputRef = useRef<HTMLInputElement | null>(null)\n\n return (\n <ButtonGroup\n aria-label=\"Filters\"\n className=\"tds-data-table-filter-controls\"\n >\n <Popover\n onOpenChange={(open) => {\n if (open) setSearchQuery(\"\")\n }}\n >\n <PopoverTrigger>\n <Button\n ref={addFilterButtonRef}\n label=\"Add filter\"\n prefix={\n <Icon\n aria-hidden\n symbol=\"general#three-reducing-horizontal-bars\"\n />\n }\n />\n </PopoverTrigger>\n <PopoverContent className=\"tds-data-table-popover\" placement=\"bottom\">\n <PendingFilterQueue>\n <Autocomplete\n filter={prefixSearch}\n inputValue={searchQuery}\n onInputChange={setSearchQuery}\n >\n <SearchField className=\"tds-data-table-filter-controls-search-input-sticky\">\n <Label\n className=\"tds-data-table-filter-controls-label--hidden\"\n htmlFor={searchInputId}\n >\n Search filters\n </Label>\n <div\n className={classNames(\n \"tds-data-table-filter-controls-search-input-control\",\n {\n \"tds-data-table-filter-controls-search-input-control--has-value\":\n searchQuery.length > 0,\n }\n )}\n >\n <Icon\n aria-hidden\n className=\"tds-data-table-filter-controls-search-input-icon\"\n symbol=\"general#search\"\n />\n <Input\n id={searchInputId}\n placeholder=\"Search filters\"\n className=\"tds-data-table-filter-controls-search-input\"\n ref={searchInputRef}\n // eslint-disable-next-line jsx-a11y/no-autofocus\n autoFocus\n />\n <IconButton\n aria-label=\"Clear\"\n icon={\n <Icon\n aria-hidden\n className=\"tds-data-table-filter-controls-search-input-clear-icon\"\n symbol=\"general#x\"\n />\n }\n kind=\"neutral-inline\"\n onClick={() => {\n setSearchQuery(\"\")\n searchInputRef.current?.focus()\n }}\n tabIndex={-1}\n />\n </div>\n </SearchField>\n <Menu\n aria-label=\"Filters\"\n items={filters}\n className=\"tds-data-table-filter-controls-list\"\n renderEmptyState={() => (\n <span className=\"tds-dropdown-item\">No filters match</span>\n )}\n >\n {searchQuery.length ? <SearchResults /> : renderFilterItem}\n </Menu>\n </Autocomplete>\n </PendingFilterQueue>\n </PopoverContent>\n </Popover>\n {activeFilters.length > 0 && (\n <Button\n aria-expanded={isShelfExpanded}\n aria-label={`${activeFilters.length} active filter${\n activeFilters.length === 1 ? \"\" : \"s\"\n }`}\n label={\n <span className=\"tds-data-table-filter-controls-badge\">\n {activeFilters.length}\n </span>\n }\n onClick={onToggleShelf}\n />\n )}\n </ButtonGroup>\n )\n}\n\nFilterControls.displayName = \"FilterControls\"\n\nfunction SearchResultItem({ filter }: { filter: SearchableSimpleFilterItem }) {\n const queuePendingFilter = useQueuePendingFilter()\n const isFilterTaken = useIsFilterTaken()\n const hide = !filter.allowMultiple && isFilterTaken(filter.name)\n\n if (hide) return null\n\n const [, ...remainingGrouping] = filter.grouping\n\n return (\n <DropdownAction\n key={filter.name}\n textValue={filter.searchable}\n id={`filter-search-${filter.name}`}\n onAction={() =>\n queuePendingFilter({\n name: filter.name,\n operator: filter.operator,\n value: undefined,\n })\n }\n >\n <span slot=\"label\">\n {remainingGrouping.length > 0 && (\n <span className={styles[\"search-result-grouping\"]}>\n {remainingGrouping.map((grouping, index) => (\n <span\n className={styles[\"search-result-grouping-chevron\"]}\n key={`${grouping}-${index}`}\n >\n {grouping}\n <span className={styles[\"search-result-grouping-separator\"]}>\n {\", \"}\n </span>\n </span>\n ))}\n </span>\n )}\n {filter.label}\n </span>\n </DropdownAction>\n )\n}\n\nfunction SearchResults() {\n const filters = useSearchableFilters()\n\n const { groups, ungrouped } = useMemo(() => {\n const ungroupedItems = filters.filter((f) => f.grouping.length === 0)\n const groupedItems = new Map<string, SearchableSimpleFilterItem[]>()\n filters.forEach((filter) => {\n const [heading] = filter.grouping\n if (!heading) return\n groupedItems.set(heading, [...(groupedItems.get(heading) ?? []), filter])\n })\n return { groups: groupedItems, ungrouped: ungroupedItems }\n }, [filters])\n\n return (\n <>\n {ungrouped.map((filter) => (\n <SearchResultItem key={filter.name} filter={filter} />\n ))}\n {Array.from(groups, ([groupLabel, items]) => (\n <DropdownSection key={groupLabel} id={groupLabel} title={groupLabel}>\n {items.map((filter) => (\n <SearchResultItem key={filter.name} filter={filter} />\n ))}\n </DropdownSection>\n ))}\n </>\n )\n}\n\nfunction prefixSearch(string: string, query: string): boolean {\n if (query.length === 0) {\n return true\n }\n\n const segments = query.normalize(\"NFC\").toLowerCase().split(/\\s+/)\n return segments.every((segment) => string.includes(segment))\n}\n"],"names":["React","AriaPopover"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ var styles = {"search-result-grouping":"search-result-grouping-4F5Lx","search-result-grouping-chevron":"search-result-grouping-chevron--AUkV","search-result-grouping-separator":"search-result-grouping-separator-dKnTA"};
2
+
3
+ export { styles as default };
4
+ //# sourceMappingURL=FilterControls.module.css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FilterControls.module.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
@@ -12,6 +12,8 @@ export interface Operator {
12
12
  name: string;
13
13
  }
14
14
  export interface FilterNodeItem extends FilterNodeBase {
15
+ /** Whether multiple instances of this filter can be active simultaneously. */
16
+ allowMultiple?: boolean;
15
17
  children?: never;
16
18
  /** Binds this filter to one active filter's operator and value. Supplied by the filter factories. */
17
19
  createActiveFilterInstance: (activeFilter: ActiveFilter, operator: Operator) => ActiveFilterInstance;
@@ -27,6 +29,20 @@ export interface FilterNodeItem extends FilterNodeBase {
27
29
  name: string;
28
30
  operators: Operator[];
29
31
  }
32
+ /**
33
+ * A filter that delegates to one of several other filters, chosen by an active
34
+ * filter's `scope` (see `scopedFilter`). The scoped filter supplies the
35
+ * `operator` and `value`, while this one still labels the chip.
36
+ *
37
+ * Distinct from a group's `children`: those render side by side in the menu,
38
+ * while these are alternatives the user picks between one at a time.
39
+ */
40
+ export interface FilterNodeScoped extends FilterNodeItem {
41
+ /** The filters a `scope` selects from, keyed by their own `name`. */
42
+ options: FilterNodeItem[];
43
+ }
44
+ /** Whether a filter delegates to scoped options. */
45
+ export declare function isScopedFilter(filter: FilterNodeItem): filter is FilterNodeScoped;
30
46
  export interface FilterNodeGroup extends FilterNodeBase {
31
47
  /** Filters and nested groups, in display order. */
32
48
  children: FilterNode[];
@@ -48,15 +64,33 @@ export type OperatorSelection<Name extends string = string> = {
48
64
  };
49
65
  export type FilterItemConfig<Name extends string = string> = Omit<FilterNodeItem, "createActiveFilterInstance" | "operators"> & OperatorSelection<Name>;
50
66
  export type UpdateActiveFilter = (updates: Partial<ActiveFilter>) => void;
67
+ /**
68
+ * How an editor reports a change, along with whether the filter can now be
69
+ * applied. Editors know this; callers would otherwise have to infer it from
70
+ * the shape of the update.
71
+ *
72
+ * `complete` defaults to true, so an editor reporting a finished value says
73
+ * nothing extra — only partial states need flagging.
74
+ */
75
+ export type FilterChange = (updates: Partial<ActiveFilter>, state?: {
76
+ complete?: boolean;
77
+ }) => void;
51
78
  export interface ActiveFilter<T = unknown> {
52
79
  /** The HTML name of the applied filter. Connects to the name of the filter. */
53
80
  name: string;
54
81
  /** The operator used by the applied filter. Corresponds to the name of the operator in the filter configuration. */
55
82
  operator: string;
83
+ /**
84
+ * For scoped filters only: which of the parent's options is selected. The
85
+ * `operator` and `value` then belong to that option's filter rather than to
86
+ * the parent, so both are resolved against the scoped filter.
87
+ */
88
+ scope?: string;
56
89
  /**
57
90
  * The value of the applied filter. Can be of any type depending on the filter configuration.
58
91
  * TODO: Add more specific typing based on the operator and input type.
59
92
  */
60
93
  value: T;
61
94
  }
95
+ export type AddPendingFilterFn = (filter: ActiveFilter) => void;
62
96
  //# sourceMappingURL=FilterTypes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"FilterTypes.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/FilterTypes.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAElE,MAAM,WAAW,cAAc;IAC7B,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,SAAS,CAAA;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,cAAe,SAAQ,cAAc;IACpD,QAAQ,CAAC,EAAE,KAAK,CAAA;IAChB,qGAAqG;IACrG,0BAA0B,EAAE,CAC1B,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,QAAQ,KACf,oBAAoB,CAAA;IACzB,gFAAgF;IAChF,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAA;IACb;;;;OAIG;IACH,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,QAAQ,EAAE,CAAA;CACtB;AAED,MAAM,WAAW,eAAgB,SAAQ,cAAc;IACrD,mDAAmD;IACnD,QAAQ,EAAE,UAAU,EAAE,CAAA;IACtB,WAAW,CAAC,EAAE,KAAK,CAAA;IACnB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,gDAAgD;IAChD,KAAK,EAAE,MAAM,CAAA;IACb,gEAAgE;IAChE,uBAAuB,CAAC,EAAE,OAAO,CAAA;CAClC;AAED,MAAM,MAAM,UAAU,GAAG,cAAc,GAAG,eAAe,CAAA;AAEzD,qIAAqI;AACrI,MAAM,MAAM,iBAAiB,CAAC,IAAI,SAAS,MAAM,GAAG,MAAM,IACtD;IAAE,QAAQ,CAAC,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAA;CAAE,GACvC;IAAE,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAC;IAAC,QAAQ,CAAC,EAAE,KAAK,CAAA;CAAE,CAAA;AAE3C,MAAM,MAAM,gBAAgB,CAAC,IAAI,SAAS,MAAM,GAAG,MAAM,IAAI,IAAI,CAC/D,cAAc,EACd,4BAA4B,GAAG,WAAW,CAC3C,GACC,iBAAiB,CAAC,IAAI,CAAC,CAAA;AAEzB,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,KAAK,IAAI,CAAA;AAEzE,MAAM,WAAW,YAAY,CAAC,CAAC,GAAG,OAAO;IACvC,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAA;IACZ,qHAAqH;IACrH,QAAQ,EAAE,MAAM,CAAA;IAChB;;;OAGG;IACH,KAAK,EAAE,CAAC,CAAA;CACT"}
1
+ {"version":3,"file":"FilterTypes.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/FilterTypes.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAElE,MAAM,WAAW,cAAc;IAC7B,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,SAAS,CAAA;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,cAAe,SAAQ,cAAc;IACpD,8EAA8E;IAC9E,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,EAAE,KAAK,CAAA;IAChB,qGAAqG;IACrG,0BAA0B,EAAE,CAC1B,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,QAAQ,KACf,oBAAoB,CAAA;IACzB,gFAAgF;IAChF,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAA;IACb;;;;OAIG;IACH,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,QAAQ,EAAE,CAAA;CACtB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAiB,SAAQ,cAAc;IACtD,qEAAqE;IACrE,OAAO,EAAE,cAAc,EAAE,CAAA;CAC1B;AAED,oDAAoD;AACpD,wBAAgB,cAAc,CAC5B,MAAM,EAAE,cAAc,GACrB,MAAM,IAAI,gBAAgB,CAE5B;AAED,MAAM,WAAW,eAAgB,SAAQ,cAAc;IACrD,mDAAmD;IACnD,QAAQ,EAAE,UAAU,EAAE,CAAA;IACtB,WAAW,CAAC,EAAE,KAAK,CAAA;IACnB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,gDAAgD;IAChD,KAAK,EAAE,MAAM,CAAA;IACb,gEAAgE;IAChE,uBAAuB,CAAC,EAAE,OAAO,CAAA;CAClC;AAED,MAAM,MAAM,UAAU,GAAG,cAAc,GAAG,eAAe,CAAA;AAEzD,qIAAqI;AACrI,MAAM,MAAM,iBAAiB,CAAC,IAAI,SAAS,MAAM,GAAG,MAAM,IACtD;IAAE,QAAQ,CAAC,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAA;CAAE,GACvC;IAAE,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAC;IAAC,QAAQ,CAAC,EAAE,KAAK,CAAA;CAAE,CAAA;AAE3C,MAAM,MAAM,gBAAgB,CAAC,IAAI,SAAS,MAAM,GAAG,MAAM,IAAI,IAAI,CAC/D,cAAc,EACd,4BAA4B,GAAG,WAAW,CAC3C,GACC,iBAAiB,CAAC,IAAI,CAAC,CAAA;AAEzB,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,KAAK,IAAI,CAAA;AAEzE;;;;;;;GAOG;AACH,MAAM,MAAM,YAAY,GAAG,CACzB,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,EAC9B,KAAK,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,KAC3B,IAAI,CAAA;AAET,MAAM,WAAW,YAAY,CAAC,CAAC,GAAG,OAAO;IACvC,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAA;IACZ,qHAAqH;IACrH,QAAQ,EAAE,MAAM,CAAA;IAChB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;OAGG;IACH,KAAK,EAAE,CAAC,CAAA;CACT;AAED,MAAM,MAAM,kBAAkB,GAAG,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,CAAA"}
@@ -0,0 +1,7 @@
1
+ /** Whether a filter delegates to scoped options. */
2
+ function isScopedFilter(filter) {
3
+ return Array.isArray(filter.options);
4
+ }
5
+
6
+ export { isScopedFilter };
7
+ //# sourceMappingURL=FilterTypes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FilterTypes.js","sources":["../../../src/components/DataTable/FilterTypes.tsx"],"sourcesContent":["import type { ActiveFilterInstance } from \"./ActiveFilterInstance\"\n\nexport interface FilterNodeBase {\n /** Extra search terms beyond the label. */\n keywords?: string[]\n}\n\nexport interface InputType {\n type: string\n}\n\nexport interface Operator {\n inputType: InputType\n label: string\n name: string\n}\n\nexport interface FilterNodeItem extends FilterNodeBase {\n /** Whether multiple instances of this filter can be active simultaneously. */\n allowMultiple?: boolean\n children?: never\n /** Binds this filter to one active filter's operator and value. Supplied by the filter factories. */\n createActiveFilterInstance: (\n activeFilter: ActiveFilter,\n operator: Operator\n ) => ActiveFilterInstance\n /** Not rendered in the menu. Carried through as data for the change handler. */\n description?: string\n /** Display name in the filter menu. */\n label: string\n /**\n * Stable id. Keys the active filter this config produces. Must be unique\n * across the whole filter tree — it's applied as the item's `id`, and\n * duplicates break the menu.\n */\n name: string\n operators: Operator[]\n}\n\n/**\n * A filter that delegates to one of several other filters, chosen by an active\n * filter's `scope` (see `scopedFilter`). The scoped filter supplies the\n * `operator` and `value`, while this one still labels the chip.\n *\n * Distinct from a group's `children`: those render side by side in the menu,\n * while these are alternatives the user picks between one at a time.\n */\nexport interface FilterNodeScoped extends FilterNodeItem {\n /** The filters a `scope` selects from, keyed by their own `name`. */\n options: FilterNodeItem[]\n}\n\n/** Whether a filter delegates to scoped options. */\nexport function isScopedFilter(\n filter: FilterNodeItem\n): filter is FilterNodeScoped {\n return Array.isArray((filter as FilterNodeScoped).options)\n}\n\nexport interface FilterNodeGroup extends FilterNodeBase {\n /** Filters and nested groups, in display order. */\n children: FilterNode[]\n description?: never\n keywords?: string[]\n /** Section header, or submenu trigger label. */\n label: string\n /** Opens children in a submenu instead of an inline section. */\n renderChildrenInSubmenu?: boolean\n}\n\nexport type FilterNode = FilterNodeItem | FilterNodeGroup\n\n/** Narrow a factory's operator set by name. `includes` keeps only the named operators, in the order given; `excludes` drops them. */\nexport type OperatorSelection<Name extends string = string> =\n | { excludes?: never; includes?: Name[] }\n | { excludes?: Name[]; includes?: never }\n\nexport type FilterItemConfig<Name extends string = string> = Omit<\n FilterNodeItem,\n \"createActiveFilterInstance\" | \"operators\"\n> &\n OperatorSelection<Name>\n\nexport type UpdateActiveFilter = (updates: Partial<ActiveFilter>) => void\n\n/**\n * How an editor reports a change, along with whether the filter can now be\n * applied. Editors know this; callers would otherwise have to infer it from\n * the shape of the update.\n *\n * `complete` defaults to true, so an editor reporting a finished value says\n * nothing extra — only partial states need flagging.\n */\nexport type FilterChange = (\n updates: Partial<ActiveFilter>,\n state?: { complete?: boolean }\n) => void\n\nexport interface ActiveFilter<T = unknown> {\n /** The HTML name of the applied filter. Connects to the name of the filter. */\n name: string\n /** The operator used by the applied filter. Corresponds to the name of the operator in the filter configuration. */\n operator: string\n /**\n * For scoped filters only: which of the parent's options is selected. The\n * `operator` and `value` then belong to that option's filter rather than to\n * the parent, so both are resolved against the scoped filter.\n */\n scope?: string\n /**\n * The value of the applied filter. Can be of any type depending on the filter configuration.\n * TODO: Add more specific typing based on the operator and input type.\n */\n value: T\n}\n\nexport type AddPendingFilterFn = (filter: ActiveFilter) => void\n"],"names":[],"mappings":"AAoDA;AACM,SAAU,cAAc,CAC5B,MAAsB,EAAA;IAEtB,OAAO,KAAK,CAAC,OAAO,CAAE,MAA2B,CAAC,OAAO,CAAC;AAC5D;;;;"}
@@ -0,0 +1,12 @@
1
+ import React, { ReactNode } from "react";
2
+ import { ActiveFilter, AddPendingFilterFn } from "./FilterTypes";
3
+ export declare function usePendingFilters(): {
4
+ addPendingFilter: AddPendingFilterFn;
5
+ pendingFilters: ActiveFilter[];
6
+ removePendingFilter: (filter: ActiveFilter) => void;
7
+ updatePendingFilter: (filter: ActiveFilter, updates: Partial<ActiveFilter>) => void;
8
+ };
9
+ export declare function PendingFilterProvider({ children }: {
10
+ children: ReactNode;
11
+ }): React.JSX.Element;
12
+ //# sourceMappingURL=PendingFilterContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PendingFilterContext.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/PendingFilterContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAiB,SAAS,EAAuB,MAAM,OAAO,CAAA;AAE5E,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAiBhE,wBAAgB,iBAAiB;sBAdb,kBAAkB;oBACpB,YAAY,EAAE;yBACT,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI;yBAC9B,CACnB,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,KAC3B,IAAI;EAUV;AAED,wBAAgB,qBAAqB,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,qBAiC1E"}
@@ -0,0 +1,33 @@
1
+ import React__default, { createContext, useMemo, useContext } from 'react';
2
+
3
+ const PendingFilterContext = createContext({
4
+ addPendingFilter: () => { },
5
+ pendingFilters: [],
6
+ removePendingFilter: () => { },
7
+ updatePendingFilter: () => { },
8
+ });
9
+ function usePendingFilters() {
10
+ return useContext(PendingFilterContext);
11
+ }
12
+ function PendingFilterProvider({ children }) {
13
+ const [pendingFilters, setPendingFilters] = React__default.useState([]);
14
+ const addPendingFilter = (filter) => {
15
+ setPendingFilters((prev) => [...prev, filter]);
16
+ };
17
+ const removePendingFilter = (filter) => {
18
+ setPendingFilters((prev) => prev.filter((f) => f !== filter));
19
+ };
20
+ const updatePendingFilter = (filter, updates) => {
21
+ setPendingFilters((prev) => prev.map((f) => (f === filter ? { ...f, ...updates } : f)));
22
+ };
23
+ const value = useMemo(() => ({
24
+ addPendingFilter,
25
+ pendingFilters,
26
+ removePendingFilter,
27
+ updatePendingFilter,
28
+ }), [pendingFilters]);
29
+ return (React__default.createElement(PendingFilterContext.Provider, { value: value }, children));
30
+ }
31
+
32
+ export { PendingFilterProvider, usePendingFilters };
33
+ //# sourceMappingURL=PendingFilterContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PendingFilterContext.js","sources":["../../../src/components/DataTable/PendingFilterContext.tsx"],"sourcesContent":["import React, { createContext, ReactNode, useContext, useMemo } from \"react\"\n\nimport { ActiveFilter, AddPendingFilterFn } from \"./FilterTypes\"\n\nconst PendingFilterContext = createContext<{\n addPendingFilter: AddPendingFilterFn\n pendingFilters: ActiveFilter[]\n removePendingFilter: (filter: ActiveFilter) => void\n updatePendingFilter: (\n filter: ActiveFilter,\n updates: Partial<ActiveFilter>\n ) => void\n}>({\n addPendingFilter: () => {},\n pendingFilters: [],\n removePendingFilter: () => {},\n updatePendingFilter: () => {},\n})\n\nexport function usePendingFilters() {\n return useContext(PendingFilterContext)\n}\n\nexport function PendingFilterProvider({ children }: { children: ReactNode }) {\n const [pendingFilters, setPendingFilters] = React.useState<ActiveFilter[]>([])\n\n const addPendingFilter = (filter: ActiveFilter) => {\n setPendingFilters((prev) => [...prev, filter])\n }\n const removePendingFilter = (filter: ActiveFilter) => {\n setPendingFilters((prev) => prev.filter((f) => f !== filter))\n }\n const updatePendingFilter = (\n filter: ActiveFilter,\n updates: Partial<ActiveFilter>\n ) => {\n setPendingFilters((prev) =>\n prev.map((f) => (f === filter ? { ...f, ...updates } : f))\n )\n }\n\n const value = useMemo(\n () => ({\n addPendingFilter,\n pendingFilters,\n removePendingFilter,\n updatePendingFilter,\n }),\n [pendingFilters]\n )\n\n return (\n <PendingFilterContext.Provider value={value}>\n {children}\n </PendingFilterContext.Provider>\n )\n}\n"],"names":["React"],"mappings":";;AAIA,MAAM,oBAAoB,GAAG,aAAa,CAQvC;AACD,IAAA,gBAAgB,EAAE,MAAK,EAAE,CAAC;AAC1B,IAAA,cAAc,EAAE,EAAE;AAClB,IAAA,mBAAmB,EAAE,MAAK,EAAE,CAAC;AAC7B,IAAA,mBAAmB,EAAE,MAAK,EAAE,CAAC;AAC9B,CAAA,CAAC;SAEc,iBAAiB,GAAA;AAC/B,IAAA,OAAO,UAAU,CAAC,oBAAoB,CAAC;AACzC;AAEM,SAAU,qBAAqB,CAAC,EAAE,QAAQ,EAA2B,EAAA;AACzE,IAAA,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAGA,cAAK,CAAC,QAAQ,CAAiB,EAAE,CAAC;AAE9E,IAAA,MAAM,gBAAgB,GAAG,CAAC,MAAoB,KAAI;AAChD,QAAA,iBAAiB,CAAC,CAAC,IAAI,KAAK,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;AAChD,IAAA,CAAC;AACD,IAAA,MAAM,mBAAmB,GAAG,CAAC,MAAoB,KAAI;QACnD,iBAAiB,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,MAAM,CAAC,CAAC;AAC/D,IAAA,CAAC;AACD,IAAA,MAAM,mBAAmB,GAAG,CAC1B,MAAoB,EACpB,OAA8B,KAC5B;AACF,QAAA,iBAAiB,CAAC,CAAC,IAAI,KACrB,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,MAAM,GAAG,EAAE,GAAG,CAAC,EAAE,GAAG,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,CAC3D;AACH,IAAA,CAAC;AAED,IAAA,MAAM,KAAK,GAAG,OAAO,CACnB,OAAO;QACL,gBAAgB;QAChB,cAAc;QACd,mBAAmB;QACnB,mBAAmB;AACpB,KAAA,CAAC,EACF,CAAC,cAAc,CAAC,CACjB;AAED,IAAA,QACEA,cAAA,CAAA,aAAA,CAAC,oBAAoB,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,KAAK,EAAA,EACxC,QAAQ,CACqB;AAEpC;;;;"}
@@ -0,0 +1,13 @@
1
+ import React, { type ReactNode } from "react";
2
+ import type { ActiveFilter } from "./FilterTypes";
3
+ /**
4
+ * Defers `addPendingFilter` for everything queued beneath it until this
5
+ * component unmounts — i.e. until the enclosing menu popover has fully closed.
6
+ */
7
+ export declare function PendingFilterQueue({ children }: {
8
+ children: ReactNode;
9
+ }): React.JSX.Element;
10
+ export declare function useQueuePendingFilter(): (filter: ActiveFilter) => void;
11
+ /** Whether a filter is active, pending, or queued to become pending. */
12
+ export declare function useIsFilterTaken(): (name: string) => boolean;
13
+ //# sourceMappingURL=PendingFilterQueue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PendingFilterQueue.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/PendingFilterQueue.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAEZ,KAAK,SAAS,EAMf,MAAM,OAAO,CAAA;AAGd,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AASjD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,qBA8BvE;AAED,wBAAgB,qBAAqB,aA1CoB,YAAY,KAAK,IAAI,CA4C7E;AAED,wEAAwE;AACxE,wBAAgB,gBAAgB,KAGtB,MAAM,MAAM,aAErB"}
@@ -0,0 +1,42 @@
1
+ import React__default, { createContext, useRef, useEffect, useState, useCallback, useContext } from 'react';
2
+ import { useHasFilterInstancesChecker } from './FilterContext.js';
3
+ import { usePendingFilters } from './PendingFilterContext.js';
4
+
5
+ const QueuePendingFilterContext = createContext(() => { });
6
+ const QueuedFilterNamesContext = createContext([]);
7
+ /**
8
+ * Defers `addPendingFilter` for everything queued beneath it until this
9
+ * component unmounts — i.e. until the enclosing menu popover has fully closed.
10
+ */
11
+ function PendingFilterQueue({ children }) {
12
+ const { addPendingFilter } = usePendingFilters();
13
+ const addPendingFilterRef = useRef(addPendingFilter);
14
+ useEffect(() => {
15
+ addPendingFilterRef.current = addPendingFilter;
16
+ }, [addPendingFilter]);
17
+ const queue = useRef([]);
18
+ const [queuedNames, setQueuedNames] = useState([]);
19
+ const queuePendingFilter = useCallback((filter) => {
20
+ queue.current.push(filter);
21
+ setQueuedNames((prev) => [...prev, filter.name]);
22
+ }, []);
23
+ useEffect(() => () => {
24
+ const filters = queue.current;
25
+ queue.current = [];
26
+ filters.forEach((filter) => addPendingFilterRef.current(filter));
27
+ }, []);
28
+ return (React__default.createElement(QueuePendingFilterContext.Provider, { value: queuePendingFilter },
29
+ React__default.createElement(QueuedFilterNamesContext.Provider, { value: queuedNames }, children)));
30
+ }
31
+ function useQueuePendingFilter() {
32
+ return useContext(QueuePendingFilterContext);
33
+ }
34
+ /** Whether a filter is active, pending, or queued to become pending. */
35
+ function useIsFilterTaken() {
36
+ const hasFilterInstances = useHasFilterInstancesChecker();
37
+ const queuedNames = useContext(QueuedFilterNamesContext);
38
+ return (name) => hasFilterInstances(name) || queuedNames.includes(name);
39
+ }
40
+
41
+ export { PendingFilterQueue, useIsFilterTaken, useQueuePendingFilter };
42
+ //# sourceMappingURL=PendingFilterQueue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PendingFilterQueue.js","sources":["../../../src/components/DataTable/PendingFilterQueue.tsx"],"sourcesContent":["import React, {\n createContext,\n type ReactNode,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n} from \"react\"\n\nimport { useHasFilterInstancesChecker } from \"./FilterContext\"\nimport type { ActiveFilter } from \"./FilterTypes\"\nimport { usePendingFilters } from \"./PendingFilterContext\"\n\nconst QueuePendingFilterContext = createContext<(filter: ActiveFilter) => void>(\n () => {}\n)\n\nconst QueuedFilterNamesContext = createContext<string[]>([])\n\n/**\n * Defers `addPendingFilter` for everything queued beneath it until this\n * component unmounts — i.e. until the enclosing menu popover has fully closed.\n */\nexport function PendingFilterQueue({ children }: { children: ReactNode }) {\n const { addPendingFilter } = usePendingFilters()\n const addPendingFilterRef = useRef(addPendingFilter)\n useEffect(() => {\n addPendingFilterRef.current = addPendingFilter\n }, [addPendingFilter])\n\n const queue = useRef<ActiveFilter[]>([])\n const [queuedNames, setQueuedNames] = useState<string[]>([])\n const queuePendingFilter = useCallback((filter: ActiveFilter) => {\n queue.current.push(filter)\n setQueuedNames((prev) => [...prev, filter.name])\n }, [])\n\n useEffect(\n () => () => {\n const filters = queue.current\n queue.current = []\n filters.forEach((filter) => addPendingFilterRef.current(filter))\n },\n []\n )\n\n return (\n <QueuePendingFilterContext.Provider value={queuePendingFilter}>\n <QueuedFilterNamesContext.Provider value={queuedNames}>\n {children}\n </QueuedFilterNamesContext.Provider>\n </QueuePendingFilterContext.Provider>\n )\n}\n\nexport function useQueuePendingFilter() {\n return useContext(QueuePendingFilterContext)\n}\n\n/** Whether a filter is active, pending, or queued to become pending. */\nexport function useIsFilterTaken() {\n const hasFilterInstances = useHasFilterInstancesChecker()\n const queuedNames = useContext(QueuedFilterNamesContext)\n return (name: string) =>\n hasFilterInstances(name) || queuedNames.includes(name)\n}\n"],"names":["React"],"mappings":";;;;AAcA,MAAM,yBAAyB,GAAG,aAAa,CAC7C,MAAK,EAAE,CAAC,CACT;AAED,MAAM,wBAAwB,GAAG,aAAa,CAAW,EAAE,CAAC;AAE5D;;;AAGG;AACG,SAAU,kBAAkB,CAAC,EAAE,QAAQ,EAA2B,EAAA;AACtE,IAAA,MAAM,EAAE,gBAAgB,EAAE,GAAG,iBAAiB,EAAE;AAChD,IAAA,MAAM,mBAAmB,GAAG,MAAM,CAAC,gBAAgB,CAAC;IACpD,SAAS,CAAC,MAAK;AACb,QAAA,mBAAmB,CAAC,OAAO,GAAG,gBAAgB;AAChD,IAAA,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC;AAEtB,IAAA,MAAM,KAAK,GAAG,MAAM,CAAiB,EAAE,CAAC;IACxC,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAW,EAAE,CAAC;AAC5D,IAAA,MAAM,kBAAkB,GAAG,WAAW,CAAC,CAAC,MAAoB,KAAI;AAC9D,QAAA,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;AAC1B,QAAA,cAAc,CAAC,CAAC,IAAI,KAAK,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IAClD,CAAC,EAAE,EAAE,CAAC;AAEN,IAAA,SAAS,CACP,MAAM,MAAK;AACT,QAAA,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO;AAC7B,QAAA,KAAK,CAAC,OAAO,GAAG,EAAE;AAClB,QAAA,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,mBAAmB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAClE,CAAC,EACD,EAAE,CACH;IAED,QACEA,6BAAC,yBAAyB,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,kBAAkB,EAAA;AAC3D,QAAAA,cAAA,CAAA,aAAA,CAAC,wBAAwB,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,WAAW,EAAA,EAClD,QAAQ,CACyB,CACD;AAEzC;SAEgB,qBAAqB,GAAA;AACnC,IAAA,OAAO,UAAU,CAAC,yBAAyB,CAAC;AAC9C;AAEA;SACgB,gBAAgB,GAAA;AAC9B,IAAA,MAAM,kBAAkB,GAAG,4BAA4B,EAAE;AACzD,IAAA,MAAM,WAAW,GAAG,UAAU,CAAC,wBAAwB,CAAC;AACxD,IAAA,OAAO,CAAC,IAAY,KAClB,kBAAkB,CAAC,IAAI,CAAC,IAAI,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC;AAC1D;;;;"}
@@ -2,9 +2,11 @@ import React from "react";
2
2
  import { FilterNode } from "./FilterTypes";
3
3
  export declare function useSearchableFilters(): SearchableSimpleFilterItem[];
4
4
  export type SearchableSimpleFilterItem = {
5
+ allowMultiple?: boolean;
5
6
  grouping: string[];
6
7
  label: string;
7
8
  name: string;
9
+ operator: string;
8
10
  searchable: string;
9
11
  };
10
12
  export declare function SearchableFiltersProvider({ children, filters, }: {
@@ -1 +1 @@
1
- {"version":3,"file":"SearchableFilters.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/SearchableFilters.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA6C,MAAM,OAAO,CAAA;AAEjE,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAE1C,wBAAgB,oBAAoB,IAAI,0BAA0B,EAAE,CAEnE;AAED,MAAM,MAAM,0BAA0B,GAAG;IACvC,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;CACnB,CAAA;AAID,wBAAgB,yBAAyB,CAAC,EACxC,QAAQ,EACR,OAAO,GACR,EAAE;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,OAAO,EAAE,UAAU,EAAE,CAAA;CACtB,qBAmCA"}
1
+ {"version":3,"file":"SearchableFilters.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/SearchableFilters.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA6C,MAAM,OAAO,CAAA;AAEjE,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAG1C,wBAAgB,oBAAoB,IAAI,0BAA0B,EAAE,CAEnE;AAED,MAAM,MAAM,0BAA0B,GAAG;IACvC,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;CACnB,CAAA;AAID,wBAAgB,yBAAyB,CAAC,EACxC,QAAQ,EACR,OAAO,GACR,EAAE;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,OAAO,EAAE,UAAU,EAAE,CAAA;CACtB,qBAqCA"}
@@ -1,4 +1,5 @@
1
1
  import React__default, { createContext, useMemo, useContext } from 'react';
2
+ import { getDefaultOperatorName } from './utils.js';
2
3
 
3
4
  function useSearchableFilters() {
4
5
  return useContext(SearchableFiltersContext);
@@ -16,9 +17,11 @@ function SearchableFiltersProvider({ children, filters, }) {
16
17
  .join(" ")
17
18
  .toLowerCase();
18
19
  result.push({
20
+ allowMultiple: filter.allowMultiple,
19
21
  grouping,
20
22
  label: filter.label,
21
23
  name: filter.name,
24
+ operator: getDefaultOperatorName(filter),
22
25
  searchable,
23
26
  });
24
27
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SearchableFilters.js","sources":["../../../src/components/DataTable/SearchableFilters.tsx"],"sourcesContent":["import React, { createContext, useContext, useMemo } from \"react\"\n\nimport { FilterNode } from \"./FilterTypes\"\n\nexport function useSearchableFilters(): SearchableSimpleFilterItem[] {\n return useContext(SearchableFiltersContext)\n}\n\nexport type SearchableSimpleFilterItem = {\n grouping: string[]\n label: string\n name: string\n searchable: string\n}\n\nconst SearchableFiltersContext = createContext<SearchableSimpleFilterItem[]>([])\n\nexport function SearchableFiltersProvider({\n children,\n filters,\n}: {\n children: React.ReactNode\n filters: FilterNode[]\n}) {\n const searchableSimpleFilterItems = useMemo(() => {\n const result: SearchableSimpleFilterItem[] = []\n\n function addFilterItem(\n filter: FilterNode,\n grouping: string[] = [],\n collectedKeywords: string[] = []\n ) {\n const keywords = [...collectedKeywords, ...(filter.keywords || [])]\n if (filter.children) {\n return filter.children.forEach((child) =>\n addFilterItem(child, [...grouping, filter.label], keywords)\n )\n }\n const searchable = dedup([...grouping, filter.label, ...keywords])\n .join(\" \")\n .toLowerCase()\n result.push({\n grouping,\n label: filter.label,\n name: filter.name,\n searchable,\n })\n }\n\n filters.forEach((filter) => addFilterItem(filter))\n return result\n }, [filters])\n\n return (\n <SearchableFiltersContext.Provider value={searchableSimpleFilterItems}>\n {children}\n </SearchableFiltersContext.Provider>\n )\n}\n\nfunction dedup(items: string[]): string[] {\n return Array.from(new Set(items))\n}\n"],"names":["React"],"mappings":";;SAIgB,oBAAoB,GAAA;AAClC,IAAA,OAAO,UAAU,CAAC,wBAAwB,CAAC;AAC7C;AASA,MAAM,wBAAwB,GAAG,aAAa,CAA+B,EAAE,CAAC;SAEhE,yBAAyB,CAAC,EACxC,QAAQ,EACR,OAAO,GAIR,EAAA;AACC,IAAA,MAAM,2BAA2B,GAAG,OAAO,CAAC,MAAK;QAC/C,MAAM,MAAM,GAAiC,EAAE;QAE/C,SAAS,aAAa,CACpB,MAAkB,EAClB,WAAqB,EAAE,EACvB,oBAA8B,EAAE,EAAA;AAEhC,YAAA,MAAM,QAAQ,GAAG,CAAC,GAAG,iBAAiB,EAAE,IAAI,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;AACnE,YAAA,IAAI,MAAM,CAAC,QAAQ,EAAE;gBACnB,OAAO,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,KAAK,KACnC,aAAa,CAAC,KAAK,EAAE,CAAC,GAAG,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,CAC5D;YACH;AACA,YAAA,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,GAAG,QAAQ,EAAE,MAAM,CAAC,KAAK,EAAE,GAAG,QAAQ,CAAC;iBAC9D,IAAI,CAAC,GAAG;AACR,iBAAA,WAAW,EAAE;YAChB,MAAM,CAAC,IAAI,CAAC;gBACV,QAAQ;gBACR,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,UAAU;AACX,aAAA,CAAC;QACJ;AAEA,QAAA,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,aAAa,CAAC,MAAM,CAAC,CAAC;AAClD,QAAA,OAAO,MAAM;AACf,IAAA,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC;AAEb,IAAA,QACEA,cAAA,CAAA,aAAA,CAAC,wBAAwB,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,2BAA2B,EAAA,EAClE,QAAQ,CACyB;AAExC;AAEA,SAAS,KAAK,CAAC,KAAe,EAAA;IAC5B,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;AACnC;;;;"}
1
+ {"version":3,"file":"SearchableFilters.js","sources":["../../../src/components/DataTable/SearchableFilters.tsx"],"sourcesContent":["import React, { createContext, useContext, useMemo } from \"react\"\n\nimport { FilterNode } from \"./FilterTypes\"\nimport { getDefaultOperatorName } from \"./utils\"\n\nexport function useSearchableFilters(): SearchableSimpleFilterItem[] {\n return useContext(SearchableFiltersContext)\n}\n\nexport type SearchableSimpleFilterItem = {\n allowMultiple?: boolean\n grouping: string[]\n label: string\n name: string\n operator: string\n searchable: string\n}\n\nconst SearchableFiltersContext = createContext<SearchableSimpleFilterItem[]>([])\n\nexport function SearchableFiltersProvider({\n children,\n filters,\n}: {\n children: React.ReactNode\n filters: FilterNode[]\n}) {\n const searchableSimpleFilterItems = useMemo(() => {\n const result: SearchableSimpleFilterItem[] = []\n\n function addFilterItem(\n filter: FilterNode,\n grouping: string[] = [],\n collectedKeywords: string[] = []\n ) {\n const keywords = [...collectedKeywords, ...(filter.keywords || [])]\n if (filter.children) {\n return filter.children.forEach((child) =>\n addFilterItem(child, [...grouping, filter.label], keywords)\n )\n }\n const searchable = dedup([...grouping, filter.label, ...keywords])\n .join(\" \")\n .toLowerCase()\n result.push({\n allowMultiple: filter.allowMultiple,\n grouping,\n label: filter.label,\n name: filter.name,\n operator: getDefaultOperatorName(filter),\n searchable,\n })\n }\n\n filters.forEach((filter) => addFilterItem(filter))\n return result\n }, [filters])\n\n return (\n <SearchableFiltersContext.Provider value={searchableSimpleFilterItems}>\n {children}\n </SearchableFiltersContext.Provider>\n )\n}\n\nfunction dedup(items: string[]): string[] {\n return Array.from(new Set(items))\n}\n"],"names":["React"],"mappings":";;;SAKgB,oBAAoB,GAAA;AAClC,IAAA,OAAO,UAAU,CAAC,wBAAwB,CAAC;AAC7C;AAWA,MAAM,wBAAwB,GAAG,aAAa,CAA+B,EAAE,CAAC;SAEhE,yBAAyB,CAAC,EACxC,QAAQ,EACR,OAAO,GAIR,EAAA;AACC,IAAA,MAAM,2BAA2B,GAAG,OAAO,CAAC,MAAK;QAC/C,MAAM,MAAM,GAAiC,EAAE;QAE/C,SAAS,aAAa,CACpB,MAAkB,EAClB,WAAqB,EAAE,EACvB,oBAA8B,EAAE,EAAA;AAEhC,YAAA,MAAM,QAAQ,GAAG,CAAC,GAAG,iBAAiB,EAAE,IAAI,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;AACnE,YAAA,IAAI,MAAM,CAAC,QAAQ,EAAE;gBACnB,OAAO,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,KAAK,KACnC,aAAa,CAAC,KAAK,EAAE,CAAC,GAAG,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,CAC5D;YACH;AACA,YAAA,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,GAAG,QAAQ,EAAE,MAAM,CAAC,KAAK,EAAE,GAAG,QAAQ,CAAC;iBAC9D,IAAI,CAAC,GAAG;AACR,iBAAA,WAAW,EAAE;YAChB,MAAM,CAAC,IAAI,CAAC;gBACV,aAAa,EAAE,MAAM,CAAC,aAAa;gBACnC,QAAQ;gBACR,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,IAAI,EAAE,MAAM,CAAC,IAAI;AACjB,gBAAA,QAAQ,EAAE,sBAAsB,CAAC,MAAM,CAAC;gBACxC,UAAU;AACX,aAAA,CAAC;QACJ;AAEA,QAAA,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,aAAa,CAAC,MAAM,CAAC,CAAC;AAClD,QAAA,OAAO,MAAM;AACf,IAAA,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC;AAEb,IAAA,QACEA,cAAA,CAAA,aAAA,CAAC,wBAAwB,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,2BAA2B,EAAA,EAClE,QAAQ,CACyB;AAExC;AAEA,SAAS,KAAK,CAAC,KAAe,EAAA;IAC5B,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;AACnC;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"collectionFilter.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/collectionFilter.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EACV,gBAAgB,EAChB,cAAc,EAGf,MAAM,eAAe,CAAA;AAItB,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,2EAA2E;AAC3E,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,MAAM,EAAE,CAAA;AAErD,MAAM,MAAM,iBAAiB,GAAG,YAAY,GAAG,UAAU,GAAG,QAAQ,CAAA;AAEpE,eAAO,MAAM,aAAa;;;;;;CAIG,CAAA;AAC7B,eAAO,MAAM,cAAc;;;;;;CAIE,CAAA;AAE7B,QAAA,MAAM,oBAAoB;;;;;;;;;;;;IAAkC,CAAA;AAE5D,MAAM,MAAM,sBAAsB,GAChC,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAA;AAE/C,MAAM,MAAM,sBAAsB,GAChC,gBAAgB,CAAC,sBAAsB,CAAC,GAAG;IACzC,OAAO,EAAE,gBAAgB,EAAE,CAAA;CAC5B,GAAG,CACE;IAAE,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAAC,QAAQ,CAAC,EAAE,KAAK,CAAA;CAAE,GACjD;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC,iBAAiB,EAAE,QAAQ,CAAC,CAAC;IAAC,QAAQ,EAAE,IAAI,CAAA;CAAE,CACrE,CAAA;AAML,wBAAgB,gBAAgB,CAAC,EAC/B,OAAkB,EAClB,QAAQ,EACR,QAAQ,EACR,QAAgB,EAChB,OAAO,EACP,GAAG,MAAM,EACV,EAAE,sBAAsB,GAAG,cAAc,CAazC"}
1
+ {"version":3,"file":"collectionFilter.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/collectionFilter.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAEV,gBAAgB,EAChB,cAAc,EAEf,MAAM,eAAe,CAAA;AAKtB,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,2EAA2E;AAC3E,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,MAAM,EAAE,CAAA;AAErD,MAAM,MAAM,iBAAiB,GAAG,YAAY,GAAG,UAAU,GAAG,QAAQ,CAAA;AAEpE,eAAO,MAAM,aAAa;;;;;;CAIG,CAAA;AAC7B,eAAO,MAAM,cAAc;;;;;;CAIE,CAAA;AAE7B,QAAA,MAAM,oBAAoB;;;;;;;;;;;;IAAkC,CAAA;AAE5D,MAAM,MAAM,sBAAsB,GAChC,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAA;AAE/C,MAAM,MAAM,sBAAsB,GAChC,gBAAgB,CAAC,sBAAsB,CAAC,GAAG;IACzC,OAAO,EAAE,gBAAgB,EAAE,CAAA;CAC5B,GAAG,CACE;IAAE,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAAC,QAAQ,CAAC,EAAE,KAAK,CAAA;CAAE,GACjD;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC,iBAAiB,EAAE,QAAQ,CAAC,CAAC;IAAC,QAAQ,EAAE,IAAI,CAAA;CAAE,CACrE,CAAA;AAML,wBAAgB,gBAAgB,CAAC,EAC/B,OAAkB,EAClB,QAAQ,EACR,QAAQ,EACR,QAAgB,EAChB,OAAO,EACP,GAAG,MAAM,EACV,EAAE,sBAAsB,GAAG,cAAc,CAazC"}