@jobber/components 4.33.0 → 4.34.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.
@@ -1,2 +1,7 @@
1
1
  /// <reference types="react" />
2
- export declare function DataListLoadMore(): JSX.Element;
2
+ interface DataListLoadMoreProps {
3
+ readonly onBackToTop: () => void;
4
+ }
5
+ export declare const MAX_DATA_COUNT = 50;
6
+ export declare function DataListLoadMore({ onBackToTop }: DataListLoadMoreProps): JSX.Element;
7
+ export {};
@@ -0,0 +1,2 @@
1
+ /// <reference types="react" />
2
+ export declare function DataListLoadMoreTrigger(): JSX.Element;
@@ -36,8 +36,8 @@ var isEmpty__default = /*#__PURE__*/_interopDefaultLegacy(isEmpty);
36
36
  var classnames__default = /*#__PURE__*/_interopDefaultLegacy(classnames);
37
37
  var debounce__default = /*#__PURE__*/_interopDefaultLegacy(debounce);
38
38
 
39
- var css_248z$8 = ".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 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.Gj9kAGnfKco- > * {\n font-weight: 500;\n}\n\n.ise8kHCfhCY- {\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.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: center;\n align-items: center;\n -ms-flex-pack: center;\n justify-content: center;\n}\n\n.m-eCShL7TU4- {\n position: sticky;\n top: 50vh;\n}\n\n.xeUxuTlqQtk- {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-pack: center;\n justify-content: center;\n padding: calc(16px / 2);\n padding: var(--space-small);\n}\n";
40
- var styles$8 = {"wrapper":"TkdrExYnvcY-","titleContainer":"IcAlZHoB4LI-","headerFilters":"TFO76ysivmg-","headerTitles":"jGHZZYZm1ZY-","headerLabel":"Gj9kAGnfKco-","listItem":"ise8kHCfhCY-","filtering":"Kkp-IYmwq-s-","filteringSpinner":"m-eCShL7TU4-","loadingMore":"xeUxuTlqQtk-"};
39
+ var css_248z$8 = ".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 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.Gj9kAGnfKco- > * {\n font-weight: 500;\n}\n\n.ise8kHCfhCY- {\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.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";
40
+ var styles$8 = {"wrapper":"TkdrExYnvcY-","titleContainer":"IcAlZHoB4LI-","headerFilters":"TFO76ysivmg-","headerTitles":"jGHZZYZm1ZY-","headerLabel":"Gj9kAGnfKco-","listItem":"ise8kHCfhCY-","filtering":"Kkp-IYmwq-s-","filteringSpinner":"m-eCShL7TU4-"};
41
41
  styleInject_es.styleInject(css_248z$8);
42
42
 
43
43
  var css_248z$7 = ".F56prQsXm3A- {\n min-width: 80px;\n margin-left: calc(16px / 2);\n margin-left: var(--space-small);\n}\n";
@@ -432,11 +432,11 @@ function getEmptyStates(components) {
432
432
  return { defaultEmptyState, filteredEmptyState };
433
433
  }
434
434
 
435
- var css_248z = ".IC-Y9bTIVFo- {\n position: relative;\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";
436
- var styles = {"trigger":"IC-Y9bTIVFo-"};
435
+ var css_248z = ".IC-Y9bTIVFo- {\n position: relative;\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\n.PbZLGpbI6ZM-,\n._6zA6B-jmz6o- {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-pack: center;\n justify-content: center;\n padding: calc(16px / 2);\n padding: var(--space-small);\n}\n\n._6zA6B-jmz6o- {\n opacity: 0;\n -webkit-animation: gZ4DUv82g5I- 200ms ease 200ms forwards;\n -webkit-animation: gZ4DUv82g5I- var(--timing-base) ease var(--timing-base) forwards;\n animation: gZ4DUv82g5I- 200ms ease 200ms forwards;\n animation: gZ4DUv82g5I- var(--timing-base) ease var(--timing-base) forwards;\n}\n\n@-webkit-keyframes gZ4DUv82g5I- {\n from {\n opacity: 0;\n }\n\n to {\n opacity: 1;\n }\n}\n\n@keyframes gZ4DUv82g5I- {\n from {\n opacity: 0;\n }\n\n to {\n opacity: 1;\n }\n}\n";
436
+ var styles = {"trigger":"IC-Y9bTIVFo-","loadingMore":"PbZLGpbI6ZM-","backToTop":"_6zA6B-jmz6o-","fadeIn":"gZ4DUv82g5I-"};
437
437
  styleInject_es.styleInject(css_248z);
438
438
 
439
- function DataListLoadMore() {
439
+ function DataListLoadMoreTrigger() {
440
440
  const { onLoadMore } = useDataListContext();
441
441
  const [inViewRef, isInView] = useInView.useInView();
442
442
  React.useEffect(() => {
@@ -445,6 +445,18 @@ function DataListLoadMore() {
445
445
  return (React__default["default"].createElement("div", { ref: inViewRef, className: styles.trigger, "data-testid": DATA_LOAD_MORE_TEST_ID }));
446
446
  }
447
447
 
448
+ const MAX_DATA_COUNT = 50;
449
+ function DataListLoadMore({ onBackToTop }) {
450
+ const { loadingState, data } = useDataListContext();
451
+ const showBackToTop = data.length > MAX_DATA_COUNT && loadingState !== "loadingMore";
452
+ return (React__default["default"].createElement(React__default["default"].Fragment, null,
453
+ React__default["default"].createElement(DataListLoadMoreTrigger, { key: data.length }),
454
+ loadingState === "loadingMore" && (React__default["default"].createElement("div", { "data-testid": DATA_LIST_LOADING_MORE_SPINNER_TEST_ID, className: styles.loadingMore },
455
+ React__default["default"].createElement(Spinner.Spinner, { size: "small" }))),
456
+ showBackToTop && (React__default["default"].createElement("div", { className: styles.backToTop },
457
+ React__default["default"].createElement(Button.Button, { label: "Back to top", onClick: onBackToTop, size: "small", variation: "subtle" })))));
458
+ }
459
+
448
460
  function useLayoutMediaQueries() {
449
461
  const mediaQueries = BREAKPOINTS.reduce((previous, breakpoint) => (Object.assign(Object.assign({}, previous), { [breakpoint]: window.matchMedia(breakpointToMediaQuery(breakpoint)) })), {});
450
462
  const initialMatches = BREAKPOINTS.reduce((previous, breakpoint) => (Object.assign(Object.assign({}, previous), { [breakpoint]: mediaQueries[breakpoint].matches })), {});
@@ -483,6 +495,7 @@ function DataList(props) {
483
495
  }
484
496
  function InternalDataList() {
485
497
  const { data, headers, title, totalCount, headerVisibility = { xs: true, sm: true, md: true, lg: true, xl: true }, loadingState = "none", layoutComponents, } = useDataListContext();
498
+ const backToTopRef = React.useRef(null);
486
499
  const headerData = generateHeaderElements(headers);
487
500
  const mediaMatches = useLayoutMediaQueries();
488
501
  const initialLoading = loadingState === "initial";
@@ -492,6 +505,7 @@ function InternalDataList() {
492
505
  React__default["default"].createElement("div", { className: styles$8.titleContainer },
493
506
  title && React__default["default"].createElement(Heading.Heading, { level: 3 }, title),
494
507
  React__default["default"].createElement(DataListTotalCount, { totalCount: totalCount, loading: initialLoading })),
508
+ React__default["default"].createElement("div", { ref: backToTopRef }),
495
509
  React__default["default"].createElement(DataListStickyHeader, null,
496
510
  React__default["default"].createElement("div", { className: styles$8.headerFilters },
497
511
  React__default["default"].createElement(InternalDataListFilters, null),
@@ -503,9 +517,19 @@ function InternalDataList() {
503
517
  loadingState === "filtering" && (React__default["default"].createElement("div", { "data-testid": DATA_LIST_FILTERING_SPINNER_TEST_ID, className: styles$8.filtering },
504
518
  React__default["default"].createElement("div", { className: styles$8.filteringSpinner },
505
519
  React__default["default"].createElement(Spinner.Spinner, { size: "small" })))),
506
- shouldRenderLoadMoreTrigger && React__default["default"].createElement(DataListLoadMore, null),
507
- loadingState === "loadingMore" && (React__default["default"].createElement("div", { "data-testid": DATA_LIST_LOADING_MORE_SPINNER_TEST_ID, className: styles$8.loadingMore },
508
- React__default["default"].createElement(Spinner.Spinner, { size: "small" })))));
520
+ shouldRenderLoadMoreTrigger && (React__default["default"].createElement(DataListLoadMore, { onBackToTop: handleBackToTop }))));
521
+ function handleBackToTop() {
522
+ var _a;
523
+ // For testing purposes since jest doesn't know scrollIntoView.
524
+ // This prevents consumer's tests from needing to mock scrollIntoView.
525
+ if (!window.HTMLElement.prototype.scrollIntoView)
526
+ return;
527
+ (_a = backToTopRef.current) === null || _a === void 0 ? void 0 : _a.scrollIntoView({
528
+ behavior: "smooth",
529
+ block: "nearest",
530
+ inline: "start",
531
+ });
532
+ }
509
533
  }
510
534
  DataList.Layout = DataListLayout;
511
535
  DataList.EmptyState = DataListEmptyState;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jobber/components",
3
- "version": "4.33.0",
3
+ "version": "4.34.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": "4ad7db01af3c57a0eefed5e714059615d71b56d3"
87
+ "gitHead": "0ec05cc759f6bc3bb8346239dadbabd009bf8aab"
88
88
  }