@planningcenter/tapestry 4.8.0-rc.1 → 4.8.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/components/DataTable/CollectionEditorsShared.d.ts +33 -0
- package/dist/components/DataTable/CollectionEditorsShared.d.ts.map +1 -0
- package/dist/components/DataTable/CollectionEditorsShared.js +16 -0
- package/dist/components/DataTable/CollectionEditorsShared.js.map +1 -0
- package/dist/components/DataTable/CollectionEditorsStatic.d.ts +14 -0
- package/dist/components/DataTable/CollectionEditorsStatic.d.ts.map +1 -0
- package/dist/components/DataTable/CollectionEditorsStatic.js +67 -0
- package/dist/components/DataTable/CollectionEditorsStatic.js.map +1 -0
- package/dist/components/DataTable/FilterControls.js +7 -3
- package/dist/components/DataTable/FilterControls.js.map +1 -1
- package/dist/components/DataTable/SearchableFilters.d.ts +2 -0
- package/dist/components/DataTable/SearchableFilters.d.ts.map +1 -1
- package/dist/components/DataTable/SearchableFilters.js +23 -0
- package/dist/components/DataTable/SearchableFilters.js.map +1 -1
- package/dist/components/DataTable/collectionFilter.d.ts +0 -2
- package/dist/components/DataTable/collectionFilter.d.ts.map +1 -1
- package/dist/components/DataTable/collectionFilter.js +2 -58
- package/dist/components/DataTable/collectionFilter.js.map +1 -1
- package/dist/reactRender.css +764 -764
- package/dist/reactRender.css.map +1 -1
- package/dist/reactRenderLegacy.css +764 -764
- package/dist/reactRenderLegacy.css.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type ComboBoxElementProps } from "../combo-box";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import type { CollectionDisplay } from "./collectionFilter";
|
|
4
|
+
import { CollectionOption } from "./collectionFilter";
|
|
5
|
+
import type { FilterChange } from "./FilterTypes";
|
|
6
|
+
/** A single option's `value`, or the selected `value`s when `multiple`. */
|
|
7
|
+
export type CollectionFilterValue = string | string[];
|
|
8
|
+
export type CollectionEditorProps = {
|
|
9
|
+
multiple: boolean;
|
|
10
|
+
operator: {
|
|
11
|
+
label: string;
|
|
12
|
+
};
|
|
13
|
+
value: CollectionFilterValue;
|
|
14
|
+
};
|
|
15
|
+
export type CollectionFilterEditorProps = {
|
|
16
|
+
config: {
|
|
17
|
+
display: CollectionDisplay;
|
|
18
|
+
multiple: boolean;
|
|
19
|
+
options: CollectionOption[];
|
|
20
|
+
};
|
|
21
|
+
filter: {
|
|
22
|
+
label: string;
|
|
23
|
+
name: string;
|
|
24
|
+
};
|
|
25
|
+
onChange: FilterChange;
|
|
26
|
+
operator: {
|
|
27
|
+
label: string;
|
|
28
|
+
};
|
|
29
|
+
value: CollectionFilterValue;
|
|
30
|
+
};
|
|
31
|
+
export declare function orderByOptions(options: CollectionOption[], selected: Set<string>): string[];
|
|
32
|
+
export declare function CollectionEditorCombobox({ value, multiple, operator, ...props }: CollectionEditorProps & Partial<ComboBoxElementProps> & Pick<ComboBoxElementProps, "children">): React.JSX.Element;
|
|
33
|
+
//# sourceMappingURL=CollectionEditorsShared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CollectionEditorsShared.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/CollectionEditorsShared.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AAC3E,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAEjD,2EAA2E;AAC3E,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,MAAM,EAAE,CAAA;AAErD,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,EAAE,OAAO,CAAA;IACjB,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;IAC3B,KAAK,EAAE,qBAAqB,CAAA;CAC7B,CAAA;AAED,MAAM,MAAM,2BAA2B,GAAG;IACxC,MAAM,EAAE;QACN,OAAO,EAAE,iBAAiB,CAAA;QAC1B,QAAQ,EAAE,OAAO,CAAA;QACjB,OAAO,EAAE,gBAAgB,EAAE,CAAA;KAC5B,CAAA;IACD,MAAM,EAAE;QACN,KAAK,EAAE,MAAM,CAAA;QACb,IAAI,EAAE,MAAM,CAAA;KACb,CAAA;IACD,QAAQ,EAAE,YAAY,CAAA;IACtB,QAAQ,EAAE;QACR,KAAK,EAAE,MAAM,CAAA;KACd,CAAA;IACD,KAAK,EAAE,qBAAqB,CAAA;CAC7B,CAAA;AAED,wBAAgB,cAAc,CAC5B,OAAO,EAAE,gBAAgB,EAAE,EAC3B,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,YAGtB;AAED,wBAAgB,wBAAwB,CAAC,EACvC,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,qBAAqB,GACtB,OAAO,CAAC,oBAAoB,CAAC,GAC7B,IAAI,CAAC,oBAAoB,EAAE,UAAU,CAAC,qBAYvC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ComboBox } from '../combo-box/ComboBox.js';
|
|
2
|
+
import React__default from 'react';
|
|
3
|
+
|
|
4
|
+
function orderByOptions(options, selected) {
|
|
5
|
+
return options.filter((o) => selected.has(o.value)).map((o) => o.value);
|
|
6
|
+
}
|
|
7
|
+
function CollectionEditorCombobox({ value, multiple, operator, ...props }) {
|
|
8
|
+
return (React__default.createElement(ComboBox
|
|
9
|
+
// eslint-disable-next-line jsx-a11y/no-autofocus -- the editor only ever renders inside a chip popover that just opened, per ARIA dialog practices
|
|
10
|
+
, {
|
|
11
|
+
// eslint-disable-next-line jsx-a11y/no-autofocus -- the editor only ever renders inside a chip popover that just opened, per ARIA dialog practices
|
|
12
|
+
autoFocus: true, hideLabel: true, label: operator.label, selectionMode: multiple ? "multiple" : "single", value: value, ...props }));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export { CollectionEditorCombobox, orderByOptions };
|
|
16
|
+
//# sourceMappingURL=CollectionEditorsShared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CollectionEditorsShared.js","sources":["../../../src/components/DataTable/CollectionEditorsShared.tsx"],"sourcesContent":["import { ComboBox, type ComboBoxElementProps } from \"@components/combo-box\"\nimport React from \"react\"\n\nimport type { CollectionDisplay } from \"./collectionFilter\"\nimport { CollectionOption } from \"./collectionFilter\"\nimport type { FilterChange } from \"./FilterTypes\"\n\n/** A single option's `value`, or the selected `value`s when `multiple`. */\nexport type CollectionFilterValue = string | string[]\n\nexport type CollectionEditorProps = {\n multiple: boolean\n operator: { label: string }\n value: CollectionFilterValue\n}\n\nexport type CollectionFilterEditorProps = {\n config: {\n display: CollectionDisplay\n multiple: boolean\n options: CollectionOption[]\n }\n filter: {\n label: string\n name: string\n }\n onChange: FilterChange\n operator: {\n label: string\n }\n value: CollectionFilterValue\n}\n\nexport function orderByOptions(\n options: CollectionOption[],\n selected: Set<string>\n) {\n return options.filter((o) => selected.has(o.value)).map((o) => o.value)\n}\n\nexport function CollectionEditorCombobox({\n value,\n multiple,\n operator,\n ...props\n}: CollectionEditorProps &\n Partial<ComboBoxElementProps> &\n Pick<ComboBoxElementProps, \"children\">) {\n return (\n <ComboBox\n // eslint-disable-next-line jsx-a11y/no-autofocus -- the editor only ever renders inside a chip popover that just opened, per ARIA dialog practices\n autoFocus\n hideLabel\n label={operator.label}\n selectionMode={multiple ? \"multiple\" : \"single\"}\n value={value}\n {...props}\n />\n )\n}\n"],"names":["React"],"mappings":";;;AAiCM,SAAU,cAAc,CAC5B,OAA2B,EAC3B,QAAqB,EAAA;AAErB,IAAA,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC;AACzE;AAEM,SAAU,wBAAwB,CAAC,EACvC,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,GAAG,KAAK,EAG8B,EAAA;IACtC,QACEA,6BAAC;;;;AAEC,QAAA,SAAS,EAAA,IAAA,EACT,SAAS,EAAA,IAAA,EACT,KAAK,EAAE,QAAQ,CAAC,KAAK,EACrB,aAAa,EAAE,QAAQ,GAAG,UAAU,GAAG,QAAQ,EAC/C,KAAK,EAAE,KAAK,EAAA,GACR,KAAK,EAAA,CACT;AAEN;;;;"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { CollectionEditorProps, CollectionFilterEditorProps, CollectionFilterValue } from "./CollectionEditorsShared";
|
|
3
|
+
import { CollectionOption } from "./collectionFilter";
|
|
4
|
+
export type CollectionEditorStaticProps = CollectionEditorProps & {
|
|
5
|
+
filterLabel: string;
|
|
6
|
+
filterName: string;
|
|
7
|
+
onCommit: (value: CollectionFilterValue) => void;
|
|
8
|
+
options: CollectionOption[];
|
|
9
|
+
};
|
|
10
|
+
export declare function CollectionFilterEditorStatic({ config, onChange, operator, value, filter, }: CollectionFilterEditorProps): React.JSX.Element;
|
|
11
|
+
export declare function CollectionEditorCheckboxes({ filterLabel, onCommit, options, value, }: CollectionEditorStaticProps): React.JSX.Element;
|
|
12
|
+
export declare function CollectionEditorRadios({ filterLabel, filterName, onCommit, options, value, }: CollectionEditorStaticProps): React.JSX.Element;
|
|
13
|
+
export declare function CollectionEditorSelect({ value, operator, options, onCommit, }: CollectionEditorStaticProps): React.JSX.Element;
|
|
14
|
+
//# sourceMappingURL=CollectionEditorsStatic.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CollectionEditorsStatic.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/CollectionEditorsStatic.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAc,MAAM,OAAO,CAAA;AAElC,OAAO,EAEL,qBAAqB,EACrB,2BAA2B,EAC3B,qBAAqB,EAEtB,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAGrD,MAAM,MAAM,2BAA2B,GAAG,qBAAqB,GAAG;IAChE,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,CAAA;IAChD,OAAO,EAAE,gBAAgB,EAAE,CAAA;CAC5B,CAAA;AAED,wBAAgB,4BAA4B,CAAC,EAC3C,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,KAAK,EACL,MAAM,GACP,EAAE,2BAA2B,qBAmB7B;AAeD,wBAAgB,0BAA0B,CAAC,EACzC,WAAW,EACX,QAAQ,EACR,OAAO,EACP,KAAK,GACN,EAAE,2BAA2B,qBAuB7B;AAED,wBAAgB,sBAAsB,CAAC,EACrC,WAAW,EACX,UAAU,EACV,QAAQ,EACR,OAAO,EACP,KAAK,GACN,EAAE,2BAA2B,qBAqB7B;AAED,wBAAgB,sBAAsB,CAAC,EACrC,KAAK,EACL,QAAQ,EACR,OAAO,EACP,QAAQ,GACT,EAAE,2BAA2B,qBAc7B"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { Checkbox } from '../checkbox/Checkbox.js';
|
|
2
|
+
import { CheckboxGroup } from '../checkbox-group/CheckboxGroup.js';
|
|
3
|
+
import { ComboBoxItem } from '../combo-box/ComboBox.js';
|
|
4
|
+
import { Radio } from '../radio/Radio.js';
|
|
5
|
+
import { RadioGroup } from '../radio-group/RadioGroup.js';
|
|
6
|
+
import { Select } from '../select/Select.js';
|
|
7
|
+
import React__default from 'react';
|
|
8
|
+
import { CollectionEditorCombobox, orderByOptions } from './CollectionEditorsShared.js';
|
|
9
|
+
import { isEmptyValue } from './utils.js';
|
|
10
|
+
|
|
11
|
+
function CollectionFilterEditorStatic({ config, onChange, operator, value, filter, }) {
|
|
12
|
+
const { display, multiple, options } = config;
|
|
13
|
+
const onCommit = (value) => onChange({ value }, { complete: !isEmptyValue(value) });
|
|
14
|
+
const Editor = getStaticEditor({ display, multiple });
|
|
15
|
+
return (React__default.createElement(Editor, { value: value, onCommit: onCommit, options: options, multiple: multiple, operator: operator, filterLabel: filter.label, filterName: filter.name }));
|
|
16
|
+
}
|
|
17
|
+
function getStaticEditor({ display, multiple, }) {
|
|
18
|
+
if (display === "combobox")
|
|
19
|
+
return CollectionEditorComboboxStatic;
|
|
20
|
+
if (multiple)
|
|
21
|
+
return CollectionEditorCheckboxes;
|
|
22
|
+
if (display === "checkboxes")
|
|
23
|
+
return CollectionEditorRadios; // TODO: This looks like it might be a mistake, should it be CollectionEditorCheckboxes? or at least allow for `radios` as an option?
|
|
24
|
+
return CollectionEditorSelect;
|
|
25
|
+
}
|
|
26
|
+
function CollectionEditorCheckboxes({ filterLabel, onCommit, options, value, }) {
|
|
27
|
+
const selected = Array.isArray(value) ? value : [value];
|
|
28
|
+
const toggle = (optionValue, checked) => {
|
|
29
|
+
const next = new Set(selected);
|
|
30
|
+
if (checked)
|
|
31
|
+
next.add(optionValue);
|
|
32
|
+
else
|
|
33
|
+
next.delete(optionValue);
|
|
34
|
+
onCommit(orderByOptions(options, next));
|
|
35
|
+
};
|
|
36
|
+
return (React__default.createElement(CheckboxGroup, { label: filterLabel }, options.map((option, index) => (React__default.createElement(Checkbox, { key: option.value,
|
|
37
|
+
// eslint-disable-next-line jsx-a11y/no-autofocus -- the editor only ever renders inside a chip popover that just opened, per ARIA dialog practices
|
|
38
|
+
autoFocus: index === 0, checked: selected.includes(option.value), label: option.label, onChange: (e) => toggle(option.value, e.target.checked) })))));
|
|
39
|
+
}
|
|
40
|
+
function CollectionEditorRadios({ filterLabel, filterName, onCommit, options, value, }) {
|
|
41
|
+
const selected = Array.isArray(value) ? value[0] : value;
|
|
42
|
+
const focusIndex = Math.max(0, options.findIndex((option) => option.value === selected));
|
|
43
|
+
return (React__default.createElement(RadioGroup, { label: filterLabel }, options.map((option, index) => (React__default.createElement(Radio, { key: option.value,
|
|
44
|
+
// eslint-disable-next-line jsx-a11y/no-autofocus -- the editor only ever renders inside a chip popover that just opened, per ARIA dialog practices
|
|
45
|
+
autoFocus: index === focusIndex, checked: selected === option.value, label: option.label, name: filterName, onChange: () => onCommit(option.value) })))));
|
|
46
|
+
}
|
|
47
|
+
function CollectionEditorSelect({ value, operator, options, onCommit, }) {
|
|
48
|
+
const selected = Array.isArray(value) ? value[0] : value;
|
|
49
|
+
return (React__default.createElement(Select
|
|
50
|
+
// eslint-disable-next-line jsx-a11y/no-autofocus -- the editor only ever renders inside a chip popover that just opened, per ARIA dialog practices
|
|
51
|
+
, {
|
|
52
|
+
// eslint-disable-next-line jsx-a11y/no-autofocus -- the editor only ever renders inside a chip popover that just opened, per ARIA dialog practices
|
|
53
|
+
autoFocus: true, hideLabel: true, label: operator.label, options: options, value: selected, onChange: (e) => onCommit(e.target.value) }));
|
|
54
|
+
}
|
|
55
|
+
function CollectionEditorComboboxStatic({ onCommit, options, filterLabel, filterName, ...props }) {
|
|
56
|
+
return (React__default.createElement(CollectionEditorCombobox, { ...props, onChange: (value) => {
|
|
57
|
+
if (value === null)
|
|
58
|
+
return;
|
|
59
|
+
const resolvedValue = Array.isArray(value)
|
|
60
|
+
? orderByOptions(options, new Set(value.map(String)))
|
|
61
|
+
: String(value);
|
|
62
|
+
onCommit(resolvedValue);
|
|
63
|
+
} }, options.map((option) => (React__default.createElement(ComboBoxItem, { key: option.value, id: option.value }, option.label)))));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export { CollectionEditorCheckboxes, CollectionEditorRadios, CollectionEditorSelect, CollectionFilterEditorStatic };
|
|
67
|
+
//# sourceMappingURL=CollectionEditorsStatic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CollectionEditorsStatic.js","sources":["../../../src/components/DataTable/CollectionEditorsStatic.tsx"],"sourcesContent":["import { Checkbox } from \"@components/checkbox\"\nimport { CheckboxGroup } from \"@components/checkbox-group\"\nimport { ComboBoxItem } from \"@components/combo-box\"\nimport { Radio } from \"@components/radio\"\nimport { RadioGroup } from \"@components/radio-group\"\nimport { Select } from \"@components/select\"\nimport React, { Key } from \"react\"\n\nimport {\n CollectionEditorCombobox,\n CollectionEditorProps,\n CollectionFilterEditorProps,\n CollectionFilterValue,\n orderByOptions,\n} from \"./CollectionEditorsShared\"\nimport { CollectionOption } from \"./collectionFilter\"\nimport { isEmptyValue } from \"./utils\"\n\nexport type CollectionEditorStaticProps = CollectionEditorProps & {\n filterLabel: string\n filterName: string\n onCommit: (value: CollectionFilterValue) => void\n options: CollectionOption[]\n}\n\nexport function CollectionFilterEditorStatic({\n config,\n onChange,\n operator,\n value,\n filter,\n}: CollectionFilterEditorProps) {\n const { display, multiple, options } = config\n\n const onCommit = (value: CollectionFilterValue) =>\n onChange({ value }, { complete: !isEmptyValue(value) })\n\n const Editor = getStaticEditor({ display, multiple })\n\n return (\n <Editor\n value={value}\n onCommit={onCommit}\n options={options}\n multiple={multiple}\n operator={operator}\n filterLabel={filter.label}\n filterName={filter.name}\n />\n )\n}\n\nfunction getStaticEditor({\n display,\n multiple,\n}: {\n display: string\n multiple: boolean\n}) {\n if (display === \"combobox\") return CollectionEditorComboboxStatic\n if (multiple) return CollectionEditorCheckboxes\n if (display === \"checkboxes\") return CollectionEditorRadios // TODO: This looks like it might be a mistake, should it be CollectionEditorCheckboxes? or at least allow for `radios` as an option?\n return CollectionEditorSelect\n}\n\nexport function CollectionEditorCheckboxes({\n filterLabel,\n onCommit,\n options,\n value,\n}: CollectionEditorStaticProps) {\n const selected = Array.isArray(value) ? value : [value]\n const toggle = (optionValue: string, checked: boolean) => {\n const next = new Set(selected)\n if (checked) next.add(optionValue)\n else next.delete(optionValue)\n onCommit(orderByOptions(options, next))\n }\n\n return (\n <CheckboxGroup label={filterLabel}>\n {options.map((option, index) => (\n <Checkbox\n key={option.value}\n // eslint-disable-next-line jsx-a11y/no-autofocus -- the editor only ever renders inside a chip popover that just opened, per ARIA dialog practices\n autoFocus={index === 0}\n checked={selected.includes(option.value)}\n label={option.label}\n onChange={(e) => toggle(option.value, e.target.checked)}\n />\n ))}\n </CheckboxGroup>\n )\n}\n\nexport function CollectionEditorRadios({\n filterLabel,\n filterName,\n onCommit,\n options,\n value,\n}: CollectionEditorStaticProps) {\n const selected = Array.isArray(value) ? value[0] : value\n const focusIndex = Math.max(\n 0,\n options.findIndex((option) => option.value === selected)\n )\n return (\n <RadioGroup label={filterLabel}>\n {options.map((option, index) => (\n <Radio\n key={option.value}\n // eslint-disable-next-line jsx-a11y/no-autofocus -- the editor only ever renders inside a chip popover that just opened, per ARIA dialog practices\n autoFocus={index === focusIndex}\n checked={selected === option.value}\n label={option.label}\n name={filterName}\n onChange={() => onCommit(option.value)}\n />\n ))}\n </RadioGroup>\n )\n}\n\nexport function CollectionEditorSelect({\n value,\n operator,\n options,\n onCommit,\n}: CollectionEditorStaticProps) {\n const selected = Array.isArray(value) ? value[0] : value\n\n return (\n <Select\n // eslint-disable-next-line jsx-a11y/no-autofocus -- the editor only ever renders inside a chip popover that just opened, per ARIA dialog practices\n autoFocus\n hideLabel\n label={operator.label}\n options={options}\n value={selected}\n onChange={(e) => onCommit(e.target.value)}\n />\n )\n}\n\nfunction CollectionEditorComboboxStatic({\n onCommit,\n options,\n filterLabel,\n filterName,\n ...props\n}: CollectionEditorStaticProps) {\n return (\n <CollectionEditorCombobox\n {...props}\n onChange={(value: Key | Key[] | null) => {\n if (value === null) return\n\n const resolvedValue = Array.isArray(value)\n ? orderByOptions(options, new Set(value.map(String)))\n : String(value)\n\n onCommit(resolvedValue)\n }}\n >\n {options.map((option) => (\n <ComboBoxItem key={option.value} id={option.value}>\n {option.label}\n </ComboBoxItem>\n ))}\n </CollectionEditorCombobox>\n )\n}\n"],"names":["React"],"mappings":"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"}
|
|
@@ -116,9 +116,13 @@ function SearchResultItem({ filter }) {
|
|
|
116
116
|
if (hide)
|
|
117
117
|
return null;
|
|
118
118
|
const [, ...remainingGrouping] = filter.grouping;
|
|
119
|
-
|
|
119
|
+
const resultId = filter.scope
|
|
120
|
+
? `filter-search-${filter.name}-${filter.scope}`
|
|
121
|
+
: `filter-search-${filter.name}`;
|
|
122
|
+
return (React__default.createElement(DropdownAction, { key: resultId, textValue: filter.searchable, id: resultId, onAction: () => queuePendingFilter({
|
|
120
123
|
name: filter.name,
|
|
121
124
|
operator: filter.operator,
|
|
125
|
+
scope: filter.scope,
|
|
122
126
|
value: undefined,
|
|
123
127
|
}) },
|
|
124
128
|
React__default.createElement("span", { slot: "label" },
|
|
@@ -141,8 +145,8 @@ function SearchResults() {
|
|
|
141
145
|
return { groups: groupedItems, ungrouped: ungroupedItems };
|
|
142
146
|
}, [filters]);
|
|
143
147
|
return (React__default.createElement(React__default.Fragment, null,
|
|
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 }))))))));
|
|
148
|
+
ungrouped.map((filter) => (React__default.createElement(SearchResultItem, { key: filter.scope ? `${filter.name}-${filter.scope}` : filter.name, filter: filter }))),
|
|
149
|
+
Array.from(groups, ([groupLabel, items]) => (React__default.createElement(DropdownSection, { key: groupLabel, id: groupLabel, title: groupLabel }, items.map((filter) => (React__default.createElement(SearchResultItem, { key: filter.scope ? `${filter.name}-${filter.scope}` : filter.name, filter: filter }))))))));
|
|
146
150
|
}
|
|
147
151
|
function prefixSearch(string, query) {
|
|
148
152
|
if (query.length === 0) {
|
|
@@ -1 +1 @@
|
|
|
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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"}
|
|
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 const resultId = filter.scope\n ? `filter-search-${filter.name}-${filter.scope}`\n : `filter-search-${filter.name}`\n\n return (\n <DropdownAction\n key={resultId}\n textValue={filter.searchable}\n id={resultId}\n onAction={() =>\n queuePendingFilter({\n name: filter.name,\n operator: filter.operator,\n scope: filter.scope,\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\n key={filter.scope ? `${filter.name}-${filter.scope}` : filter.name}\n filter={filter}\n />\n ))}\n {Array.from(groups, ([groupLabel, items]) => (\n <DropdownSection key={groupLabel} id={groupLabel} title={groupLabel}>\n {items.map((filter) => (\n <SearchResultItem\n key={\n filter.scope ? `${filter.name}-${filter.scope}` : filter.name\n }\n filter={filter}\n />\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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"}
|
|
@@ -7,6 +7,8 @@ export type SearchableSimpleFilterItem = {
|
|
|
7
7
|
label: string;
|
|
8
8
|
name: string;
|
|
9
9
|
operator: string;
|
|
10
|
+
/** For a scoped filter's option: the scope to pre-select on the pending filter. */
|
|
11
|
+
scope?: string;
|
|
10
12
|
searchable: string;
|
|
11
13
|
};
|
|
12
14
|
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,
|
|
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,EAAkB,MAAM,eAAe,CAAA;AAG1D,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,mFAAmF;IACnF,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,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,qBA6DA"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React__default, { createContext, useMemo, useContext } from 'react';
|
|
2
|
+
import { isScopedFilter } from './FilterTypes.js';
|
|
2
3
|
import { getDefaultOperatorName } from './utils.js';
|
|
3
4
|
|
|
4
5
|
function useSearchableFilters() {
|
|
@@ -13,6 +14,28 @@ function SearchableFiltersProvider({ children, filters, }) {
|
|
|
13
14
|
if (filter.children) {
|
|
14
15
|
return filter.children.forEach((child) => addFilterItem(child, [...grouping, filter.label], keywords));
|
|
15
16
|
}
|
|
17
|
+
if (isScopedFilter(filter)) {
|
|
18
|
+
return filter.options.forEach((option) => {
|
|
19
|
+
const optionGrouping = [...grouping, filter.label];
|
|
20
|
+
const optionKeywords = [...keywords, ...(option.keywords || [])];
|
|
21
|
+
const optionSearchable = dedup([
|
|
22
|
+
...optionGrouping,
|
|
23
|
+
option.label,
|
|
24
|
+
...optionKeywords,
|
|
25
|
+
])
|
|
26
|
+
.join(" ")
|
|
27
|
+
.toLowerCase();
|
|
28
|
+
result.push({
|
|
29
|
+
allowMultiple: filter.allowMultiple,
|
|
30
|
+
grouping: optionGrouping,
|
|
31
|
+
label: option.label,
|
|
32
|
+
name: filter.name,
|
|
33
|
+
operator: getDefaultOperatorName(option),
|
|
34
|
+
scope: option.name,
|
|
35
|
+
searchable: optionSearchable,
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
}
|
|
16
39
|
const searchable = dedup([...grouping, filter.label, ...keywords])
|
|
17
40
|
.join(" ")
|
|
18
41
|
.toLowerCase();
|
|
@@ -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\"\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":"
|
|
1
|
+
{"version":3,"file":"SearchableFilters.js","sources":["../../../src/components/DataTable/SearchableFilters.tsx"],"sourcesContent":["import React, { createContext, useContext, useMemo } from \"react\"\n\nimport { FilterNode, isScopedFilter } 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 /** For a scoped filter's option: the scope to pre-select on the pending filter. */\n scope?: 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\n if (isScopedFilter(filter)) {\n return filter.options.forEach((option) => {\n const optionGrouping = [...grouping, filter.label]\n const optionKeywords = [...keywords, ...(option.keywords || [])]\n const optionSearchable = dedup([\n ...optionGrouping,\n option.label,\n ...optionKeywords,\n ])\n .join(\" \")\n .toLowerCase()\n result.push({\n allowMultiple: filter.allowMultiple,\n grouping: optionGrouping,\n label: option.label,\n name: filter.name,\n operator: getDefaultOperatorName(option),\n scope: option.name,\n searchable: optionSearchable,\n })\n })\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;AAaA,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;AAEA,YAAA,IAAI,cAAc,CAAC,MAAM,CAAC,EAAE;gBAC1B,OAAO,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,KAAI;oBACvC,MAAM,cAAc,GAAG,CAAC,GAAG,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC;AAClD,oBAAA,MAAM,cAAc,GAAG,CAAC,GAAG,QAAQ,EAAE,IAAI,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;oBAChE,MAAM,gBAAgB,GAAG,KAAK,CAAC;AAC7B,wBAAA,GAAG,cAAc;AACjB,wBAAA,MAAM,CAAC,KAAK;AACZ,wBAAA,GAAG,cAAc;qBAClB;yBACE,IAAI,CAAC,GAAG;AACR,yBAAA,WAAW,EAAE;oBAChB,MAAM,CAAC,IAAI,CAAC;wBACV,aAAa,EAAE,MAAM,CAAC,aAAa;AACnC,wBAAA,QAAQ,EAAE,cAAc;wBACxB,KAAK,EAAE,MAAM,CAAC,KAAK;wBACnB,IAAI,EAAE,MAAM,CAAC,IAAI;AACjB,wBAAA,QAAQ,EAAE,sBAAsB,CAAC,MAAM,CAAC;wBACxC,KAAK,EAAE,MAAM,CAAC,IAAI;AAClB,wBAAA,UAAU,EAAE,gBAAgB;AAC7B,qBAAA,CAAC;AACJ,gBAAA,CAAC,CAAC;YACJ;AAEA,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;;;;"}
|
|
@@ -3,8 +3,6 @@ export type CollectionOption = {
|
|
|
3
3
|
label: string;
|
|
4
4
|
value: string;
|
|
5
5
|
};
|
|
6
|
-
/** A single option's `value`, or the selected `value`s when `multiple`. */
|
|
7
|
-
export type CollectionFilterValue = string | string[];
|
|
8
6
|
export type CollectionDisplay = "checkboxes" | "combobox" | "select";
|
|
9
7
|
export declare const COLLECTION_IS: {
|
|
10
8
|
readonly inputType: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collectionFilter.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/collectionFilter.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"collectionFilter.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/collectionFilter.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAEV,gBAAgB,EAChB,cAAc,EAEf,MAAM,eAAe,CAAA;AAItB,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,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;AAEL,wBAAgB,gBAAgB,CAAC,EAC/B,OAAkB,EAClB,QAAQ,EACR,QAAQ,EACR,QAAgB,EAChB,OAAO,EACP,GAAG,MAAM,EACV,EAAE,sBAAsB,GAAG,cAAc,CAazC"}
|
|
@@ -1,13 +1,7 @@
|
|
|
1
|
-
import { Checkbox } from '../checkbox/Checkbox.js';
|
|
2
|
-
import { CheckboxGroup } from '../checkbox-group/CheckboxGroup.js';
|
|
3
|
-
import { ComboBox, ComboBoxItem } from '../combo-box/ComboBox.js';
|
|
4
|
-
import { Radio } from '../radio/Radio.js';
|
|
5
|
-
import { RadioGroup } from '../radio-group/RadioGroup.js';
|
|
6
|
-
import { Select } from '../select/Select.js';
|
|
7
1
|
import React__default from 'react';
|
|
8
2
|
import { ActiveFilterInstance } from './ActiveFilterInstance.js';
|
|
3
|
+
import { CollectionFilterEditorStatic } from './CollectionEditorsStatic.js';
|
|
9
4
|
import { resolveOperators } from './resolveOperators.js';
|
|
10
|
-
import { isEmptyValue } from './utils.js';
|
|
11
5
|
|
|
12
6
|
const COLLECTION_IS = {
|
|
13
7
|
inputType: { type: "collection" },
|
|
@@ -20,9 +14,6 @@ const COLLECTION_NOT = {
|
|
|
20
14
|
name: "not",
|
|
21
15
|
};
|
|
22
16
|
const COLLECTION_OPERATORS = [COLLECTION_IS, COLLECTION_NOT];
|
|
23
|
-
function orderByOptions(options, selected) {
|
|
24
|
-
return options.filter((o) => selected.has(o.value)).map((o) => o.value);
|
|
25
|
-
}
|
|
26
17
|
function collectionFilter({ display = "select", excludes, includes, multiple = false, options, ...config }) {
|
|
27
18
|
const filter = {
|
|
28
19
|
...config,
|
|
@@ -45,56 +36,9 @@ class CollectionActiveFilter extends ActiveFilterInstance {
|
|
|
45
36
|
.join(", ");
|
|
46
37
|
}
|
|
47
38
|
renderEditor(onChange) {
|
|
48
|
-
|
|
49
|
-
const onCommit = (value) => onChange({ value }, { complete: !isEmptyValue(value) });
|
|
50
|
-
if (display === "combobox") {
|
|
51
|
-
return (React__default.createElement(ComboBox
|
|
52
|
-
// eslint-disable-next-line jsx-a11y/no-autofocus -- the editor only ever renders inside a chip popover that just opened, per ARIA dialog practices
|
|
53
|
-
, {
|
|
54
|
-
// eslint-disable-next-line jsx-a11y/no-autofocus -- the editor only ever renders inside a chip popover that just opened, per ARIA dialog practices
|
|
55
|
-
autoFocus: true, hideLabel: true, label: this.operator.label, selectionMode: multiple ? "multiple" : "single", value: this.value, onChange: (value) => {
|
|
56
|
-
if (Array.isArray(value)) {
|
|
57
|
-
onCommit(orderByOptions(options, new Set(value.map(String))));
|
|
58
|
-
}
|
|
59
|
-
else if (value !== null) {
|
|
60
|
-
onCommit(String(value));
|
|
61
|
-
}
|
|
62
|
-
} }, options.map((option) => (React__default.createElement(ComboBoxItem, { key: option.value, id: option.value }, option.label)))));
|
|
63
|
-
}
|
|
64
|
-
if (multiple) {
|
|
65
|
-
const selected = Array.isArray(this.value) ? this.value : [this.value];
|
|
66
|
-
return (React__default.createElement(CheckboxesEditor, { label: this.filter.label, options: options, value: selected, onCommit: onCommit }));
|
|
67
|
-
}
|
|
68
|
-
const selected = Array.isArray(this.value) ? this.value[0] : this.value;
|
|
69
|
-
if (display === "checkboxes") {
|
|
70
|
-
return (React__default.createElement(RadiosEditor, { label: this.filter.label, name: this.filter.name, options: options, value: selected, onCommit: onCommit }));
|
|
71
|
-
}
|
|
72
|
-
return (React__default.createElement(Select
|
|
73
|
-
// eslint-disable-next-line jsx-a11y/no-autofocus -- the editor only ever renders inside a chip popover that just opened, per ARIA dialog practices
|
|
74
|
-
, {
|
|
75
|
-
// eslint-disable-next-line jsx-a11y/no-autofocus -- the editor only ever renders inside a chip popover that just opened, per ARIA dialog practices
|
|
76
|
-
autoFocus: true, hideLabel: true, label: this.operator.label, options: options, value: selected, onChange: (e) => onCommit(e.target.value) }));
|
|
39
|
+
return (React__default.createElement(CollectionFilterEditorStatic, { config: this.config, onChange: onChange, operator: this.operator, value: this.value, filter: this.filter }));
|
|
77
40
|
}
|
|
78
41
|
}
|
|
79
|
-
function CheckboxesEditor({ label, onCommit, options, value, }) {
|
|
80
|
-
const toggle = (optionValue, checked) => {
|
|
81
|
-
const next = new Set(value);
|
|
82
|
-
if (checked)
|
|
83
|
-
next.add(optionValue);
|
|
84
|
-
else
|
|
85
|
-
next.delete(optionValue);
|
|
86
|
-
onCommit(orderByOptions(options, next));
|
|
87
|
-
};
|
|
88
|
-
return (React__default.createElement(CheckboxGroup, { label: label }, options.map((option, index) => (React__default.createElement(Checkbox, { key: option.value,
|
|
89
|
-
// eslint-disable-next-line jsx-a11y/no-autofocus -- the editor only ever renders inside a chip popover that just opened, per ARIA dialog practices
|
|
90
|
-
autoFocus: index === 0, checked: value.includes(option.value), label: option.label, onChange: (e) => toggle(option.value, e.target.checked) })))));
|
|
91
|
-
}
|
|
92
|
-
function RadiosEditor({ label, name, onCommit, options, value, }) {
|
|
93
|
-
const focusIndex = Math.max(0, options.findIndex((option) => option.value === value));
|
|
94
|
-
return (React__default.createElement(RadioGroup, { label: label }, options.map((option, index) => (React__default.createElement(Radio, { key: option.value,
|
|
95
|
-
// eslint-disable-next-line jsx-a11y/no-autofocus -- the editor only ever renders inside a chip popover that just opened, per ARIA dialog practices
|
|
96
|
-
autoFocus: index === focusIndex, checked: value === option.value, label: option.label, name: name, onChange: () => onCommit(option.value) })))));
|
|
97
|
-
}
|
|
98
42
|
|
|
99
43
|
export { COLLECTION_IS, COLLECTION_NOT, collectionFilter };
|
|
100
44
|
//# sourceMappingURL=collectionFilter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collectionFilter.js","sources":["../../../src/components/DataTable/collectionFilter.tsx"],"sourcesContent":["import { Checkbox } from \"@components/checkbox\"\nimport { CheckboxGroup } from \"@components/checkbox-group\"\nimport { ComboBox, ComboBoxItem } from \"@components/combo-box\"\nimport { Radio } from \"@components/radio\"\nimport { RadioGroup } from \"@components/radio-group\"\nimport { Select } from \"@components/select\"\nimport React from \"react\"\n\nimport { ActiveFilterInstance } from \"./ActiveFilterInstance\"\nimport type {\n FilterChange,\n FilterItemConfig,\n FilterNodeItem,\n Operator,\n} from \"./FilterTypes\"\nimport { resolveOperators } from \"./resolveOperators\"\nimport { isEmptyValue } from \"./utils\"\n\n// A type alias (not an interface) so it satisfies `Select`'s `data-*` index signature.\nexport type CollectionOption = {\n label: string\n value: string\n}\n\n/** A single option's `value`, or the selected `value`s when `multiple`. */\nexport type CollectionFilterValue = string | string[]\n\nexport type CollectionDisplay = \"checkboxes\" | \"combobox\" | \"select\"\n\nexport const COLLECTION_IS = {\n inputType: { type: \"collection\" },\n label: \"is\",\n name: \"eq\",\n} as const satisfies Operator\nexport const COLLECTION_NOT = {\n inputType: { type: \"collection\" },\n label: \"is not\",\n name: \"not\",\n} as const satisfies Operator\n\nconst COLLECTION_OPERATORS = [COLLECTION_IS, COLLECTION_NOT]\n\nexport type CollectionOperatorName =\n (typeof COLLECTION_OPERATORS)[number][\"name\"]\n\nexport type CollectionFilterConfig =\n FilterItemConfig<CollectionOperatorName> & {\n options: CollectionOption[]\n } & (\n | { display?: CollectionDisplay; multiple?: false }\n | { display?: Exclude<CollectionDisplay, \"select\">; multiple: true }\n )\n\nfunction orderByOptions(options: CollectionOption[], selected: Set<string>) {\n return options.filter((o) => selected.has(o.value)).map((o) => o.value)\n}\n\nexport function collectionFilter({\n display = \"select\",\n excludes,\n includes,\n multiple = false,\n options,\n ...config\n}: CollectionFilterConfig): FilterNodeItem {\n const filter: FilterNodeItem = {\n ...config,\n createActiveFilterInstance: (activeFilter, operator) =>\n new CollectionActiveFilter(\n filter,\n operator,\n activeFilter.value as CollectionFilterValue,\n { display, multiple, options }\n ),\n operators: resolveOperators(COLLECTION_OPERATORS, { excludes, includes }),\n }\n return filter\n}\n\nclass CollectionActiveFilter extends ActiveFilterInstance<CollectionFilterValue> {\n constructor(\n filter: FilterNodeItem,\n operator: FilterNodeItem[\"operators\"][number],\n value: CollectionFilterValue,\n private readonly config: {\n display: CollectionDisplay\n multiple: boolean\n options: CollectionOption[]\n }\n ) {\n super(filter, operator, value)\n }\n\n formatValue() {\n const values = Array.isArray(this.value) ? this.value : [this.value]\n return values\n .map(\n (value) =>\n this.config.options.find((option) => option.value === value)?.label ??\n value\n )\n .join(\", \")\n }\n\n renderEditor(onChange: FilterChange) {\n const { display, multiple, options } = this.config\n const onCommit = (value: CollectionFilterValue) =>\n onChange({ value }, { complete: !isEmptyValue(value) })\n\n if (display === \"combobox\") {\n return (\n <ComboBox\n // eslint-disable-next-line jsx-a11y/no-autofocus -- the editor only ever renders inside a chip popover that just opened, per ARIA dialog practices\n autoFocus\n hideLabel\n label={this.operator.label}\n selectionMode={multiple ? \"multiple\" : \"single\"}\n value={this.value}\n onChange={(value: React.Key | React.Key[] | null) => {\n if (Array.isArray(value)) {\n onCommit(orderByOptions(options, new Set(value.map(String))))\n } else if (value !== null) {\n onCommit(String(value))\n }\n }}\n >\n {options.map((option) => (\n <ComboBoxItem key={option.value} id={option.value}>\n {option.label}\n </ComboBoxItem>\n ))}\n </ComboBox>\n )\n }\n\n if (multiple) {\n const selected = Array.isArray(this.value) ? this.value : [this.value]\n return (\n <CheckboxesEditor\n label={this.filter.label}\n options={options}\n value={selected}\n onCommit={onCommit}\n />\n )\n }\n\n const selected = Array.isArray(this.value) ? this.value[0] : this.value\n if (display === \"checkboxes\") {\n return (\n <RadiosEditor\n label={this.filter.label}\n name={this.filter.name}\n options={options}\n value={selected}\n onCommit={onCommit}\n />\n )\n }\n return (\n <Select\n // eslint-disable-next-line jsx-a11y/no-autofocus -- the editor only ever renders inside a chip popover that just opened, per ARIA dialog practices\n autoFocus\n hideLabel\n label={this.operator.label}\n options={options}\n value={selected}\n onChange={(e) => onCommit(e.target.value)}\n />\n )\n }\n}\n\nfunction CheckboxesEditor({\n label,\n onCommit,\n options,\n value,\n}: {\n label: string\n onCommit: (value: string[]) => void\n options: CollectionOption[]\n value: string[]\n}) {\n const toggle = (optionValue: string, checked: boolean) => {\n const next = new Set(value)\n if (checked) next.add(optionValue)\n else next.delete(optionValue)\n onCommit(orderByOptions(options, next))\n }\n return (\n <CheckboxGroup label={label}>\n {options.map((option, index) => (\n <Checkbox\n key={option.value}\n // eslint-disable-next-line jsx-a11y/no-autofocus -- the editor only ever renders inside a chip popover that just opened, per ARIA dialog practices\n autoFocus={index === 0}\n checked={value.includes(option.value)}\n label={option.label}\n onChange={(e) => toggle(option.value, e.target.checked)}\n />\n ))}\n </CheckboxGroup>\n )\n}\n\nfunction RadiosEditor({\n label,\n name,\n onCommit,\n options,\n value,\n}: {\n label: string\n name: string\n onCommit: (value: string) => void\n options: CollectionOption[]\n value: string\n}) {\n const focusIndex = Math.max(\n 0,\n options.findIndex((option) => option.value === value)\n )\n return (\n <RadioGroup label={label}>\n {options.map((option, index) => (\n <Radio\n key={option.value}\n // eslint-disable-next-line jsx-a11y/no-autofocus -- the editor only ever renders inside a chip popover that just opened, per ARIA dialog practices\n autoFocus={index === focusIndex}\n checked={value === option.value}\n label={option.label}\n name={name}\n onChange={() => onCommit(option.value)}\n />\n ))}\n </RadioGroup>\n )\n}\n"],"names":["React"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"collectionFilter.js","sources":["../../../src/components/DataTable/collectionFilter.tsx"],"sourcesContent":["import React from \"react\"\n\nimport { ActiveFilterInstance } from \"./ActiveFilterInstance\"\nimport type { CollectionFilterValue } from \"./CollectionEditorsShared\"\nimport { CollectionFilterEditorStatic } from \"./CollectionEditorsStatic\"\nimport type {\n FilterChange,\n FilterItemConfig,\n FilterNodeItem,\n Operator,\n} from \"./FilterTypes\"\nimport { resolveOperators } from \"./resolveOperators\"\n\n// A type alias (not an interface) so it satisfies `Select`'s `data-*` index signature.\nexport type CollectionOption = {\n label: string\n value: string\n}\n\nexport type CollectionDisplay = \"checkboxes\" | \"combobox\" | \"select\"\n\nexport const COLLECTION_IS = {\n inputType: { type: \"collection\" },\n label: \"is\",\n name: \"eq\",\n} as const satisfies Operator\nexport const COLLECTION_NOT = {\n inputType: { type: \"collection\" },\n label: \"is not\",\n name: \"not\",\n} as const satisfies Operator\n\nconst COLLECTION_OPERATORS = [COLLECTION_IS, COLLECTION_NOT]\n\nexport type CollectionOperatorName =\n (typeof COLLECTION_OPERATORS)[number][\"name\"]\n\nexport type CollectionFilterConfig =\n FilterItemConfig<CollectionOperatorName> & {\n options: CollectionOption[]\n } & (\n | { display?: CollectionDisplay; multiple?: false }\n | { display?: Exclude<CollectionDisplay, \"select\">; multiple: true }\n )\n\nexport function collectionFilter({\n display = \"select\",\n excludes,\n includes,\n multiple = false,\n options,\n ...config\n}: CollectionFilterConfig): FilterNodeItem {\n const filter: FilterNodeItem = {\n ...config,\n createActiveFilterInstance: (activeFilter, operator) =>\n new CollectionActiveFilter(\n filter,\n operator,\n activeFilter.value as CollectionFilterValue,\n { display, multiple, options }\n ),\n operators: resolveOperators(COLLECTION_OPERATORS, { excludes, includes }),\n }\n return filter\n}\n\nclass CollectionActiveFilter extends ActiveFilterInstance<CollectionFilterValue> {\n constructor(\n filter: FilterNodeItem,\n operator: FilterNodeItem[\"operators\"][number],\n value: CollectionFilterValue,\n private readonly config: {\n display: CollectionDisplay\n multiple: boolean\n options: CollectionOption[]\n }\n ) {\n super(filter, operator, value)\n }\n\n formatValue() {\n const values = Array.isArray(this.value) ? this.value : [this.value]\n return values\n .map(\n (value) =>\n this.config.options.find((option) => option.value === value)?.label ??\n value\n )\n .join(\", \")\n }\n\n renderEditor(onChange: FilterChange) {\n return (\n <CollectionFilterEditorStatic\n config={this.config}\n onChange={onChange}\n operator={this.operator}\n value={this.value}\n filter={this.filter}\n />\n )\n }\n}\n"],"names":["React"],"mappings":";;;;;AAqBO,MAAM,aAAa,GAAG;AAC3B,IAAA,SAAS,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE;AACjC,IAAA,KAAK,EAAE,IAAI;AACX,IAAA,IAAI,EAAE,IAAI;;AAEL,MAAM,cAAc,GAAG;AAC5B,IAAA,SAAS,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE;AACjC,IAAA,KAAK,EAAE,QAAQ;AACf,IAAA,IAAI,EAAE,KAAK;;AAGb,MAAM,oBAAoB,GAAG,CAAC,aAAa,EAAE,cAAc,CAAC;AAatD,SAAU,gBAAgB,CAAC,EAC/B,OAAO,GAAG,QAAQ,EAClB,QAAQ,EACR,QAAQ,EACR,QAAQ,GAAG,KAAK,EAChB,OAAO,EACP,GAAG,MAAM,EACc,EAAA;AACvB,IAAA,MAAM,MAAM,GAAmB;AAC7B,QAAA,GAAG,MAAM;QACT,0BAA0B,EAAE,CAAC,YAAY,EAAE,QAAQ,KACjD,IAAI,sBAAsB,CACxB,MAAM,EACN,QAAQ,EACR,YAAY,CAAC,KAA8B,EAC3C,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAC/B;QACH,SAAS,EAAE,gBAAgB,CAAC,oBAAoB,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;KAC1E;AACD,IAAA,OAAO,MAAM;AACf;AAEA,MAAM,sBAAuB,SAAQ,oBAA2C,CAAA;AAK3D,IAAA,MAAA;AAJnB,IAAA,WAAA,CACE,MAAsB,EACtB,QAA6C,EAC7C,KAA4B,EACX,MAIhB,EAAA;AAED,QAAA,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC;QANb,IAAA,CAAA,MAAM,GAAN,MAAM;IAOzB;IAEA,WAAW,GAAA;QACT,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC;AACpE,QAAA,OAAO;aACJ,GAAG,CACF,CAAC,KAAK,KACJ,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,KAAK,KAAK,KAAK,CAAC,EAAE,KAAK;AACnE,YAAA,KAAK;aAER,IAAI,CAAC,IAAI,CAAC;IACf;AAEA,IAAA,YAAY,CAAC,QAAsB,EAAA;AACjC,QAAA,QACEA,cAAA,CAAA,aAAA,CAAC,4BAA4B,EAAA,EAC3B,MAAM,EAAE,IAAI,CAAC,MAAM,EACnB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,IAAI,CAAC,QAAQ,EACvB,KAAK,EAAE,IAAI,CAAC,KAAK,EACjB,MAAM,EAAE,IAAI,CAAC,MAAM,EAAA,CACnB;IAEN;AACD;;;;"}
|