@jobber/components 4.39.0 → 4.41.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.
@@ -8,10 +8,10 @@ var styleInject_es = require('../style-inject.es-9d2f5f4e.js');
8
8
  var Text = require('../Text-e7ed0974.js');
9
9
  var Glimmer = require('../Glimmer-cfa92a88.js');
10
10
  var framerMotion = require('framer-motion');
11
+ var classnames = require('classnames');
11
12
  var design = require('@jobber/design');
12
13
  var isEmpty = require('lodash/isEmpty');
13
14
  var InlineLabel = require('../InlineLabel-afd5fc6f.js');
14
- var classnames = require('classnames');
15
15
  var FormatDate = require('../FormatDate-70ea5b43.js');
16
16
  var Heading = require('../Heading-a1191b15.js');
17
17
  require('uuid');
@@ -29,22 +29,30 @@ var useOnKeyDown = require('@jobber/hooks/useOnKeyDown');
29
29
  var AnimatedSwitcher = require('../AnimatedSwitcher-d1e1ddcf.js');
30
30
  var Icon = require('../Icon-405a216c.js');
31
31
  var useInView = require('@jobber/hooks/useInView');
32
+ var Popover = require('../Popover-bbfc6aa1.js');
33
+ var Content = require('../Content-2ca1ffe1.js');
34
+ var Chip = require('../Chip-4916a642.js');
35
+ require('@jobber/hooks/useAssert');
36
+ require('../Avatar-1aa30ee1.js');
37
+ require('color');
32
38
  var debounce = require('lodash/debounce');
33
39
  var InputText = require('../InputText-d1a52550.js');
34
40
  var Spinner = require('../Spinner-9d8fc7ff.js');
35
- require('../Content-2ca1ffe1.js');
41
+ require('../ButtonDismiss-82680c7d.js');
42
+ require('lodash/sortBy');
43
+ require('@jobber/hooks/useLiveAnnounce');
36
44
  require('../FormField-d6138b7f.js');
37
45
  require('../InputValidation-b5a3d92c.js');
38
46
 
39
47
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
40
48
 
41
49
  var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
42
- var isEmpty__default = /*#__PURE__*/_interopDefaultLegacy(isEmpty);
43
50
  var classnames__default = /*#__PURE__*/_interopDefaultLegacy(classnames);
51
+ var isEmpty__default = /*#__PURE__*/_interopDefaultLegacy(isEmpty);
44
52
  var debounce__default = /*#__PURE__*/_interopDefaultLegacy(debounce);
45
53
 
46
- var css_248z$d = ".TkdrExYnvcY-,\n.TkdrExYnvcY- * {\n box-sizing: border-box;\n}\n\n.TkdrExYnvcY- {\n display: -ms-flexbox;\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.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) 0;\n padding: var(--space-small) 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 -webkit-max-content;\n grid-template-columns: auto max-content;\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(225, 225, 225);\n border-bottom: var(--border-thick) solid var(--color-border);\n}\n\n.jMSVGIAr5tk- > p {\n font-weight: 500;\n}\n\n.jMSVGIAr5tk- {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-align: center;\n align-items: center;\n gap: calc(16px / 4);\n gap: var(--space-smaller);\n margin: calc((16px / 2) * -1) 0;\n margin: calc(calc(16px / 2) * -1) 0;\n margin: calc(var(--space-small) * -1) 0;\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(225, 225, 225);\n border-bottom: var(--border-base) solid var(--color-border);\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\n.qm-SSuWTXkI-.VA9RnQp6nbI- {\n visibility: visible;\n}\n\n.ise8kHCfhCY- .d-79rkMqufg- > :first-child {\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- > :first-child {\n padding-top: 0;\n opacity: 0;\n}\n }\n\n@media (--medium-screens-and-up) {\n\n.ise8kHCfhCY- .d-79rkMqufg- > :first-child {\n padding-top: 0;\n opacity: 0;\n}\n }\n\n.ise8kHCfhCY-:hover .d-79rkMqufg- > :first-child,\n.ise8kHCfhCY-:focus-within .d-79rkMqufg- > :first-child,\n.ise8kHCfhCY- .d-79rkMqufg-._4L7iXXzLr5k- > :first-child {\n opacity: 1;\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";
47
- var styles$d = {"wrapper":"TkdrExYnvcY-","titleContainer":"IcAlZHoB4LI-","headerFilters":"TFO76ysivmg-","headerTitles":"jGHZZYZm1ZY-","headerBatchSelect":"jMSVGIAr5tk-","listItem":"ise8kHCfhCY-","selectable":"d-79rkMqufg-","selectAllCheckbox":"qm-SSuWTXkI-","visible":"VA9RnQp6nbI-","selected":"_4L7iXXzLr5k-","filtering":"Kkp-IYmwq-s-","filteringSpinner":"m-eCShL7TU4-"};
54
+ var css_248z$d = ".TkdrExYnvcY-,\n.TkdrExYnvcY- * {\n box-sizing: border-box;\n}\n\n.TkdrExYnvcY- {\n display: -ms-flexbox;\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.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) 0;\n padding: var(--space-small) 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 -webkit-max-content;\n grid-template-columns: auto max-content;\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(225, 225, 225);\n border-bottom: var(--border-thick) solid var(--color-border);\n}\n\n.jMSVGIAr5tk- > p {\n font-weight: 500;\n}\n\n.jMSVGIAr5tk- {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-align: center;\n align-items: center;\n gap: calc(16px / 4);\n gap: var(--space-smaller);\n margin: calc((16px / 2) * -1) 0;\n margin: calc(calc(16px / 2) * -1) 0;\n margin: calc(var(--space-small) * -1) 0;\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(225, 225, 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-.Pc0JGX6jCD4- {\n --data-list-item-active-color: var(--color-surface--background);\n background-color: rgb(244, 244, 244);\n background-color: var(--data-list-item-active-color);\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\n.qm-SSuWTXkI-.VA9RnQp6nbI- {\n visibility: visible;\n}\n\n.ise8kHCfhCY- .d-79rkMqufg- > :first-child {\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- > :first-child {\n padding-top: 0;\n opacity: 0;\n}\n }\n\n@media (--medium-screens-and-up) {\n\n.ise8kHCfhCY- .d-79rkMqufg- > :first-child {\n padding-top: 0;\n opacity: 0;\n}\n }\n\n.ise8kHCfhCY-:hover .d-79rkMqufg- > :first-child,\n.ise8kHCfhCY-:focus-within .d-79rkMqufg- > :first-child,\n.ise8kHCfhCY- .d-79rkMqufg-._4L7iXXzLr5k- > :first-child {\n opacity: 1;\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";
55
+ var styles$d = {"wrapper":"TkdrExYnvcY-","titleContainer":"IcAlZHoB4LI-","headerFilters":"TFO76ysivmg-","headerTitles":"jGHZZYZm1ZY-","headerBatchSelect":"jMSVGIAr5tk-","listItem":"ise8kHCfhCY-","active":"Pc0JGX6jCD4-","selectable":"d-79rkMqufg-","selectAllCheckbox":"qm-SSuWTXkI-","visible":"VA9RnQp6nbI-","selected":"_4L7iXXzLr5k-","filtering":"Kkp-IYmwq-s-","filteringSpinner":"m-eCShL7TU4-"};
48
56
  styleInject_es.styleInject(css_248z$d);
49
57
 
50
58
  var css_248z$c = ".F56prQsXm3A- {\n min-width: 80px;\n margin-left: calc(16px / 2);\n margin-left: var(--space-small);\n}\n";
@@ -93,7 +101,7 @@ const DATA_LOAD_MORE_TEST_ID = "ATL-DataList-LoadMore-trigger";
93
101
  const TRANSITION_DURATION_IN_SECONDS = design.tokens["timing-base"] / 1000;
94
102
  const TRANSITION_DELAY_IN_SECONDS = design.tokens["timing-quick"] / 1000;
95
103
 
96
- var css_248z$a = ".WRV-UmQmPzo- {\n display: -ms-flexbox;\n display: flex;\n position: relative;\n z-index: 0;\n z-index: var(--elevation-default);\n overflow: hidden;\n gap: calc(16px / 2);\n gap: var(--space-small);\n}\n\n.liQeWCMenD0- {\n --overflow-bg: var(--color-white);\n\n display: -ms-flexbox;\n\n display: flex;\n position: absolute;\n top: 0;\n right: 0;\n height: 100%;\n padding-left: calc(16px * 1);\n padding-left: var(--space-base);\n background-image: linear-gradient(\n 90deg,\n transparent 0,\n rgba(255, 255, 255, 1) calc(16px * 1),\n rgba(255, 255, 255, 1) 100%\n );\n background-image: linear-gradient(\n 90deg,\n transparent 0,\n var(--overflow-bg) var(--space-base),\n var(--overflow-bg) 100%\n );\n -ms-flex-align: center;\n align-items: center;\n}\n";
104
+ var css_248z$a = ".WRV-UmQmPzo- {\n display: -ms-flexbox;\n display: flex;\n position: relative;\n z-index: 0;\n z-index: var(--elevation-default);\n overflow: hidden;\n gap: calc(16px / 2);\n gap: var(--space-small);\n}\n\n.liQeWCMenD0- {\n --overflow-bg: var(--data-list-item-active-color, var(--color-surface));\n\n display: -ms-flexbox;\n\n display: flex;\n position: absolute;\n top: 0;\n right: 0;\n height: 100%;\n padding-left: calc(16px * 1);\n padding-left: var(--space-base);\n background-image: linear-gradient(\n 90deg,\n transparent 0,\n rgba(255, 255, 255, 1) calc(16px * 1),\n rgba(255, 255, 255, 1) 100%\n );\n background-image: linear-gradient(\n 90deg,\n transparent 0,\n var(--overflow-bg) var(--space-base),\n var(--overflow-bg) 100%\n );\n -ms-flex-align: center;\n align-items: center;\n transition: all 200ms;\n transition: all var(--timing-base);\n}\n";
97
105
  var styles$a = {"tags":"WRV-UmQmPzo-","tagCount":"liQeWCMenD0-"};
98
106
  styleInject_es.styleInject(css_248z$a);
99
107
 
@@ -187,14 +195,14 @@ function DataListHeaderTile({ headers, headerKey, }) {
187
195
  [styles$9.sortable]: isSortable,
188
196
  }), onClick: handleOnClick },
189
197
  React__default["default"].createElement(Text.Text, { maxLines: "single" }, headers[headerKey]),
190
- (sortingState === null || sortingState === void 0 ? void 0 : sortingState.key) === headerKey && (React__default["default"].createElement(DataListSortingArrows, { order: sortingState.direction }))));
198
+ (sortingState === null || sortingState === void 0 ? void 0 : sortingState.key) === headerKey && (React__default["default"].createElement(DataListSortingArrows, { order: sortingState.order }))));
191
199
  function toggleSorting(sortingKey) {
192
- if ((sortingState === null || sortingState === void 0 ? void 0 : sortingState.direction) === "desc") {
200
+ if ((sortingState === null || sortingState === void 0 ? void 0 : sortingState.order) === "desc") {
193
201
  sorting === null || sorting === void 0 ? void 0 : sorting.onSort(undefined);
194
202
  return;
195
203
  }
196
204
  sorting === null || sorting === void 0 ? void 0 : sorting.onSort({
197
- direction: (sortingState === null || sortingState === void 0 ? void 0 : sortingState.direction) === "asc" ? "desc" : "asc",
205
+ order: (sortingState === null || sortingState === void 0 ? void 0 : sortingState.order) === "asc" ? "desc" : "asc",
198
206
  key: sortingKey,
199
207
  });
200
208
  }
@@ -349,7 +357,7 @@ function DataListActionsMenu({ visible = false, position, onRequestClose, childr
349
357
  useOnKeyDown.useOnKeyDown(onRequestClose, "Escape");
350
358
  return (React__default["default"].createElement(framerMotion.AnimatePresence, null, visible && (React__default["default"].createElement(React__default["default"].Fragment, null,
351
359
  React__default["default"].createElement("div", { className: styles$5.overlay, onClick: onRequestClose }),
352
- React__default["default"].createElement(framerMotion.motion.div, { ref: setRef, variants: variants$1, initial: "hidden", animate: "visible", exit: "hidden", transition: { duration: TRANSITION_DELAY_IN_SECONDS }, className: styles$5.menu, style: getPositionCssVars() },
360
+ React__default["default"].createElement(framerMotion.motion.div, { role: "menu", ref: setRef, variants: variants$1, initial: "hidden", animate: "visible", exit: "hidden", transition: { duration: TRANSITION_DELAY_IN_SECONDS }, className: styles$5.menu, style: getPositionCssVars() },
353
361
  React__default["default"].createElement("div", { tabIndex: 0, ref: focusTrapRef }, children))))));
354
362
  function getPositionCssVars() {
355
363
  const { posX, posY } = getPosition();
@@ -411,7 +419,7 @@ function InternalDataListItemActions({ item, }) {
411
419
  return (React__default["default"].createElement(framerMotion.motion.div, { variants: variants, initial: "hidden", animate: "visible", exit: "hidden", transition: {
412
420
  duration: TRANSITION_DURATION_IN_SECONDS,
413
421
  delay: TRANSITION_DELAY_IN_SECONDS,
414
- }, className: styles$7.menu },
422
+ }, className: styles$7.menu, onContextMenu: handleContextMenu },
415
423
  exposedActions.map(({ props }) => {
416
424
  if (!props.icon)
417
425
  return null;
@@ -420,6 +428,9 @@ function InternalDataListItemActions({ item, }) {
420
428
  }),
421
429
  React__default["default"].createElement(DataListItemActionsOverflow, { actions: childrenArray, item: item })));
422
430
  }
431
+ function handleContextMenu(event) {
432
+ event.stopPropagation();
433
+ }
423
434
  function getExposedActions(childrenArray) {
424
435
  const firstTwoChildren = childrenArray.slice(0, 2);
425
436
  return firstTwoChildren.reduce((result, child, i) => {
@@ -438,16 +449,40 @@ function getExposedActions(childrenArray) {
438
449
  }
439
450
 
440
451
  function DataListItems({ layouts, mediaMatches, data, }) {
441
- const elementData = generateListItemElements(data);
442
- const [hover, setHover] = React.useState();
443
- return (React__default["default"].createElement(DataListLayoutInternal, { layouts: layouts, mediaMatches: mediaMatches, renderLayout: layout => {
444
- return (React__default["default"].createElement(React__default["default"].Fragment, null, elementData.map((child, i) => {
445
- const item = data[i];
446
- return (React__default["default"].createElement("div", { onMouseEnter: () => setHover(item.id), onMouseLeave: () => setHover(undefined), className: styles$d.listItem, key: item.id },
447
- React__default["default"].createElement(DataListItemInternal, { item: data[i] }, layout.props.children(child)),
448
- React__default["default"].createElement(framerMotion.AnimatePresence, null, hover === item.id && (React__default["default"].createElement(InternalDataListItemActions, { item: item })))));
449
- })));
450
- } }));
452
+ const { itemActionComponent } = useDataListContext();
453
+ const elementData = React.useMemo(() => generateListItemElements(data), [data]);
454
+ const [activeID, setActiveID] = React.useState();
455
+ const [contextPosition, setContextPosition] = React.useState();
456
+ const contextMenuActions = itemActionComponent === null || itemActionComponent === void 0 ? void 0 : itemActionComponent.props.children;
457
+ const isContextMenuVisible = Boolean(contextPosition);
458
+ return (React__default["default"].createElement(DataListLayoutInternal, { layouts: layouts, mediaMatches: mediaMatches, renderLayout: layout => (React__default["default"].createElement(React__default["default"].Fragment, null, elementData.map((child, i) => {
459
+ const item = data[i];
460
+ const isActive = activeID === item.id;
461
+ const shouldShowContextMenu = isActive && isContextMenuVisible && Boolean(contextMenuActions);
462
+ return (React__default["default"].createElement("div", { onMouseEnter: handleMouseEnter(item), onMouseLeave: handleMouseLeave, onContextMenu: handleContextMenu, className: classnames__default["default"](styles$d.listItem, {
463
+ [styles$d.active]: isActive && isContextMenuVisible,
464
+ }), key: item.id },
465
+ React__default["default"].createElement(DataListItemInternal, { item: data[i] }, layout.props.children(child)),
466
+ React__default["default"].createElement(framerMotion.AnimatePresence, null,
467
+ isActive && React__default["default"].createElement(InternalDataListItemActions, { item: item }),
468
+ React__default["default"].createElement(DataListActionsMenu, { key: item.id, visible: shouldShowContextMenu, position: contextPosition || { x: 0, y: 0 }, onRequestClose: () => setContextPosition(undefined) }, contextMenuActions &&
469
+ React.Children.map(contextMenuActions, action => (React__default["default"].createElement(InternalDataListAction, Object.assign({ key: item.id }, action.props, { item: item }))))))));
470
+ }))) }));
471
+ function handleMouseEnter(item) {
472
+ return () => setActiveID(item.id);
473
+ }
474
+ function handleMouseLeave() {
475
+ !isContextMenuVisible && setActiveID(undefined);
476
+ }
477
+ function handleContextMenu(event) {
478
+ if (!contextMenuActions || isContextMenuVisible)
479
+ return;
480
+ event.preventDefault();
481
+ setContextPosition({
482
+ x: event.clientX,
483
+ y: event.clientY,
484
+ });
485
+ }
451
486
  }
452
487
 
453
488
  function DataListHeaderCheckbox({ children }) {
@@ -479,14 +514,45 @@ function DataListHeaderCheckbox({ children }) {
479
514
  }
480
515
  }
481
516
 
482
- function DataListHeader({ layouts, mediaMatches, headerData, headerVisibility, }) {
483
- const matchingMediaQueries = Object.keys(mediaMatches || {}).filter((key) => !!(mediaMatches === null || mediaMatches === void 0 ? void 0 : mediaMatches[key]));
484
- const sortedVisibleBreakpoints = sortSizeProp(matchingMediaQueries);
485
- // Determines if the header should be visible based on the headerVisibility
486
- const showHeader = sortedVisibleBreakpoints.reduce((previousVisibility, breakpoint) => {
487
- var _a;
488
- return (_a = headerVisibility[breakpoint]) !== null && _a !== void 0 ? _a : previousVisibility;
489
- }, true);
517
+ function useMediaQuery(CSSMediaQuery) {
518
+ const [matches, setMatches] = React.useState(window.matchMedia(CSSMediaQuery).matches);
519
+ React.useEffect(() => {
520
+ const media = window.matchMedia(CSSMediaQuery);
521
+ if (media.matches !== matches) {
522
+ setMatches(media.matches);
523
+ }
524
+ const listener = () => setMatches(media.matches);
525
+ media.addEventListener("change", listener);
526
+ return () => media.removeEventListener("change", listener);
527
+ }, [CSSMediaQuery]);
528
+ return matches;
529
+ }
530
+
531
+ function useResponsiveSizing() {
532
+ const xs = useMediaQuery(`(width > ${BREAKPOINT_SIZES.xs}px)`);
533
+ const sm = useMediaQuery(`(width >= ${BREAKPOINT_SIZES.sm}px)`);
534
+ const md = useMediaQuery(`(width >= ${BREAKPOINT_SIZES.md}px)`);
535
+ const lg = useMediaQuery(`(width >= ${BREAKPOINT_SIZES.lg}px)`);
536
+ const xl = useMediaQuery(`(width >= ${BREAKPOINT_SIZES.xl}px)`);
537
+ return { xs, sm, md, lg, xl };
538
+ }
539
+
540
+ function useShowHeader() {
541
+ const { headerVisibility } = useDataListContext();
542
+ if (headerVisibility === undefined)
543
+ return true;
544
+ const sizes = useResponsiveSizing();
545
+ const sizeKeys = Object.keys(sizes);
546
+ const showHeader = sizeKeys.reduce((previous, breakpoint) => {
547
+ const isHeaderVisible = headerVisibility[breakpoint] || false;
548
+ const isBreakpointTriggered = sizes[breakpoint];
549
+ return previous || (isBreakpointTriggered && isHeaderVisible);
550
+ }, false);
551
+ return showHeader;
552
+ }
553
+
554
+ function DataListHeader({ layouts, mediaMatches, headerData, }) {
555
+ const showHeader = useShowHeader();
490
556
  if (!showHeader || !headerData)
491
557
  return null;
492
558
  return (React__default["default"].createElement(DataListLayoutInternal, { layouts: layouts, mediaMatches: mediaMatches, renderLayout: layout => (React__default["default"].createElement("div", { className: classnames__default["default"](styles$d.headerTitles) },
@@ -528,6 +594,59 @@ styleInject_es.styleInject(css_248z$4);
528
594
 
529
595
  const CONTAINER_TEST_ID = "ATL-DataListFilters-Container";
530
596
 
597
+ function DataListSort() {
598
+ const { sorting, headers } = useDataListContext();
599
+ const divRef = React.useRef(null);
600
+ const [showPopover, setShowPopover] = React.useState(false);
601
+ if (!sorting)
602
+ return null;
603
+ const { sortable, state, onSort } = sorting;
604
+ const sortByOptions = getSortByOptions();
605
+ const canChangeOrder = !(state === null || state === void 0 ? void 0 : state.key);
606
+ return (React__default["default"].createElement(React__default["default"].Fragment, null,
607
+ React__default["default"].createElement("span", { ref: divRef },
608
+ React__default["default"].createElement(Button.Button, Object.assign({}, (!state && { icon: "add", iconOnRight: true }), { label: getButtonLabel(), variation: "subtle", onClick: () => setShowPopover(!showPopover) }))),
609
+ React__default["default"].createElement(Popover.Popover, { attachTo: divRef, open: showPopover, onRequestClose: () => setShowPopover(false) },
610
+ React__default["default"].createElement(Content.Content, null,
611
+ React__default["default"].createElement(Heading.Heading, { level: 5 }, "Sort by"),
612
+ React__default["default"].createElement(Chip.Chips, { selected: (state === null || state === void 0 ? void 0 : state.key) || "none", onChange: handleKeyChange }, sortByOptions.map(({ label, value }) => (React__default["default"].createElement(Chip.Chip, { key: label, label: label, value: value })))),
613
+ React__default["default"].createElement(Heading.Heading, { level: 5 }, "Ordered by"),
614
+ React__default["default"].createElement(Chip.Chips, { selected: state === null || state === void 0 ? void 0 : state.order, onChange: handleSortingChange },
615
+ React__default["default"].createElement(Chip.Chip, { label: "Ascending", value: "asc", disabled: canChangeOrder }),
616
+ React__default["default"].createElement(Chip.Chip, { label: "Descending", value: "desc", disabled: canChangeOrder }))))));
617
+ function getSortByOptions() {
618
+ const options = sortable.reduce((acc, sort) => {
619
+ const label = headers[sort];
620
+ if (!label)
621
+ return acc;
622
+ acc.push({ label, value: sort.toString() });
623
+ return acc;
624
+ }, []);
625
+ // Inject a none option as the first option
626
+ options.unshift({ label: "None", value: "none" });
627
+ return options;
628
+ }
629
+ function getButtonLabel() {
630
+ const label = state && headers[state.key];
631
+ if (!label)
632
+ return "Sort by";
633
+ return `Sort by: ${label}, ${state.order}`;
634
+ }
635
+ function handleKeyChange(value) {
636
+ if (value && value !== "none") {
637
+ onSort({ key: value, order: (state === null || state === void 0 ? void 0 : state.order) || "asc" });
638
+ return;
639
+ }
640
+ onSort(undefined);
641
+ }
642
+ function handleSortingChange(value) {
643
+ if ((state === null || state === void 0 ? void 0 : state.key) && value) {
644
+ onSort({ key: state.key, order: value });
645
+ return;
646
+ }
647
+ }
648
+ }
649
+
531
650
  // This component is meant to capture the props of the DataList.Filters
532
651
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
533
652
  function DataListFilters(_) {
@@ -538,19 +657,22 @@ function DataListFilters(_) {
538
657
  */
539
658
  function InternalDataListFilters() {
540
659
  const { children: parentChildren } = useDataListContext();
660
+ const showHeader = useShowHeader();
661
+ const showSortButton = !showHeader;
541
662
  const component = getCompoundComponent(parentChildren, DataListFilters);
542
663
  const [leftRef, isLeftVisible] = useInView.useInView();
543
664
  const [rightRef, isRightVisible] = useInView.useInView();
544
- if (!component)
665
+ if (!showSortButton && !component)
545
666
  return null;
546
- const { children } = component.props;
667
+ const children = component === null || component === void 0 ? void 0 : component.props.children;
547
668
  return (React__default["default"].createElement("div", { "data-testid": CONTAINER_TEST_ID, className: classnames__default["default"](styles$4.filters, {
548
669
  [styles$4.overflowLeft]: !isLeftVisible,
549
670
  [styles$4.overflowRight]: !isRightVisible,
550
671
  }) },
551
672
  React__default["default"].createElement("div", { className: styles$4.filterActions },
552
673
  React__default["default"].createElement("span", { ref: leftRef, className: styles$4.overflowTrigger }),
553
- children,
674
+ children && children,
675
+ showSortButton && React__default["default"].createElement(DataListSort, null),
554
676
  React__default["default"].createElement("span", { ref: rightRef, className: styles$4.overflowTrigger }))));
555
677
  }
556
678
 
@@ -574,7 +696,7 @@ function DataListStickyHeader({ children }) {
574
696
  return (React__default["default"].createElement("div", { ref: ref, className: classnames__default["default"](styles$3.header, { [styles$3.stuck]: isStuck }) }, children));
575
697
  }
576
698
 
577
- var css_248z$2 = ".SaPMOnvw-3c- {\n --transition-properties: var(--timing-base) ease-in-out;\n --button-offset: calc(var(--space-largest) - var(--space-smallest));\n\n position: absolute;\n /* Inputs are off by 1 when put beside a button */\n top: calc((16px / 2) - 1px);\n top: calc(calc(16px / 2) - 1px);\n top: calc(var(--space-small) - 1px);\n right: calc((16px * 3) - (16px / 8));\n right: calc(calc(16px * 3) - calc(16px / 8));\n right: var(--button-offset);\n visibility: hidden;\n width: 0;\n opacity: 0;\n transition: opacity 200ms ease-in-out,\n width 200ms ease-in-out, visibility 200ms ease-in-out;\n transition: opacity var(--transition-properties),\n width var(--transition-properties), visibility var(--transition-properties);\n}\n\n._3S1-91v2SYI- {\n visibility: visible;\n width: calc(100% - var(--button-offset));\n opacity: 1;\n}\n\n@media (min-width: 768px) {\n\n.SaPMOnvw-3c-,\n._3S1-91v2SYI- {\n position: static;\n visibility: visible;\n width: auto;\n opacity: 1;\n transition: none;\n}\n }\n\n@media (--medium-screens-and-up) {\n\n.SaPMOnvw-3c-,\n._3S1-91v2SYI- {\n position: static;\n visibility: visible;\n width: auto;\n opacity: 1;\n transition: none;\n}\n }\n\n._9GlBktsUALw- {\n display: block;\n}\n\n@media (min-width: 768px) {\n\n._9GlBktsUALw- {\n display: none;\n}\n }\n\n@media (--medium-screens-and-up) {\n\n._9GlBktsUALw- {\n display: none;\n}\n }\n\n/*\n * No Filters Styling\n *\n * When there are no filters, the search input is always visible.\n * ------------------------------------------------------------------------- */\n\n._3Pjrt42x454- .SaPMOnvw-3c- {\n position: static;\n visibility: visible;\n width: auto;\n opacity: 1;\n transition: none;\n}\n\n@media (min-width: 768px) {\n\n._3Pjrt42x454- .SaPMOnvw-3c- {\n max-width: 30%;\n}\n }\n\n@media (--medium-screens-and-up) {\n\n._3Pjrt42x454- .SaPMOnvw-3c- {\n max-width: 30%;\n}\n }\n\n._3Pjrt42x454- ._9GlBktsUALw- {\n display: none;\n}\n";
699
+ var css_248z$2 = ".SaPMOnvw-3c- {\n --transition-properties: var(--timing-base) ease-in-out;\n --button-offset: calc(var(--space-largest) - var(--space-smallest));\n\n position: absolute;\n /* Inputs are off by 1 when put beside a button */\n top: calc((16px / 2) + 1px);\n top: calc(calc(16px / 2) + 1px);\n top: calc(var(--space-small) + 1px);\n right: calc((16px * 3) - (16px / 8));\n right: calc(calc(16px * 3) - calc(16px / 8));\n right: var(--button-offset);\n visibility: hidden;\n width: 0;\n opacity: 0;\n transition: opacity 200ms ease-in-out,\n width 200ms ease-in-out, visibility 200ms ease-in-out;\n transition: opacity var(--transition-properties),\n width var(--transition-properties), visibility var(--transition-properties);\n}\n\n._3S1-91v2SYI- {\n visibility: visible;\n width: calc(100% - var(--button-offset));\n opacity: 1;\n}\n\n@media (min-width: 768px) {\n\n.SaPMOnvw-3c-,\n._3S1-91v2SYI- {\n position: static;\n visibility: visible;\n width: auto;\n opacity: 1;\n transition: none;\n}\n }\n\n@media (--medium-screens-and-up) {\n\n.SaPMOnvw-3c-,\n._3S1-91v2SYI- {\n position: static;\n visibility: visible;\n width: auto;\n opacity: 1;\n transition: none;\n}\n }\n\n._9GlBktsUALw- {\n display: block;\n}\n\n@media (min-width: 768px) {\n\n._9GlBktsUALw- {\n display: none;\n}\n }\n\n@media (--medium-screens-and-up) {\n\n._9GlBktsUALw- {\n display: none;\n}\n }\n\n/*\n * No Filters Styling\n *\n * When there are no filters, the search input is always visible.\n * ------------------------------------------------------------------------- */\n\n._3Pjrt42x454- .SaPMOnvw-3c- {\n position: static;\n visibility: visible;\n width: auto;\n opacity: 1;\n transition: none;\n}\n\n@media (min-width: 768px) {\n\n._3Pjrt42x454- .SaPMOnvw-3c- {\n max-width: 30%;\n}\n }\n\n@media (--medium-screens-and-up) {\n\n._3Pjrt42x454- .SaPMOnvw-3c- {\n max-width: 30%;\n}\n }\n\n._3Pjrt42x454- ._9GlBktsUALw- {\n display: none;\n}\n";
578
700
  var styles$2 = {"searchInput":"SaPMOnvw-3c-","searchInputVisible":"_3S1-91v2SYI-","searchButton":"_9GlBktsUALw-","withNoFilters":"_3Pjrt42x454-"};
579
701
  styleInject_es.styleInject(css_248z$2);
580
702
 
@@ -590,12 +712,14 @@ function DataListSearch(_) {
590
712
  function InternalDataListSearch() {
591
713
  const inputRef = React.useRef(null);
592
714
  const [visible, setVisible] = React.useState(false);
593
- const { searchComponent, filterComponent, title } = useDataListContext();
715
+ const { searchComponent, filterComponent, sorting, title } = useDataListContext();
594
716
  const debouncedSearch = React.useCallback(debounce__default["default"]((value) => { var _a; return (_a = searchComponent === null || searchComponent === void 0 ? void 0 : searchComponent.props) === null || _a === void 0 ? void 0 : _a.onSearch(value); }, SEARCH_DEBOUNCE_DELAY), [searchComponent === null || searchComponent === void 0 ? void 0 : searchComponent.props.onSearch]);
595
717
  if (!searchComponent)
596
718
  return null;
597
719
  const { placeholder } = searchComponent.props;
598
- return (React__default["default"].createElement("div", { className: classnames__default["default"]({ [styles$2.withNoFilters]: !filterComponent }) },
720
+ return (React__default["default"].createElement("div", { className: classnames__default["default"]({
721
+ [styles$2.withNoFilters]: !filterComponent && !sorting,
722
+ }) },
599
723
  React__default["default"].createElement("div", { "data-testid": DATA_LIST_SEARCH_TEST_ID, className: classnames__default["default"](styles$2.searchInput, {
600
724
  [styles$2.searchInputVisible]: visible,
601
725
  }) },
@@ -2,11 +2,12 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var React = require('react');
6
- var reactPopper = require('react-popper');
7
- var useRefocusOnActivator = require('@jobber/hooks/useRefocusOnActivator');
8
- var styleInject_es = require('../style-inject.es-9d2f5f4e.js');
9
- var ButtonDismiss = require('../ButtonDismiss-82680c7d.js');
5
+ var Popover = require('../Popover-bbfc6aa1.js');
6
+ require('react');
7
+ require('react-popper');
8
+ require('@jobber/hooks/useRefocusOnActivator');
9
+ require('../style-inject.es-9d2f5f4e.js');
10
+ require('../ButtonDismiss-82680c7d.js');
10
11
  require('../Button-fd8413b2.js');
11
12
  require('classnames');
12
13
  require('react-router-dom');
@@ -14,48 +15,6 @@ require('../Icon-405a216c.js');
14
15
  require('@jobber/design');
15
16
  require('../Typography-fd6f932a.js');
16
17
 
17
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
18
18
 
19
- var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
20
19
 
21
- var css_248z = ":root {\n --card--base-padding: var(--space-base);\n --popover--padding: var(--space-base);\n --popover--width: calc(var(--base-unit) * 21.875);\n --dismiss--button-padding: calc(var(--base-unit) / 4);\n}\n\n.oSlK4rLUvzE- {\n display: -ms-flexbox;\n display: flex;\n position: \"relative\";\n padding: calc(16px * 1);\n padding: var(--popover--padding);\n -ms-flex-pack: justify;\n justify-content: space-between;\n -ms-flex-align: center;\n align-items: center;\n}\n\n.XVPpPb-7e30- {\n float: right;\n padding: calc(16px / 4);\n padding: var(--dismiss--button-padding);\n text-align: right;\n}\n\n.TDuYbqXaLW0- {\n z-index: 1002;\n z-index: var(--elevation-tooltip);\n width: -webkit-max-content;\n width: max-content;\n max-width: calc(16px * 21.875);\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 border: calc(16px / 16) solid rgb(225, 225, 225);\n border: var(--border-base) solid var(--color-border);\n border-radius: calc(16px / 8);\n border-radius: var(--radius-base);\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 line-height: normal;\n background: rgba(255, 255, 255, 1);\n background: var(--color-surface);\n}\n\n.TDuYbqXaLW0- > * {\n --public-content--padding: var(--card--base-padding);\n}\n\n.LJCpn0zf1e8- {\n visibility: hidden;\n}\n\n.LJCpn0zf1e8-,\n.LJCpn0zf1e8-::before {\n position: absolute;\n width: 16px;\n width: var(--base-unit);\n height: 16px;\n height: var(--base-unit);\n background: inherit;\n}\n\n.LJCpn0zf1e8-::before {\n content: \"\";\n visibility: visible;\n border: calc(16px / 16) solid rgb(225, 225, 225);\n border: var(--border-base) solid var(--color-border);\n -webkit-transform: rotate(45deg);\n transform: rotate(45deg);\n -webkit-transform-origin: center;\n transform-origin: center;\n -webkit-clip-path: polygon(-4px -4px, 15.3px 0, 0 15.3px);\n clip-path: polygon(-4px -4px, 15.3px 0, 0 15.3px);\n}\n\n.TDuYbqXaLW0-[data-popper-placement^=\"top\"] > .LJCpn0zf1e8- {\n bottom: -5px;\n}\n\n.TDuYbqXaLW0-[data-popper-placement^=\"top\"] > .LJCpn0zf1e8-::before {\n -webkit-transform: rotate(-135deg);\n transform: rotate(-135deg);\n}\n\n.TDuYbqXaLW0-[data-popper-placement^=\"bottom\"] > .LJCpn0zf1e8- {\n top: -7px;\n}\n\n.TDuYbqXaLW0-[data-popper-placement^=\"left\"] > .LJCpn0zf1e8- {\n right: -5px;\n}\n\n.TDuYbqXaLW0-[data-popper-placement^=\"left\"] > .LJCpn0zf1e8-::before {\n -webkit-transform: rotate(135deg);\n transform: rotate(135deg);\n}\n\n.TDuYbqXaLW0-[data-popper-placement^=\"right\"] > .LJCpn0zf1e8- {\n left: -7px;\n}\n\n.TDuYbqXaLW0-[data-popper-placement^=\"right\"] > .LJCpn0zf1e8-::before {\n -webkit-transform: rotate(-45deg);\n transform: rotate(-45deg);\n}\n";
22
- var classes = {"header":"oSlK4rLUvzE-","dismissButton":"XVPpPb-7e30-","popover":"TDuYbqXaLW0-","arrow":"LJCpn0zf1e8-"};
23
- styleInject_es.styleInject(css_248z);
24
-
25
- function Popover({ onRequestClose, children, attachTo, open, preferredPlacement = "auto", }) {
26
- const [popperElement, setPopperElement] = React.useState();
27
- const [arrowElement, setArrowElement] = React.useState();
28
- const { styles: popperStyles, attributes } = reactPopper.usePopper(attachTo instanceof Element ? attachTo : attachTo.current, popperElement, {
29
- modifiers: buildModifiers(arrowElement),
30
- placement: preferredPlacement,
31
- });
32
- useRefocusOnActivator.useRefocusOnActivator(open);
33
- return (React__default["default"].createElement(React__default["default"].Fragment, null, open && (React__default["default"].createElement("div", Object.assign({ role: "dialog", ref: setPopperElement, style: popperStyles.popper, className: classes.popover }, attributes.popper),
34
- React__default["default"].createElement("div", { className: classes.dismissButton },
35
- React__default["default"].createElement(ButtonDismiss.ButtonDismiss, { onClick: onRequestClose, ariaLabel: "Close dialog" })),
36
- children,
37
- React__default["default"].createElement("div", { ref: setArrowElement, className: classes.arrow, style: popperStyles.arrow })))));
38
- }
39
- function buildModifiers(arrowElement) {
40
- const modifiers = [
41
- {
42
- name: "arrow",
43
- options: { element: arrowElement, padding: 10 },
44
- },
45
- {
46
- name: "offset",
47
- options: {
48
- offset: [0, 10],
49
- },
50
- },
51
- {
52
- name: "flip",
53
- options: {
54
- fallbackPlacements: ["auto"],
55
- },
56
- },
57
- ];
58
- return modifiers;
59
- }
60
-
61
- exports.Popover = Popover;
20
+ exports.Popover = Popover.Popover;
@@ -0,0 +1,53 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+ var reactPopper = require('react-popper');
5
+ var useRefocusOnActivator = require('@jobber/hooks/useRefocusOnActivator');
6
+ var styleInject_es = require('./style-inject.es-9d2f5f4e.js');
7
+ var ButtonDismiss = require('./ButtonDismiss-82680c7d.js');
8
+
9
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
10
+
11
+ var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
12
+
13
+ var css_248z = ":root {\n --card--base-padding: var(--space-base);\n --popover--padding: var(--space-base);\n --popover--width: calc(var(--base-unit) * 21.875);\n --dismiss--button-padding: calc(var(--base-unit) / 4);\n}\n\n.oSlK4rLUvzE- {\n display: -ms-flexbox;\n display: flex;\n position: \"relative\";\n padding: calc(16px * 1);\n padding: var(--popover--padding);\n -ms-flex-pack: justify;\n justify-content: space-between;\n -ms-flex-align: center;\n align-items: center;\n}\n\n.XVPpPb-7e30- {\n float: right;\n padding: calc(16px / 4);\n padding: var(--dismiss--button-padding);\n text-align: right;\n}\n\n.TDuYbqXaLW0- {\n z-index: 1002;\n z-index: var(--elevation-tooltip);\n width: -webkit-max-content;\n width: max-content;\n max-width: calc(16px * 21.875);\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 border: calc(16px / 16) solid rgb(225, 225, 225);\n border: var(--border-base) solid var(--color-border);\n border-radius: calc(16px / 8);\n border-radius: var(--radius-base);\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 line-height: normal;\n background: rgba(255, 255, 255, 1);\n background: var(--color-surface);\n}\n\n.TDuYbqXaLW0- > * {\n --public-content--padding: var(--card--base-padding);\n}\n\n.LJCpn0zf1e8- {\n visibility: hidden;\n}\n\n.LJCpn0zf1e8-,\n.LJCpn0zf1e8-::before {\n position: absolute;\n width: 16px;\n width: var(--base-unit);\n height: 16px;\n height: var(--base-unit);\n background: inherit;\n}\n\n.LJCpn0zf1e8-::before {\n content: \"\";\n visibility: visible;\n border: calc(16px / 16) solid rgb(225, 225, 225);\n border: var(--border-base) solid var(--color-border);\n -webkit-transform: rotate(45deg);\n transform: rotate(45deg);\n -webkit-transform-origin: center;\n transform-origin: center;\n -webkit-clip-path: polygon(-4px -4px, 15.3px 0, 0 15.3px);\n clip-path: polygon(-4px -4px, 15.3px 0, 0 15.3px);\n}\n\n.TDuYbqXaLW0-[data-popper-placement^=\"top\"] > .LJCpn0zf1e8- {\n bottom: -5px;\n}\n\n.TDuYbqXaLW0-[data-popper-placement^=\"top\"] > .LJCpn0zf1e8-::before {\n -webkit-transform: rotate(-135deg);\n transform: rotate(-135deg);\n}\n\n.TDuYbqXaLW0-[data-popper-placement^=\"bottom\"] > .LJCpn0zf1e8- {\n top: -7px;\n}\n\n.TDuYbqXaLW0-[data-popper-placement^=\"left\"] > .LJCpn0zf1e8- {\n right: -5px;\n}\n\n.TDuYbqXaLW0-[data-popper-placement^=\"left\"] > .LJCpn0zf1e8-::before {\n -webkit-transform: rotate(135deg);\n transform: rotate(135deg);\n}\n\n.TDuYbqXaLW0-[data-popper-placement^=\"right\"] > .LJCpn0zf1e8- {\n left: -7px;\n}\n\n.TDuYbqXaLW0-[data-popper-placement^=\"right\"] > .LJCpn0zf1e8-::before {\n -webkit-transform: rotate(-45deg);\n transform: rotate(-45deg);\n}\n";
14
+ var classes = {"header":"oSlK4rLUvzE-","dismissButton":"XVPpPb-7e30-","popover":"TDuYbqXaLW0-","arrow":"LJCpn0zf1e8-"};
15
+ styleInject_es.styleInject(css_248z);
16
+
17
+ function Popover({ onRequestClose, children, attachTo, open, preferredPlacement = "auto", }) {
18
+ const [popperElement, setPopperElement] = React.useState();
19
+ const [arrowElement, setArrowElement] = React.useState();
20
+ const { styles: popperStyles, attributes } = reactPopper.usePopper(attachTo instanceof Element ? attachTo : attachTo.current, popperElement, {
21
+ modifiers: buildModifiers(arrowElement),
22
+ placement: preferredPlacement,
23
+ });
24
+ useRefocusOnActivator.useRefocusOnActivator(open);
25
+ return (React__default["default"].createElement(React__default["default"].Fragment, null, open && (React__default["default"].createElement("div", Object.assign({ role: "dialog", ref: setPopperElement, style: popperStyles.popper, className: classes.popover }, attributes.popper),
26
+ React__default["default"].createElement("div", { className: classes.dismissButton },
27
+ React__default["default"].createElement(ButtonDismiss.ButtonDismiss, { onClick: onRequestClose, ariaLabel: "Close dialog" })),
28
+ children,
29
+ React__default["default"].createElement("div", { ref: setArrowElement, className: classes.arrow, style: popperStyles.arrow })))));
30
+ }
31
+ function buildModifiers(arrowElement) {
32
+ const modifiers = [
33
+ {
34
+ name: "arrow",
35
+ options: { element: arrowElement, padding: 10 },
36
+ },
37
+ {
38
+ name: "offset",
39
+ options: {
40
+ offset: [0, 10],
41
+ },
42
+ },
43
+ {
44
+ name: "flip",
45
+ options: {
46
+ fallbackPlacements: ["auto"],
47
+ },
48
+ },
49
+ ];
50
+ return modifiers;
51
+ }
52
+
53
+ exports.Popover = Popover;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jobber/components",
3
- "version": "4.39.0",
3
+ "version": "4.41.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": "3ebee9c0f86bbe3a2fe26bf09572a5b4599a9a0c"
87
+ "gitHead": "43230912b7cb5c6e144d2d44331dfcc904f6e4ec"
88
88
  }