@planningcenter/tapestry 4.8.0-rc.1 → 4.8.1-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/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.d.ts.map +1 -1
- package/dist/components/DataTable/FilterControls.js +17 -11
- package/dist/components/DataTable/FilterControls.js.map +1 -1
- package/dist/components/DataTable/FilterControls.module.css.js +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/TruncatedFilterLabel.d.ts +16 -0
- package/dist/components/DataTable/TruncatedFilterLabel.d.ts.map +1 -0
- package/dist/components/DataTable/TruncatedFilterLabel.js +41 -0
- package/dist/components/DataTable/TruncatedFilterLabel.js.map +1 -0
- 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 +1329 -1318
- package/dist/reactRender.css.map +1 -1
- package/dist/reactRenderLegacy.css +1329 -1318
- package/dist/reactRenderLegacy.css.map +1 -1
- package/dist/unstable.css +11 -0
- package/dist/unstable.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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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilterControls.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/FilterControls.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAuD,MAAM,OAAO,CAAA;AAY3E,OAAO,KAAK,EACV,YAAY,EACZ,UAAU,EAGX,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"FilterControls.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/FilterControls.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAuD,MAAM,OAAO,CAAA;AAY3E,OAAO,KAAK,EACV,YAAY,EACZ,UAAU,EAGX,MAAM,eAAe,CAAA;AAmItB,MAAM,WAAW,mBAAmB;IAClC,2FAA2F;IAC3F,aAAa,CAAC,EAAE,YAAY,EAAE,CAAA;IAC9B,OAAO,EAAE,UAAU,EAAE,CAAA;IACrB,uDAAuD;IACvD,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,gDAAgD;IAChD,aAAa,CAAC,EAAE,MAAM,IAAI,CAAA;CAC3B;AAED,wEAAwE;AACxE,wBAAgB,cAAc,CAAC,EAC7B,aAAkB,EAClB,OAAO,EACP,eAAuB,EACvB,aAAwB,GACzB,EAAE,mBAAmB,qBAgHrB;yBArHe,cAAc"}
|
|
@@ -20,9 +20,12 @@ import { useAddFilterButtonRef } from './FilterContext.js';
|
|
|
20
20
|
import styles from './FilterControls.module.css.js';
|
|
21
21
|
import { PendingFilterQueue, useQueuePendingFilter, useIsFilterTaken } from './PendingFilterQueue.js';
|
|
22
22
|
import { useSearchableFilters } from './SearchableFilters.js';
|
|
23
|
+
import { TruncatedFilterLabel } from './TruncatedFilterLabel.js';
|
|
23
24
|
import { getDefaultOperatorName } from './utils.js';
|
|
24
25
|
|
|
25
26
|
const NOOP_ACTION = () => { };
|
|
27
|
+
/** Mirrors the `::after` separator in `.search-result-grouping-chevron`. */
|
|
28
|
+
const GROUPING_SEPARATOR = " › ";
|
|
26
29
|
const useVisibleChildren = (group) => {
|
|
27
30
|
const isFilterTaken = useIsFilterTaken();
|
|
28
31
|
return group.children.filter((child) => isFilterNodeVisible(child, isFilterTaken));
|
|
@@ -58,8 +61,7 @@ function FilterItem({ node }) {
|
|
|
58
61
|
name: node.name,
|
|
59
62
|
operator: getDefaultOperatorName(node),
|
|
60
63
|
value: undefined,
|
|
61
|
-
}), textValue: node.label },
|
|
62
|
-
React__default.createElement("span", { slot: "label" }, node.label)));
|
|
64
|
+
}), textValue: node.label }, ({ isFocusVisible, isHovered }) => (React__default.createElement(TruncatedFilterLabel, { active: isFocusVisible || isHovered, text: node.label }))));
|
|
63
65
|
}
|
|
64
66
|
function FilterGroupSection({ group }) {
|
|
65
67
|
const visibleChildren = useVisibleChildren(group);
|
|
@@ -116,16 +118,20 @@ function SearchResultItem({ filter }) {
|
|
|
116
118
|
if (hide)
|
|
117
119
|
return null;
|
|
118
120
|
const [, ...remainingGrouping] = filter.grouping;
|
|
119
|
-
|
|
121
|
+
const resultId = filter.scope
|
|
122
|
+
? `filter-search-${filter.name}-${filter.scope}`
|
|
123
|
+
: `filter-search-${filter.name}`;
|
|
124
|
+
const visibleLabel = [...remainingGrouping, filter.label].join(GROUPING_SEPARATOR);
|
|
125
|
+
return (React__default.createElement(DropdownAction, { key: resultId, textValue: filter.searchable, id: resultId, onAction: () => queuePendingFilter({
|
|
120
126
|
name: filter.name,
|
|
121
127
|
operator: filter.operator,
|
|
128
|
+
scope: filter.scope,
|
|
122
129
|
value: undefined,
|
|
123
|
-
}) },
|
|
124
|
-
React__default.createElement("span", {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
filter.label)));
|
|
130
|
+
}) }, ({ isFocusVisible, isHovered }) => (React__default.createElement(TruncatedFilterLabel, { active: isFocusVisible || isHovered, text: visibleLabel },
|
|
131
|
+
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}` },
|
|
132
|
+
grouping,
|
|
133
|
+
React__default.createElement("span", { className: styles["search-result-grouping-separator"] }, ", ")))))),
|
|
134
|
+
filter.label))));
|
|
129
135
|
}
|
|
130
136
|
function SearchResults() {
|
|
131
137
|
const filters = useSearchableFilters();
|
|
@@ -141,8 +147,8 @@ function SearchResults() {
|
|
|
141
147
|
return { groups: groupedItems, ungrouped: ungroupedItems };
|
|
142
148
|
}, [filters]);
|
|
143
149
|
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 }))))))));
|
|
150
|
+
ungrouped.map((filter) => (React__default.createElement(SearchResultItem, { key: filter.scope ? `${filter.name}-${filter.scope}` : filter.name, filter: filter }))),
|
|
151
|
+
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
152
|
}
|
|
147
153
|
function prefixSearch(string, query) {
|
|
148
154
|
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 { TruncatedFilterLabel } from \"./TruncatedFilterLabel\"\nimport { getDefaultOperatorName } from \"./utils\"\n\nconst NOOP_ACTION = () => {}\n\n/** Mirrors the `::after` separator in `.search-result-grouping-chevron`. */\nconst GROUPING_SEPARATOR = \" › \"\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 {({ isFocusVisible, isHovered }) => (\n <TruncatedFilterLabel\n active={isFocusVisible || isHovered}\n text={node.label}\n />\n )}\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 const visibleLabel = [...remainingGrouping, filter.label].join(\n GROUPING_SEPARATOR\n )\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 {({ isFocusVisible, isHovered }) => (\n <TruncatedFilterLabel\n active={isFocusVisible || isHovered}\n text={visibleLabel}\n >\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 </TruncatedFilterLabel>\n )}\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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"}
|
|
@@ -1,4 +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"};
|
|
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","truncation-tooltip":"truncation-tooltip-q6xkT"};
|
|
2
2
|
|
|
3
3
|
export { styles as default };
|
|
4
4
|
//# sourceMappingURL=FilterControls.module.css.js.map
|
|
@@ -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;;;;"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React, { type ReactNode } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* A filter menu item's label, with a tooltip repeating the full text when it
|
|
4
|
+
* is too long to fit. The tooltip is hidden from assistive tech — the
|
|
5
|
+
* untruncated label is already the item's accessible name, so announcing it
|
|
6
|
+
* again would be redundant.
|
|
7
|
+
*/
|
|
8
|
+
export declare function TruncatedFilterLabel({ active, children, text, }: {
|
|
9
|
+
/** Whether the owning menu item is hovered or focused. */
|
|
10
|
+
active: boolean;
|
|
11
|
+
/** Label markup. Defaults to `text` when omitted. */
|
|
12
|
+
children?: ReactNode;
|
|
13
|
+
/** The full label, shown in the tooltip when the visible label is clipped. */
|
|
14
|
+
text: string;
|
|
15
|
+
}): React.JSX.Element;
|
|
16
|
+
//# sourceMappingURL=TruncatedFilterLabel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TruncatedFilterLabel.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/TruncatedFilterLabel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EACZ,KAAK,SAAS,EAKf,MAAM,OAAO,CAAA;AAad;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,MAAM,EACN,QAAQ,EACR,IAAI,GACL,EAAE;IACD,0DAA0D;IAC1D,MAAM,EAAE,OAAO,CAAA;IACf,qDAAqD;IACrD,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,8EAA8E;IAC9E,IAAI,EAAE,MAAM,CAAA;CACb,qBAgBA"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import React__default, { useRef, useState, useLayoutEffect } from 'react';
|
|
2
|
+
import { Overlay } from 'react-aria/Overlay';
|
|
3
|
+
import { useOverlayPosition } from 'react-aria/useOverlayPosition';
|
|
4
|
+
import styles from './FilterControls.module.css.js';
|
|
5
|
+
|
|
6
|
+
const TRUNCATION_TOLERANCE = 1;
|
|
7
|
+
const TOOLTIP_OFFSET = 12;
|
|
8
|
+
function isTruncated(el) {
|
|
9
|
+
return !!el && el.scrollWidth - el.clientWidth > TRUNCATION_TOLERANCE;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* A filter menu item's label, with a tooltip repeating the full text when it
|
|
13
|
+
* is too long to fit. The tooltip is hidden from assistive tech — the
|
|
14
|
+
* untruncated label is already the item's accessible name, so announcing it
|
|
15
|
+
* again would be redundant.
|
|
16
|
+
*/
|
|
17
|
+
function TruncatedFilterLabel({ active, children, text, }) {
|
|
18
|
+
const labelRef = useRef(null);
|
|
19
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
20
|
+
useLayoutEffect(() => {
|
|
21
|
+
setIsOpen(active && isTruncated(labelRef.current));
|
|
22
|
+
}, [active, text]);
|
|
23
|
+
return (React__default.createElement(React__default.Fragment, null,
|
|
24
|
+
React__default.createElement("span", { ref: labelRef, slot: "label" }, children ?? text),
|
|
25
|
+
isOpen && React__default.createElement(LabelTooltip, { targetRef: labelRef, text: text })));
|
|
26
|
+
}
|
|
27
|
+
function LabelTooltip({ targetRef, text, }) {
|
|
28
|
+
const overlayRef = useRef(null);
|
|
29
|
+
const { overlayProps } = useOverlayPosition({
|
|
30
|
+
isOpen: true,
|
|
31
|
+
offset: TOOLTIP_OFFSET,
|
|
32
|
+
overlayRef,
|
|
33
|
+
placement: "bottom",
|
|
34
|
+
targetRef,
|
|
35
|
+
});
|
|
36
|
+
return (React__default.createElement(Overlay, { disableFocusManagement: true },
|
|
37
|
+
React__default.createElement("div", { ...overlayProps, ref: overlayRef, "aria-hidden": true, className: styles["truncation-tooltip"] }, text)));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export { TruncatedFilterLabel };
|
|
41
|
+
//# sourceMappingURL=TruncatedFilterLabel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TruncatedFilterLabel.js","sources":["../../../src/components/DataTable/TruncatedFilterLabel.tsx"],"sourcesContent":["import React, {\n type ReactNode,\n type RefObject,\n useLayoutEffect,\n useRef,\n useState,\n} from \"react\"\nimport { Overlay } from \"react-aria/Overlay\"\nimport { useOverlayPosition } from \"react-aria/useOverlayPosition\"\n\nimport styles from \"./FilterControls.module.css\"\n\nconst TRUNCATION_TOLERANCE = 1\nconst TOOLTIP_OFFSET = 12\n\nfunction isTruncated(el: HTMLElement | null) {\n return !!el && el.scrollWidth - el.clientWidth > TRUNCATION_TOLERANCE\n}\n\n/**\n * A filter menu item's label, with a tooltip repeating the full text when it\n * is too long to fit. The tooltip is hidden from assistive tech — the\n * untruncated label is already the item's accessible name, so announcing it\n * again would be redundant.\n */\nexport function TruncatedFilterLabel({\n active,\n children,\n text,\n}: {\n /** Whether the owning menu item is hovered or focused. */\n active: boolean\n /** Label markup. Defaults to `text` when omitted. */\n children?: ReactNode\n /** The full label, shown in the tooltip when the visible label is clipped. */\n text: string\n}) {\n const labelRef = useRef<HTMLSpanElement>(null)\n const [isOpen, setIsOpen] = useState(false)\n\n useLayoutEffect(() => {\n setIsOpen(active && isTruncated(labelRef.current))\n }, [active, text])\n\n return (\n <>\n <span ref={labelRef} slot=\"label\">\n {children ?? text}\n </span>\n {isOpen && <LabelTooltip targetRef={labelRef} text={text} />}\n </>\n )\n}\n\nfunction LabelTooltip({\n targetRef,\n text,\n}: {\n targetRef: RefObject<HTMLElement>\n text: string\n}) {\n const overlayRef = useRef<HTMLDivElement>(null)\n const { overlayProps } = useOverlayPosition({\n isOpen: true,\n offset: TOOLTIP_OFFSET,\n overlayRef,\n placement: \"bottom\",\n targetRef,\n })\n\n return (\n <Overlay disableFocusManagement>\n <div\n {...overlayProps}\n ref={overlayRef}\n aria-hidden\n className={styles[\"truncation-tooltip\"]}\n >\n {text}\n </div>\n </Overlay>\n )\n}\n"],"names":["React"],"mappings":";;;;;AAYA,MAAM,oBAAoB,GAAG,CAAC;AAC9B,MAAM,cAAc,GAAG,EAAE;AAEzB,SAAS,WAAW,CAAC,EAAsB,EAAA;AACzC,IAAA,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,WAAW,GAAG,EAAE,CAAC,WAAW,GAAG,oBAAoB;AACvE;AAEA;;;;;AAKG;AACG,SAAU,oBAAoB,CAAC,EACnC,MAAM,EACN,QAAQ,EACR,IAAI,GAQL,EAAA;AACC,IAAA,MAAM,QAAQ,GAAG,MAAM,CAAkB,IAAI,CAAC;IAC9C,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;IAE3C,eAAe,CAAC,MAAK;QACnB,SAAS,CAAC,MAAM,IAAI,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AACpD,IAAA,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAElB,IAAA,QACEA,cAAA,CAAA,aAAA,CAAAA,cAAA,CAAA,QAAA,EAAA,IAAA;QACEA,cAAA,CAAA,aAAA,CAAA,MAAA,EAAA,EAAM,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAC,OAAO,EAAA,EAC9B,QAAQ,IAAI,IAAI,CACZ;AACN,QAAA,MAAM,IAAIA,cAAA,CAAA,aAAA,CAAC,YAAY,EAAA,EAAC,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAA,CAAI,CAC3D;AAEP;AAEA,SAAS,YAAY,CAAC,EACpB,SAAS,EACT,IAAI,GAIL,EAAA;AACC,IAAA,MAAM,UAAU,GAAG,MAAM,CAAiB,IAAI,CAAC;AAC/C,IAAA,MAAM,EAAE,YAAY,EAAE,GAAG,kBAAkB,CAAC;AAC1C,QAAA,MAAM,EAAE,IAAI;AACZ,QAAA,MAAM,EAAE,cAAc;QACtB,UAAU;AACV,QAAA,SAAS,EAAE,QAAQ;QACnB,SAAS;AACV,KAAA,CAAC;AAEF,IAAA,QACEA,cAAA,CAAA,aAAA,CAAC,OAAO,EAAA,EAAC,sBAAsB,EAAA,IAAA,EAAA;AAC7B,QAAAA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAA,GACM,YAAY,EAChB,GAAG,EAAE,UAAU,uBAEf,SAAS,EAAE,MAAM,CAAC,oBAAoB,CAAC,EAAA,EAEtC,IAAI,CACD,CACE;AAEd;;;;"}
|
|
@@ -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
|