@jobber/components 4.31.1 → 4.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/DataList/DataList.const.d.ts +2 -0
- package/dist/DataList/DataList.types.d.ts +26 -4
- package/dist/DataList/components/DataListLayout/DataListLayout.d.ts +1 -9
- package/dist/DataList/components/DataListLayoutInternal/DataListHeader.d.ts +1 -2
- package/dist/DataList/components/DataListLayoutInternal/DataListItems.d.ts +1 -2
- package/dist/DataList/components/DataListLayoutInternal/DataListLayoutInternal.d.ts +1 -2
- package/dist/DataList/components/DataListLoadingState/DataListLoadingState.d.ts +2 -4
- package/dist/DataList/index.js +20 -14
- package/package.json +2 -2
|
@@ -11,4 +11,6 @@ export declare const EMPTY_FILTER_RESULTS_ACTION_LABEL = "Clear Filters";
|
|
|
11
11
|
export declare const BREAKPOINTS: readonly ["xs", "sm", "md", "lg", "xl"];
|
|
12
12
|
export declare const BREAKPOINT_SIZES: Record<Breakpoints, number>;
|
|
13
13
|
export declare const SEARCH_DEBOUNCE_DELAY: number;
|
|
14
|
+
export declare const DATA_LIST_FILTERING_SPINNER_TEST_ID = "ATL-DataList-filteringSpinner";
|
|
15
|
+
export declare const DATA_LIST_LOADING_MORE_SPINNER_TEST_ID = "ATL-DataList-loadingMoreSpinner";
|
|
14
16
|
export {};
|
|
@@ -29,21 +29,29 @@ export type DataListHeader<T extends DataListObject> = {
|
|
|
29
29
|
readonly [K in keyof T]?: string;
|
|
30
30
|
};
|
|
31
31
|
export interface DataListProps<T extends DataListObject> {
|
|
32
|
+
/**
|
|
33
|
+
* The data to render in the DataList.
|
|
34
|
+
*/
|
|
32
35
|
readonly data: T[];
|
|
36
|
+
/**
|
|
37
|
+
* The header of the DataList. The object keys are determined by the
|
|
38
|
+
* keys in the data.
|
|
39
|
+
*/
|
|
33
40
|
readonly headers: DataListHeader<T>;
|
|
34
41
|
/**
|
|
35
|
-
*
|
|
42
|
+
* Set the loading state of the DataList. There are a few guidelines on when to use what.
|
|
36
43
|
*
|
|
37
|
-
*
|
|
44
|
+
* - `"initial"` - loading the first set of data
|
|
45
|
+
* - `"filtering"` - loading after a filter is applied
|
|
46
|
+
* - `"loadingMore"` - loading more data after the user scrolls to the bottom
|
|
38
47
|
*/
|
|
39
|
-
readonly
|
|
48
|
+
readonly loadingState?: "initial" | "filtering" | "loadingMore" | "none";
|
|
40
49
|
/**
|
|
41
50
|
* Temporary prop for setting default state for if filters are applied
|
|
42
51
|
*
|
|
43
52
|
* @default false
|
|
44
53
|
*/
|
|
45
54
|
readonly filterApplied?: boolean;
|
|
46
|
-
readonly children: ReactElement | ReactElement[];
|
|
47
55
|
/**
|
|
48
56
|
* The title of the DataList.
|
|
49
57
|
*/
|
|
@@ -64,8 +72,21 @@ export interface DataListProps<T extends DataListObject> {
|
|
|
64
72
|
readonly headerVisibility?: {
|
|
65
73
|
[Breakpoint in Breakpoints]?: boolean;
|
|
66
74
|
};
|
|
75
|
+
readonly children: ReactElement | ReactElement[];
|
|
76
|
+
}
|
|
77
|
+
export interface DataListLayoutProps<T extends DataListObject> {
|
|
78
|
+
readonly children: (item: DataListItemType<T[]>) => JSX.Element;
|
|
79
|
+
/**
|
|
80
|
+
* The breakpoint at which the layout should be displayed. It will be rendered until a layout with a larger breakpoint is found.
|
|
81
|
+
* @default "xs"
|
|
82
|
+
*/
|
|
83
|
+
readonly size?: Breakpoints;
|
|
67
84
|
}
|
|
68
85
|
export interface DataListSearchProps {
|
|
86
|
+
/**
|
|
87
|
+
* The placeholder text for the search input. This either uses the title prop
|
|
88
|
+
* prepended by "Search" or just falls back to "Search".
|
|
89
|
+
*/
|
|
69
90
|
readonly placeholder?: string;
|
|
70
91
|
readonly onSearch: (search: string) => void;
|
|
71
92
|
}
|
|
@@ -75,4 +96,5 @@ export interface DataListFiltersProps {
|
|
|
75
96
|
export interface DataListContextProps<T extends DataListObject> extends DataListProps<T> {
|
|
76
97
|
readonly filterComponent?: ReactElement<DataListFiltersProps>;
|
|
77
98
|
readonly searchComponent?: ReactElement<DataListSearchProps>;
|
|
99
|
+
readonly layoutComponents?: ReactElement<DataListLayoutProps<T>>[];
|
|
78
100
|
}
|
|
@@ -1,11 +1,3 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
import {
|
|
3
|
-
export interface DataListLayoutProps<T extends DataListObject> {
|
|
4
|
-
readonly children: (item: DataListItemType<T[]>) => JSX.Element;
|
|
5
|
-
/**
|
|
6
|
-
* The breakpoint at which the layout should be displayed. It will be rendered until a layout with a larger breakpoint is found.
|
|
7
|
-
* @default "xs"
|
|
8
|
-
*/
|
|
9
|
-
readonly size?: Breakpoints;
|
|
10
|
-
}
|
|
2
|
+
import { DataListLayoutProps, DataListObject } from "../../DataList.types";
|
|
11
3
|
export declare function DataListLayout<T extends DataListObject>(_: DataListLayoutProps<T>): JSX.Element;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { Breakpoints } from "../../DataList.const";
|
|
3
|
-
import { DataListHeader as DataListHeaderType, DataListItemTypeFromHeader, DataListObject, DataListProps } from "../../DataList.types";
|
|
4
|
-
import { DataListLayoutProps } from "../DataListLayout/DataListLayout";
|
|
3
|
+
import { DataListHeader as DataListHeaderType, DataListItemTypeFromHeader, DataListLayoutProps, DataListObject, DataListProps } from "../../DataList.types";
|
|
5
4
|
interface DataListHeaderProps<T extends DataListObject> {
|
|
6
5
|
readonly layouts: React.ReactElement<DataListLayoutProps<T>>[] | undefined;
|
|
7
6
|
readonly mediaMatches?: Record<Breakpoints, boolean>;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { Breakpoints } from "../../DataList.const";
|
|
3
|
-
import { DataListObject } from "../../DataList.types";
|
|
4
|
-
import { DataListLayoutProps } from "../DataListLayout/DataListLayout";
|
|
3
|
+
import { DataListLayoutProps, DataListObject } from "../../DataList.types";
|
|
5
4
|
interface DataListItemsProps<T extends DataListObject> {
|
|
6
5
|
readonly layouts: React.ReactElement<DataListLayoutProps<T>>[] | undefined;
|
|
7
6
|
readonly mediaMatches?: Record<Breakpoints, boolean>;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { Breakpoints } from "../../DataList.const";
|
|
3
|
-
import { DataListObject } from "../../DataList.types";
|
|
4
|
-
import { DataListLayoutProps } from "../DataListLayout/DataListLayout";
|
|
3
|
+
import { DataListLayoutProps, DataListObject } from "../../DataList.types";
|
|
5
4
|
interface DataListLayoutInternalProps<T extends DataListObject> {
|
|
6
5
|
readonly layouts: React.ReactElement<DataListLayoutProps<T>>[] | undefined;
|
|
7
6
|
readonly renderLayout: (layout: React.ReactElement<DataListLayoutProps<T>>) => JSX.Element;
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { Breakpoints, DataListHeader, DataListObject } from "../../DataList.types";
|
|
3
|
-
import { DataListLayoutProps } from "../DataListLayout";
|
|
2
|
+
import { Breakpoints, DataListHeader, DataListLayoutProps, DataListObject } from "../../DataList.types";
|
|
4
3
|
interface DataListLoadingStateProps<T extends DataListObject> {
|
|
5
|
-
readonly loading: boolean;
|
|
6
4
|
readonly headers: DataListHeader<T>;
|
|
7
5
|
readonly layouts: React.ReactElement<DataListLayoutProps<T>>[] | undefined;
|
|
8
6
|
readonly mediaMatches?: Record<Breakpoints, boolean>;
|
|
9
7
|
}
|
|
10
8
|
export declare const LOADING_STATE_LIMIT_ITEMS = 10;
|
|
11
9
|
export declare const DATALIST_LOADINGSTATE_ROW_TEST_ID = "ATL-DataList-LoadingState-Row";
|
|
12
|
-
export declare function DataListLoadingState<T extends DataListObject>({
|
|
10
|
+
export declare function DataListLoadingState<T extends DataListObject>({ headers, layouts, mediaMatches, }: DataListLoadingStateProps<T>): JSX.Element;
|
|
13
11
|
export {};
|
package/dist/DataList/index.js
CHANGED
|
@@ -19,6 +19,7 @@ var useInView = require('@jobber/hooks/useInView');
|
|
|
19
19
|
var debounce = require('lodash/debounce');
|
|
20
20
|
var InputText = require('../InputText-bb03f6d1.js');
|
|
21
21
|
var AnimatedSwitcher = require('../AnimatedSwitcher-d1e1ddcf.js');
|
|
22
|
+
var Spinner = require('../Spinner-9d8fc7ff.js');
|
|
22
23
|
require('../Icon-405a216c.js');
|
|
23
24
|
require('../tslib.es6-5b8768b7.js');
|
|
24
25
|
require('../Content-2ca1ffe1.js');
|
|
@@ -27,7 +28,6 @@ require('uuid');
|
|
|
27
28
|
require('react-hook-form');
|
|
28
29
|
require('../InputValidation-b5a3d92c.js');
|
|
29
30
|
require('framer-motion');
|
|
30
|
-
require('../Spinner-9d8fc7ff.js');
|
|
31
31
|
|
|
32
32
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
33
33
|
|
|
@@ -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$7 = ".TkdrExYnvcY- {\n -ms-flex: 1;\n flex: 1;\n}\n\n.IcAlZHoB4LI- {\n display: -ms-flexbox;\n display: flex;\n
|
|
40
|
-
var styles$7 = {"wrapper":"TkdrExYnvcY-","titleContainer":"IcAlZHoB4LI-","
|
|
39
|
+
var css_248z$7 = ".TkdrExYnvcY- {\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$7 = {"wrapper":"TkdrExYnvcY-","titleContainer":"IcAlZHoB4LI-","headerFilters":"TFO76ysivmg-","headerTitles":"jGHZZYZm1ZY-","headerLabel":"Gj9kAGnfKco-","listItem":"ise8kHCfhCY-","filtering":"Kkp-IYmwq-s-","filteringSpinner":"m-eCShL7TU4-","loadingMore":"xeUxuTlqQtk-"};
|
|
41
41
|
styleInject_es.styleInject(css_248z$7);
|
|
42
42
|
|
|
43
43
|
var css_248z$6 = "._--dXJma0jX0- {\n display: -ms-flexbox;\n display: flex;\n height: 100%;\n box-sizing: border-box;\n padding: calc(16px * 1);\n padding: var(--space-base);\n -ms-flex-pack: center;\n justify-content: center;\n -ms-flex-direction: column;\n flex-direction: column;\n row-gap: calc(16px * 1);\n row-gap: var(--space-base);\n -ms-flex-align: center;\n align-items: center;\n}\n";
|
|
@@ -70,6 +70,8 @@ const BREAKPOINT_SIZES = {
|
|
|
70
70
|
xl: 1440,
|
|
71
71
|
};
|
|
72
72
|
const SEARCH_DEBOUNCE_DELAY = design.tokens["timing-slowest"];
|
|
73
|
+
const DATA_LIST_FILTERING_SPINNER_TEST_ID = "ATL-DataList-filteringSpinner";
|
|
74
|
+
const DATA_LIST_LOADING_MORE_SPINNER_TEST_ID = "ATL-DataList-loadingMoreSpinner";
|
|
73
75
|
|
|
74
76
|
var css_248z$5 = ".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";
|
|
75
77
|
var styles$5 = {"tags":"WRV-UmQmPzo-","tagCount":"liQeWCMenD0-"};
|
|
@@ -292,9 +294,7 @@ function DataListHeader({ layouts, mediaMatches, headerData, headerVisibility, }
|
|
|
292
294
|
|
|
293
295
|
const LOADING_STATE_LIMIT_ITEMS = 10;
|
|
294
296
|
const DATALIST_LOADINGSTATE_ROW_TEST_ID = "ATL-DataList-LoadingState-Row";
|
|
295
|
-
function DataListLoadingState({
|
|
296
|
-
if (!loading)
|
|
297
|
-
return null;
|
|
297
|
+
function DataListLoadingState({ headers, layouts, mediaMatches, }) {
|
|
298
298
|
const loadingData = new Array(LOADING_STATE_LIMIT_ITEMS).fill(headers);
|
|
299
299
|
const loadingElements = loadingData.map(item => Object.keys(item).reduce((acc, key) => {
|
|
300
300
|
acc[key] = React__default["default"].createElement(Glimmer.Glimmer, null);
|
|
@@ -450,15 +450,16 @@ function DataListStickyHeader({ children }) {
|
|
|
450
450
|
function DataList(props) {
|
|
451
451
|
const searchComponent = getCompoundComponent(props.children, DataListSearch);
|
|
452
452
|
const filterComponent = getCompoundComponent(props.children, DataListFilters);
|
|
453
|
-
|
|
453
|
+
const layoutComponents = getCompoundComponents(props.children, DataListLayout);
|
|
454
|
+
return (React__default["default"].createElement(DataListContext.Provider, { value: Object.assign({ searchComponent, filterComponent, layoutComponents }, props) },
|
|
454
455
|
React__default["default"].createElement(InternalDataList, null)));
|
|
455
456
|
}
|
|
456
457
|
function InternalDataList() {
|
|
457
|
-
const { data, headers,
|
|
458
|
-
const allLayouts = getCompoundComponents(children, DataListLayout);
|
|
458
|
+
const { data, headers, filterApplied = false, children, title, totalCount, headerVisibility = { xs: true, sm: true, md: true, lg: true, xl: true }, loadingState = "none", layoutComponents, } = useDataListContext();
|
|
459
459
|
const headerData = generateHeaderElements(headers);
|
|
460
460
|
const mediaMatches = useLayoutMediaQueries();
|
|
461
|
-
const
|
|
461
|
+
const initialLoading = loadingState === "initial";
|
|
462
|
+
const showEmptyState = !initialLoading && data.length === 0;
|
|
462
463
|
const [isFilterApplied, setIsFilterApplied] = React.useState(filterApplied);
|
|
463
464
|
const EmptyStateComponent = generateDataListEmptyState({
|
|
464
465
|
children,
|
|
@@ -468,14 +469,19 @@ function InternalDataList() {
|
|
|
468
469
|
return (React__default["default"].createElement("div", { className: styles$7.wrapper },
|
|
469
470
|
React__default["default"].createElement("div", { className: styles$7.titleContainer },
|
|
470
471
|
title && React__default["default"].createElement(Heading.Heading, { level: 3 }, title),
|
|
471
|
-
React__default["default"].createElement(DataListTotalCount, { totalCount: totalCount, loading:
|
|
472
|
+
React__default["default"].createElement(DataListTotalCount, { totalCount: totalCount, loading: initialLoading })),
|
|
472
473
|
React__default["default"].createElement(DataListStickyHeader, null,
|
|
473
474
|
React__default["default"].createElement("div", { className: styles$7.headerFilters },
|
|
474
475
|
React__default["default"].createElement(InternalDataListFilters, null),
|
|
475
476
|
React__default["default"].createElement(InternalDataListSearch, null)),
|
|
476
|
-
headerData && (React__default["default"].createElement(DataListHeader, { layouts:
|
|
477
|
-
React__default["default"].createElement(DataListLoadingState, {
|
|
478
|
-
!
|
|
477
|
+
headerData && (React__default["default"].createElement(DataListHeader, { layouts: layoutComponents, headerData: headerData, headerVisibility: headerVisibility, mediaMatches: mediaMatches }))),
|
|
478
|
+
initialLoading && (React__default["default"].createElement(DataListLoadingState, { headers: headers, layouts: layoutComponents, mediaMatches: mediaMatches })),
|
|
479
|
+
!initialLoading && (React__default["default"].createElement(DataListItems, { data: data, layouts: layoutComponents, mediaMatches: mediaMatches })),
|
|
480
|
+
loadingState === "filtering" && (React__default["default"].createElement("div", { "data-testid": DATA_LIST_FILTERING_SPINNER_TEST_ID, className: styles$7.filtering },
|
|
481
|
+
React__default["default"].createElement("div", { className: styles$7.filteringSpinner },
|
|
482
|
+
React__default["default"].createElement(Spinner.Spinner, { size: "small" })))),
|
|
483
|
+
loadingState === "loadingMore" && (React__default["default"].createElement("div", { "data-testid": DATA_LIST_LOADING_MORE_SPINNER_TEST_ID, className: styles$7.loadingMore },
|
|
484
|
+
React__default["default"].createElement(Spinner.Spinner, { size: "small" }))),
|
|
479
485
|
showEmptyState && EmptyStateComponent));
|
|
480
486
|
}
|
|
481
487
|
DataList.Layout = DataListLayout;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jobber/components",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.32.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": "
|
|
87
|
+
"gitHead": "a4f52ed97ef70b37eaee9a3b1fd09e26fcc595c1"
|
|
88
88
|
}
|