@jobber/components 4.32.0 → 4.33.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 +4 -2
- package/dist/DataList/DataList.d.ts +3 -2
- package/dist/DataList/DataList.types.d.ts +29 -4
- package/dist/DataList/DataList.utils.d.ts +1 -12
- package/dist/DataList/components/DataListEmptyState/DataListEmptyState.d.ts +4 -0
- package/dist/DataList/components/DataListEmptyState/index.d.ts +1 -0
- package/dist/DataList/components/DataListLoadMore/DataListLoadMore.d.ts +2 -0
- package/dist/DataList/components/DataListLoadMore/index.d.ts +1 -0
- package/dist/DataList/components/DataListStickyHeader/index.d.ts +1 -0
- package/dist/DataList/index.js +173 -150
- package/package.json +2 -2
- package/dist/DataList/components/EmptyState/EmptyState.d.ts +0 -21
- package/dist/DataList/components/EmptyState/index.d.ts +0 -1
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
*/
|
|
4
4
|
type ValuesOf<T extends readonly unknown[]> = T[number];
|
|
5
5
|
export type Breakpoints = ValuesOf<typeof BREAKPOINTS>;
|
|
6
|
-
export declare const
|
|
7
|
-
export declare const
|
|
6
|
+
export declare const EMPTY_RESULTS_MESSAGE = "List is looking empty";
|
|
7
|
+
export declare const EMPTY_FILTER_RESULTS_MESSAGE = "No results for selected filters";
|
|
8
|
+
export declare const EMPTY_STATE_ACTION_BUTTON_ONLY_ERROR = "DataListEmptyState action prop must be a Button component";
|
|
8
9
|
/**
|
|
9
10
|
* Breakpoints that we support
|
|
10
11
|
*/
|
|
@@ -13,4 +14,5 @@ export declare const BREAKPOINT_SIZES: Record<Breakpoints, number>;
|
|
|
13
14
|
export declare const SEARCH_DEBOUNCE_DELAY: number;
|
|
14
15
|
export declare const DATA_LIST_FILTERING_SPINNER_TEST_ID = "ATL-DataList-filteringSpinner";
|
|
15
16
|
export declare const DATA_LIST_LOADING_MORE_SPINNER_TEST_ID = "ATL-DataList-loadingMoreSpinner";
|
|
17
|
+
export declare const DATA_LOAD_MORE_TEST_ID = "ATL-DataList-LoadMore-trigger";
|
|
16
18
|
export {};
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import { DataListLayout } from "./components/DataListLayout";
|
|
3
|
-
import { DataListObject, DataListProps } from "./DataList.types";
|
|
4
3
|
import { DataListFilters } from "./components/DataListFilters";
|
|
5
4
|
import { DataListSearch } from "./components/DataListSearch";
|
|
5
|
+
import { DataListEmptyState } from "./components/DataListEmptyState";
|
|
6
|
+
import { DataListObject, DataListProps } from "./DataList.types";
|
|
6
7
|
export declare function DataList<T extends DataListObject>(props: DataListProps<T>): JSX.Element;
|
|
7
8
|
export declare namespace DataList {
|
|
8
9
|
var Layout: typeof DataListLayout;
|
|
9
|
-
var EmptyState: typeof
|
|
10
|
+
var EmptyState: typeof DataListEmptyState;
|
|
10
11
|
var Filters: typeof DataListFilters;
|
|
11
12
|
var Search: typeof DataListSearch;
|
|
12
13
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ReactElement, ReactNode } from "react";
|
|
2
2
|
import { Breakpoints } from "./DataList.const";
|
|
3
|
+
import { ButtonProps } from "../Button";
|
|
3
4
|
export { Breakpoints } from "./DataList.const";
|
|
4
5
|
export type DataListItemType<T extends DataListObject[]> = Record<keyof T[number], ReactElement>;
|
|
5
6
|
export type DataListItemTypeFromHeader<TData extends DataListObject, THeader extends DataListHeader<TData>> = Record<keyof THeader, ReactElement>;
|
|
@@ -47,11 +48,9 @@ export interface DataListProps<T extends DataListObject> {
|
|
|
47
48
|
*/
|
|
48
49
|
readonly loadingState?: "initial" | "filtering" | "loadingMore" | "none";
|
|
49
50
|
/**
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
* @default false
|
|
51
|
+
* Adjusts the DataList to show the UX when it is filtered.
|
|
53
52
|
*/
|
|
54
|
-
readonly
|
|
53
|
+
readonly filtered?: boolean;
|
|
55
54
|
/**
|
|
56
55
|
* The title of the DataList.
|
|
57
56
|
*/
|
|
@@ -73,6 +72,10 @@ export interface DataListProps<T extends DataListObject> {
|
|
|
73
72
|
[Breakpoint in Breakpoints]?: boolean;
|
|
74
73
|
};
|
|
75
74
|
readonly children: ReactElement | ReactElement[];
|
|
75
|
+
/**
|
|
76
|
+
* The callback function when the user scrolls to the bottom of the list.
|
|
77
|
+
*/
|
|
78
|
+
readonly onLoadMore?: () => void;
|
|
76
79
|
}
|
|
77
80
|
export interface DataListLayoutProps<T extends DataListObject> {
|
|
78
81
|
readonly children: (item: DataListItemType<T[]>) => JSX.Element;
|
|
@@ -93,8 +96,30 @@ export interface DataListSearchProps {
|
|
|
93
96
|
export interface DataListFiltersProps {
|
|
94
97
|
readonly children: ReactElement | ReactElement[];
|
|
95
98
|
}
|
|
99
|
+
export interface DataListEmptyStateProps {
|
|
100
|
+
/**
|
|
101
|
+
* The message that shows when the DataList is empty.
|
|
102
|
+
*/
|
|
103
|
+
readonly message: string;
|
|
104
|
+
/**
|
|
105
|
+
* The action that shows when the DataList is empty.
|
|
106
|
+
*
|
|
107
|
+
* This only accepts a Button component. Adding a non-Button component will
|
|
108
|
+
* throw an error.
|
|
109
|
+
*/
|
|
110
|
+
readonly action?: ReactElement<ButtonProps>;
|
|
111
|
+
/**
|
|
112
|
+
* Determine the type of empty state to show.
|
|
113
|
+
*
|
|
114
|
+
* By default, it will show the "empty" state when there is no data. If you
|
|
115
|
+
* want to show the "filtered" type, you need to set the `filtered` prop
|
|
116
|
+
* to the DataList component.
|
|
117
|
+
*/
|
|
118
|
+
readonly type?: "filtered" | "empty";
|
|
119
|
+
}
|
|
96
120
|
export interface DataListContextProps<T extends DataListObject> extends DataListProps<T> {
|
|
97
121
|
readonly filterComponent?: ReactElement<DataListFiltersProps>;
|
|
98
122
|
readonly searchComponent?: ReactElement<DataListSearchProps>;
|
|
123
|
+
readonly emptyStateComponents?: ReactElement<DataListEmptyStateProps>[];
|
|
99
124
|
readonly layoutComponents?: ReactElement<DataListLayoutProps<T>>[];
|
|
100
125
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { ReactElement } from "react";
|
|
2
2
|
import { DataListHeader, DataListItemType, DataListItemTypeFromHeader, DataListObject } from "./DataList.types";
|
|
3
|
-
import { EmptyStateProps } from "./components/EmptyState";
|
|
4
3
|
import { Breakpoints } from "./DataList.const";
|
|
5
4
|
/**
|
|
6
5
|
* Return the child component that matches the `type` provided
|
|
@@ -18,14 +17,4 @@ export declare function generateListItemElements<T extends DataListObject>(data:
|
|
|
18
17
|
* Generate the header elements with the default styling
|
|
19
18
|
*/
|
|
20
19
|
export declare function generateHeaderElements<T extends DataListObject>(headers: DataListHeader<T>): DataListItemTypeFromHeader<T, DataListHeader<T>> | undefined;
|
|
21
|
-
interface UseDataListEmptyStateProps {
|
|
22
|
-
readonly children?: ReactElement | ReactElement[];
|
|
23
|
-
readonly isFilterApplied: boolean;
|
|
24
|
-
readonly setIsFilterApplied: (isFilterApplied: boolean) => void;
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Modify EmptyState to include an empty filter results when filtering happens
|
|
28
|
-
*/
|
|
29
|
-
export declare function generateDataListEmptyState({ children, isFilterApplied, setIsFilterApplied, }: UseDataListEmptyStateProps): React.ReactElement<EmptyStateProps> | undefined;
|
|
30
20
|
export declare function sortSizeProp(sizeProp: Breakpoints[]): ("xs" | "sm" | "md" | "lg" | "xl")[];
|
|
31
|
-
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./DataListEmptyState";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./DataListLoadMore";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./DataListStickyHeader";
|
package/dist/DataList/index.js
CHANGED
|
@@ -4,30 +4,30 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
var React = require('react');
|
|
6
6
|
var styleInject_es = require('../style-inject.es-9d2f5f4e.js');
|
|
7
|
-
var Button = require('../Button-7698424c.js');
|
|
8
7
|
var Text = require('../Text-e7ed0974.js');
|
|
9
|
-
var
|
|
8
|
+
var Glimmer = require('../Glimmer-cfa92a88.js');
|
|
10
9
|
var design = require('@jobber/design');
|
|
10
|
+
var isEmpty = require('lodash/isEmpty');
|
|
11
11
|
var InlineLabel = require('../InlineLabel-afd5fc6f.js');
|
|
12
12
|
var FormatDate = require('../FormatDate-70ea5b43.js');
|
|
13
13
|
var Heading = require('../Heading-a1191b15.js');
|
|
14
|
-
var Glimmer = require('../Glimmer-cfa92a88.js');
|
|
15
14
|
var classnames = require('classnames');
|
|
16
|
-
require('react-router-dom');
|
|
17
15
|
require('../Typography-fd6f932a.js');
|
|
18
16
|
var useInView = require('@jobber/hooks/useInView');
|
|
19
17
|
var debounce = require('lodash/debounce');
|
|
20
18
|
var InputText = require('../InputText-bb03f6d1.js');
|
|
19
|
+
var Button = require('../Button-7698424c.js');
|
|
21
20
|
var AnimatedSwitcher = require('../AnimatedSwitcher-d1e1ddcf.js');
|
|
22
21
|
var Spinner = require('../Spinner-9d8fc7ff.js');
|
|
23
|
-
require('../Icon-405a216c.js');
|
|
24
22
|
require('../tslib.es6-5b8768b7.js');
|
|
25
23
|
require('../Content-2ca1ffe1.js');
|
|
26
24
|
require('../FormField-0f880b07.js');
|
|
27
25
|
require('uuid');
|
|
28
26
|
require('react-hook-form');
|
|
27
|
+
require('../Icon-405a216c.js');
|
|
29
28
|
require('../InputValidation-b5a3d92c.js');
|
|
30
29
|
require('framer-motion');
|
|
30
|
+
require('react-router-dom');
|
|
31
31
|
|
|
32
32
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
33
33
|
|
|
@@ -36,28 +36,38 @@ 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$
|
|
40
|
-
var styles$
|
|
41
|
-
styleInject_es.styleInject(css_248z$
|
|
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-"};
|
|
41
|
+
styleInject_es.styleInject(css_248z$8);
|
|
42
42
|
|
|
43
|
-
var css_248z$
|
|
44
|
-
var styles$
|
|
45
|
-
styleInject_es.styleInject(css_248z$
|
|
43
|
+
var css_248z$7 = ".F56prQsXm3A- {\n min-width: 80px;\n margin-left: calc(16px / 2);\n margin-left: var(--space-small);\n}\n";
|
|
44
|
+
var styles$7 = {"results":"F56prQsXm3A-"};
|
|
45
|
+
styleInject_es.styleInject(css_248z$7);
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
const DATALIST_TOTALCOUNT_TEST_ID = "ATL-DataList-TotalCount";
|
|
48
|
+
function DataListTotalCount({ totalCount, loading, }) {
|
|
49
|
+
if (totalCount === undefined)
|
|
50
|
+
return null;
|
|
51
|
+
let output = null;
|
|
52
|
+
if (totalCount === null && loading) {
|
|
53
|
+
output = React__default["default"].createElement(Glimmer.Glimmer, { size: "auto", shape: "rectangle" });
|
|
54
|
+
}
|
|
55
|
+
if (typeof totalCount === "number") {
|
|
56
|
+
output = (React__default["default"].createElement(Text.Text, { variation: "subdued" },
|
|
57
|
+
"(",
|
|
58
|
+
totalCount.toLocaleString(),
|
|
59
|
+
" results)"));
|
|
60
|
+
}
|
|
61
|
+
return (React__default["default"].createElement("div", { className: styles$7.results, "data-testid": DATALIST_TOTALCOUNT_TEST_ID }, output));
|
|
51
62
|
}
|
|
52
63
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
return React__default["default"].createElement(React__default["default"].Fragment, null);
|
|
57
|
-
}
|
|
64
|
+
var css_248z$6 = ".Rh--6fVpkm4- {\n padding: calc(16px / 2);\n padding: var(--space-small);\n}\n\n.zbS7UvpVoWI- {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-direction: column;\n flex-direction: column;\n -ms-flex-pack: justify;\n justify-content: space-between;\n height: calc(16px * 3);\n height: var(--space-largest);\n padding: calc(16px * 1) 0;\n padding: var(--space-base) 0;\n}\n";
|
|
65
|
+
var styles$6 = {"loadingItem":"Rh--6fVpkm4-","mobileLoadingState":"zbS7UvpVoWI-"};
|
|
66
|
+
styleInject_es.styleInject(css_248z$6);
|
|
58
67
|
|
|
59
|
-
const
|
|
60
|
-
const
|
|
68
|
+
const EMPTY_RESULTS_MESSAGE = "List is looking empty";
|
|
69
|
+
const EMPTY_FILTER_RESULTS_MESSAGE = "No results for selected filters";
|
|
70
|
+
const EMPTY_STATE_ACTION_BUTTON_ONLY_ERROR = "DataListEmptyState action prop must be a Button component";
|
|
61
71
|
/**
|
|
62
72
|
* Breakpoints that we support
|
|
63
73
|
*/
|
|
@@ -72,6 +82,7 @@ const BREAKPOINT_SIZES = {
|
|
|
72
82
|
const SEARCH_DEBOUNCE_DELAY = design.tokens["timing-slowest"];
|
|
73
83
|
const DATA_LIST_FILTERING_SPINNER_TEST_ID = "ATL-DataList-filteringSpinner";
|
|
74
84
|
const DATA_LIST_LOADING_MORE_SPINNER_TEST_ID = "ATL-DataList-loadingMoreSpinner";
|
|
85
|
+
const DATA_LOAD_MORE_TEST_ID = "ATL-DataList-LoadMore-trigger";
|
|
75
86
|
|
|
76
87
|
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";
|
|
77
88
|
var styles$5 = {"tags":"WRV-UmQmPzo-","tagCount":"liQeWCMenD0-"};
|
|
@@ -85,8 +96,6 @@ function DataListTags({ items }) {
|
|
|
85
96
|
var _a;
|
|
86
97
|
if (!window.IntersectionObserver)
|
|
87
98
|
return;
|
|
88
|
-
// Reset counter every time the items change
|
|
89
|
-
setVisibleIndex([]);
|
|
90
99
|
const observer = new IntersectionObserver(handleIntersection, {
|
|
91
100
|
root: ref.current,
|
|
92
101
|
threshold: buildIntersectionThreshold(items),
|
|
@@ -178,64 +187,14 @@ function generateListItemElements(data) {
|
|
|
178
187
|
* Generate the header elements with the default styling
|
|
179
188
|
*/
|
|
180
189
|
function generateHeaderElements(headers) {
|
|
181
|
-
const headerElements = Object.keys(headers).reduce((acc, key) => (Object.assign(Object.assign({}, acc), { [key]: (React__default["default"].createElement("div", { className: styles$
|
|
190
|
+
const headerElements = Object.keys(headers).reduce((acc, key) => (Object.assign(Object.assign({}, acc), { [key]: (React__default["default"].createElement("div", { className: styles$8.headerLabel },
|
|
182
191
|
React__default["default"].createElement(Text.Text, { variation: "subdued", maxLines: "single", size: "small" }, headers[key]))) })), {});
|
|
183
192
|
return isEmpty__default["default"](headerElements) ? undefined : headerElements;
|
|
184
193
|
}
|
|
185
|
-
/**
|
|
186
|
-
* Modify EmptyState to include an empty filter results when filtering happens
|
|
187
|
-
*/
|
|
188
|
-
function generateDataListEmptyState({ children, isFilterApplied, setIsFilterApplied, }) {
|
|
189
|
-
if (!children)
|
|
190
|
-
return;
|
|
191
|
-
const EmptyStateComponent = getCompoundComponent(children, DataListEmptyState);
|
|
192
|
-
if (isFilterApplied && React.isValidElement(EmptyStateComponent)) {
|
|
193
|
-
let overrideEmptyStateProps;
|
|
194
|
-
if (isFilterApplied) {
|
|
195
|
-
overrideEmptyStateProps = {
|
|
196
|
-
message: EMPTY_FILTER_RESULTS_MESSAGE,
|
|
197
|
-
action: {
|
|
198
|
-
label: EMPTY_FILTER_RESULTS_ACTION_LABEL,
|
|
199
|
-
onClick: () => {
|
|
200
|
-
setIsFilterApplied(false);
|
|
201
|
-
alert("Filters Cleared");
|
|
202
|
-
},
|
|
203
|
-
},
|
|
204
|
-
};
|
|
205
|
-
}
|
|
206
|
-
return React__default["default"].cloneElement(EmptyStateComponent, overrideEmptyStateProps);
|
|
207
|
-
}
|
|
208
|
-
return EmptyStateComponent;
|
|
209
|
-
}
|
|
210
194
|
function sortSizeProp(sizeProp) {
|
|
211
195
|
return sizeProp.sort((a, b) => BREAKPOINTS.indexOf(a) - BREAKPOINTS.indexOf(b));
|
|
212
196
|
}
|
|
213
197
|
|
|
214
|
-
var css_248z$4 = ".F56prQsXm3A- {\n min-width: 80px;\n margin-left: calc(16px / 2);\n margin-left: var(--space-small);\n}\n";
|
|
215
|
-
var styles$4 = {"results":"F56prQsXm3A-"};
|
|
216
|
-
styleInject_es.styleInject(css_248z$4);
|
|
217
|
-
|
|
218
|
-
const DATALIST_TOTALCOUNT_TEST_ID = "ATL-DataList-TotalCount";
|
|
219
|
-
function DataListTotalCount({ totalCount, loading, }) {
|
|
220
|
-
if (totalCount === undefined)
|
|
221
|
-
return null;
|
|
222
|
-
let output = null;
|
|
223
|
-
if (totalCount === null && loading) {
|
|
224
|
-
output = React__default["default"].createElement(Glimmer.Glimmer, { size: "auto", shape: "rectangle" });
|
|
225
|
-
}
|
|
226
|
-
if (typeof totalCount === "number") {
|
|
227
|
-
output = (React__default["default"].createElement(Text.Text, { variation: "subdued" },
|
|
228
|
-
"(",
|
|
229
|
-
totalCount.toLocaleString(),
|
|
230
|
-
" results)"));
|
|
231
|
-
}
|
|
232
|
-
return (React__default["default"].createElement("div", { className: styles$4.results, "data-testid": DATALIST_TOTALCOUNT_TEST_ID }, output));
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
var css_248z$3 = ".Rh--6fVpkm4- {\n padding: calc(16px / 2);\n padding: var(--space-small);\n}\n\n.zbS7UvpVoWI- {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-direction: column;\n flex-direction: column;\n -ms-flex-pack: justify;\n justify-content: space-between;\n height: calc(16px * 3);\n height: var(--space-largest);\n padding: calc(16px * 1) 0;\n padding: var(--space-base) 0;\n}\n";
|
|
236
|
-
var styles$3 = {"loadingItem":"Rh--6fVpkm4-","mobileLoadingState":"zbS7UvpVoWI-"};
|
|
237
|
-
styleInject_es.styleInject(css_248z$3);
|
|
238
|
-
|
|
239
198
|
function DataListLayoutInternal({ layouts, renderLayout, mediaMatches, }) {
|
|
240
199
|
const sizePropsOfLayouts = layouts === null || layouts === void 0 ? void 0 : layouts.map(layout => layout.props.size || "xs");
|
|
241
200
|
const layoutToRender = layouts === null || layouts === void 0 ? void 0 : layouts.find(layout => {
|
|
@@ -272,7 +231,7 @@ function DataListItems({ layouts, mediaMatches, data, }) {
|
|
|
272
231
|
const elementData = generateListItemElements(data);
|
|
273
232
|
return (React__default["default"].createElement(DataListLayoutInternal, { layouts: layouts, mediaMatches: mediaMatches, renderLayout: layout => {
|
|
274
233
|
return (React__default["default"].createElement(React__default["default"].Fragment, null, elementData.map((child, i) => {
|
|
275
|
-
return (React__default["default"].createElement("div", { className: styles$
|
|
234
|
+
return (React__default["default"].createElement("div", { className: styles$8.listItem, key: `${data[i].id}` }, layout.props.children(child)));
|
|
276
235
|
})));
|
|
277
236
|
} }));
|
|
278
237
|
}
|
|
@@ -288,7 +247,7 @@ function DataListHeader({ layouts, mediaMatches, headerData, headerVisibility, }
|
|
|
288
247
|
if (!showHeader || !headerData)
|
|
289
248
|
return React__default["default"].createElement(React__default["default"].Fragment, null);
|
|
290
249
|
return (React__default["default"].createElement(DataListLayoutInternal, { layouts: layouts, renderLayout: layout => {
|
|
291
|
-
return (React__default["default"].createElement("div", { className: styles$
|
|
250
|
+
return (React__default["default"].createElement("div", { className: styles$8.headerTitles }, layout.props.children(headerData)));
|
|
292
251
|
}, mediaMatches: mediaMatches }));
|
|
293
252
|
}
|
|
294
253
|
|
|
@@ -304,42 +263,29 @@ function DataListLoadingState({ headers, layouts, mediaMatches, }) {
|
|
|
304
263
|
if (layout.props.size === "xs") {
|
|
305
264
|
return React__default["default"].createElement(LoadingStateXSBreakpoint, null);
|
|
306
265
|
}
|
|
307
|
-
return (React__default["default"].createElement(React__default["default"].Fragment, null, loadingElements.map((child, i) => (React__default["default"].createElement("div", { className: styles$
|
|
266
|
+
return (React__default["default"].createElement(React__default["default"].Fragment, null, loadingElements.map((child, i) => (React__default["default"].createElement("div", { className: styles$6.loadingItem, key: i, "data-testid": DATALIST_LOADINGSTATE_ROW_TEST_ID }, layout.props.children(child))))));
|
|
308
267
|
} }));
|
|
309
268
|
}
|
|
310
269
|
function LoadingStateXSBreakpoint() {
|
|
311
270
|
const loadingData = new Array(LOADING_STATE_LIMIT_ITEMS).fill(0);
|
|
312
271
|
return (React__default["default"].createElement(React__default["default"].Fragment, null, loadingData.map((_, i) => {
|
|
313
|
-
return (React__default["default"].createElement("div", { className: styles$
|
|
272
|
+
return (React__default["default"].createElement("div", { className: styles$6.mobileLoadingState, key: i },
|
|
314
273
|
React__default["default"].createElement(Glimmer.Glimmer.Text, null)));
|
|
315
274
|
})));
|
|
316
275
|
}
|
|
317
276
|
|
|
318
|
-
function
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
const handlers = BREAKPOINTS.reduce((previous, breakpoint) => {
|
|
323
|
-
const handler = (e) => setMatches(previousMatches => (Object.assign(Object.assign({}, previousMatches), { [breakpoint]: e.matches })));
|
|
324
|
-
return Object.assign(Object.assign({}, previous), { [breakpoint]: handler });
|
|
325
|
-
}, {});
|
|
326
|
-
// Set up mediaQuery event handlers
|
|
327
|
-
React.useEffect(() => {
|
|
328
|
-
BREAKPOINTS.forEach(breakpoint => {
|
|
329
|
-
mediaQueries[breakpoint].addEventListener("change", handlers[breakpoint]);
|
|
330
|
-
});
|
|
331
|
-
return () => {
|
|
332
|
-
BREAKPOINTS.forEach(breakpoint => {
|
|
333
|
-
mediaQueries[breakpoint].removeEventListener("change", handlers[breakpoint]);
|
|
334
|
-
});
|
|
335
|
-
};
|
|
336
|
-
}, [mediaQueries]);
|
|
337
|
-
return matches;
|
|
338
|
-
}
|
|
339
|
-
function breakpointToMediaQuery(breakpoint) {
|
|
340
|
-
return `(min-width: ${BREAKPOINT_SIZES[breakpoint]}px)`;
|
|
277
|
+
function DataListLayout(
|
|
278
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
279
|
+
_) {
|
|
280
|
+
return React__default["default"].createElement(React__default["default"].Fragment, null);
|
|
341
281
|
}
|
|
342
282
|
|
|
283
|
+
var css_248z$4 = ".E-mG3prPSN8- {\n -ms-flex-item-align: center;\n align-self: center;\n position: relative;\n min-width: 0;\n}\n\n._0LGNoZxtqSE- {\n display: grid;\n overflow-x: auto;\n grid-auto-flow: column;\n grid-auto-columns: -webkit-max-content;\n grid-auto-columns: max-content;\n -ms-flex-align: center;\n align-items: center;\n}\n\n._0LGNoZxtqSE- > :nth-child(n + 3):not(:last-child) {\n margin-left: calc(16px / 2);\n margin-left: var(--space-small);\n}\n\n.LA3-gtgehrE- {\n visibility: hidden;\n}\n\n.fSPvawYWzZ8-::before,\n.ChfEJMPPVTk-::after {\n content: \"\";\n position: absolute;\n top: 0;\n width: calc(16px * 1.5);\n width: var(--space-large);\n height: 100%;\n background-image: linear-gradient(\n to right,\n rgba(255, 255, 255, 1) 0%,\n rgba(255, 255, 255, 0) 100%\n );\n background-image: linear-gradient(\n var(--data-list-filters-overflow-shadow-angle, to right),\n var(--color-surface) 0%,\n rgba(var(--color-white--rgb), 0) 100%\n );\n pointer-events: none;\n}\n\n.fSPvawYWzZ8-::before {\n left: 0;\n}\n\n.ChfEJMPPVTk-::after {\n --data-list-filters-overflow-shadow-angle: to left;\n right: 0;\n}\n";
|
|
284
|
+
var styles$4 = {"filters":"E-mG3prPSN8-","filterActions":"_0LGNoZxtqSE-","overflowTrigger":"LA3-gtgehrE-","overflowLeft":"fSPvawYWzZ8-","overflowRight":"ChfEJMPPVTk-"};
|
|
285
|
+
styleInject_es.styleInject(css_248z$4);
|
|
286
|
+
|
|
287
|
+
const CONTAINER_TEST_ID = "ATL-DataListFilters-Container";
|
|
288
|
+
|
|
343
289
|
const defaultValues = {
|
|
344
290
|
title: "",
|
|
345
291
|
data: [],
|
|
@@ -351,12 +297,6 @@ function useDataListContext() {
|
|
|
351
297
|
return React.useContext(DataListContext);
|
|
352
298
|
}
|
|
353
299
|
|
|
354
|
-
var css_248z$2 = ".E-mG3prPSN8- {\n -ms-flex-item-align: center;\n align-self: center;\n position: relative;\n min-width: 0;\n}\n\n._0LGNoZxtqSE- {\n display: grid;\n overflow-x: auto;\n grid-auto-flow: column;\n grid-auto-columns: -webkit-max-content;\n grid-auto-columns: max-content;\n -ms-flex-align: center;\n align-items: center;\n}\n\n._0LGNoZxtqSE- > :nth-child(n + 3):not(:last-child) {\n margin-left: calc(16px / 2);\n margin-left: var(--space-small);\n}\n\n.LA3-gtgehrE- {\n visibility: hidden;\n}\n\n.fSPvawYWzZ8-::before,\n.ChfEJMPPVTk-::after {\n content: \"\";\n position: absolute;\n top: 0;\n width: calc(16px * 1.5);\n width: var(--space-large);\n height: 100%;\n background-image: linear-gradient(\n to right,\n rgba(255, 255, 255, 1) 0%,\n rgba(255, 255, 255, 0) 100%\n );\n background-image: linear-gradient(\n var(--data-list-filters-overflow-shadow-angle, to right),\n var(--color-surface) 0%,\n rgba(var(--color-white--rgb), 0) 100%\n );\n pointer-events: none;\n}\n\n.fSPvawYWzZ8-::before {\n left: 0;\n}\n\n.ChfEJMPPVTk-::after {\n --data-list-filters-overflow-shadow-angle: to left;\n right: 0;\n}\n";
|
|
355
|
-
var styles$2 = {"filters":"E-mG3prPSN8-","filterActions":"_0LGNoZxtqSE-","overflowTrigger":"LA3-gtgehrE-","overflowLeft":"fSPvawYWzZ8-","overflowRight":"ChfEJMPPVTk-"};
|
|
356
|
-
styleInject_es.styleInject(css_248z$2);
|
|
357
|
-
|
|
358
|
-
const CONTAINER_TEST_ID = "ATL-DataListFilters-Container";
|
|
359
|
-
|
|
360
300
|
// This component is meant to capture the props of the DataList.Filters
|
|
361
301
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
362
302
|
function DataListFilters(_) {
|
|
@@ -373,19 +313,39 @@ function InternalDataListFilters() {
|
|
|
373
313
|
if (!component)
|
|
374
314
|
return null;
|
|
375
315
|
const { children } = component.props;
|
|
376
|
-
return (React__default["default"].createElement("div", { "data-testid": CONTAINER_TEST_ID, className: classnames__default["default"](styles$
|
|
377
|
-
[styles$
|
|
378
|
-
[styles$
|
|
316
|
+
return (React__default["default"].createElement("div", { "data-testid": CONTAINER_TEST_ID, className: classnames__default["default"](styles$4.filters, {
|
|
317
|
+
[styles$4.overflowLeft]: !isLeftVisible,
|
|
318
|
+
[styles$4.overflowRight]: !isRightVisible,
|
|
379
319
|
}) },
|
|
380
|
-
React__default["default"].createElement("div", { className: styles$
|
|
381
|
-
React__default["default"].createElement("span", { ref: leftRef, className: styles$
|
|
320
|
+
React__default["default"].createElement("div", { className: styles$4.filterActions },
|
|
321
|
+
React__default["default"].createElement("span", { ref: leftRef, className: styles$4.overflowTrigger }),
|
|
382
322
|
children,
|
|
383
|
-
React__default["default"].createElement("span", { ref: rightRef, className: styles$
|
|
323
|
+
React__default["default"].createElement("span", { ref: rightRef, className: styles$4.overflowTrigger }))));
|
|
384
324
|
}
|
|
385
325
|
|
|
386
|
-
var css_248z$
|
|
387
|
-
var styles$
|
|
388
|
-
styleInject_es.styleInject(css_248z$
|
|
326
|
+
var css_248z$3 = ".PGOHzrMh374- {\n --offset: 1px;\n --sticky-header-transition-properties: var(--timing-base) ease-in-out;\n\n position: sticky;\n top: calc(1px * -1);\n top: calc(var(--offset) * -1);\n z-index: 1;\n z-index: var(--elevation-base);\n padding-top: 1px;\n padding-top: var(--offset);\n background-color: rgba(255, 255, 255, 1);\n background-color: var(--color-surface);\n}\n\n/**\n * Draw a border that gets covered by the column headers border when it shows up.\n *\n * Mostly to prevent us from writing some complex JS to remove the border when\n * the column headers show up.\n */\n\n.PGOHzrMh374-::before {\n content: \"\";\n display: block;\n position: absolute;\n bottom: 0;\n left: 50%;\n z-index: -1;\n width: 0;\n height: 0;\n background-color: rgb(225, 225, 225);\n background-color: var(--color-border);\n -webkit-transform: translateX(-50%);\n transform: translateX(-50%);\n transition: height var(--sticky-header-transition-properties)\n 100ms,\n width var(--sticky-header-transition-properties);\n transition: height var(--sticky-header-transition-properties)\n var(--timing-quick),\n width var(--sticky-header-transition-properties);\n}\n\n.PGjWc5ocjpI-::before {\n width: 100%;\n height: calc(16px / 8);\n height: var(--border-thick);\n transition: height var(--sticky-header-transition-properties),\n width var(--sticky-header-transition-properties) 100ms;\n transition: height var(--sticky-header-transition-properties),\n width var(--sticky-header-transition-properties) var(--timing-quick);\n}\n";
|
|
327
|
+
var styles$3 = {"header":"PGOHzrMh374-","stuck":"PGjWc5ocjpI-"};
|
|
328
|
+
styleInject_es.styleInject(css_248z$3);
|
|
329
|
+
|
|
330
|
+
function DataListStickyHeader({ children }) {
|
|
331
|
+
const [isStuck, setIsStuck] = React.useState(false);
|
|
332
|
+
const ref = React.useRef(null);
|
|
333
|
+
const handleObserver = React.useCallback(([e]) => setIsStuck(e.intersectionRatio < 1), [setIsStuck]);
|
|
334
|
+
React.useEffect(() => {
|
|
335
|
+
if (!window.IntersectionObserver)
|
|
336
|
+
return;
|
|
337
|
+
const observer = new IntersectionObserver(handleObserver, { threshold: 1 });
|
|
338
|
+
ref.current && observer.observe(ref.current);
|
|
339
|
+
return () => {
|
|
340
|
+
ref.current && observer.unobserve(ref.current);
|
|
341
|
+
};
|
|
342
|
+
}, [handleObserver, ref.current]);
|
|
343
|
+
return (React__default["default"].createElement("div", { ref: ref, className: classnames__default["default"](styles$3.header, { [styles$3.stuck]: isStuck }) }, children));
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
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";
|
|
347
|
+
var styles$2 = {"searchInput":"SaPMOnvw-3c-","searchInputVisible":"_3S1-91v2SYI-","searchButton":"_9GlBktsUALw-","withNoFilters":"_3Pjrt42x454-"};
|
|
348
|
+
styleInject_es.styleInject(css_248z$2);
|
|
389
349
|
|
|
390
350
|
const DATA_LIST_SEARCH_TEST_ID = "ATL-DataList-Search-input-wrapper";
|
|
391
351
|
// This component is meant to capture the props of the DataList.Search
|
|
@@ -404,12 +364,12 @@ function InternalDataListSearch() {
|
|
|
404
364
|
if (!searchComponent)
|
|
405
365
|
return null;
|
|
406
366
|
const { placeholder } = searchComponent.props;
|
|
407
|
-
return (React__default["default"].createElement("div", { className: classnames__default["default"]({ [styles$
|
|
408
|
-
React__default["default"].createElement("div", { "data-testid": DATA_LIST_SEARCH_TEST_ID, className: classnames__default["default"](styles$
|
|
409
|
-
[styles$
|
|
367
|
+
return (React__default["default"].createElement("div", { className: classnames__default["default"]({ [styles$2.withNoFilters]: !filterComponent }) },
|
|
368
|
+
React__default["default"].createElement("div", { "data-testid": DATA_LIST_SEARCH_TEST_ID, className: classnames__default["default"](styles$2.searchInput, {
|
|
369
|
+
[styles$2.searchInputVisible]: visible,
|
|
410
370
|
}) },
|
|
411
371
|
React__default["default"].createElement(InputText.InputText, { ref: inputRef, placeholder: getPlaceholder(), onChange: debouncedSearch, prefix: { icon: "search" }, size: "small" })),
|
|
412
|
-
React__default["default"].createElement("div", { className: styles$
|
|
372
|
+
React__default["default"].createElement("div", { className: styles$2.searchButton },
|
|
413
373
|
React__default["default"].createElement(AnimatedSwitcher.AnimatedSwitcher, { switched: visible, initialChild: React__default["default"].createElement(Button.Button, { variation: "subtle", icon: "search", ariaLabel: "Search", onClick: toggleSearch }), switchTo: React__default["default"].createElement(Button.Button, { variation: "subtle", icon: "remove", ariaLabel: "Close search bar", onClick: toggleSearch }) }))));
|
|
414
374
|
function getPlaceholder() {
|
|
415
375
|
if (placeholder)
|
|
@@ -427,62 +387,125 @@ function InternalDataListSearch() {
|
|
|
427
387
|
}
|
|
428
388
|
}
|
|
429
389
|
|
|
430
|
-
var css_248z = ".
|
|
431
|
-
var styles = {"
|
|
390
|
+
var css_248z$1 = ".zg3w9nQga-M- {\n display: -ms-flexbox;\n display: flex;\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 -ms-flex: 1;\n flex: 1;\n}\n";
|
|
391
|
+
var styles$1 = {"emptyStateWrapper":"zg3w9nQga-M-"};
|
|
392
|
+
styleInject_es.styleInject(css_248z$1);
|
|
393
|
+
|
|
394
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
395
|
+
function DataListEmptyState(_) {
|
|
396
|
+
return null;
|
|
397
|
+
}
|
|
398
|
+
function InternalDataListEmptyState() {
|
|
399
|
+
const { emptyStateComponents: components, filtered } = React.useContext(DataListContext);
|
|
400
|
+
const { message, action } = getMessages();
|
|
401
|
+
return (React__default["default"].createElement("div", { className: styles$1.emptyStateWrapper },
|
|
402
|
+
React__default["default"].createElement(Text.Text, { align: "center" }, message),
|
|
403
|
+
renderButton(action)));
|
|
404
|
+
function getMessages() {
|
|
405
|
+
const { defaultEmptyState, filteredEmptyState } = getEmptyStates(components);
|
|
406
|
+
if (filtered) {
|
|
407
|
+
return {
|
|
408
|
+
message: (filteredEmptyState === null || filteredEmptyState === void 0 ? void 0 : filteredEmptyState.props.message) || EMPTY_FILTER_RESULTS_MESSAGE,
|
|
409
|
+
action: filteredEmptyState === null || filteredEmptyState === void 0 ? void 0 : filteredEmptyState.props.action,
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
return {
|
|
413
|
+
message: (defaultEmptyState === null || defaultEmptyState === void 0 ? void 0 : defaultEmptyState.props.message) || EMPTY_RESULTS_MESSAGE,
|
|
414
|
+
action: defaultEmptyState === null || defaultEmptyState === void 0 ? void 0 : defaultEmptyState.props.action,
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
function renderButton(action) {
|
|
419
|
+
if (action) {
|
|
420
|
+
if (action.type === Button.Button) {
|
|
421
|
+
return React.cloneElement(action, {
|
|
422
|
+
variation: action.props.variation || "subtle",
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
throw new Error(EMPTY_STATE_ACTION_BUTTON_ONLY_ERROR);
|
|
426
|
+
}
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
function getEmptyStates(components) {
|
|
430
|
+
const defaultEmptyState = components === null || components === void 0 ? void 0 : components.find(es => es.props.type === "empty" || es.props.type === undefined);
|
|
431
|
+
const filteredEmptyState = components === null || components === void 0 ? void 0 : components.find(es => es.props.type === "filtered");
|
|
432
|
+
return { defaultEmptyState, filteredEmptyState };
|
|
433
|
+
}
|
|
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-"};
|
|
432
437
|
styleInject_es.styleInject(css_248z);
|
|
433
438
|
|
|
434
|
-
function
|
|
435
|
-
const
|
|
436
|
-
const
|
|
437
|
-
const handleObserver = React.useCallback(([e]) => setIsStuck(e.intersectionRatio < 1), [setIsStuck]);
|
|
439
|
+
function DataListLoadMore() {
|
|
440
|
+
const { onLoadMore } = useDataListContext();
|
|
441
|
+
const [inViewRef, isInView] = useInView.useInView();
|
|
438
442
|
React.useEffect(() => {
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
+
isInView && (onLoadMore === null || onLoadMore === void 0 ? void 0 : onLoadMore());
|
|
444
|
+
}, [isInView]);
|
|
445
|
+
return (React__default["default"].createElement("div", { ref: inViewRef, className: styles.trigger, "data-testid": DATA_LOAD_MORE_TEST_ID }));
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
function useLayoutMediaQueries() {
|
|
449
|
+
const mediaQueries = BREAKPOINTS.reduce((previous, breakpoint) => (Object.assign(Object.assign({}, previous), { [breakpoint]: window.matchMedia(breakpointToMediaQuery(breakpoint)) })), {});
|
|
450
|
+
const initialMatches = BREAKPOINTS.reduce((previous, breakpoint) => (Object.assign(Object.assign({}, previous), { [breakpoint]: mediaQueries[breakpoint].matches })), {});
|
|
451
|
+
const [matches, setMatches] = React.useState(initialMatches);
|
|
452
|
+
const handlers = BREAKPOINTS.reduce((previous, breakpoint) => {
|
|
453
|
+
const handler = (e) => setMatches(previousMatches => (Object.assign(Object.assign({}, previousMatches), { [breakpoint]: e.matches })));
|
|
454
|
+
return Object.assign(Object.assign({}, previous), { [breakpoint]: handler });
|
|
455
|
+
}, {});
|
|
456
|
+
// Set up mediaQuery event handlers
|
|
457
|
+
React.useEffect(() => {
|
|
458
|
+
BREAKPOINTS.forEach(breakpoint => {
|
|
459
|
+
mediaQueries[breakpoint].addEventListener("change", handlers[breakpoint]);
|
|
460
|
+
});
|
|
443
461
|
return () => {
|
|
444
|
-
|
|
462
|
+
BREAKPOINTS.forEach(breakpoint => {
|
|
463
|
+
mediaQueries[breakpoint].removeEventListener("change", handlers[breakpoint]);
|
|
464
|
+
});
|
|
445
465
|
};
|
|
446
|
-
}, [
|
|
447
|
-
return
|
|
466
|
+
}, [mediaQueries]);
|
|
467
|
+
return matches;
|
|
468
|
+
}
|
|
469
|
+
function breakpointToMediaQuery(breakpoint) {
|
|
470
|
+
return `(min-width: ${BREAKPOINT_SIZES[breakpoint]}px)`;
|
|
448
471
|
}
|
|
449
472
|
|
|
450
473
|
function DataList(props) {
|
|
451
474
|
const searchComponent = getCompoundComponent(props.children, DataListSearch);
|
|
452
475
|
const filterComponent = getCompoundComponent(props.children, DataListFilters);
|
|
453
476
|
const layoutComponents = getCompoundComponents(props.children, DataListLayout);
|
|
454
|
-
|
|
477
|
+
const emptyStateComponents = getCompoundComponents(props.children, DataListEmptyState);
|
|
478
|
+
return (React__default["default"].createElement(DataListContext.Provider, { value: Object.assign({ searchComponent,
|
|
479
|
+
filterComponent,
|
|
480
|
+
layoutComponents,
|
|
481
|
+
emptyStateComponents }, props) },
|
|
455
482
|
React__default["default"].createElement(InternalDataList, null)));
|
|
456
483
|
}
|
|
457
484
|
function InternalDataList() {
|
|
458
|
-
const { data, headers,
|
|
485
|
+
const { data, headers, title, totalCount, headerVisibility = { xs: true, sm: true, md: true, lg: true, xl: true }, loadingState = "none", layoutComponents, } = useDataListContext();
|
|
459
486
|
const headerData = generateHeaderElements(headers);
|
|
460
487
|
const mediaMatches = useLayoutMediaQueries();
|
|
461
488
|
const initialLoading = loadingState === "initial";
|
|
462
489
|
const showEmptyState = !initialLoading && data.length === 0;
|
|
463
|
-
const
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
isFilterApplied,
|
|
467
|
-
setIsFilterApplied,
|
|
468
|
-
});
|
|
469
|
-
return (React__default["default"].createElement("div", { className: styles$7.wrapper },
|
|
470
|
-
React__default["default"].createElement("div", { className: styles$7.titleContainer },
|
|
490
|
+
const shouldRenderLoadMoreTrigger = !initialLoading && !showEmptyState;
|
|
491
|
+
return (React__default["default"].createElement("div", { className: styles$8.wrapper },
|
|
492
|
+
React__default["default"].createElement("div", { className: styles$8.titleContainer },
|
|
471
493
|
title && React__default["default"].createElement(Heading.Heading, { level: 3 }, title),
|
|
472
494
|
React__default["default"].createElement(DataListTotalCount, { totalCount: totalCount, loading: initialLoading })),
|
|
473
495
|
React__default["default"].createElement(DataListStickyHeader, null,
|
|
474
|
-
React__default["default"].createElement("div", { className: styles$
|
|
496
|
+
React__default["default"].createElement("div", { className: styles$8.headerFilters },
|
|
475
497
|
React__default["default"].createElement(InternalDataListFilters, null),
|
|
476
498
|
React__default["default"].createElement(InternalDataListSearch, null)),
|
|
477
499
|
headerData && (React__default["default"].createElement(DataListHeader, { layouts: layoutComponents, headerData: headerData, headerVisibility: headerVisibility, mediaMatches: mediaMatches }))),
|
|
478
500
|
initialLoading && (React__default["default"].createElement(DataListLoadingState, { headers: headers, layouts: layoutComponents, mediaMatches: mediaMatches })),
|
|
501
|
+
showEmptyState && React__default["default"].createElement(InternalDataListEmptyState, null),
|
|
479
502
|
!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$
|
|
481
|
-
React__default["default"].createElement("div", { className: styles$
|
|
503
|
+
loadingState === "filtering" && (React__default["default"].createElement("div", { "data-testid": DATA_LIST_FILTERING_SPINNER_TEST_ID, className: styles$8.filtering },
|
|
504
|
+
React__default["default"].createElement("div", { className: styles$8.filteringSpinner },
|
|
482
505
|
React__default["default"].createElement(Spinner.Spinner, { size: "small" })))),
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
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" })))));
|
|
486
509
|
}
|
|
487
510
|
DataList.Layout = DataListLayout;
|
|
488
511
|
DataList.EmptyState = DataListEmptyState;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jobber/components",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.33.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": "4ad7db01af3c57a0eefed5e714059615d71b56d3"
|
|
88
88
|
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
|
-
import { XOR } from "ts-xor";
|
|
3
|
-
import { ButtonProps } from "../../../Button";
|
|
4
|
-
interface ActionBase {
|
|
5
|
-
label: string;
|
|
6
|
-
}
|
|
7
|
-
interface AnchorAction extends ActionBase {
|
|
8
|
-
url: ButtonProps["url"];
|
|
9
|
-
}
|
|
10
|
-
interface LinkAction extends ActionBase {
|
|
11
|
-
to: ButtonProps["to"];
|
|
12
|
-
}
|
|
13
|
-
interface ClickAction extends ActionBase {
|
|
14
|
-
onClick: ButtonProps["onClick"];
|
|
15
|
-
}
|
|
16
|
-
export interface EmptyStateProps {
|
|
17
|
-
message: string;
|
|
18
|
-
action?: XOR<ClickAction, XOR<AnchorAction, LinkAction>>;
|
|
19
|
-
}
|
|
20
|
-
export declare function DataListEmptyState({ message, action }: EmptyStateProps): JSX.Element;
|
|
21
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { DataListEmptyState as EmptyState, EmptyStateProps, } from "./EmptyState";
|