@jobber/components 4.78.3 → 4.79.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.
@@ -34,6 +34,10 @@ export interface ComboboxProps {
34
34
  * The amount of time in ms to debounce the onSearch callback. Defaults to 300ms.
35
35
  */
36
36
  readonly onSearchDebounce?: number;
37
+ /**
38
+ * Callback to load more options, this is called when the user scrolls to the bottom of the list.
39
+ */
40
+ readonly onLoadMore?: () => void;
37
41
  /**
38
42
  * The Chip heading for the trigger
39
43
  */
@@ -97,6 +101,10 @@ export interface ComboboxContentProps {
97
101
  * Function called when search input changes.
98
102
  */
99
103
  readonly handleSearchChange: (value: string) => void;
104
+ /**
105
+ * Callback to load more options, this is called when the user scrolls to the bottom of the list.
106
+ */
107
+ readonly onLoadMore?: () => void;
100
108
  /**
101
109
  * Reference to the wrapping div element of all the Combobox pieces
102
110
  */
@@ -191,6 +199,10 @@ export interface ComboboxListProps {
191
199
  * Should loading state be shown.
192
200
  */
193
201
  readonly loading?: boolean;
202
+ /**
203
+ * Callback to load more options, this is called when the user scrolls to the bottom of the list.
204
+ */
205
+ readonly onLoadMore?: () => void;
194
206
  }
195
207
  export interface ComboboxActionProps {
196
208
  /**
@@ -0,0 +1,6 @@
1
+ /// <reference types="react" />
2
+ interface ComboboxLoadMoreProps {
3
+ readonly onLoadMore: () => void;
4
+ }
5
+ export declare function ComboboxLoadMore({ onLoadMore }: ComboboxLoadMoreProps): JSX.Element;
6
+ export {};
@@ -0,0 +1 @@
1
+ export { ComboboxLoadMore } from "./ComboboxLoadMore";
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var Combobox = require('../Combobox-1c91da1f.js');
5
+ var Combobox = require('../Combobox-d4b84edf.js');
6
6
  require('react');
7
7
  require('classnames');
8
8
  require('react-dom');
@@ -14,6 +14,8 @@ require('../Typography-c45bf216.js');
14
14
  require('../Glimmer-7c317864.js');
15
15
  require('../tslib.es6-754e2961.js');
16
16
  require('../Content-e3f7b6fc.js');
17
+ require('../Spinner-9d8fc7ff.js');
18
+ require('@jobber/hooks/useInView');
17
19
  require('../Button-b73a5e01.js');
18
20
  require('react-router-dom');
19
21
  require('@jobber/hooks/useRefocusOnActivator');
@@ -21,7 +23,6 @@ require('@jobber/hooks/useFocusTrap');
21
23
  require('react-popper');
22
24
  require('@jobber/hooks/useOnKeyDown');
23
25
  require('../Chip-c91fd6c8.js');
24
- require('@jobber/hooks/useInView');
25
26
  require('../Avatar-76a799fa.js');
26
27
  require('color');
27
28
  require('../Tooltip-27771182.js');
@@ -7,7 +7,9 @@ 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
9
  var Glimmer = require('./Glimmer-7c317864.js');
10
+ var Spinner = require('./Spinner-9d8fc7ff.js');
10
11
  var tslib_es6 = require('./tslib.es6-754e2961.js');
12
+ var useInView = require('@jobber/hooks/useInView');
11
13
  var Typography = require('./Typography-c45bf216.js');
12
14
  var Button = require('./Button-b73a5e01.js');
13
15
  var useRefocusOnActivator = require('@jobber/hooks/useRefocusOnActivator');
@@ -28,13 +30,13 @@ var ReactDOM__default = /*#__PURE__*/_interopDefaultLegacy(ReactDOM);
28
30
  var debounce__default = /*#__PURE__*/_interopDefaultLegacy(debounce);
29
31
  var noop__default = /*#__PURE__*/_interopDefaultLegacy(noop);
30
32
 
31
- var css_248z$6 = ".m1w5vdUZ6rQ- {\n z-index: 1002;\n z-index: var(--elevation-tooltip);\n width: calc((16px * 4) * 3.75);\n width: calc(calc(16px * 4) * 3.75);\n 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";
32
- var styles$6 = {"content":"m1w5vdUZ6rQ-","hidden":"Zlkv2HA096A-","actions":"YQry-Rd6zfQ-","actionPadding":"TcpqL34s4lI-"};
33
- styleInject_es.styleInject(css_248z$6);
33
+ var css_248z$7 = ".m1w5vdUZ6rQ- {\n z-index: 1002;\n z-index: var(--elevation-tooltip);\n width: calc((16px * 4) * 3.75);\n width: calc(calc(16px * 4) * 3.75);\n 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";
34
+ var styles$7 = {"content":"m1w5vdUZ6rQ-","hidden":"Zlkv2HA096A-","actions":"YQry-Rd6zfQ-","actionPadding":"TcpqL34s4lI-"};
35
+ styleInject_es.styleInject(css_248z$7);
34
36
 
35
- var css_248z$5 = ".MIyb-oFZg9w- {\n position: relative;\n}\n\n.WZPK91I4aJs- {\n width: 100%;\n padding: calc(16px * 1);\n padding: var(--space-base);\n padding-right: calc((16px * 1.5) * 2.25);\n padding-right: calc(calc(16px * 1.5) * 2.25);\n padding-right: calc(var(--space-large) * 2.25);\n border: none;\n border-bottom: calc(16px / 16) solid rgb(217, 223, 225);\n border-bottom: var(--border-base) solid var(--color-border);\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}\n\n.WZPK91I4aJs-::-webkit-search-decoration,\n.WZPK91I4aJs-::-webkit-search-cancel-button,\n.WZPK91I4aJs-::-webkit-search-results-button,\n.WZPK91I4aJs-::-webkit-search-results-decoration {\n -webkit-appearance: none;\n}\n\n.WZPK91I4aJs-:focus {\n outline: none;\n}\n\n._7loHrVUe-Rk- {\n display: -ms-flexbox;\n display: flex;\n position: absolute;\n top: 50%;\n right: calc(16px * 1);\n right: var(--space-base);\n z-index: 1002;\n z-index: var(--elevation-tooltip);\n width: calc(16px * 1.5);\n width: var(--space-large);\n height: calc(16px * 1.5);\n height: var(--space-large);\n padding: 0;\n border: none;\n border-radius: 100%;\n border-radius: var(--radius-circle);\n background-color: rgb(238, 240, 242);\n background-color: var(--color-surface--background);\n cursor: pointer;\n -webkit-transform: translateY(-50%);\n transform: translateY(-50%);\n -ms-flex-pack: center;\n justify-content: center;\n -ms-flex-align: center;\n align-items: center;\n}\n\n._7loHrVUe-Rk-:focus {\n outline: transparent;\n}\n\n._7loHrVUe-Rk-: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";
36
- var styles$5 = {"search":"MIyb-oFZg9w-","searchInput":"WZPK91I4aJs-","clearSearch":"_7loHrVUe-Rk-"};
37
- styleInject_es.styleInject(css_248z$5);
37
+ var css_248z$6 = ".MIyb-oFZg9w- {\n position: relative;\n}\n\n.WZPK91I4aJs- {\n width: 100%;\n padding: calc(16px * 1);\n padding: var(--space-base);\n padding-right: calc((16px * 1.5) * 2.25);\n padding-right: calc(calc(16px * 1.5) * 2.25);\n padding-right: calc(var(--space-large) * 2.25);\n border: none;\n border-bottom: calc(16px / 16) solid rgb(217, 223, 225);\n border-bottom: var(--border-base) solid var(--color-border);\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}\n\n.WZPK91I4aJs-::-webkit-search-decoration,\n.WZPK91I4aJs-::-webkit-search-cancel-button,\n.WZPK91I4aJs-::-webkit-search-results-button,\n.WZPK91I4aJs-::-webkit-search-results-decoration {\n -webkit-appearance: none;\n}\n\n.WZPK91I4aJs-:focus {\n outline: none;\n}\n\n._7loHrVUe-Rk- {\n display: -ms-flexbox;\n display: flex;\n position: absolute;\n top: 50%;\n right: calc(16px * 1);\n right: var(--space-base);\n z-index: 1002;\n z-index: var(--elevation-tooltip);\n width: calc(16px * 1.5);\n width: var(--space-large);\n height: calc(16px * 1.5);\n height: var(--space-large);\n padding: 0;\n border: none;\n border-radius: 100%;\n border-radius: var(--radius-circle);\n background-color: rgb(238, 240, 242);\n background-color: var(--color-surface--background);\n cursor: pointer;\n -webkit-transform: translateY(-50%);\n transform: translateY(-50%);\n -ms-flex-pack: center;\n justify-content: center;\n -ms-flex-align: center;\n align-items: center;\n}\n\n._7loHrVUe-Rk-:focus {\n outline: transparent;\n}\n\n._7loHrVUe-Rk-: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";
38
+ var styles$6 = {"search":"MIyb-oFZg9w-","searchInput":"WZPK91I4aJs-","clearSearch":"_7loHrVUe-Rk-"};
39
+ styleInject_es.styleInject(css_248z$6);
38
40
 
39
41
  function ComboboxContentSearch(props) {
40
42
  const searchRef = React.useRef(null);
@@ -46,9 +48,9 @@ function ComboboxContentSearch(props) {
46
48
  }, 0);
47
49
  }
48
50
  }, [props.open]);
49
- return (React__default["default"].createElement("div", { className: styles$5.search },
50
- React__default["default"].createElement("input", { type: "search", ref: searchRef, className: styles$5.searchInput, placeholder: props.placeholder ? `Search ${props.placeholder}` : "Search", onChange: (event) => handleSearch(event), value: props.searchValue }),
51
- props.searchValue && (React__default["default"].createElement("button", { className: styles$5.clearSearch, onClick: clearSearch, type: "button", "data-testid": "ATL-Combobox-Content-Search-Clear", "aria-label": "Clear search" },
51
+ return (React__default["default"].createElement("div", { className: styles$6.search },
52
+ React__default["default"].createElement("input", { type: "search", ref: searchRef, className: styles$6.searchInput, placeholder: props.placeholder ? `Search ${props.placeholder}` : "Search", onChange: (event) => handleSearch(event), value: props.searchValue }),
53
+ props.searchValue && (React__default["default"].createElement("button", { className: styles$6.clearSearch, onClick: clearSearch, type: "button", "data-testid": "ATL-Combobox-Content-Search-Clear", "aria-label": "Clear search" },
52
54
  React__default["default"].createElement(Icon.Icon, { name: "remove", size: "small" })))));
53
55
  function clearSearch() {
54
56
  var _a;
@@ -62,13 +64,13 @@ function ComboboxContentSearch(props) {
62
64
  }
63
65
  }
64
66
 
65
- 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";
66
- var styles$4 = {"container":"SgMzjOcdE-E-","optionsList":"TwoTCjgcssc-","filterMessage":"_8T5M7MGwCRE-","emptyStateMessage":"_4y5NXkNeIQM-","scrollTop":"T6E3VwBGoQM-","scrollNone":"_6HQzxMQkXnE-","scrollBottom":"_5YsJZyMDkbA-","loadingContainer":"A6z4OI58xoE-"};
67
- styleInject_es.styleInject(css_248z$4);
67
+ var css_248z$5 = ".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\n max-height: calc((16px / 2) * 33.33);\n\n max-height: calc(calc(16px / 2) * 33.33);\n\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\n.A6z4OI58xoE-.QqHBSf52fPk- {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-pack: center;\n justify-content: center;\n\n position: fixed;\n bottom: 0;\n\n width: 100%;\n\n padding: calc(16px * 1) 0;\n\n padding: var(--space-base) 0;\n}\n";
68
+ var styles$5 = {"container":"SgMzjOcdE-E-","optionsList":"TwoTCjgcssc-","filterMessage":"_8T5M7MGwCRE-","emptyStateMessage":"_4y5NXkNeIQM-","scrollTop":"T6E3VwBGoQM-","scrollNone":"_6HQzxMQkXnE-","scrollBottom":"_5YsJZyMDkbA-","loadingContainer":"A6z4OI58xoE-","hasOptions":"QqHBSf52fPk-"};
69
+ styleInject_es.styleInject(css_248z$5);
68
70
 
69
- var css_248z$3 = "._5QdRGmaNHvc- {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-negative: 0;\n flex-shrink: 0;\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";
70
- var styles$3 = {"option":"_5QdRGmaNHvc-"};
71
- styleInject_es.styleInject(css_248z$3);
71
+ var css_248z$4 = "._5QdRGmaNHvc- {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-negative: 0;\n flex-shrink: 0;\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";
72
+ var styles$4 = {"option":"_5QdRGmaNHvc-"};
73
+ styleInject_es.styleInject(css_248z$4);
72
74
 
73
75
  const ComboboxContext = React__default["default"].createContext({});
74
76
  function ComboboxContextProvider(_a) {
@@ -80,29 +82,45 @@ function ComboboxOption(props) {
80
82
  const { selected, selectionHandler } = React.useContext(ComboboxContext);
81
83
  const isSelected = selected.some(selection => selection.id.toString() === props.id.toString());
82
84
  return (React__default["default"].createElement("li", { key: props.id, tabIndex: -1, "data-selected": isSelected, role: "option", "aria-selected": isSelected, onClick: () => selectionHandler &&
83
- selectionHandler({ id: props.id, label: props.label }), className: classnames__default["default"](styles$3.option) },
85
+ selectionHandler({ id: props.id, label: props.label }), className: classnames__default["default"](styles$4.option) },
84
86
  props.label,
85
87
  React__default["default"].createElement("div", null, isSelected && React__default["default"].createElement(Icon.Icon, { name: "checkmark", color: "blue" }))));
86
88
  }
87
89
 
90
+ var css_248z$3 = "._3s8-RC5Ky3s- {\n -webkit-transform: translateY(calc((16px * 3) * -1));\n -webkit-transform: translateY(calc(calc(16px * 3) * -1));\n -webkit-transform: translateY(calc(var(--space-largest) * -1));\n transform: translateY(calc((16px * 3) * -1));\n transform: translateY(calc(calc(16px * 3) * -1));\n transform: translateY(calc(var(--space-largest) * -1));\n}\n";
91
+ var styles$3 = {"trigger":"_3s8-RC5Ky3s-"};
92
+ styleInject_es.styleInject(css_248z$3);
93
+
94
+ function ComboboxLoadMore({ onLoadMore }) {
95
+ const [inViewRef, isInView] = useInView.useInView();
96
+ React.useEffect(() => {
97
+ isInView && onLoadMore();
98
+ }, [isInView]);
99
+ return (React__default["default"].createElement("div", { "data-testid": "ATL-Combobox-Loadmore-Trigger", ref: inViewRef, className: styles$3.trigger }));
100
+ }
101
+
88
102
  function ComboboxContentList(props) {
89
103
  const optionsExist = props.options.length > 0;
90
- const showOptions = optionsExist && !props.loading;
91
104
  const hasSearchTerm = props.searchValue.length > 0;
92
105
  const { listScrollState } = useScrollState(props.optionsListRef, props.options);
93
- return (React__default["default"].createElement("div", { className: classnames__default["default"](styles$4.container, styles$4[listScrollState]) },
94
- optionsExist && (React__default["default"].createElement("ul", { className: styles$4.optionsList, role: "listbox", "aria-multiselectable": props.multiselect, ref: props.optionsListRef },
95
- showOptions &&
96
- props.options.map(option => {
97
- return (React__default["default"].createElement(ComboboxOption, { key: option.id, id: option.id, label: option.label }));
98
- }),
99
- 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 },
100
- React__default["default"].createElement(Glimmer.Glimmer, { shape: "rectangle", size: "small" })))))))),
101
- hasSearchTerm && !optionsExist && (React__default["default"].createElement("div", { className: styles$4.filterMessage },
106
+ return (React__default["default"].createElement("div", { className: classnames__default["default"](styles$5.container, styles$5[listScrollState]) },
107
+ optionsExist && (React__default["default"].createElement("ul", { className: styles$5.optionsList, role: "listbox", "aria-multiselectable": props.multiselect, ref: props.optionsListRef },
108
+ props.options.map(option => {
109
+ return (React__default["default"].createElement(ComboboxOption, { key: option.id, id: option.id, label: option.label }));
110
+ }),
111
+ props.loading && optionsExist && (React__default["default"].createElement("div", { className: classnames__default["default"]([
112
+ styles$5.loadingContainer,
113
+ styles$5.hasOptions,
114
+ ]) },
115
+ React__default["default"].createElement(Spinner.Spinner, { size: "small" }))),
116
+ props.onLoadMore && (React__default["default"].createElement(ComboboxLoadMore, { onLoadMore: props.onLoadMore })))),
117
+ props.loading && !optionsExist && (React__default["default"].createElement(React__default["default"].Fragment, null, Array.from({ length: 5 }).map((_, index) => (React__default["default"].createElement("div", { className: styles$5.loadingContainer, key: index },
118
+ React__default["default"].createElement(Glimmer.Glimmer, { shape: "rectangle", size: "small" })))))),
119
+ hasSearchTerm && !props.loading && !optionsExist && (React__default["default"].createElement("div", { className: styles$5.filterMessage },
102
120
  React__default["default"].createElement(Text.Text, { variation: "subdued" },
103
121
  "No results for ",
104
122
  `“${props.searchValue}”`))),
105
- !hasSearchTerm && !optionsExist && (React__default["default"].createElement("div", { className: styles$4.emptyStateMessage },
123
+ !hasSearchTerm && !props.loading && !optionsExist && (React__default["default"].createElement("div", { className: styles$5.emptyStateMessage },
106
124
  React__default["default"].createElement(Text.Text, { variation: "subdued" }, getZeroIndexStateText(props.subjectNoun))))));
107
125
  }
108
126
  function getZeroIndexStateText(subjectNoun) {
@@ -283,16 +301,16 @@ function ComboboxContent(props) {
283
301
  const optionsExist = props.options.length > 0;
284
302
  const { optionsListRef } = useComboboxContent(props.open, props.selected);
285
303
  const { popperRef, popperStyles, attributes } = useComboboxAccessibility(props.handleSelection, props.options, optionsListRef, props.open, props.wrapperRef);
286
- 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),
304
+ 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$7.content, { [styles$7.hidden]: !props.open }), style: popperStyles.popper }, attributes.popper),
287
305
  React__default["default"].createElement(ComboboxContentSearch, { open: props.open, placeholder: props.subjectNoun, searchValue: props.searchValue, setSearchValue: props.setSearchValue, handleSearchChange: props.handleSearchChange }),
288
306
  props.multiselect && optionsExist && (React__default["default"].createElement(ComboboxContentHeader, { hasOptionsVisible: optionsExist, subjectNoun: props.subjectNoun, selectedCount: props.selected.length, onClearAll: () => {
289
307
  props.selectedStateSetter([]);
290
308
  }, onSelectAll: () => {
291
309
  props.selectedStateSetter(props.options);
292
310
  } })),
293
- 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 }),
294
- 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"]({
295
- [styles$6.actionPadding]: index === childrenArray.length - 1,
311
+ 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, onLoadMore: props.onLoadMore }),
312
+ props.actionElements && (React__default["default"].createElement("div", { className: styles$7.actions, role: "group" }, props.actionElements.map((child, index, childrenArray) => (React__default["default"].createElement("div", { key: index, className: classnames__default["default"]({
313
+ [styles$7.actionPadding]: index === childrenArray.length - 1,
296
314
  }) }, child)))))));
297
315
  return ReactDOM__default["default"].createPortal(template, document.body);
298
316
  }
@@ -448,7 +466,7 @@ function Combobox(props) {
448
466
  React__default["default"].createElement("div", { ref: wrapperRef, className: styles.wrapper },
449
467
  open && (React__default["default"].createElement("div", { className: styles.overlay, onClick: () => handleClose(), "data-testid": "ATL-Combobox-Overlay" })),
450
468
  triggerElement || (React__default["default"].createElement(ComboboxTrigger, { label: props.label, selected: props.selected })),
451
- 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 }))));
469
+ 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, onLoadMore: props.onLoadMore }))));
452
470
  }
453
471
  Combobox.Activator = ComboboxActivator;
454
472
  Combobox.Action = ComboboxAction;
@@ -26,7 +26,7 @@ var ReactDOM = require('react-dom');
26
26
  var Checkbox = require('../Checkbox-99f6297f.js');
27
27
  var reactRouterDom = require('react-router-dom');
28
28
  var AnimatedSwitcher = require('../AnimatedSwitcher-3d45ec5d.js');
29
- var Combobox = require('../Combobox-1c91da1f.js');
29
+ var Combobox = require('../Combobox-d4b84edf.js');
30
30
  var Chip = require('../Chip-c91fd6c8.js');
31
31
  var debounce = require('lodash/debounce');
32
32
  var InputText = require('../InputText-6e356985.js');
@@ -304,13 +304,13 @@ styleInject_es.styleInject(css_248z$8);
304
304
  function DataListSortingOptions({ options, selectedOption, onSelectChange, onClose, optionsListRef, dataListHeaderTileRef, }) {
305
305
  useRefocusOnActivator.useRefocusOnActivator(!optionsListRef.current);
306
306
  useOnKeyDown.useOnKeyDown(() => onClose(), "Escape");
307
- React__default["default"].useEffect(() => {
307
+ React.useEffect(() => {
308
308
  document.addEventListener("mousedown", handleClickOutside);
309
309
  return () => {
310
310
  document.removeEventListener("mousedown", handleClickOutside);
311
311
  };
312
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, "data-value": option.id },
313
+ return (React__default["default"].createElement("ul", { className: styles$8.optionsList, ref: optionsListRef }, options.map(option => (React__default["default"].createElement("li", { className: styles$8.option, key: option.id, onClick: () => onSelectChange(option), onKeyDown: event => handleKeyDown(event, option), tabIndex: 0, "data-value": option.id },
314
314
  option.label,
315
315
  option.label === (selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.label) && (React__default["default"].createElement(Icon.Icon, { name: "checkmark", color: "blue" })))))));
316
316
  function handleKeyDown(event, option) {
@@ -320,9 +320,9 @@ function DataListSortingOptions({ options, selectedOption, onSelectChange, onClo
320
320
  }
321
321
  function handleClickOutside(event) {
322
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) {
323
+ const isClickInside = ((_a = optionsListRef.current) === null || _a === void 0 ? void 0 : _a.contains(event.target)) ||
324
+ ((_b = dataListHeaderTileRef.current) === null || _b === void 0 ? void 0 : _b.contains(event.target));
325
+ if (!isClickInside) {
326
326
  onClose();
327
327
  }
328
328
  }
@@ -332,9 +332,9 @@ function DataListSortingOptions({ options, selectedOption, onSelectChange, onClo
332
332
  function DataListHeaderTile({ headers, headerKey, visible = false, }) {
333
333
  useRefocusOnActivator.useRefocusOnActivator(visible);
334
334
  const { sorting } = useDataListContext();
335
- const [isDropDownOpen, setIsDropDownOpen] = React__default["default"].useState(false);
335
+ const [isDropDownOpen, setIsDropDownOpen] = React.useState(false);
336
336
  const optionsListRef = useFocusTrap.useFocusTrap(isDropDownOpen);
337
- const dataListHeaderTileRef = React__default["default"].useRef(null);
337
+ const dataListHeaderTileRef = React.useRef(null);
338
338
  const sortableItem = sorting === null || sorting === void 0 ? void 0 : sorting.sortable.find(item => item.key === headerKey);
339
339
  const isSortable = Boolean(sortableItem);
340
340
  const sortingState = sorting === null || sorting === void 0 ? void 0 : sorting.state;
@@ -344,15 +344,15 @@ function DataListHeaderTile({ headers, headerKey, visible = false, }) {
344
344
  }), onClick: handleOnClick, ref: dataListHeaderTileRef },
345
345
  React__default["default"].createElement(Text.Text, { maxLines: "single" }, headers[headerKey]),
346
346
  isSortable && (sortableItem === null || sortableItem === void 0 ? void 0 : sortableItem.options) && isDropDownOpen && (React__default["default"].createElement(DataListSortingOptions, { options: sortableItem.options, selectedOption: (sorting === null || sorting === void 0 ? void 0 : sorting.state) || null, onSelectChange: handleSelectChange, onClose: () => setIsDropDownOpen(false), optionsListRef: optionsListRef, dataListHeaderTileRef: dataListHeaderTileRef })),
347
- (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));
348
- function toggleSorting(newSortingKey, newId, newLabel, newOrder) {
347
+ isSortable && (React__default["default"].createElement(DataListSortingArrows, { order: (sortingState === null || sortingState === void 0 ? void 0 : sortingState.key) === headerKey ? sortingState.order : "none" }))));
348
+ function toggleSorting(newSortingKey, newId, newLabel) {
349
349
  const isSameKey = newSortingKey === (sortingState === null || sortingState === void 0 ? void 0 : sortingState.key);
350
350
  const isDescending = (sortingState === null || sortingState === void 0 ? void 0 : sortingState.order) === "desc";
351
- if (isSameKey && isDescending && newOrder === undefined) {
351
+ if (isSameKey && isDescending) {
352
352
  sorting === null || sorting === void 0 ? void 0 : sorting.onSort(undefined);
353
353
  return;
354
354
  }
355
- const sortingOrder = newOrder || (isSameKey && !isDescending ? "desc" : "asc");
355
+ const sortingOrder = isSameKey ? "desc" : "asc";
356
356
  setSorting(newSortingKey, newId, newLabel, sortingOrder);
357
357
  }
358
358
  function setSorting(newSortingKey, newId, newLabel, newOrder) {
@@ -371,11 +371,8 @@ function DataListHeaderTile({ headers, headerKey, visible = false, }) {
371
371
  setIsDropDownOpen(!isDropDownOpen);
372
372
  }
373
373
  else {
374
- const headerValue = headers[headerKey];
375
374
  const id = ((_b = (_a = sortableItem === null || sortableItem === void 0 ? void 0 : sortableItem.options) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.id) || headerKey;
376
- if (headerValue !== undefined) {
377
- toggleSorting(id, headerKey, headerValue);
378
- }
375
+ toggleSorting(id, headerKey, headers[headerKey]);
379
376
  }
380
377
  }
381
378
  function handleSelectChange(newSortOption) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jobber/components",
3
- "version": "4.78.3",
3
+ "version": "4.79.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": "3caaa43e03388b7d034d0606dc803218394929c2"
87
+ "gitHead": "01c73a7bc9171ba85c75f5f0f5046baf8469f35a"
88
88
  }