@jobber/components 4.74.2 → 4.76.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.
@@ -26,10 +26,22 @@ export interface ComboboxProps {
26
26
  * Callback function invoked upon the Combobox menu closing.
27
27
  */
28
28
  readonly onClose?: () => void;
29
+ /**
30
+ * Debounced callback function invoked on Combobox search input change. Receives the current search value as an argument.
31
+ */
32
+ readonly onSearch?: (searchValue: string) => void;
33
+ /**
34
+ * The amount of time in ms to debounce the onSearch callback. Defaults to 300ms.
35
+ */
36
+ readonly onSearchDebounce?: number;
29
37
  /**
30
38
  * The Chip heading for the trigger
31
39
  */
32
40
  readonly label?: string;
41
+ /**
42
+ * Should the Combobox display the loading state.
43
+ */
44
+ readonly loading?: boolean;
33
45
  }
34
46
  export interface ComboboxActivatorProps {
35
47
  readonly children: React.ReactElement;
@@ -81,6 +93,10 @@ export interface ComboboxContentProps {
81
93
  * Setter for the current search term.
82
94
  */
83
95
  readonly setSearchValue: Dispatch<SetStateAction<string>>;
96
+ /**
97
+ * Function called when search input changes.
98
+ */
99
+ readonly handleSearchChange: (value: string) => void;
84
100
  /**
85
101
  * Reference to the wrapping div element of all the Combobox pieces
86
102
  */
@@ -97,6 +113,10 @@ export interface ComboboxContentProps {
97
113
  * The full set of options for the Combobox in the shape of data, not elements.
98
114
  */
99
115
  readonly options: ComboboxOption[];
116
+ /**
117
+ * Should loading state be shown.
118
+ */
119
+ readonly loading?: boolean;
100
120
  }
101
121
  export interface ComboboxSearchProps {
102
122
  /**
@@ -115,6 +135,10 @@ export interface ComboboxSearchProps {
115
135
  * Setter for the search input value.
116
136
  */
117
137
  setSearchValue: Dispatch<SetStateAction<string>>;
138
+ /**
139
+ * Function called when search input changes.
140
+ */
141
+ readonly handleSearchChange: (value: string) => void;
118
142
  }
119
143
  export interface ComboboxHeaderProps {
120
144
  /**
@@ -143,10 +167,6 @@ export interface ComboboxListProps {
143
167
  * The options to display in the list. May be the full set of the Combobox or could be filtered.
144
168
  */
145
169
  readonly options: ComboboxOption[];
146
- /**
147
- * Used to determine if the empty state should be shown and given priority over the options list.
148
- */
149
- readonly showEmptyState: boolean;
150
170
  /**
151
171
  * The currently selected options.
152
172
  */
@@ -167,6 +187,10 @@ export interface ComboboxListProps {
167
187
  * The noun to be used in the empty state message.
168
188
  */
169
189
  readonly subjectNoun?: string;
190
+ /**
191
+ * Should loading state be shown.
192
+ */
193
+ readonly loading?: boolean;
170
194
  }
171
195
  export interface ComboboxActionProps {
172
196
  /**
@@ -10,6 +10,8 @@ type UseComboboxReturn = {
10
10
  selectedOptions: ComboboxOption[];
11
11
  selectedStateSetter: (selection: ComboboxOption[]) => void;
12
12
  shouldScroll: MutableRefObject<boolean>;
13
+ internalFilteredOptions: ComboboxOption[];
14
+ handleSearchChange: (value: string) => void;
13
15
  } & UseMakeComboboxHandlersReturn;
14
- export declare function useCombobox(selected: ComboboxOption[], onSelect: (selection: ComboboxOption[]) => void, onClose?: () => void, multiSelect?: boolean): UseComboboxReturn;
16
+ export declare function useCombobox(selected: ComboboxOption[], onSelect: (selection: ComboboxOption[]) => void, options: ComboboxOption[], onClose?: () => void, multiSelect?: boolean, onSearch?: (searchValue: string) => void, debounceTime?: number): UseComboboxReturn;
15
17
  export {};
@@ -1,8 +1,7 @@
1
1
  /// <reference types="react" />
2
2
  import { ComboboxOption } from "../Combobox.types";
3
3
  interface useComboboxContent {
4
- filteredOptions: ComboboxOption[];
5
4
  optionsListRef: React.RefObject<HTMLUListElement>;
6
5
  }
7
- export declare function useComboboxContent(options: ComboboxOption[], open: boolean, selected: ComboboxOption[], searchValue: string): useComboboxContent;
6
+ export declare function useComboboxContent(open: boolean, selected: ComboboxOption[]): useComboboxContent;
8
7
  export {};
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var Combobox = require('../Combobox-95b3c413.js');
5
+ var Combobox = require('../Combobox-ac089920.js');
6
6
  require('react');
7
7
  require('classnames');
8
8
  require('react-dom');
@@ -11,7 +11,9 @@ require('../Icon-405a216c.js');
11
11
  require('@jobber/design');
12
12
  require('../Text-259af966.js');
13
13
  require('../Typography-c45bf216.js');
14
+ require('../Glimmer-f40d5ea5.js');
14
15
  require('../tslib.es6-5b8768b7.js');
16
+ require('../Content-e3f7b6fc.js');
15
17
  require('../Button-b73a5e01.js');
16
18
  require('react-router-dom');
17
19
  require('@jobber/hooks/useRefocusOnActivator');
@@ -24,6 +26,7 @@ require('../Avatar-76a799fa.js');
24
26
  require('color');
25
27
  require('../Tooltip-27771182.js');
26
28
  require('framer-motion');
29
+ require('lodash/debounce');
27
30
  require('@jobber/hooks/useAssert');
28
31
 
29
32
 
@@ -6,6 +6,7 @@ var ReactDOM = require('react-dom');
6
6
  var styleInject_es = require('./style-inject.es-9d2f5f4e.js');
7
7
  var Icon = require('./Icon-405a216c.js');
8
8
  var Text = require('./Text-259af966.js');
9
+ var Glimmer = require('./Glimmer-f40d5ea5.js');
9
10
  var tslib_es6 = require('./tslib.es6-5b8768b7.js');
10
11
  var Typography = require('./Typography-c45bf216.js');
11
12
  var Button = require('./Button-b73a5e01.js');
@@ -14,6 +15,7 @@ var useFocusTrap = require('@jobber/hooks/useFocusTrap');
14
15
  var reactPopper = require('react-popper');
15
16
  var useOnKeyDown = require('@jobber/hooks/useOnKeyDown');
16
17
  var Chip = require('./Chip-c91fd6c8.js');
18
+ var debounce = require('lodash/debounce');
17
19
  require('@jobber/design');
18
20
  var useAssert = require('@jobber/hooks/useAssert');
19
21
 
@@ -22,6 +24,7 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
22
24
  var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
23
25
  var classnames__default = /*#__PURE__*/_interopDefaultLegacy(classnames);
24
26
  var ReactDOM__default = /*#__PURE__*/_interopDefaultLegacy(ReactDOM);
27
+ var debounce__default = /*#__PURE__*/_interopDefaultLegacy(debounce);
25
28
 
26
29
  var css_248z$6 = ".m1w5vdUZ6rQ- {\n z-index: 1002;\n z-index: var(--elevation-tooltip);\n max-width: var(--popover--width);\n min-width: calc((16px * 4) * 3.75);\n min-width: calc(calc(16px * 4) * 3.75);\n min-width: calc(var(--space-extravagant) * 3.75);\n box-shadow: 0px calc(16px / 16) calc(16px / 4) 0px\n rgba(0, 0, 0, 0.1),\n 0px calc(16px / 4) 12px 0px rgba(0, 0, 0, 0.05);\n box-shadow: var(--shadow-base);\n margin-top: calc(16px / 2);\n margin-top: var(--space-small);\n border: calc(16px / 16) solid rgb(217, 223, 225);\n border: var(--border-base) solid var(--color-border);\n border-radius: calc(16px / 2);\n border-radius: var(--radius-larger);\n overflow: auto;\n background: rgba(255, 255, 255, 1);\n background: var(--color-surface);\n}\n\n.jobber-retheme .m1w5vdUZ6rQ- {\n border-radius: calc(16px / 8);\n border-radius: var(--radius-base);\n}\n\n/* CAUTION: Tests for content visibility assume this class' presence hides the content\n* so please be careful if you change this class name, or the css rules within.\n*/\n\n.m1w5vdUZ6rQ-.Zlkv2HA096A- {\n display: none;\n visibility: hidden;\n}\n\n.m1w5vdUZ6rQ-:focus,\n.m1w5vdUZ6rQ-:focus-visible {\n outline: none;\n}\n\n.m1w5vdUZ6rQ-:focus-visible {\n box-shadow: 0px 0px 0px calc(16px / 8) rgba(255, 255, 255, 1),\n 0px 0px 0px calc(16px / 4) rgb(147, 161, 169);\n box-shadow: var(--shadow-focus);\n}\n\n.YQry-Rd6zfQ- {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-direction: column;\n flex-direction: column;\n position: sticky;\n gap: calc(16px / 4);\n gap: var(--space-smaller);\n bottom: 0;\n width: 100%;\n background-color: rgba(255, 255, 255, 1);\n background-color: var(--color-surface);\n}\n\n.TcpqL34s4lI- {\n padding-bottom: calc(16px / 2);\n padding-bottom: var(--space-small);\n}\n";
27
30
  var styles$6 = {"content":"m1w5vdUZ6rQ-","hidden":"Zlkv2HA096A-","actions":"YQry-Rd6zfQ-","actionPadding":"TcpqL34s4lI-"};
@@ -48,15 +51,17 @@ function ComboboxContentSearch(props) {
48
51
  function clearSearch() {
49
52
  var _a;
50
53
  props.setSearchValue("");
54
+ props.handleSearchChange("");
51
55
  (_a = searchRef.current) === null || _a === void 0 ? void 0 : _a.focus();
52
56
  }
53
57
  function handleSearch(event) {
54
- props.setSearchValue(event.target.value);
58
+ props.setSearchValue(event.currentTarget.value);
59
+ props.handleSearchChange(event.currentTarget.value);
55
60
  }
56
61
  }
57
62
 
58
- var css_248z$4 = ".SgMzjOcdE-E- {\n position: relative;\n padding: calc(16px / 2) 0;\n padding: var(--space-small) 0;\n}\n\n.TwoTCjgcssc- {\n display: -ms-flexbox;\n display: flex;\n max-height: calc((16px / 2) * 33.33);\n max-height: calc(calc(16px / 2) * 33.33);\n max-height: calc(var(--space-small) * 33.33);\n margin: 0;\n padding: 0;\n overflow: auto;\n list-style: none;\n -ms-flex-direction: column;\n flex-direction: column;\n gap: calc(16px / 4);\n gap: var(--space-smaller);\n}\n\n._8T5M7MGwCRE-,\n._4y5NXkNeIQM- {\n padding: calc(16px / 2) calc(16px * 1);\n padding: var(--space-small) var(--space-base);\n}\n\n.SgMzjOcdE-E-::before,\n.SgMzjOcdE-E-::after {\n content: \"\";\n display: block;\n position: absolute;\n right: 0;\n left: 0;\n height: calc(16px * 1);\n height: var(--space-base);\n pointer-events: none;\n transition: opacity 0.3s ease-in-out;\n}\n\n.SgMzjOcdE-E-::after {\n bottom: calc(16px / 2);\n bottom: var(--space-small);\n background: linear-gradient(\n 180deg,\n rgba(255, 255, 255, 0) 0%,\n rgb(255, 255, 255) 100%\n );\n}\n\n.SgMzjOcdE-E-::before {\n top: calc(16px / 2);\n top: var(--space-small);\n background: linear-gradient(\n to bottom,\n rgba(255, 255, 255, 1),\n rgba(255, 255, 255, 0)\n );\n}\n\n.T6E3VwBGoQM-::before,\n._6HQzxMQkXnE-::before {\n opacity: 0;\n}\n\n._5YsJZyMDkbA-::after,\n._6HQzxMQkXnE-::after {\n opacity: 0;\n}\n";
59
- var styles$4 = {"container":"SgMzjOcdE-E-","optionsList":"TwoTCjgcssc-","filterMessage":"_8T5M7MGwCRE-","emptyStateMessage":"_4y5NXkNeIQM-","scrollTop":"T6E3VwBGoQM-","scrollNone":"_6HQzxMQkXnE-","scrollBottom":"_5YsJZyMDkbA-"};
63
+ var css_248z$4 = ".SgMzjOcdE-E- {\n position: relative;\n padding: calc(16px / 2) 0;\n padding: var(--space-small) 0;\n}\n\n.TwoTCjgcssc- {\n display: -ms-flexbox;\n display: flex;\n max-height: calc((16px / 2) * 33.33);\n max-height: calc(calc(16px / 2) * 33.33);\n max-height: calc(var(--space-small) * 33.33);\n margin: 0;\n padding: 0;\n overflow: auto;\n list-style: none;\n -ms-flex-direction: column;\n flex-direction: column;\n gap: calc(16px / 4);\n gap: var(--space-smaller);\n}\n\n._8T5M7MGwCRE-,\n._4y5NXkNeIQM- {\n padding: calc(16px / 2) calc(16px * 1);\n padding: var(--space-small) var(--space-base);\n}\n\n.SgMzjOcdE-E-::before,\n.SgMzjOcdE-E-::after {\n content: \"\";\n display: block;\n position: absolute;\n right: 0;\n left: 0;\n height: calc(16px * 1);\n height: var(--space-base);\n pointer-events: none;\n transition: opacity 0.3s ease-in-out;\n}\n\n.SgMzjOcdE-E-::after {\n bottom: calc(16px / 2);\n bottom: var(--space-small);\n background: linear-gradient(\n 180deg,\n rgba(255, 255, 255, 0) 0%,\n rgb(255, 255, 255) 100%\n );\n}\n\n.SgMzjOcdE-E-::before {\n top: calc(16px / 2);\n top: var(--space-small);\n background: linear-gradient(\n to bottom,\n rgba(255, 255, 255, 1),\n rgba(255, 255, 255, 0)\n );\n}\n\n.T6E3VwBGoQM-::before,\n._6HQzxMQkXnE-::before {\n opacity: 0;\n}\n\n._5YsJZyMDkbA-::after,\n._6HQzxMQkXnE-::after {\n opacity: 0;\n}\n\n.A6z4OI58xoE- {\n padding: calc(16px * 1) calc(16px * 1);\n padding: var(--space-base) var(--space-base);\n}\n";
64
+ var styles$4 = {"container":"SgMzjOcdE-E-","optionsList":"TwoTCjgcssc-","filterMessage":"_8T5M7MGwCRE-","emptyStateMessage":"_4y5NXkNeIQM-","scrollTop":"T6E3VwBGoQM-","scrollNone":"_6HQzxMQkXnE-","scrollBottom":"_5YsJZyMDkbA-","loadingContainer":"A6z4OI58xoE-"};
60
65
  styleInject_es.styleInject(css_248z$4);
61
66
 
62
67
  var css_248z$3 = "._5QdRGmaNHvc- {\n display: -ms-flexbox;\n display: flex;\n min-height: calc((calc(16px * 3) - calc(16px / 4)));\n min-height: calc((var(--space-largest) - var(--space-smaller)));\n box-sizing: border-box;\n margin: 0 calc(16px / 2);\n margin: 0 var(--space-small);\n padding: calc(16px / 2);\n padding: var(--space-small);\n border-radius: calc(16px / 4);\n border-radius: var(--radius-large);\n color: rgb(1, 41, 57);\n color: var(--color-heading);\n font-weight: 500;\n cursor: pointer;\n transition: all 200ms;\n transition: all var(--timing-base);\n -ms-flex-pack: justify;\n justify-content: space-between;\n -ms-flex-align: center;\n align-items: center;\n}\n\n.jobber-retheme ._5QdRGmaNHvc- {\n border-radius: calc(16px / 8);\n border-radius: var(--radius-base);\n}\n\n._5QdRGmaNHvc-:hover,\n._5QdRGmaNHvc-:focus-visible {\n background-color: rgb(244, 246, 250);\n background-color: var(--color-surface--hover);\n}\n\n._5QdRGmaNHvc-:focus,\n._5QdRGmaNHvc-:focus-visible {\n outline: none;\n}\n\n._5QdRGmaNHvc-:focus-visible {\n box-shadow: 0px 0px 0px calc(16px / 8) rgba(255, 255, 255, 1),\n 0px 0px 0px calc(16px / 4) rgb(147, 161, 169);\n box-shadow: var(--shadow-focus);\n}\n";
@@ -79,11 +84,37 @@ function ComboboxOption(props) {
79
84
  }
80
85
 
81
86
  function ComboboxContentList(props) {
87
+ const optionsExist = props.options.length > 0;
88
+ const showOptions = optionsExist && !props.loading;
89
+ const hasSearchTerm = props.searchValue.length > 0;
90
+ const { listScrollState } = useScrollState(props.optionsListRef, props.options);
91
+ return (React__default["default"].createElement("div", { className: classnames__default["default"](styles$4.container, styles$4[listScrollState]) },
92
+ optionsExist && (React__default["default"].createElement("ul", { className: styles$4.optionsList, role: "listbox", "aria-multiselectable": props.multiselect, ref: props.optionsListRef },
93
+ showOptions &&
94
+ props.options.map(option => {
95
+ return (React__default["default"].createElement(ComboboxOption, { key: option.id, id: option.id, label: option.label }));
96
+ }),
97
+ props.loading && (React__default["default"].createElement(React__default["default"].Fragment, null, Array.from({ length: 5 }).map((_, index) => (React__default["default"].createElement("div", { className: styles$4.loadingContainer, key: index },
98
+ React__default["default"].createElement(Glimmer.Glimmer, { shape: "rectangle", size: "small" })))))))),
99
+ hasSearchTerm && !optionsExist && (React__default["default"].createElement("div", { className: styles$4.filterMessage },
100
+ React__default["default"].createElement(Text.Text, { variation: "subdued" },
101
+ "No results for ",
102
+ `“${props.searchValue}”`))),
103
+ !hasSearchTerm && !optionsExist && (React__default["default"].createElement("div", { className: styles$4.emptyStateMessage },
104
+ React__default["default"].createElement(Text.Text, { variation: "subdued" }, getZeroIndexStateText(props.subjectNoun))))));
105
+ }
106
+ function getZeroIndexStateText(subjectNoun) {
107
+ if (subjectNoun) {
108
+ return `You don't have any ${subjectNoun} yet`;
109
+ }
110
+ return "No options yet";
111
+ }
112
+ function useScrollState(optionsListRef, options) {
82
113
  const [listScrollState, setlistScrollState] = React.useState("");
83
114
  React.useEffect(() => {
84
115
  const handleScroll = () => {
85
- if (props.optionsListRef.current) {
86
- const { scrollTop, clientHeight, scrollHeight } = props.optionsListRef.current;
116
+ if (optionsListRef.current) {
117
+ const { scrollTop, clientHeight, scrollHeight } = optionsListRef.current;
87
118
  if (scrollHeight === clientHeight) {
88
119
  setlistScrollState("scrollNone");
89
120
  }
@@ -98,36 +129,20 @@ function ComboboxContentList(props) {
98
129
  }
99
130
  }
100
131
  };
101
- if (!props.showEmptyState && props.options.length === 0) {
132
+ if (options.length === 0) {
102
133
  handleScroll();
103
134
  }
104
- if (props.optionsListRef.current) {
105
- props.optionsListRef.current.addEventListener("scroll", handleScroll);
135
+ if (optionsListRef.current) {
136
+ optionsListRef.current.addEventListener("scroll", handleScroll);
106
137
  handleScroll();
107
138
  }
108
139
  return () => {
109
- if (props.optionsListRef.current) {
110
- props.optionsListRef.current.removeEventListener("scroll", handleScroll);
140
+ if (optionsListRef.current) {
141
+ optionsListRef.current.removeEventListener("scroll", handleScroll);
111
142
  }
112
143
  };
113
- }, [props.options]);
114
- return (React__default["default"].createElement("div", { className: classnames__default["default"](styles$4.container, styles$4[listScrollState]) },
115
- !props.showEmptyState && props.options.length > 0 && (React__default["default"].createElement("ul", { className: styles$4.optionsList, role: "listbox", "aria-multiselectable": props.multiselect, ref: props.optionsListRef }, !props.showEmptyState &&
116
- props.options.map(option => {
117
- return (React__default["default"].createElement(ComboboxOption, { key: option.id, id: option.id, label: option.label }));
118
- }))),
119
- !props.showEmptyState && props.options.length === 0 && (React__default["default"].createElement("div", { className: styles$4.filterMessage },
120
- React__default["default"].createElement(Text.Text, { variation: "subdued" },
121
- "No results for ",
122
- `“${props.searchValue}”`))),
123
- props.showEmptyState && (React__default["default"].createElement("div", { className: styles$4.emptyStateMessage },
124
- React__default["default"].createElement(Text.Text, { variation: "subdued" }, getZeroIndexStateText(props.subjectNoun))))));
125
- }
126
- function getZeroIndexStateText(subjectNoun) {
127
- if (subjectNoun) {
128
- return `You don't have any ${subjectNoun} yet`;
129
- }
130
- return "No options yet";
144
+ }, [options]);
145
+ return { listScrollState };
131
146
  }
132
147
 
133
148
  var css_248z$2 = ".Q-mwo-g5Fi8- {\n display: -ms-flexbox;\n display: flex;\n padding: calc(16px * 1) calc(16px / 2) 0 calc(16px * 1);\n padding: var(--space-base) var(--space-small) 0 var(--space-base);\n -ms-flex-pack: justify;\n justify-content: space-between;\n gap: calc(16px / 4);\n gap: var(--space-smaller);\n}\n";
@@ -154,10 +169,9 @@ function getLabel(hasSelected, count, subjectNoun) {
154
169
  return "Select";
155
170
  }
156
171
 
157
- function useComboboxContent(options, open, selected, searchValue) {
172
+ function useComboboxContent(open, selected) {
158
173
  const { shouldScroll } = React.useContext(ComboboxContext);
159
174
  const optionsListRef = React.useRef(null);
160
- const filteredOptions = options.filter(option => option.label.toLowerCase().includes(searchValue.toLowerCase()));
161
175
  React.useEffect(() => {
162
176
  var _a;
163
177
  if (open && shouldScroll.current && optionsListRef.current) {
@@ -170,7 +184,6 @@ function useComboboxContent(options, open, selected, searchValue) {
170
184
  }
171
185
  }, [open, selected]);
172
186
  return {
173
- filteredOptions,
174
187
  optionsListRef,
175
188
  };
176
189
  }
@@ -266,16 +279,16 @@ function useComboboxAccessibility(selectionCallback, filteredOptions, optionsLis
266
279
 
267
280
  function ComboboxContent(props) {
268
281
  const optionsExist = props.options.length > 0;
269
- const { filteredOptions, optionsListRef } = useComboboxContent(props.options, props.open, props.selected, props.searchValue);
270
- const { popperRef, popperStyles, attributes } = useComboboxAccessibility(props.handleSelection, filteredOptions, optionsListRef, props.open, props.wrapperRef);
282
+ const { optionsListRef } = useComboboxContent(props.open, props.selected);
283
+ const { popperRef, popperStyles, attributes } = useComboboxAccessibility(props.handleSelection, props.options, optionsListRef, props.open, props.wrapperRef);
271
284
  const template = (React__default["default"].createElement("div", Object.assign({ ref: popperRef, id: "ATL-Combobox-Content", "data-testid": "ATL-Combobox-Content", tabIndex: 0, className: classnames__default["default"](styles$6.content, { [styles$6.hidden]: !props.open }), style: popperStyles.popper }, attributes.popper),
272
- React__default["default"].createElement(ComboboxContentSearch, { open: props.open, placeholder: props.subjectNoun, searchValue: props.searchValue, setSearchValue: props.setSearchValue }),
273
- props.multiselect && optionsExist && (React__default["default"].createElement(ComboboxContentHeader, { hasOptionsVisible: filteredOptions.length > 0, subjectNoun: props.subjectNoun, selectedCount: props.selected.length, onClearAll: () => {
285
+ React__default["default"].createElement(ComboboxContentSearch, { open: props.open, placeholder: props.subjectNoun, searchValue: props.searchValue, setSearchValue: props.setSearchValue, handleSearchChange: props.handleSearchChange }),
286
+ props.multiselect && optionsExist && (React__default["default"].createElement(ComboboxContentHeader, { hasOptionsVisible: optionsExist, subjectNoun: props.subjectNoun, selectedCount: props.selected.length, onClearAll: () => {
274
287
  props.selectedStateSetter([]);
275
288
  }, onSelectAll: () => {
276
- props.selectedStateSetter(filteredOptions);
289
+ props.selectedStateSetter(props.options);
277
290
  } })),
278
- React__default["default"].createElement(ComboboxContentList, { multiselect: props.multiselect, showEmptyState: !optionsExist, options: filteredOptions, selected: props.selected, optionsListRef: optionsListRef, searchValue: props.searchValue, subjectNoun: props.subjectNoun }),
291
+ React__default["default"].createElement(ComboboxContentList, { multiselect: props.multiselect, options: props.options, selected: props.selected, optionsListRef: optionsListRef, searchValue: props.searchValue, subjectNoun: props.subjectNoun, loading: props.loading }),
279
292
  props.actionElements && (React__default["default"].createElement("div", { className: styles$6.actions, role: "group" }, props.actionElements.map((child, index, childrenArray) => (React__default["default"].createElement("div", { key: index, className: classnames__default["default"]({
280
293
  [styles$6.actionPadding]: index === childrenArray.length - 1,
281
294
  }) }, child)))))));
@@ -355,11 +368,19 @@ function handleMultiSelect(selectCallback, selected, selection) {
355
368
  }
356
369
  }
357
370
 
358
- function useCombobox(selected, onSelect, onClose, multiSelect) {
371
+ function useCombobox(selected, onSelect, options, onClose, multiSelect, onSearch, debounceTime = 300) {
359
372
  const wrapperRef = React.useRef(null);
360
373
  const shouldScroll = React.useRef(false);
361
374
  const [open, setOpen] = React.useState(false);
362
375
  const [searchValue, setSearchValue] = React.useState("");
376
+ const [internalFilteredOptions, setInternalFilteredOptions] = React.useState(options);
377
+ const searchCallback = React.useCallback(debounce__default["default"]((value) => onSearch && onSearch(value), debounceTime), []);
378
+ const debouncedFilterOptions = React.useCallback((value) => {
379
+ const filtered = options.filter(option => {
380
+ return option.label.toLowerCase().includes(value.toLowerCase());
381
+ });
382
+ setInternalFilteredOptions(filtered);
383
+ }, []);
363
384
  const { handleClose, handleSelection } = useMakeComboboxHandlers(setOpen, setSearchValue, selected, shouldScroll, onSelect, multiSelect, onClose);
364
385
  return {
365
386
  wrapperRef,
@@ -372,6 +393,8 @@ function useCombobox(selected, onSelect, onClose, multiSelect) {
372
393
  shouldScroll,
373
394
  handleClose,
374
395
  handleSelection,
396
+ internalFilteredOptions,
397
+ handleSearchChange: onSearch ? searchCallback : debouncedFilterOptions,
375
398
  };
376
399
  }
377
400
 
@@ -424,12 +447,12 @@ function Combobox(props) {
424
447
  id: option.props.id,
425
448
  label: option.props.label,
426
449
  }))) || [], [optionElements]);
427
- const { selectedOptions, selectedStateSetter, shouldScroll, wrapperRef, searchValue, setSearchValue, open, setOpen, handleClose, handleSelection, } = useCombobox(props.selected, props.onSelect, props.onClose, props.multiSelect);
450
+ const { selectedOptions, selectedStateSetter, shouldScroll, wrapperRef, searchValue, setSearchValue, open, setOpen, handleClose, handleSelection, internalFilteredOptions, handleSearchChange, } = useCombobox(props.selected, props.onSelect, options, props.onClose, props.multiSelect, props.onSearch, props.onSearchDebounce);
428
451
  return (React__default["default"].createElement(ComboboxContextProvider, { selected: selectedOptions, selectionHandler: handleSelection, open: open, setOpen: setOpen, handleClose: handleClose, shouldScroll: shouldScroll, searchValue: searchValue },
429
452
  React__default["default"].createElement("div", { ref: wrapperRef, className: styles.wrapper },
430
453
  open && (React__default["default"].createElement("div", { className: styles.overlay, onClick: () => handleClose(), "data-testid": "ATL-Combobox-Overlay" })),
431
454
  triggerElement || (React__default["default"].createElement(ComboboxTrigger, { label: props.label, selected: props.selected })),
432
- React__default["default"].createElement(ComboboxContent, { multiselect: props.multiSelect, subjectNoun: props.subjectNoun, selected: selectedOptions, actionElements: actionElements, selectedStateSetter: selectedStateSetter, handleSelection: handleSelection, searchValue: searchValue, setSearchValue: setSearchValue, wrapperRef: wrapperRef, open: open, setOpen: setOpen, options: options }))));
455
+ React__default["default"].createElement(ComboboxContent, { multiselect: props.multiSelect, subjectNoun: props.subjectNoun, selected: selectedOptions, actionElements: actionElements, selectedStateSetter: selectedStateSetter, handleSelection: handleSelection, searchValue: searchValue, setSearchValue: setSearchValue, wrapperRef: wrapperRef, open: open, setOpen: setOpen, options: props.onSearch ? options : internalFilteredOptions, loading: props.loading, handleSearchChange: handleSearchChange }))));
433
456
  }
434
457
  Combobox.Activator = ComboboxActivator;
435
458
  Combobox.Action = ComboboxAction;
@@ -31,8 +31,11 @@ export interface DataListObject {
31
31
  export type DataListHeader<T extends DataListObject> = {
32
32
  readonly [K in keyof T]?: string;
33
33
  };
34
- export interface DataListSorting {
34
+ export interface DataListSorting extends SortableOptions {
35
35
  readonly key: string;
36
+ }
37
+ export interface SortableOptions {
38
+ readonly label: string;
36
39
  readonly order: "asc" | "desc";
37
40
  }
38
41
  export interface DataListProps<T extends DataListObject> {
@@ -88,7 +91,10 @@ export interface DataListProps<T extends DataListObject> {
88
91
  * `onSort`: The callback function when the user sorting a column.
89
92
  */
90
93
  readonly sorting?: {
91
- readonly sortable: (keyof DataListHeader<T>)[];
94
+ readonly sortable: {
95
+ key: string;
96
+ options?: SortableOptions[];
97
+ }[];
92
98
  readonly state: DataListSorting | undefined;
93
99
  readonly onSort: (sorting?: DataListSorting) => void;
94
100
  };
@@ -3,6 +3,7 @@ import { DataListHeader, DataListObject } from "../../DataList.types";
3
3
  interface DataListHeaderTileProps<T extends DataListObject> {
4
4
  readonly headers: DataListHeader<T>;
5
5
  readonly headerKey: string;
6
+ readonly visible: boolean;
6
7
  }
7
- export declare function DataListHeaderTile<T extends DataListObject>({ headers, headerKey, }: DataListHeaderTileProps<T>): JSX.Element;
8
+ export declare function DataListHeaderTile<T extends DataListObject>({ headers, headerKey, visible, }: DataListHeaderTileProps<T>): JSX.Element;
8
9
  export {};
@@ -0,0 +1,12 @@
1
+ import React from "react";
2
+ import { SortableOptions } from "../../../DataList.types";
3
+ interface DataListSortingOptionsProps {
4
+ readonly options: SortableOptions[];
5
+ readonly selectedOption: SortableOptions | null;
6
+ readonly onSelectChange: (selectedOption: SortableOptions) => void;
7
+ readonly onClose: () => void;
8
+ readonly optionsListRef: React.RefObject<HTMLUListElement>;
9
+ readonly dataListHeaderTileRef: React.RefObject<HTMLElement>;
10
+ }
11
+ export declare function DataListSortingOptions({ options, selectedOption, onSelectChange, onClose, optionsListRef, dataListHeaderTileRef, }: DataListSortingOptionsProps): JSX.Element;
12
+ export {};
@@ -0,0 +1 @@
1
+ export * from "./DataListSortingOptions";
@@ -16,18 +16,18 @@ var Button = require('../Button-b73a5e01.js');
16
16
  var useInView = require('@jobber/hooks/useInView');
17
17
  var isEmpty = require('lodash/isEmpty');
18
18
  var InlineLabel = require('../InlineLabel-a6557829.js');
19
- var FormatDate = require('../FormatDate-70ea5b43.js');
20
- var Heading = require('../Heading-1e8e4bd3.js');
21
19
  var useFocusTrap = require('@jobber/hooks/useFocusTrap');
22
20
  var useRefocusOnActivator = require('@jobber/hooks/useRefocusOnActivator');
23
21
  var useOnKeyDown = require('@jobber/hooks/useOnKeyDown');
22
+ var Icon = require('../Icon-405a216c.js');
23
+ var FormatDate = require('../FormatDate-70ea5b43.js');
24
+ var Heading = require('../Heading-1e8e4bd3.js');
24
25
  var ReactDOM = require('react-dom');
25
26
  var Checkbox = require('../Checkbox-1cdd5cf6.js');
26
27
  var reactRouterDom = require('react-router-dom');
27
28
  var AnimatedSwitcher = require('../AnimatedSwitcher-d1e1ddcf.js');
28
- var Combobox = require('../Combobox-95b3c413.js');
29
+ var Combobox = require('../Combobox-ac089920.js');
29
30
  var Chip = require('../Chip-c91fd6c8.js');
30
- var Icon = require('../Icon-405a216c.js');
31
31
  var debounce = require('lodash/debounce');
32
32
  var InputText = require('../InputText-9e61365c.js');
33
33
  var Spinner = require('../Spinner-9d8fc7ff.js');
@@ -52,13 +52,13 @@ var classnames__default = /*#__PURE__*/_interopDefaultLegacy(classnames);
52
52
  var isEmpty__default = /*#__PURE__*/_interopDefaultLegacy(isEmpty);
53
53
  var debounce__default = /*#__PURE__*/_interopDefaultLegacy(debounce);
54
54
 
55
- var css_248z$f = ".TkdrExYnvcY-,\n.TkdrExYnvcY- * {\n box-sizing: border-box;\n}\n\n.TkdrExYnvcY- {\n --data-list--minimum-item-height: calc(var(--base-unit) * 3.5);\n\n display: -ms-flexbox;\n\n display: flex;\n -ms-flex-direction: column;\n flex-direction: column;\n position: relative;\n z-index: 0;\n z-index: var(--elevation-default);\n -ms-flex: 1;\n flex: 1;\n}\n\n/*\n * Header\n */\n\n.IcAlZHoB4LI- {\n display: -ms-flexbox;\n display: flex;\n position: relative;\n z-index: 1;\n z-index: var(--elevation-base);\n margin-bottom: calc(16px / 2);\n margin-bottom: var(--space-small);\n -ms-flex-align: center;\n align-items: center;\n}\n\n.TFO76ysivmg- {\n display: grid;\n padding: calc((16px / 2) + (16px / 4)) 0;\n padding: calc(calc(16px / 2) + calc(16px / 4)) 0;\n padding: calc(var(--space-small) + var(--space-smaller)) 0;\n gap: calc(16px / 2);\n grid-gap: calc(16px / 2);\n grid-gap: var(--space-small);\n gap: var(--space-small);\n grid-template-columns: auto fit-content(calc(16px * 14));\n grid-template-columns: auto fit-content(calc(var(--base-unit) * 14));\n}\n\n.jGHZZYZm1ZY- {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-direction: column;\n flex-direction: column;\n -ms-flex-pack: center;\n justify-content: center;\n min-height: calc(16px * 3);\n min-height: var(--space-largest);\n padding: calc(16px / 2);\n padding: var(--space-small);\n border-bottom: calc(16px / 8) solid rgb(217, 223, 225);\n border-bottom: var(--border-thick) solid var(--color-border);\n}\n\n.GiD7MjZJbcw- {\n --data-list--header-actions-gap: var(--space-small);\n display: -ms-flexbox;\n display: flex;\n gap: calc(16px / 2);\n gap: var(--data-list--header-actions-gap);\n}\n\n@media (max-width: 489px) {\n\n.GiD7MjZJbcw- {\n -ms-flex-pack: justify;\n justify-content: space-between;\n width: 100%;\n}\n }\n\n@media (--small-screens-and-below) {\n\n.GiD7MjZJbcw- {\n -ms-flex-pack: justify;\n justify-content: space-between;\n width: 100%;\n}\n }\n\n.jMSVGIAr5tk- > p {\n font-weight: 500;\n white-space: nowrap;\n}\n\n.jMSVGIAr5tk- {\n display: -ms-flexbox;\n display: flex;\n margin: calc((16px / 2) * -1) 0;\n margin: calc(calc(16px / 2) * -1) 0;\n margin: calc(var(--space-small) * -1) 0;\n -ms-flex-align: center;\n align-items: center;\n gap: var(--data-list--header-actions-gap);\n}\n\n/*\n * List Item\n */\n\n.ise8kHCfhCY- {\n position: relative;\n padding: calc(16px / 2);\n padding: var(--space-small);\n border-bottom: calc(16px / 16) solid rgb(217, 223, 225);\n border-bottom: var(--border-base) solid var(--color-border);\n transition: all 200ms;\n transition: all var(--timing-base);\n}\n\n.ise8kHCfhCY-,\n.Tq6e0BGwcSM- {\n display: grid;\n grid-template-columns: minmax(0px, auto);\n min-height: var(--data-list--minimum-item-height);\n -ms-flex-align: center;\n align-items: center;\n}\n\n.ise8kHCfhCY-.Pc0JGX6jCD4-,\n.ise8kHCfhCY-:hover,\n.ise8kHCfhCY-:focus-within {\n --data-list-item-active-color: var(--color-surface--hover);\n background-color: rgb(244, 246, 250);\n background-color: var(--data-list-item-active-color);\n}\n\n.Tq6e0BGwcSM- {\n margin: calc((16px / 2) * -1) 0;\n margin: calc(calc(16px / 2) * -1) 0;\n margin: calc(var(--space-small) * -1) 0;\n padding: calc(16px / 2) 0;\n padding: var(--space-small) 0;\n border: none;\n text-align: left;\n -webkit-text-decoration: none;\n text-decoration: none;\n background-color: transparent;\n cursor: pointer;\n}\n\n/**\n * Reset CSS properties on focus to ensure we only have the focus state on the\n * parent .listItem\n */\n\n.Tq6e0BGwcSM-:focus {\n outline: none;\n background-color: transparent;\n}\n\n/**\n * Enable a better hover and focus experience when :has() is supported.\n * This is a workaround for Firefox where the :has() selector is not supported.\n */\n\n@supports selector(*:has(*)) {\n .ise8kHCfhCY-:hover,\n .ise8kHCfhCY-:focus-within {\n background-color: transparent;\n }\n\n .ise8kHCfhCY-:has(.Tq6e0BGwcSM-:hover, .Tq6e0BGwcSM-:focus) {\n background-color: var(--data-list-item-active-color);\n }\n}\n\n/*\n * List Item Selection\n */\n\n.d-79rkMqufg- {\n display: grid;\n -ms-flex-align: start;\n align-items: flex-start;\n}\n\n@media (min-width: 768px) {\n\n.d-79rkMqufg- {\n -ms-flex-align: center;\n align-items: center;\n}\n }\n\n@media (--medium-screens-and-up) {\n\n.d-79rkMqufg- {\n -ms-flex-align: center;\n align-items: center;\n}\n }\n\n.d-79rkMqufg-,\n.jGHZZYZm1ZY- .d-79rkMqufg- {\n grid-template-columns: -webkit-max-content minmax(0px, auto);\n grid-template-columns: max-content minmax(0px, auto);\n -webkit-column-gap: calc(16px / 2);\n -webkit-column-gap: var(--space-small);\n -moz-column-gap: calc(16px / 2);\n -moz-column-gap: var(--space-small);\n column-gap: calc(16px / 2);\n column-gap: var(--space-small);\n}\n\n.jGHZZYZm1ZY- .d-79rkMqufg- {\n display: grid;\n -ms-flex-align: center;\n align-items: center;\n}\n\n.qm-SSuWTXkI- {\n display: -ms-flexbox;\n display: flex;\n visibility: hidden;\n\n /* To compensate the Checkbox's label margin that we are using for screen-readers */\n margin-right: calc((16px * 1) * -1);\n margin-right: calc(calc(16px * 1) * -1);\n margin-right: calc(var(--space-base) * -1);\n}\n\n.qm-SSuWTXkI-.VA9RnQp6nbI- {\n visibility: visible;\n}\n\n.ise8kHCfhCY- .d-79rkMqufg- > :first-child {\n -ms-flex-order: 2;\n order: 2;\n}\n\n.ise8kHCfhCY- .d-79rkMqufg- > :last-child {\n -ms-flex-order: 1;\n order: 1;\n padding-top: calc(16px / 4);\n padding-top: var(--space-smaller);\n opacity: 1;\n transition: opacity 100ms ease-in-out;\n transition: opacity var(--transition-properties);\n --transition-properties: var(--timing-quick) ease-in-out;\n}\n\n@media (min-width: 768px) {\n\n.ise8kHCfhCY- .d-79rkMqufg- > :last-child {\n padding-top: 0;\n opacity: 0;\n}\n }\n\n@media (--medium-screens-and-up) {\n\n.ise8kHCfhCY- .d-79rkMqufg- > :last-child {\n padding-top: 0;\n opacity: 0;\n}\n }\n\n.ise8kHCfhCY-:hover .d-79rkMqufg- > :last-child,\n.ise8kHCfhCY-:focus-within .d-79rkMqufg- > :last-child,\n.ise8kHCfhCY- .d-79rkMqufg-._4L7iXXzLr5k- > :last-child {\n opacity: 1;\n}\n\n/*\n * Filters\n */\n\n.Kkp-IYmwq-s- {\n display: -ms-flexbox;\n display: flex;\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n background-color: rgba(255, 255, 255, 0.6);\n background-color: var(--color-overlay--dimmed);\n -ms-flex-align: start;\n align-items: flex-start;\n -ms-flex-pack: center;\n justify-content: center;\n}\n\n.m-eCShL7TU4- {\n position: sticky;\n top: 50vh;\n}\n\n/* This hides the text from the UI but not from the screen readers */\n\n.esUiRgWabYw- {\n position: absolute;\n top: auto;\n left: -10000px;\n width: 1px;\n height: 1px;\n overflow: hidden;\n text-indent: -10000px;\n}\n";
56
- var styles$f = {"wrapper":"TkdrExYnvcY-","titleContainer":"IcAlZHoB4LI-","headerFilters":"TFO76ysivmg-","headerTitles":"jGHZZYZm1ZY-","batchSelectContainer":"GiD7MjZJbcw-","headerBatchSelect":"jMSVGIAr5tk-","listItem":"ise8kHCfhCY-","listItemClickable":"Tq6e0BGwcSM-","active":"Pc0JGX6jCD4-","selectable":"d-79rkMqufg-","selectAllCheckbox":"qm-SSuWTXkI-","visible":"VA9RnQp6nbI-","selected":"_4L7iXXzLr5k-","filtering":"Kkp-IYmwq-s-","filteringSpinner":"m-eCShL7TU4-","srOnly":"esUiRgWabYw-"};
57
- styleInject_es.styleInject(css_248z$f);
55
+ var css_248z$g = ".TkdrExYnvcY-,\n.TkdrExYnvcY- * {\n box-sizing: border-box;\n}\n\n.TkdrExYnvcY- {\n --data-list--minimum-item-height: calc(var(--base-unit) * 3.5);\n\n display: -ms-flexbox;\n\n display: flex;\n -ms-flex-direction: column;\n flex-direction: column;\n position: relative;\n z-index: 0;\n z-index: var(--elevation-default);\n -ms-flex: 1;\n flex: 1;\n}\n\n/*\n * Header\n */\n\n.IcAlZHoB4LI- {\n display: -ms-flexbox;\n display: flex;\n position: relative;\n z-index: 1;\n z-index: var(--elevation-base);\n margin-bottom: calc(16px / 2);\n margin-bottom: var(--space-small);\n -ms-flex-align: center;\n align-items: center;\n}\n\n.TFO76ysivmg- {\n display: grid;\n padding: calc((16px / 2) + (16px / 4)) 0;\n padding: calc(calc(16px / 2) + calc(16px / 4)) 0;\n padding: calc(var(--space-small) + var(--space-smaller)) 0;\n gap: calc(16px / 2);\n grid-gap: calc(16px / 2);\n grid-gap: var(--space-small);\n gap: var(--space-small);\n grid-template-columns: auto fit-content(calc(16px * 14));\n grid-template-columns: auto fit-content(calc(var(--base-unit) * 14));\n}\n\n.jGHZZYZm1ZY- {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-direction: column;\n flex-direction: column;\n -ms-flex-pack: center;\n justify-content: center;\n min-height: calc(16px * 3);\n min-height: var(--space-largest);\n padding: calc(16px / 2);\n padding: var(--space-small);\n border-bottom: calc(16px / 8) solid rgb(217, 223, 225);\n border-bottom: var(--border-thick) solid var(--color-border);\n}\n\n.GiD7MjZJbcw- {\n --data-list--header-actions-gap: var(--space-small);\n display: -ms-flexbox;\n display: flex;\n gap: calc(16px / 2);\n gap: var(--data-list--header-actions-gap);\n}\n\n@media (max-width: 489px) {\n\n.GiD7MjZJbcw- {\n -ms-flex-pack: justify;\n justify-content: space-between;\n width: 100%;\n}\n }\n\n@media (--small-screens-and-below) {\n\n.GiD7MjZJbcw- {\n -ms-flex-pack: justify;\n justify-content: space-between;\n width: 100%;\n}\n }\n\n.jMSVGIAr5tk- > p {\n font-weight: 500;\n white-space: nowrap;\n}\n\n.jMSVGIAr5tk- {\n display: -ms-flexbox;\n display: flex;\n margin: calc((16px / 2) * -1) 0;\n margin: calc(calc(16px / 2) * -1) 0;\n margin: calc(var(--space-small) * -1) 0;\n -ms-flex-align: center;\n align-items: center;\n gap: var(--data-list--header-actions-gap);\n}\n\n/*\n * List Item\n */\n\n.ise8kHCfhCY- {\n position: relative;\n padding: calc(16px / 2);\n padding: var(--space-small);\n border-bottom: calc(16px / 16) solid rgb(217, 223, 225);\n border-bottom: var(--border-base) solid var(--color-border);\n transition: all 200ms;\n transition: all var(--timing-base);\n}\n\n.ise8kHCfhCY-,\n.Tq6e0BGwcSM- {\n display: grid;\n grid-template-columns: minmax(0px, auto);\n min-height: var(--data-list--minimum-item-height);\n -ms-flex-align: center;\n align-items: center;\n}\n\n.ise8kHCfhCY-.Pc0JGX6jCD4-,\n.ise8kHCfhCY-:hover,\n.ise8kHCfhCY-:focus-within {\n --data-list-item-active-color: var(--color-surface--hover);\n background-color: rgb(244, 246, 250);\n background-color: var(--data-list-item-active-color);\n}\n\n.Tq6e0BGwcSM- {\n margin: calc((16px / 2) * -1) 0;\n margin: calc(calc(16px / 2) * -1) 0;\n margin: calc(var(--space-small) * -1) 0;\n padding: calc(16px / 2) 0;\n padding: var(--space-small) 0;\n border: none;\n text-align: left;\n -webkit-text-decoration: none;\n text-decoration: none;\n background-color: transparent;\n cursor: pointer;\n}\n\n/**\n * Reset CSS properties on focus to ensure we only have the focus state on the\n * parent .listItem\n */\n\n.Tq6e0BGwcSM-:focus {\n outline: none;\n background-color: transparent;\n}\n\n/**\n * Enable a better hover and focus experience when :has() is supported.\n * This is a workaround for Firefox where the :has() selector is not supported.\n */\n\n@supports selector(*:has(*)) {\n .ise8kHCfhCY-:hover,\n .ise8kHCfhCY-:focus-within {\n background-color: transparent;\n }\n\n .ise8kHCfhCY-:has(.Tq6e0BGwcSM-:hover, .Tq6e0BGwcSM-:focus) {\n background-color: var(--data-list-item-active-color);\n }\n}\n\n/*\n * List Item Selection\n */\n\n.d-79rkMqufg- {\n display: grid;\n -ms-flex-align: start;\n align-items: flex-start;\n}\n\n@media (min-width: 768px) {\n\n.d-79rkMqufg- {\n -ms-flex-align: center;\n align-items: center;\n}\n }\n\n@media (--medium-screens-and-up) {\n\n.d-79rkMqufg- {\n -ms-flex-align: center;\n align-items: center;\n}\n }\n\n.d-79rkMqufg-,\n.jGHZZYZm1ZY- .d-79rkMqufg- {\n grid-template-columns: -webkit-max-content minmax(0px, auto);\n grid-template-columns: max-content minmax(0px, auto);\n -webkit-column-gap: calc(16px / 2);\n -webkit-column-gap: var(--space-small);\n -moz-column-gap: calc(16px / 2);\n -moz-column-gap: var(--space-small);\n column-gap: calc(16px / 2);\n column-gap: var(--space-small);\n}\n\n.jGHZZYZm1ZY- .d-79rkMqufg- {\n display: grid;\n -ms-flex-align: center;\n align-items: center;\n}\n\n.qm-SSuWTXkI- {\n display: -ms-flexbox;\n display: flex;\n visibility: hidden;\n\n /* To compensate the Checkbox's label margin that we are using for screen-readers */\n margin-right: calc((16px * 1) * -1);\n margin-right: calc(calc(16px * 1) * -1);\n margin-right: calc(var(--space-base) * -1);\n}\n\n.qm-SSuWTXkI-.VA9RnQp6nbI- {\n visibility: visible;\n}\n\n.ise8kHCfhCY- .d-79rkMqufg- > :first-child {\n -ms-flex-order: 2;\n order: 2;\n}\n\n.ise8kHCfhCY- .d-79rkMqufg- > :last-child {\n -ms-flex-order: 1;\n order: 1;\n padding-top: calc(16px / 4);\n padding-top: var(--space-smaller);\n opacity: 1;\n transition: opacity 100ms ease-in-out;\n transition: opacity var(--transition-properties);\n --transition-properties: var(--timing-quick) ease-in-out;\n}\n\n@media (min-width: 768px) {\n\n.ise8kHCfhCY- .d-79rkMqufg- > :last-child {\n padding-top: 0;\n opacity: 0;\n}\n }\n\n@media (--medium-screens-and-up) {\n\n.ise8kHCfhCY- .d-79rkMqufg- > :last-child {\n padding-top: 0;\n opacity: 0;\n}\n }\n\n.ise8kHCfhCY-:hover .d-79rkMqufg- > :last-child,\n.ise8kHCfhCY-:focus-within .d-79rkMqufg- > :last-child,\n.ise8kHCfhCY- .d-79rkMqufg-._4L7iXXzLr5k- > :last-child {\n opacity: 1;\n}\n\n/*\n * Filters\n */\n\n.Kkp-IYmwq-s- {\n display: -ms-flexbox;\n display: flex;\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n background-color: rgba(255, 255, 255, 0.6);\n background-color: var(--color-overlay--dimmed);\n -ms-flex-align: start;\n align-items: flex-start;\n -ms-flex-pack: center;\n justify-content: center;\n}\n\n.m-eCShL7TU4- {\n position: sticky;\n top: 50vh;\n}\n\n/* This hides the text from the UI but not from the screen readers */\n\n.esUiRgWabYw- {\n position: absolute;\n top: auto;\n left: -10000px;\n width: 1px;\n height: 1px;\n overflow: hidden;\n text-indent: -10000px;\n}\n";
56
+ var styles$g = {"wrapper":"TkdrExYnvcY-","titleContainer":"IcAlZHoB4LI-","headerFilters":"TFO76ysivmg-","headerTitles":"jGHZZYZm1ZY-","batchSelectContainer":"GiD7MjZJbcw-","headerBatchSelect":"jMSVGIAr5tk-","listItem":"ise8kHCfhCY-","listItemClickable":"Tq6e0BGwcSM-","active":"Pc0JGX6jCD4-","selectable":"d-79rkMqufg-","selectAllCheckbox":"qm-SSuWTXkI-","visible":"VA9RnQp6nbI-","selected":"_4L7iXXzLr5k-","filtering":"Kkp-IYmwq-s-","filteringSpinner":"m-eCShL7TU4-","srOnly":"esUiRgWabYw-"};
57
+ styleInject_es.styleInject(css_248z$g);
58
58
 
59
- var css_248z$e = ".F56prQsXm3A- {\n min-width: 80px;\n margin-left: calc(16px / 2);\n margin-left: var(--space-small);\n}\n";
60
- var styles$e = {"results":"F56prQsXm3A-"};
61
- styleInject_es.styleInject(css_248z$e);
59
+ var css_248z$f = ".F56prQsXm3A- {\n min-width: 80px;\n margin-left: calc(16px / 2);\n margin-left: var(--space-small);\n}\n";
60
+ var styles$f = {"results":"F56prQsXm3A-"};
61
+ styleInject_es.styleInject(css_248z$f);
62
62
 
63
63
  const DATALIST_TOTALCOUNT_TEST_ID = "ATL-DataList-TotalCount";
64
64
  function DataListTotalCount({ totalCount, loading, }) {
@@ -74,7 +74,7 @@ function DataListTotalCount({ totalCount, loading, }) {
74
74
  totalCount.toLocaleString(),
75
75
  " results)"));
76
76
  }
77
- return (React__default["default"].createElement("div", { className: styles$e.results, "data-testid": DATALIST_TOTALCOUNT_TEST_ID }, output));
77
+ return (React__default["default"].createElement("div", { className: styles$f.results, "data-testid": DATALIST_TOTALCOUNT_TEST_ID }, output));
78
78
  }
79
79
 
80
80
  const defaultValues$1 = {
@@ -169,9 +169,9 @@ function useActiveLayout() {
169
169
  return { layout, activeBreakpoint };
170
170
  }
171
171
 
172
- var css_248z$d = "._8cMzUF8XEwY- {\n position: relative;\n}\n\n._8cMzUF8XEwY-::after {\n content: \"\";\n display: block;\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n height: 100px;\n background-image: linear-gradient(\n to top,\n rgba(255, 255, 255, 1) 0%,\n rgba(255, 255, 255, 0) 100%\n );\n background-image: linear-gradient(\n to top,\n var(--color-surface) 0%,\n rgba(var(--color-white--rgb), 0) 100%\n );\n}\n\n.Rh--6fVpkm4- {\n padding: calc(16px * 1) calc(16px / 2);\n padding: var(--space-base) var(--space-small);\n}\n\n.NFaWWvmxtkw- {\n width: 100%;\n min-width: calc(16px * 3);\n min-width: var(--space-largest);\n}\n";
173
- var styles$d = {"wrapper":"_8cMzUF8XEwY-","loadingItem":"Rh--6fVpkm4-","glimmer":"NFaWWvmxtkw-"};
174
- styleInject_es.styleInject(css_248z$d);
172
+ var css_248z$e = "._8cMzUF8XEwY- {\n position: relative;\n}\n\n._8cMzUF8XEwY-::after {\n content: \"\";\n display: block;\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n height: 100px;\n background-image: linear-gradient(\n to top,\n rgba(255, 255, 255, 1) 0%,\n rgba(255, 255, 255, 0) 100%\n );\n background-image: linear-gradient(\n to top,\n var(--color-surface) 0%,\n rgba(var(--color-white--rgb), 0) 100%\n );\n}\n\n.Rh--6fVpkm4- {\n padding: calc(16px * 1) calc(16px / 2);\n padding: var(--space-base) var(--space-small);\n}\n\n.NFaWWvmxtkw- {\n width: 100%;\n min-width: calc(16px * 3);\n min-width: var(--space-largest);\n}\n";
173
+ var styles$e = {"wrapper":"_8cMzUF8XEwY-","loadingItem":"Rh--6fVpkm4-","glimmer":"NFaWWvmxtkw-"};
174
+ styleInject_es.styleInject(css_248z$e);
175
175
 
176
176
  const LOADING_STATE_LIMIT_ITEMS = 10;
177
177
  const DATALIST_LOADINGSTATE_ROW_TEST_ID = "ATL-DataList-LoadingState-Row";
@@ -181,10 +181,10 @@ function DataListLoadingState() {
181
181
  if (!layout)
182
182
  return null;
183
183
  const glimmerSize = activeBreakpoint === "xs" ? "small" : "large";
184
- const glimmersFromHeader = Object.keys(headers).reduce((data, key) => (Object.assign(Object.assign({}, data), { [key]: (React__default["default"].createElement("div", { className: styles$d.glimmer },
184
+ const glimmersFromHeader = Object.keys(headers).reduce((data, key) => (Object.assign(Object.assign({}, data), { [key]: (React__default["default"].createElement("div", { className: styles$e.glimmer },
185
185
  React__default["default"].createElement(Glimmer.Glimmer, { size: glimmerSize }))) })), {});
186
186
  const loadingData = new Array(LOADING_STATE_LIMIT_ITEMS).fill(glimmersFromHeader);
187
- return (React__default["default"].createElement("div", { className: styles$d.wrapper }, loadingData.map((child, i) => (React__default["default"].createElement("div", { key: i, className: styles$d.loadingItem, "data-testid": DATALIST_LOADINGSTATE_ROW_TEST_ID }, layout(child))))));
187
+ return (React__default["default"].createElement("div", { className: styles$e.wrapper }, loadingData.map((child, i) => (React__default["default"].createElement("div", { key: i, className: styles$e.loadingItem, "data-testid": DATALIST_LOADINGSTATE_ROW_TEST_ID }, layout(child))))));
188
188
  }
189
189
 
190
190
  const defaultValues = {
@@ -197,32 +197,32 @@ function useDataListLayoutContext() {
197
197
  return React.useContext(DataListLayoutContext);
198
198
  }
199
199
 
200
- var css_248z$c = ".jHcHGQ-HDbk- {\n display: -ms-flexbox;\n display: flex;\n position: absolute;\n top: calc((16px / 2) * -1);\n top: calc(calc(16px / 2) * -1);\n top: calc(var(--space-small) * -1);\n right: 0;\n z-index: 6;\n z-index: var(--elevation-menu);\n box-shadow: 0px calc(16px / 16) calc(16px / 4) 0px\n rgba(0, 0, 0, 0.1),\n 0px calc(16px / 4) 12px 0px rgba(0, 0, 0, 0.05);\n box-shadow: var(--shadow-base);\n padding: calc(16px / 4);\n padding: var(--space-smaller);\n border: calc(16px / 16) solid rgb(217, 223, 225);\n border: var(--border-base) solid var(--color-border);\n border-radius: calc(16px / 2);\n border-radius: var(--radius-larger);\n background-color: rgba(255, 255, 255, 1);\n background-color: var(--color-surface);\n gap: calc(16px / 4);\n gap: var(--space-smaller);\n}\n\n.jobber-retheme .jHcHGQ-HDbk- {\n border-radius: calc(16px / 8);\n border-radius: var(--radius-base);\n}\n";
201
- var styles$c = {"menu":"jHcHGQ-HDbk-"};
202
- styleInject_es.styleInject(css_248z$c);
200
+ var css_248z$d = ".jHcHGQ-HDbk- {\n display: -ms-flexbox;\n display: flex;\n position: absolute;\n top: calc((16px / 2) * -1);\n top: calc(calc(16px / 2) * -1);\n top: calc(var(--space-small) * -1);\n right: 0;\n z-index: 6;\n z-index: var(--elevation-menu);\n box-shadow: 0px calc(16px / 16) calc(16px / 4) 0px\n rgba(0, 0, 0, 0.1),\n 0px calc(16px / 4) 12px 0px rgba(0, 0, 0, 0.05);\n box-shadow: var(--shadow-base);\n padding: calc(16px / 4);\n padding: var(--space-smaller);\n border: calc(16px / 16) solid rgb(217, 223, 225);\n border: var(--border-base) solid var(--color-border);\n border-radius: calc(16px / 2);\n border-radius: var(--radius-larger);\n background-color: rgba(255, 255, 255, 1);\n background-color: var(--color-surface);\n gap: calc(16px / 4);\n gap: var(--space-smaller);\n}\n\n.jobber-retheme .jHcHGQ-HDbk- {\n border-radius: calc(16px / 8);\n border-radius: var(--radius-base);\n}\n";
201
+ var styles$d = {"menu":"jHcHGQ-HDbk-"};
202
+ styleInject_es.styleInject(css_248z$d);
203
203
 
204
204
  const CONTAINER_TEST_ID = "ATL-DataListFilters-Container";
205
205
 
206
- var css_248z$b = ".jbBRoxlZlNI- {\n --overflow-fade--offset: var(--space-smaller);\n --overflow-fade--negative-offset: calc(var(--overflow-fade--offset) * -1);\n\n -ms-flex-item-align: center;\n\n align-self: center;\n position: relative;\n min-width: 0;\n}\n\n.P6uJ-vHfKrM-,\n.MnN8qbS4hw4- {\n display: grid;\n grid-auto-flow: column;\n grid-auto-columns: -webkit-max-content;\n grid-auto-columns: max-content;\n -ms-flex-align: center;\n align-items: center;\n}\n\n.P6uJ-vHfKrM- {\n gap: calc(16px / 2);\n gap: var(--space-small);\n}\n\n.MnN8qbS4hw4- {\n margin: var(--overflow-fade--negative-offset);\n padding: var(--overflow-fade--offset);\n overflow-x: auto;\n overflow-y: visible;\n}\n\n.b-5P7Z8eGO8- {\n visibility: hidden;\n}\n\n.xzaCS4slLpI-::before,\n.Jf227kC8Nu0-::after {\n content: \"\";\n position: absolute;\n top: 0;\n width: calc(16px * 1.5);\n width: var(--space-large);\n height: 100%;\n background-image: linear-gradient(\n to right,\n rgba(255, 255, 255, 1) 0%,\n rgba(255, 255, 255, 0) 100%\n );\n background-image: linear-gradient(\n var(--data-list-overflow-shadow-angle, to right),\n var(--color-surface) 0%,\n rgba(var(--color-white--rgb), 0) 100%\n );\n pointer-events: none;\n}\n\n.xzaCS4slLpI-::before {\n left: var(--overflow-fade--negative-offset);\n}\n\n.Jf227kC8Nu0-::after {\n --data-list-overflow-shadow-angle: to left;\n right: var(--overflow-fade--negative-offset);\n}\n";
207
- var styles$b = {"fadeContainer":"jbBRoxlZlNI-","overflowItems":"P6uJ-vHfKrM-","overflowGrid":"MnN8qbS4hw4-","overflowTrigger":"b-5P7Z8eGO8-","overflowLeft":"xzaCS4slLpI-","overflowRight":"Jf227kC8Nu0-"};
208
- styleInject_es.styleInject(css_248z$b);
206
+ var css_248z$c = ".jbBRoxlZlNI- {\n --overflow-fade--offset: var(--space-smaller);\n --overflow-fade--negative-offset: calc(var(--overflow-fade--offset) * -1);\n\n -ms-flex-item-align: center;\n\n align-self: center;\n position: relative;\n min-width: 0;\n}\n\n.P6uJ-vHfKrM-,\n.MnN8qbS4hw4- {\n display: grid;\n grid-auto-flow: column;\n grid-auto-columns: -webkit-max-content;\n grid-auto-columns: max-content;\n -ms-flex-align: center;\n align-items: center;\n}\n\n.P6uJ-vHfKrM- {\n gap: calc(16px / 2);\n gap: var(--space-small);\n}\n\n.MnN8qbS4hw4- {\n margin: var(--overflow-fade--negative-offset);\n padding: var(--overflow-fade--offset);\n overflow-x: auto;\n overflow-y: visible;\n}\n\n.b-5P7Z8eGO8- {\n visibility: hidden;\n}\n\n.xzaCS4slLpI-::before,\n.Jf227kC8Nu0-::after {\n content: \"\";\n position: absolute;\n top: 0;\n width: calc(16px * 1.5);\n width: var(--space-large);\n height: 100%;\n background-image: linear-gradient(\n to right,\n rgba(255, 255, 255, 1) 0%,\n rgba(255, 255, 255, 0) 100%\n );\n background-image: linear-gradient(\n var(--data-list-overflow-shadow-angle, to right),\n var(--color-surface) 0%,\n rgba(var(--color-white--rgb), 0) 100%\n );\n pointer-events: none;\n}\n\n.xzaCS4slLpI-::before {\n left: var(--overflow-fade--negative-offset);\n}\n\n.Jf227kC8Nu0-::after {\n --data-list-overflow-shadow-angle: to left;\n right: var(--overflow-fade--negative-offset);\n}\n";
207
+ var styles$c = {"fadeContainer":"jbBRoxlZlNI-","overflowItems":"P6uJ-vHfKrM-","overflowGrid":"MnN8qbS4hw4-","overflowTrigger":"b-5P7Z8eGO8-","overflowLeft":"xzaCS4slLpI-","overflowRight":"Jf227kC8Nu0-"};
208
+ styleInject_es.styleInject(css_248z$c);
209
209
 
210
210
  function DataListOverflowFade({ children }) {
211
211
  const [leftRef, isLeftVisible] = useInView.useInView();
212
212
  const [rightRef, isRightVisible] = useInView.useInView();
213
- return (React__default["default"].createElement("div", { "data-testid": CONTAINER_TEST_ID, className: classnames__default["default"](styles$b.fadeContainer, {
214
- [styles$b.overflowLeft]: !isLeftVisible,
215
- [styles$b.overflowRight]: !isRightVisible,
213
+ return (React__default["default"].createElement("div", { "data-testid": CONTAINER_TEST_ID, className: classnames__default["default"](styles$c.fadeContainer, {
214
+ [styles$c.overflowLeft]: !isLeftVisible,
215
+ [styles$c.overflowRight]: !isRightVisible,
216
216
  }) },
217
- React__default["default"].createElement("div", { className: styles$b.overflowGrid },
218
- React__default["default"].createElement("span", { ref: leftRef, className: styles$b.overflowTrigger }),
219
- React__default["default"].createElement("div", { className: styles$b.overflowItems }, children),
220
- React__default["default"].createElement("span", { ref: rightRef, className: styles$b.overflowTrigger }))));
217
+ React__default["default"].createElement("div", { className: styles$c.overflowGrid },
218
+ React__default["default"].createElement("span", { ref: leftRef, className: styles$c.overflowTrigger }),
219
+ React__default["default"].createElement("div", { className: styles$c.overflowItems }, children),
220
+ React__default["default"].createElement("span", { ref: rightRef, className: styles$c.overflowTrigger }))));
221
221
  }
222
222
 
223
- var css_248z$a = "._8MYxAQYdZzM- {\n position: relative;\n}\n\n.WRV-UmQmPzo- {\n --inline-label-height: calc(\n var(--typography--fontSize-small) * 1.5 + calc(var(--space-smaller) * 1.25) *\n 2\n );\n\n display: -ms-flexbox;\n\n display: flex;\n z-index: 0;\n z-index: var(--elevation-default);\n max-height: calc((\n ((16px * 1) * 0.75) * 1.5 + ((16px / 4) * 1.25) *\n 2\n ) * 2);\n max-height: calc(calc(\n calc(calc(16px * 1) * 0.75) * 1.5 + calc(calc(16px / 4) * 1.25) *\n 2\n ) * 2);\n max-height: calc(var(--inline-label-height) * 2);\n overflow: hidden;\n white-space: nowrap;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n gap: calc(16px / 4);\n gap: var(--space-smaller);\n}\n\n.ND-cN-mX5-c- {\n -webkit-mask-image: linear-gradient(\n to left,\n transparent,\n transparent calc(16px * 1.5),\n rgba(0, 0, 0, 1) calc(16px * 3),\n rgba(0, 0, 0, 1)\n );\n -webkit-mask-image: linear-gradient(\n to left,\n transparent,\n transparent var(--space-large),\n rgba(0, 0, 0, 1) var(--space-largest),\n rgba(0, 0, 0, 1)\n );\n mask-image: linear-gradient(\n to left,\n transparent,\n transparent calc(16px * 1.5),\n rgba(0, 0, 0, 1) calc(16px * 3),\n rgba(0, 0, 0, 1)\n );\n mask-image: linear-gradient(\n to left,\n transparent,\n transparent var(--space-large),\n rgba(0, 0, 0, 1) var(--space-largest),\n rgba(0, 0, 0, 1)\n );\n}\n\n.liQeWCMenD0- {\n display: -ms-flexbox;\n display: flex;\n position: absolute;\n top: 0;\n right: 0;\n height: 100%;\n -ms-flex-align: center;\n align-items: center;\n}\n";
224
- var styles$a = {"tagWrapper":"_8MYxAQYdZzM-","tags":"WRV-UmQmPzo-","tagsMask":"ND-cN-mX5-c-","tagCount":"liQeWCMenD0-"};
225
- styleInject_es.styleInject(css_248z$a);
223
+ var css_248z$b = "._8MYxAQYdZzM- {\n position: relative;\n}\n\n.WRV-UmQmPzo- {\n --inline-label-height: calc(\n var(--typography--fontSize-small) * 1.5 + calc(var(--space-smaller) * 1.25) *\n 2\n );\n\n display: -ms-flexbox;\n\n display: flex;\n z-index: 0;\n z-index: var(--elevation-default);\n max-height: calc((\n ((16px * 1) * 0.75) * 1.5 + ((16px / 4) * 1.25) *\n 2\n ) * 2);\n max-height: calc(calc(\n calc(calc(16px * 1) * 0.75) * 1.5 + calc(calc(16px / 4) * 1.25) *\n 2\n ) * 2);\n max-height: calc(var(--inline-label-height) * 2);\n overflow: hidden;\n white-space: nowrap;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n gap: calc(16px / 4);\n gap: var(--space-smaller);\n}\n\n.ND-cN-mX5-c- {\n -webkit-mask-image: linear-gradient(\n to left,\n transparent,\n transparent calc(16px * 1.5),\n rgba(0, 0, 0, 1) calc(16px * 3),\n rgba(0, 0, 0, 1)\n );\n -webkit-mask-image: linear-gradient(\n to left,\n transparent,\n transparent var(--space-large),\n rgba(0, 0, 0, 1) var(--space-largest),\n rgba(0, 0, 0, 1)\n );\n mask-image: linear-gradient(\n to left,\n transparent,\n transparent calc(16px * 1.5),\n rgba(0, 0, 0, 1) calc(16px * 3),\n rgba(0, 0, 0, 1)\n );\n mask-image: linear-gradient(\n to left,\n transparent,\n transparent var(--space-large),\n rgba(0, 0, 0, 1) var(--space-largest),\n rgba(0, 0, 0, 1)\n );\n}\n\n.liQeWCMenD0- {\n display: -ms-flexbox;\n display: flex;\n position: absolute;\n top: 0;\n right: 0;\n height: 100%;\n -ms-flex-align: center;\n align-items: center;\n}\n";
224
+ var styles$b = {"tagWrapper":"_8MYxAQYdZzM-","tags":"WRV-UmQmPzo-","tagsMask":"ND-cN-mX5-c-","tagCount":"liQeWCMenD0-"};
225
+ styleInject_es.styleInject(css_248z$b);
226
226
 
227
227
  function DataListTags({ items }) {
228
228
  const ref = React.useRef(null);
@@ -244,12 +244,12 @@ function DataListTags({ items }) {
244
244
  elements === null || elements === void 0 ? void 0 : elements.forEach(element => observer.unobserve(element));
245
245
  };
246
246
  }, [items]);
247
- return (React__default["default"].createElement("div", { className: styles$a.tagWrapper, ref: ref },
248
- React__default["default"].createElement("div", { className: classnames__default["default"](styles$a.tags, {
249
- [styles$a.tagsMask]: shouldShowTagCount,
247
+ return (React__default["default"].createElement("div", { className: styles$b.tagWrapper, ref: ref },
248
+ React__default["default"].createElement("div", { className: classnames__default["default"](styles$b.tags, {
249
+ [styles$b.tagsMask]: shouldShowTagCount,
250
250
  }) }, items.filter(Boolean).map((tag, index) => (React__default["default"].createElement("div", { key: tag, "data-tag-element": index },
251
251
  React__default["default"].createElement(InlineLabel.InlineLabel, null, tag))))),
252
- shouldShowTagCount && (React__default["default"].createElement("div", { className: styles$a.tagCount },
252
+ shouldShowTagCount && (React__default["default"].createElement("div", { className: styles$b.tagCount },
253
253
  React__default["default"].createElement(Text.Text, null,
254
254
  "+",
255
255
  visibleItems)))));
@@ -278,50 +278,109 @@ function buildIntersectionThreshold(items) {
278
278
  return thresholds;
279
279
  }
280
280
 
281
- var css_248z$9 = ".fLmJZJJqMcE- {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-align: center;\n align-items: center;\n padding: 0;\n border: none;\n background-color: transparent;\n}\n\n.fLmJZJJqMcE-:focus,\n.fLmJZJJqMcE-:focus-visible {\n outline: none;\n}\n\n.fLmJZJJqMcE-:focus-visible {\n box-shadow: 0px 0px 0px calc(16px / 8) rgba(255, 255, 255, 1),\n 0px 0px 0px calc(16px / 4) rgb(147, 161, 169);\n box-shadow: var(--shadow-focus);\n}\n\n.UG8cHUT3Hds- {\n cursor: pointer;\n}\n";
282
- var styles$9 = {"headerLabel":"fLmJZJJqMcE-","sortable":"UG8cHUT3Hds-"};
283
- styleInject_es.styleInject(css_248z$9);
281
+ var css_248z$a = ".fLmJZJJqMcE- {\n display: -ms-flexbox;\n display: flex;\n position: relative;\n -ms-flex-align: center;\n align-items: center;\n padding: 0;\n border: none;\n background-color: transparent;\n}\n\n.fLmJZJJqMcE-:focus,\n.fLmJZJJqMcE-:focus-visible {\n outline: none;\n}\n\n.fLmJZJJqMcE-:focus-visible {\n box-shadow: 0px 0px 0px calc(16px / 8) rgba(255, 255, 255, 1),\n 0px 0px 0px calc(16px / 4) rgb(147, 161, 169);\n box-shadow: var(--shadow-focus);\n}\n\n.UG8cHUT3Hds- {\n cursor: pointer;\n}\n";
282
+ var styles$a = {"headerLabel":"fLmJZJJqMcE-","sortable":"UG8cHUT3Hds-"};
283
+ styleInject_es.styleInject(css_248z$a);
284
284
 
285
- var css_248z$8 = ".AN5egORYy-0- {\n width: calc(16px * 1.5);\n width: var(--space-large);\n height: calc(16px * 1.5);\n height: var(--space-large);\n margin-right: calc(16px / 2);\n margin-right: var(--space-small);\n}\n\n.AN5egORYy-0- path {\n fill: rgba(101, 120, 132, 1);\n fill: var(--color-interactive--subtle);\n transition: all 200ms ease;\n transition: all var(--timing-base) ease;\n}\n\n.AN5egORYy-0- path.F1uTDCK0Sb0- {\n fill: rgb(1, 41, 57);\n fill: var(--color-heading);\n}\n\n.AN5egORYy-0- path._6KYeQXWXLQ8- {\n fill: rgb(217, 223, 225);\n fill: var(--color-inactive--surface);\n}\n\n.AN5egORYy-0-:hover path {\n fill: rgba(101, 120, 132, 1);\n fill: var(--color-interactive--subtle);\n transition: all 200ms ease;\n transition: all var(--timing-base) ease;\n}\n";
286
- var styles$8 = {"sortIcon":"AN5egORYy-0-","active":"F1uTDCK0Sb0-","inactive":"_6KYeQXWXLQ8-"};
287
- styleInject_es.styleInject(css_248z$8);
285
+ var css_248z$9 = ".AN5egORYy-0- {\n width: calc(16px * 1.5);\n width: var(--space-large);\n height: calc(16px * 1.5);\n height: var(--space-large);\n margin-right: calc(16px / 2);\n margin-right: var(--space-small);\n}\n\n.AN5egORYy-0- path {\n fill: rgba(101, 120, 132, 1);\n fill: var(--color-interactive--subtle);\n transition: all 200ms ease;\n transition: all var(--timing-base) ease;\n}\n\n.AN5egORYy-0- path.F1uTDCK0Sb0- {\n fill: rgb(1, 41, 57);\n fill: var(--color-heading);\n}\n\n.AN5egORYy-0- path._6KYeQXWXLQ8- {\n fill: rgb(217, 223, 225);\n fill: var(--color-inactive--surface);\n}\n\n.AN5egORYy-0-:hover path {\n fill: rgba(101, 120, 132, 1);\n fill: var(--color-interactive--subtle);\n transition: all 200ms ease;\n transition: all var(--timing-base) ease;\n}\n";
286
+ var styles$9 = {"sortIcon":"AN5egORYy-0-","active":"F1uTDCK0Sb0-","inactive":"_6KYeQXWXLQ8-"};
287
+ styleInject_es.styleInject(css_248z$9);
288
288
 
289
289
  const SORTING_ICON_TEST_ID = "ATL-DataList-Sorting-Icon";
290
290
  function DataListSortingArrows({ order }) {
291
- return (React__default["default"].createElement("div", { className: styles$8.sortIcon, "data-testid": SORTING_ICON_TEST_ID },
291
+ return (React__default["default"].createElement("div", { className: styles$9.sortIcon, "data-testid": SORTING_ICON_TEST_ID },
292
292
  React__default["default"].createElement("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg" },
293
293
  React__default["default"].createElement("path", { className: getActiveClassName("asc"), d: "M16.2929 10.6661C15.9024 11.0566 15.2692 11.0566 14.8787 10.6661L12.2891 8.14263L9.70711 10.6661C9.31658 11.0566 8.68342 11.0566 8.29289 10.6661C7.90237 10.2756 7.90237 9.64239 8.29289 9.25186L11.5858 5.95897C11.9763 5.56845 12.6095 5.56845 13 5.95897L16.2929 9.25186C16.6834 9.64239 16.6834 10.2756 16.2929 10.6661Z" }),
294
294
  React__default["default"].createElement("path", { className: getActiveClassName("desc"), d: "M8.29292 13.3339C8.68345 12.9434 9.31661 12.9434 9.70714 13.3339L12.2968 15.8573L14.8787 13.3339C15.2692 12.9434 15.9024 12.9434 16.2929 13.3339C16.6834 13.7244 16.6834 14.3576 16.2929 14.7481L13 18.041C12.6095 18.4315 11.9763 18.4315 11.5858 18.041L8.29292 14.7481C7.9024 14.3576 7.9024 13.7244 8.29292 13.3339Z" }))));
295
295
  function getActiveClassName(targetOrder) {
296
- return order === targetOrder ? styles$8.active : styles$8.inactive;
296
+ return order === targetOrder ? styles$9.active : styles$9.inactive;
297
297
  }
298
298
  }
299
299
 
300
- function DataListHeaderTile({ headers, headerKey, }) {
300
+ var css_248z$8 = ".thBUfVNaigs- {\n position: absolute;\n top: 100%;\n left: 0;\n max-width: var(--popover--width);\n box-shadow: 0px calc(16px / 16) calc(16px / 4) 0px\n rgba(0, 0, 0, 0.1),\n 0px calc(16px / 4) 12px 0px rgba(0, 0, 0, 0.05);\n box-shadow: var(--shadow-base);\n margin-top: calc(16px / 4);\n margin-top: var(--space-smaller);\n padding: calc(16px / 2);\n padding: var(--space-small);\n border: calc(16px / 16) solid rgb(217, 223, 225);\n border: var(--border-base) solid var(--color-border);\n border-radius: calc(16px / 2);\n border-radius: var(--radius-larger);\n background: rgba(255, 255, 255, 1);\n background: var(--color-surface);\n -ms-flex-align: start;\n align-items: flex-start;\n}\n\n.QaXuqbVjG04- {\n display: -ms-flexbox;\n display: flex;\n min-width: calc((16px * 3) * 3.5);\n min-width: calc(calc(16px * 3) * 3.5);\n min-width: calc(var(--space-largest) * 3.5);\n min-height: calc((calc(16px * 3) - calc(16px / 4)));\n min-height: calc((var(--space-largest) - var(--space-smaller)));\n box-sizing: border-box;\n padding: calc(16px / 2);\n padding: var(--space-small);\n border-radius: calc(16px / 4);\n border-radius: var(--radius-large);\n font-family: \"Inter\", Helvetica, Arial, sans-serif;\n font-family: var(--typography--fontFamily-normal);\n font-size: calc((16px * 1) * 0.875);\n font-size: calc(calc(16px * 1) * 0.875);\n font-size: var(--typography--fontSize-base);\n font-weight: 500;\n white-space: nowrap;\n list-style: none;\n cursor: pointer;\n -ms-flex-align: center;\n align-items: center;\n -ms-flex-pack: justify;\n justify-content: space-between;\n gap: calc(16px / 4);\n gap: var(--space-smaller);\n}\n\n.jobber-retheme .QaXuqbVjG04-,\n.jobber-retheme .thBUfVNaigs- {\n border-radius: calc(16px / 8);\n border-radius: var(--radius-base);\n}\n\n.QaXuqbVjG04-:hover,\n.QaXuqbVjG04-:focus {\n background-color: rgb(244, 246, 250);\n background-color: var(--color-surface--hover);\n}\n\n.QaXuqbVjG04-:focus-visible {\n box-shadow: 0px 0px 0px calc(16px / 8) rgba(255, 255, 255, 1),\n 0px 0px 0px calc(16px / 4) rgb(147, 161, 169);\n box-shadow: var(--shadow-focus);\n}\n";
301
+ var styles$8 = {"optionsList":"thBUfVNaigs-","option":"QaXuqbVjG04-"};
302
+ styleInject_es.styleInject(css_248z$8);
303
+
304
+ function DataListSortingOptions({ options, selectedOption, onSelectChange, onClose, optionsListRef, dataListHeaderTileRef, }) {
305
+ useRefocusOnActivator.useRefocusOnActivator(!optionsListRef.current);
306
+ useOnKeyDown.useOnKeyDown(() => onClose(), "Escape");
307
+ React__default["default"].useEffect(() => {
308
+ document.addEventListener("mousedown", handleClickOutside);
309
+ return () => {
310
+ document.removeEventListener("mousedown", handleClickOutside);
311
+ };
312
+ }, [optionsListRef, dataListHeaderTileRef, onClose]);
313
+ return (React__default["default"].createElement("ul", { className: styles$8.optionsList, ref: optionsListRef }, options.map((option, index) => (React__default["default"].createElement("li", { className: styles$8.option, key: index, onClick: () => onSelectChange(option), onKeyDown: event => handleKeyDown(event, option), tabIndex: 0 },
314
+ option.label,
315
+ option.label === (selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.label) && (React__default["default"].createElement(Icon.Icon, { name: "checkmark", color: "blue" })))))));
316
+ function handleKeyDown(event, option) {
317
+ if (event.key === "Enter") {
318
+ onSelectChange(option);
319
+ }
320
+ }
321
+ function handleClickOutside(event) {
322
+ var _a, _b;
323
+ const isClickInsideOptions = (_a = optionsListRef.current) === null || _a === void 0 ? void 0 : _a.contains(event.target);
324
+ const isClickInsideHeader = (_b = dataListHeaderTileRef.current) === null || _b === void 0 ? void 0 : _b.contains(event.target);
325
+ if (!isClickInsideOptions && !isClickInsideHeader) {
326
+ onClose();
327
+ }
328
+ }
329
+ }
330
+
331
+ /* eslint-disable max-statements */
332
+ function DataListHeaderTile({ headers, headerKey, visible = false, }) {
333
+ useRefocusOnActivator.useRefocusOnActivator(visible);
301
334
  const { sorting } = useDataListContext();
302
- const isSortable = sorting === null || sorting === void 0 ? void 0 : sorting.sortable.includes(headerKey);
335
+ const [isDropDownOpen, setIsDropDownOpen] = React__default["default"].useState(false);
336
+ const [selectedSortOption, setSelectedSortOption] = React__default["default"].useState(null);
337
+ const optionsListRef = useFocusTrap.useFocusTrap(isDropDownOpen);
338
+ const dataListHeaderTileRef = React__default["default"].useRef(null);
339
+ const sortableItem = sorting === null || sorting === void 0 ? void 0 : sorting.sortable.find(item => item.key === headerKey);
340
+ const isSortable = Boolean(sortableItem);
303
341
  const sortingState = sorting === null || sorting === void 0 ? void 0 : sorting.state;
304
342
  const Tag = isSortable ? "button" : "div";
305
- return (React__default["default"].createElement(Tag, { className: classnames__default["default"](styles$9.headerLabel, {
306
- [styles$9.sortable]: isSortable,
307
- }), onClick: handleOnClick },
343
+ return (React__default["default"].createElement(Tag, { className: classnames__default["default"](styles$a.headerLabel, {
344
+ [styles$a.sortable]: isSortable,
345
+ }), onClick: handleOnClick, ref: dataListHeaderTileRef },
308
346
  React__default["default"].createElement(Text.Text, { maxLines: "single" }, headers[headerKey]),
347
+ isSortable && (sortableItem === null || sortableItem === void 0 ? void 0 : sortableItem.options) && isDropDownOpen && (React__default["default"].createElement(DataListSortingOptions, { options: sortableItem.options, selectedOption: selectedSortOption, onSelectChange: handleSelectChange, onClose: () => setIsDropDownOpen(false), optionsListRef: optionsListRef, dataListHeaderTileRef: dataListHeaderTileRef })),
309
348
  (sortingState === null || sortingState === void 0 ? void 0 : sortingState.key) === headerKey ? (React__default["default"].createElement(DataListSortingArrows, { order: sortingState.order })) : (sortingState === null || sortingState === void 0 ? void 0 : sortingState.key) !== headerKey && isSortable ? (React__default["default"].createElement(DataListSortingArrows, { order: "none" })) : null));
310
- function toggleSorting(sortingKey) {
311
- const isSameKey = sortingKey === (sortingState === null || sortingState === void 0 ? void 0 : sortingState.key);
312
- if (isSameKey && (sortingState === null || sortingState === void 0 ? void 0 : sortingState.order) === "desc") {
349
+ function toggleSorting(sortingKey, label, order) {
350
+ const isSameKey = (sortingState === null || sortingState === void 0 ? void 0 : sortingState.label) === label && sortingKey === (sortingState === null || sortingState === void 0 ? void 0 : sortingState.key);
351
+ const isDescending = (sortingState === null || sortingState === void 0 ? void 0 : sortingState.order) === "desc";
352
+ if (isSameKey && isDescending && order !== "asc") {
353
+ if (order === "desc")
354
+ return;
313
355
  sorting === null || sorting === void 0 ? void 0 : sorting.onSort(undefined);
314
356
  return;
315
357
  }
358
+ const sortingOrder = order || (isSameKey && !isDescending ? "desc" : "asc");
316
359
  sorting === null || sorting === void 0 ? void 0 : sorting.onSort({
317
- order: isSameKey && (sortingState === null || sortingState === void 0 ? void 0 : sortingState.order) === "asc" ? "desc" : "asc",
318
360
  key: sortingKey,
361
+ label,
362
+ order: sortingOrder,
319
363
  });
320
364
  }
321
365
  function handleOnClick() {
322
366
  if (!isSortable)
323
367
  return;
324
- toggleSorting(headerKey);
368
+ if (sortableItem === null || sortableItem === void 0 ? void 0 : sortableItem.options) {
369
+ setIsDropDownOpen(!isDropDownOpen);
370
+ }
371
+ else {
372
+ const headerValue = headers[headerKey];
373
+ if (headerValue !== undefined) {
374
+ toggleSorting(headerKey, headerValue);
375
+ }
376
+ }
377
+ }
378
+ function handleSelectChange(selectedOption) {
379
+ if (sortableItem) {
380
+ toggleSorting(sortableItem.key, selectedOption.label, selectedOption.order);
381
+ }
382
+ setSelectedSortOption(selectedOption);
383
+ setIsDropDownOpen(true);
325
384
  }
326
385
  }
327
386
 
@@ -374,7 +433,7 @@ function generateListItemElement(item) {
374
433
  * Generate the header elements with the default styling
375
434
  */
376
435
  function generateHeaderElements(headers) {
377
- const headerElements = Object.keys(headers).reduce((acc, key) => (Object.assign(Object.assign({}, acc), { [key]: React__default["default"].createElement(DataListHeaderTile, { headers: headers, headerKey: key }) })), {});
436
+ const headerElements = Object.keys(headers).reduce((acc, key) => (Object.assign(Object.assign({}, acc), { [key]: React__default["default"].createElement(DataListHeaderTile, { headers: headers, headerKey: key, visible: true }) })), {});
378
437
  return isEmpty__default["default"](headerElements) ? undefined : headerElements;
379
438
  }
380
439
  function sortBreakpoints(sizeProp) {
@@ -517,7 +576,7 @@ function InternalDataListItemActions({ actions, }) {
517
576
  return (React__default["default"].createElement(framerMotion.motion.div, { variants: variants, initial: "hidden", animate: "visible", exit: "hidden", transition: {
518
577
  duration: TRANSITION_DURATION_IN_SECONDS,
519
578
  delay: TRANSITION_DELAY_IN_SECONDS,
520
- }, className: styles$c.menu, onContextMenu: handleContextMenu },
579
+ }, className: styles$d.menu, onContextMenu: handleContextMenu },
521
580
  React__default["default"].createElement(DataListActions, null, actions)));
522
581
  }
523
582
  function handleContextMenu(event) {
@@ -561,8 +620,8 @@ function DataListItemInternal({ children, item, }) {
561
620
  const { canSelect, hasAtLeastOneSelected, isSelectAll, selectedIDs, selected, onSelect, } = useBatchSelect();
562
621
  if (!canSelect)
563
622
  return children;
564
- return (React__default["default"].createElement("div", { className: classnames__default["default"](styles$f.selectable, {
565
- [styles$f.selected]: hasAtLeastOneSelected,
623
+ return (React__default["default"].createElement("div", { className: classnames__default["default"](styles$g.selectable, {
624
+ [styles$g.selected]: hasAtLeastOneSelected,
566
625
  }) },
567
626
  children,
568
627
  React__default["default"].createElement(Checkbox.Checkbox, { checked: getIsChecked(), onChange: handleChange })));
@@ -607,17 +666,17 @@ function DataListItemClickableInternal({ onClick, url, to, children, }) {
607
666
  return React__default["default"].createElement(React__default["default"].Fragment, null, children);
608
667
  if (to) {
609
668
  const computedTo = typeof to === "string" ? to : to(activeItem);
610
- return (React__default["default"].createElement(reactRouterDom.Link, { className: styles$f.listItemClickable, to: computedTo, onClick: handleClick }, children));
669
+ return (React__default["default"].createElement(reactRouterDom.Link, { className: styles$g.listItemClickable, to: computedTo, onClick: handleClick }, children));
611
670
  }
612
671
  if (url) {
613
672
  const href = typeof url === "string" ? url : url(activeItem);
614
- return (React__default["default"].createElement("a", { className: styles$f.listItemClickable, href: href, onClick: handleClick }, children));
673
+ return (React__default["default"].createElement("a", { className: styles$g.listItemClickable, href: href, onClick: handleClick }, children));
615
674
  }
616
675
  if (onClick) {
617
676
  return (
618
677
  // A button can be nested within the list item. To prevent a button inside
619
678
  // button error, we need to manually declare a div to be a button
620
- React__default["default"].createElement("div", { role: "button", tabIndex: 0, className: styles$f.listItemClickable, onClick: handleClick, onKeyDown: e => {
679
+ React__default["default"].createElement("div", { role: "button", tabIndex: 0, className: styles$g.listItemClickable, onClick: handleClick, onKeyDown: e => {
621
680
  if (e.key === "Enter" || e.key === " ") {
622
681
  e.preventDefault();
623
682
  handleClick();
@@ -667,8 +726,8 @@ function DataListItem({ item, layout, }) {
667
726
  const isContextMenuVisible = Boolean(contextPosition);
668
727
  const shouldShowContextMenu = showMenu && isContextMenuVisible && hasActions;
669
728
  return (React__default["default"].createElement(DataListLayoutActionsContext.Provider, { value: { activeItem: item } },
670
- React__default["default"].createElement("div", { onMouseEnter: handleShowMenu, onMouseLeave: handleHideMenu, onFocus: handleShowMenu, onBlur: handleHideMenu, onContextMenu: handleContextMenu, className: classnames__default["default"](styles$f.listItem, {
671
- [styles$f.active]: showMenu && isContextMenuVisible,
729
+ React__default["default"].createElement("div", { onMouseEnter: handleShowMenu, onMouseLeave: handleHideMenu, onFocus: handleShowMenu, onBlur: handleHideMenu, onContextMenu: handleContextMenu, className: classnames__default["default"](styles$g.listItem, {
730
+ [styles$g.active]: showMenu && isContextMenuVisible,
672
731
  }), key: item.id },
673
732
  React__default["default"].createElement(DataListItemInternal, { item: item },
674
733
  React__default["default"].createElement(DataListItemClickable, null, layout(generatedItem))),
@@ -754,14 +813,14 @@ function DataListHeaderCheckbox({ children }) {
754
813
  return children;
755
814
  const deselectText = sm ? "Deselect All" : "Deselect";
756
815
  const selectedLabel = selectedCount ? `${selectedCount} selected` : "";
757
- return (React__default["default"].createElement("div", { className: styles$f.selectable },
758
- React__default["default"].createElement("div", { className: classnames__default["default"](styles$f.selectAllCheckbox, {
759
- [styles$f.visible]: canSelectAll,
816
+ return (React__default["default"].createElement("div", { className: styles$g.selectable },
817
+ React__default["default"].createElement("div", { className: classnames__default["default"](styles$g.selectAllCheckbox, {
818
+ [styles$g.visible]: canSelectAll,
760
819
  }) },
761
820
  React__default["default"].createElement(Checkbox.Checkbox, { checked: isAllSelected(), indeterminate: isIndeterminate(), onChange: handleSelectAll },
762
- React__default["default"].createElement("div", { className: styles$f.srOnly }, selectedLabel))),
763
- React__default["default"].createElement(AnimatedSwitcher.AnimatedSwitcher, { switched: hasAtLeastOneSelected, initialChild: children, switchTo: React__default["default"].createElement("div", { className: styles$f.batchSelectContainer },
764
- React__default["default"].createElement("div", { className: styles$f.headerBatchSelect },
821
+ React__default["default"].createElement("div", { className: styles$g.srOnly }, selectedLabel))),
822
+ React__default["default"].createElement(AnimatedSwitcher.AnimatedSwitcher, { switched: hasAtLeastOneSelected, initialChild: children, switchTo: React__default["default"].createElement("div", { className: styles$g.batchSelectContainer },
823
+ React__default["default"].createElement("div", { className: styles$g.headerBatchSelect },
765
824
  Boolean(selectedCount) && React__default["default"].createElement(Text.Text, null,
766
825
  selectedCount,
767
826
  " selected"),
@@ -813,7 +872,7 @@ function DataListHeader() {
813
872
  const headerData = generateHeaderElements(headers);
814
873
  if (!headerData)
815
874
  return null;
816
- return (React__default["default"].createElement("div", { className: styles$f.headerTitles },
875
+ return (React__default["default"].createElement("div", { className: styles$g.headerTitles },
817
876
  React__default["default"].createElement(DataListHeaderCheckbox, null, layout(headerData))));
818
877
  function getVisibleSize() {
819
878
  const visibilityKeys = Object.keys(headerVisibility);
@@ -831,7 +890,7 @@ function DataListSort() {
831
890
  const sortByOptions = getSortByOptions();
832
891
  return (React__default["default"].createElement(Combobox.Combobox, { onSelect: selection => handleKeyChange(selection[0].id.toString()), selected: [
833
892
  {
834
- id: `${state === null || state === void 0 ? void 0 : state.key},${state === null || state === void 0 ? void 0 : state.order}`,
893
+ id: `${state === null || state === void 0 ? void 0 : state.key},${state === null || state === void 0 ? void 0 : state.order},${state === null || state === void 0 ? void 0 : state.label}`,
835
894
  label: (state === null || state === void 0 ? void 0 : state.order) || "",
836
895
  },
837
896
  ] },
@@ -841,17 +900,27 @@ function DataListSort() {
841
900
  sortByOptions.map(({ label, value }) => (React__default["default"].createElement(Combobox.Combobox.Option, { key: value, id: value, label: label })))));
842
901
  function getSortByOptions() {
843
902
  const options = sortable.reduce((acc, sort) => {
844
- const label = headers[sort];
903
+ const label = headers[sort.key];
845
904
  if (!label)
846
905
  return acc;
847
- if (label === "Last activity") {
848
- acc.push({ label: "Last Activity (Newest)", value: `${sort},desc` });
849
- acc.push({ label: "Last Activity (Oldest)", value: `${sort},asc` });
850
- }
851
- else {
852
- acc.push({ label: `${label} (A-Z)`, value: `${sort},asc` });
853
- acc.push({ label: `${label} (Z-A)`, value: `${sort},desc` });
906
+ const customOptions = sort.options;
907
+ if (customOptions) {
908
+ customOptions.forEach(option => {
909
+ acc.push({
910
+ label: option.label || "",
911
+ value: `${sort.key},${option.order},${option.label}`,
912
+ });
913
+ });
914
+ return acc;
854
915
  }
916
+ acc.push({
917
+ label: `${label} (A-Z)`,
918
+ value: `${sort.key},asc,${label}`,
919
+ });
920
+ acc.push({
921
+ label: `${label} (Z-A)`,
922
+ value: `${sort.key},desc,${label}`,
923
+ });
855
924
  return acc;
856
925
  }, []);
857
926
  // Inject a none option as the first option
@@ -859,13 +928,13 @@ function DataListSort() {
859
928
  return options;
860
929
  }
861
930
  function getButtonLabel() {
862
- const selectedOption = sortByOptions.find(option => option.value === `${state === null || state === void 0 ? void 0 : state.key},${state === null || state === void 0 ? void 0 : state.order}`);
931
+ const selectedOption = sortByOptions.find(option => option.value === `${state === null || state === void 0 ? void 0 : state.key},${state === null || state === void 0 ? void 0 : state.order},${state === null || state === void 0 ? void 0 : state.label}`);
863
932
  return (selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.label) || "";
864
933
  }
865
934
  function handleKeyChange(value) {
866
935
  if (value && value !== "none") {
867
- const [key, order] = value.split(",");
868
- onSort({ key, order: order });
936
+ const [key, order, label] = value.split(",");
937
+ onSort({ key, order: order, label });
869
938
  return;
870
939
  }
871
940
  onSort(undefined);
@@ -1164,13 +1233,13 @@ function InternalDataList() {
1164
1233
  const initialLoading = loadingState === "initial";
1165
1234
  const showEmptyState = !initialLoading && data.length === 0;
1166
1235
  const shouldRenderLoadMoreTrigger = !initialLoading && !showEmptyState;
1167
- return (React__default["default"].createElement("div", { className: styles$f.wrapper },
1168
- React__default["default"].createElement("div", { className: styles$f.titleContainer },
1236
+ return (React__default["default"].createElement("div", { className: styles$g.wrapper },
1237
+ React__default["default"].createElement("div", { className: styles$g.titleContainer },
1169
1238
  title && React__default["default"].createElement(Heading.Heading, { level: 3 }, title),
1170
1239
  React__default["default"].createElement(DataListTotalCount, { totalCount: totalCount, loading: initialLoading })),
1171
1240
  React__default["default"].createElement("div", { ref: backToTopRef }),
1172
1241
  React__default["default"].createElement(DataListStickyHeader, null,
1173
- React__default["default"].createElement("div", { className: styles$f.headerFilters },
1242
+ React__default["default"].createElement("div", { className: styles$g.headerFilters },
1174
1243
  React__default["default"].createElement(InternalDataListFilters, null),
1175
1244
  React__default["default"].createElement(InternalDataListSearch, null)),
1176
1245
  React__default["default"].createElement(InternalDataListStatusBar, null),
@@ -1178,8 +1247,8 @@ function InternalDataList() {
1178
1247
  initialLoading && React__default["default"].createElement(DataListLoadingState, null),
1179
1248
  showEmptyState && React__default["default"].createElement(InternalDataListEmptyState, null),
1180
1249
  layoutComponents,
1181
- loadingState === "filtering" && (React__default["default"].createElement("div", { "data-testid": DATA_LIST_FILTERING_SPINNER_TEST_ID, className: styles$f.filtering },
1182
- React__default["default"].createElement("div", { className: styles$f.filteringSpinner },
1250
+ loadingState === "filtering" && (React__default["default"].createElement("div", { "data-testid": DATA_LIST_FILTERING_SPINNER_TEST_ID, className: styles$g.filtering },
1251
+ React__default["default"].createElement("div", { className: styles$g.filteringSpinner },
1183
1252
  React__default["default"].createElement(Spinner.Spinner, { size: "small" })))),
1184
1253
  shouldRenderLoadMoreTrigger && (React__default["default"].createElement(DataListLoadMore, { onBackToTop: handleBackToTop }))));
1185
1254
  function handleBackToTop() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jobber/components",
3
- "version": "4.74.2",
3
+ "version": "4.76.0",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -84,5 +84,5 @@
84
84
  "> 1%",
85
85
  "IE 10"
86
86
  ],
87
- "gitHead": "6e716d91f2c63e59026724fc088b9db29ea7ffec"
87
+ "gitHead": "03135427c5c110b2922e22328fa0469dcede77a1"
88
88
  }