@jobber/components 4.42.0 → 4.43.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,5 +1,6 @@
1
1
  import { ReactElement, ReactNode } from "react";
2
2
  import { IconNames } from "@jobber/design";
3
+ import { XOR } from "ts-xor";
3
4
  import { Breakpoints } from "./DataList.const";
4
5
  import { ButtonProps } from "../Button";
5
6
  export { Breakpoints } from "./DataList.const";
@@ -148,9 +149,8 @@ export interface DataListContextProps<T extends DataListObject> extends DataList
148
149
  readonly layoutComponents?: ReactElement<DataListLayoutProps<T>>[];
149
150
  readonly itemActionComponent?: ReactElement<DataListItemActionsProps<T>>;
150
151
  }
151
- export interface DataListLayoutContextProps<T extends DataListObject> {
152
+ export interface DataListLayoutContextProps {
152
153
  readonly isInLayoutProvider: boolean;
153
- readonly activeItem?: T;
154
154
  /**
155
155
  * Determine if the consumer of the DataList manually added an action to the
156
156
  * layout. This is used to determine if the DataList should render the
@@ -159,14 +159,36 @@ export interface DataListLayoutContextProps<T extends DataListObject> {
159
159
  readonly hasInLayoutActions: boolean;
160
160
  readonly setHasInLayoutActions: (state: boolean) => void;
161
161
  }
162
+ export interface DataListLayoutActionsContextProps<T extends DataListObject> {
163
+ readonly activeItem?: T;
164
+ }
162
165
  type Fragment<T> = T | T[];
163
- export interface DataListItemActionsProps<T extends DataListObject> {
166
+ interface BaseDataListItemActionsProps<T extends DataListObject> {
164
167
  /**
165
168
  * The actions to render for each item in the DataList. This only accepts the
166
169
  * DataList.Action component.
167
170
  */
168
171
  readonly children?: Fragment<ReactElement<DataListActionProps<T>>>;
172
+ /**
173
+ * Callback when an item is clicked.
174
+ */
175
+ readonly onClick?: (item: T) => void;
176
+ }
177
+ interface DataListItemActionsPropsWithURL<T extends DataListObject> extends BaseDataListItemActionsProps<T> {
178
+ /**
179
+ * If a normal page navigation is needed, use this prop to change the element
180
+ * to an `a` tag with an `href`.
181
+ */
182
+ readonly url?: string | ((item: T) => string);
183
+ }
184
+ interface DataListItemActionsPropsWithTo<T extends DataListObject> extends BaseDataListItemActionsProps<T> {
185
+ /**
186
+ * If a React Navigation is needed, use this prop to use the `Link` component
187
+ * that comes with React Router.
188
+ */
189
+ readonly to?: string | ((item: T) => string);
169
190
  }
191
+ export type DataListItemActionsProps<T extends DataListObject> = XOR<DataListItemActionsPropsWithURL<T>, DataListItemActionsPropsWithTo<T>>;
170
192
  export interface DataListActionProps<T extends DataListObject> {
171
193
  /**
172
194
  * The label of the action
@@ -10,9 +10,9 @@ export declare function getCompoundComponent<T>(children: ReactElement | ReactEl
10
10
  */
11
11
  export declare function getCompoundComponents<T>(children: ReactElement | ReactElement[], type: ReactElement<T>["type"]): ReactElement<T>[];
12
12
  /**
13
- * Generate the default elements the DataList would use on the data provided.
13
+ * Generate the default element the DataList would use on the data provided.
14
14
  */
15
- export declare function generateListItemElements<T extends DataListObject>(data: T[]): DataListItemType<T[]>[];
15
+ export declare function generateListItemElement<T extends DataListObject>(item: T): DataListItemType<T[]>;
16
16
  /**
17
17
  * Generate the header elements with the default styling
18
18
  */
@@ -0,0 +1,9 @@
1
+ import { ReactElement } from "react";
2
+ import { DataListLayoutProps, DataListObject } from "@jobber/components/DataList/DataList.types";
3
+ interface DataListItem<T extends DataListObject> {
4
+ readonly item: T;
5
+ readonly index: number;
6
+ readonly layout: ReactElement<DataListLayoutProps<T>>;
7
+ }
8
+ export declare function DataListItem<T extends DataListObject>({ item, layout, }: DataListItem<T>): JSX.Element;
9
+ export {};
@@ -1,5 +1,5 @@
1
1
  /// <reference types="react" />
2
- import { DataListObject } from "../../DataList.types";
2
+ import { DataListObject } from "@jobber/components/DataList/DataList.types";
3
3
  interface ListItemInternalProps<T extends DataListObject> {
4
4
  readonly children: JSX.Element;
5
5
  readonly item: T;
@@ -0,0 +1,2 @@
1
+ import { PropsWithChildren } from "react";
2
+ export declare function DataListItemClickable({ children }: PropsWithChildren<object>): JSX.Element;
@@ -0,0 +1,3 @@
1
+ import { PropsWithChildren } from "react";
2
+ import { DataListItemActionsProps, DataListObject } from "@jobber/components/DataList/DataList.types";
3
+ export declare function DataListItemClickableInternal<T extends DataListObject>({ onClick, url, to, children, }: PropsWithChildren<Pick<DataListItemActionsProps<T>, "onClick" | "url" | "to">>): JSX.Element;
@@ -0,0 +1 @@
1
+ export * from "./DataListItemClickable";
@@ -0,0 +1 @@
1
+ export * from "./DataListItem";
@@ -1 +1,2 @@
1
1
  export * from "./DataListItemActions";
2
+ export * from "./DataListItemActionsOverflow";
@@ -0,0 +1,4 @@
1
+ /// <reference types="react" />
2
+ import { DataListLayoutActionsContextProps, DataListObject } from "@jobber/components/DataList/DataList.types";
3
+ export declare const DataListLayoutActionsContext: import("react").Context<DataListLayoutActionsContextProps<DataListObject>>;
4
+ export declare function useDataListLayoutActionsContext<T extends DataListObject>(): DataListLayoutActionsContextProps<T>;
@@ -0,0 +1 @@
1
+ export * from "./DataListLayoutContext";
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
- import { Breakpoints } from "../../DataList.const";
3
- import { DataListLayoutProps, DataListObject } from "../../DataList.types";
2
+ import { Breakpoints } from "@jobber/components/DataList/DataList.const";
3
+ import { DataListLayoutProps, DataListObject } from "@jobber/components/DataList/DataList.types";
4
4
  interface DataListItemsProps<T extends DataListObject> {
5
5
  readonly layouts: React.ReactElement<DataListLayoutProps<T>>[] | undefined;
6
6
  readonly mediaMatches?: Record<Breakpoints, boolean>;
@@ -1,5 +1,5 @@
1
1
  /// <reference types="react" />
2
- import { DataListLayoutContextProps, DataListObject } from "../../DataList.types";
3
- export declare const defaultValues: DataListLayoutContextProps<DataListObject>;
4
- export declare const DataListLayoutContext: import("react").Context<DataListLayoutContextProps<DataListObject>>;
5
- export declare function useDataListLayoutContext(): DataListLayoutContextProps<DataListObject>;
2
+ import { DataListLayoutContextProps } from "@jobber/components/DataList/DataList.types";
3
+ export declare const defaultValues: DataListLayoutContextProps;
4
+ export declare const DataListLayoutContext: import("react").Context<DataListLayoutContextProps>;
5
+ export declare function useDataListLayoutContext(): DataListLayoutContextProps;
@@ -9,17 +9,11 @@ var Text = require('../Text-e7ed0974.js');
9
9
  var Glimmer = require('../Glimmer-cfa92a88.js');
10
10
  var framerMotion = require('framer-motion');
11
11
  var classnames = require('classnames');
12
+ var noop = require('lodash/noop');
13
+ var reactRouterDom = require('react-router-dom');
14
+ var Button = require('../Button-fd8413b2.js');
12
15
  var design = require('@jobber/design');
13
- var isEmpty = require('lodash/isEmpty');
14
- var InlineLabel = require('../InlineLabel-afd5fc6f.js');
15
- var FormatDate = require('../FormatDate-70ea5b43.js');
16
- var Heading = require('../Heading-a1191b15.js');
17
- require('uuid');
18
- require('react-hook-form');
19
- var Checkbox = require('../Checkbox-3bccf65c.js');
20
16
  var Typography = require('../Typography-fd6f932a.js');
21
- require('react-router-dom');
22
- var Button = require('../Button-fd8413b2.js');
23
17
  var ReactDOM = require('react-dom');
24
18
  var Tooltip = require('../Tooltip-bf67fe6e.js');
25
19
  require('react-popper');
@@ -27,7 +21,14 @@ var useFocusTrap = require('@jobber/hooks/useFocusTrap');
27
21
  var useRefocusOnActivator = require('@jobber/hooks/useRefocusOnActivator');
28
22
  var useOnKeyDown = require('@jobber/hooks/useOnKeyDown');
29
23
  var foundation = require('@jobber/design/foundation');
30
- var noop = require('lodash/noop');
24
+ var styles$f = require('@jobber/components/DataList/DataList.css');
25
+ require('uuid');
26
+ require('react-hook-form');
27
+ var Checkbox = require('../Checkbox-3bccf65c.js');
28
+ var isEmpty = require('lodash/isEmpty');
29
+ var InlineLabel = require('../InlineLabel-afd5fc6f.js');
30
+ var FormatDate = require('../FormatDate-70ea5b43.js');
31
+ var Heading = require('../Heading-a1191b15.js');
31
32
  var AnimatedSwitcher = require('../AnimatedSwitcher-d1e1ddcf.js');
32
33
  var Icon = require('../Icon-405a216c.js');
33
34
  var useInView = require('@jobber/hooks/useInView');
@@ -50,12 +51,13 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
50
51
 
51
52
  var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
52
53
  var classnames__default = /*#__PURE__*/_interopDefaultLegacy(classnames);
53
- var isEmpty__default = /*#__PURE__*/_interopDefaultLegacy(isEmpty);
54
54
  var noop__default = /*#__PURE__*/_interopDefaultLegacy(noop);
55
+ var styles__default = /*#__PURE__*/_interopDefaultLegacy(styles$f);
56
+ var isEmpty__default = /*#__PURE__*/_interopDefaultLegacy(isEmpty);
55
57
  var debounce__default = /*#__PURE__*/_interopDefaultLegacy(debounce);
56
58
 
57
- var css_248z$e = ".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";
58
- var styles$e = {"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-"};
59
+ var css_248z$e = ".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/*\n * Header\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/*\n * List Item\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.ise8kHCfhCY-:hover,\n.ise8kHCfhCY-:focus-within {\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.Tq6e0BGwcSM- {\n display: block;\n margin: calc((16px / 2) * -1) 0;\n margin: calc(calc(16px / 2) * -1) 0;\n margin: calc(var(--space-small) * -1) 0;\n padding: calc(16px / 2) 0;\n padding: var(--space-small) 0;\n border: none;\n text-align: left;\n -webkit-text-decoration: none;\n text-decoration: none;\n background-color: transparent;\n cursor: pointer;\n}\n\n/**\n * Enable a better hover and focus experience when :has() is supported.\n * This is a workaround for Firefox where the :has() selector is not supported.\n */\n\n@supports selector(*:has(*)) {\n .ise8kHCfhCY-:hover,\n .ise8kHCfhCY-:focus-within {\n background-color: transparent;\n }\n\n .ise8kHCfhCY-:has(.Tq6e0BGwcSM-:hover, .Tq6e0BGwcSM-:focus) {\n background-color: var(--data-list-item-active-color);\n }\n}\n\n/*\n * List Item Selection\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 -ms-flex-order: 2;\n order: 2;\n}\n\n.ise8kHCfhCY- .d-79rkMqufg- > :last-child {\n -ms-flex-order: 1;\n order: 1;\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- > :last-child {\n padding-top: 0;\n opacity: 0;\n}\n }\n\n@media (--medium-screens-and-up) {\n\n.ise8kHCfhCY- .d-79rkMqufg- > :last-child {\n padding-top: 0;\n opacity: 0;\n}\n }\n\n.ise8kHCfhCY-:hover .d-79rkMqufg- > :last-child,\n.ise8kHCfhCY-:focus-within .d-79rkMqufg- > :last-child,\n.ise8kHCfhCY- .d-79rkMqufg-._4L7iXXzLr5k- > :last-child {\n opacity: 1;\n}\n\n/*\n * Filters\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";
60
+ var styles$e = {"wrapper":"TkdrExYnvcY-","titleContainer":"IcAlZHoB4LI-","headerFilters":"TFO76ysivmg-","headerTitles":"jGHZZYZm1ZY-","headerBatchSelect":"jMSVGIAr5tk-","listItem":"ise8kHCfhCY-","active":"Pc0JGX6jCD4-","listItemClickable":"Tq6e0BGwcSM-","selectable":"d-79rkMqufg-","selectAllCheckbox":"qm-SSuWTXkI-","visible":"VA9RnQp6nbI-","selected":"_4L7iXXzLr5k-","filtering":"Kkp-IYmwq-s-","filteringSpinner":"m-eCShL7TU4-"};
59
61
  styleInject_es.styleInject(css_248z$e);
60
62
 
61
63
  var css_248z$d = ".F56prQsXm3A- {\n min-width: 80px;\n margin-left: calc(16px / 2);\n margin-left: var(--space-small);\n}\n";
@@ -83,6 +85,53 @@ var css_248z$c = ".Rh--6fVpkm4- {\n padding: calc(16px / 2);\n padding: var(--
83
85
  var styles$c = {"loadingItem":"Rh--6fVpkm4-","mobileLoadingState":"zbS7UvpVoWI-"};
84
86
  styleInject_es.styleInject(css_248z$c);
85
87
 
88
+ const defaultValues$1 = {
89
+ title: "",
90
+ data: [],
91
+ headers: {},
92
+ children: [],
93
+ selected: [],
94
+ };
95
+ const DataListContext = React.createContext(defaultValues$1);
96
+ function useDataListContext() {
97
+ return React.useContext(DataListContext);
98
+ }
99
+
100
+ const defaultValues = {
101
+ isInLayoutProvider: false,
102
+ hasInLayoutActions: false,
103
+ setHasInLayoutActions: noop__default["default"],
104
+ };
105
+ const DataListLayoutContext = React.createContext(defaultValues);
106
+ function useDataListLayoutContext() {
107
+ return React.useContext(DataListLayoutContext);
108
+ }
109
+
110
+ var css_248z$b = ".jHcHGQ-HDbk- {\n display: -ms-flexbox;\n display: flex;\n position: absolute;\n top: calc((16px / 2) * -1);\n top: calc(calc(16px / 2) * -1);\n top: calc(var(--space-small) * -1);\n right: 0;\n z-index: 6;\n z-index: var(--elevation-menu);\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 padding: calc(16px / 4);\n padding: var(--space-smaller);\n border: calc(16px / 16) solid rgb(225, 225, 225);\n border: var(--border-base) solid var(--color-border);\n border-radius: calc(16px / 2);\n border-radius: var(--radius-larger);\n background-color: rgba(255, 255, 255, 1);\n background-color: var(--color-surface);\n gap: calc(16px / 4);\n gap: var(--space-smaller);\n}\n";
111
+ var styles$b = {"menu":"jHcHGQ-HDbk-"};
112
+ styleInject_es.styleInject(css_248z$b);
113
+
114
+ var css_248z$a = ".iyg43v-S9yU- {\n display: -ms-flexbox;\n display: flex;\n width: 100%;\n min-height: 44px;\n padding: calc(16px / 2);\n padding: var(--space-small);\n border: none;\n border-radius: 0;\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 text-align: left;\n background: none;\n cursor: pointer;\n transition: background 200ms ease;\n transition: background var(--timing-base) ease;\n -webkit-appearance: none;\n appearance: none;\n -ms-flex-align: center;\n align-items: center;\n gap: calc(16px / 2);\n gap: var(--space-small);\n}\n\n.iyg43v-S9yU-:hover,\n.iyg43v-S9yU-:focus {\n background-color: rgb(250, 246, 219);\n background-color: var(--color-surface--hover);\n}\n\n.AUJNqz93ZDA- {\n font-weight: 500;\n}\n";
115
+ var styles$a = {"action":"iyg43v-S9yU-","label":"AUJNqz93ZDA-"};
116
+ styleInject_es.styleInject(css_248z$a);
117
+
118
+ function DataListAction(
119
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
120
+ _) {
121
+ return null;
122
+ }
123
+ function InternalDataListAction({ label, icon, destructive, onClick, item, }) {
124
+ const color = destructive ? "critical" : "blue";
125
+ return (React__default["default"].createElement("button", { className: styles$a.action, onClick: () => onClick === null || onClick === void 0 ? void 0 : onClick(item) },
126
+ icon && React__default["default"].createElement(Icon.Icon, { name: icon, color: color }),
127
+ React__default["default"].createElement(Typography.Typography, { textColor: color },
128
+ React__default["default"].createElement("span", { className: styles$a.label }, label))));
129
+ }
130
+
131
+ var css_248z$9 = ".aokwZU8jbWU- {\n position: fixed;\n top: 0;\n top: var(--actions-menu-y, 0);\n left: 0;\n left: var(--actions-menu-x, 0);\n z-index: 6;\n z-index: var(--elevation-menu);\n min-width: 150px;\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 padding: calc(16px / 4);\n padding: var(--space-smaller);\n border: calc(16px / 16) solid rgb(225, 225, 225);\n border: var(--border-base) solid var(--color-border);\n border-radius: calc(16px / 2);\n border-radius: var(--radius-larger);\n background-color: rgba(255, 255, 255, 1);\n background-color: var(--color-surface);\n}\n\n.XtVRP97TVSE- {\n position: fixed;\n top: 0;\n left: 0;\n z-index: calc(6 - 1);\n z-index: calc(var(--elevation-menu) - 1);\n width: 100%;\n height: 100%;\n padding: 0;\n border: none;\n background-color: transparent;\n}\n";
132
+ var styles$9 = {"menu":"aokwZU8jbWU-","overlay":"XtVRP97TVSE-"};
133
+ styleInject_es.styleInject(css_248z$9);
134
+
86
135
  const EMPTY_RESULTS_MESSAGE = "List is looking empty";
87
136
  const EMPTY_FILTER_RESULTS_MESSAGE = "No results for selected filters";
88
137
  const EMPTY_STATE_ACTION_BUTTON_ONLY_ERROR = "DataListEmptyState action prop must be a Button component";
@@ -104,9 +153,166 @@ const DATA_LOAD_MORE_TEST_ID = "ATL-DataList-LoadMore-trigger";
104
153
  const TRANSITION_DURATION_IN_SECONDS = design.tokens["timing-base"] / 1000;
105
154
  const TRANSITION_DELAY_IN_SECONDS = design.tokens["timing-quick"] / 1000;
106
155
 
107
- var css_248z$b = ".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";
108
- var styles$b = {"tags":"WRV-UmQmPzo-","tagCount":"liQeWCMenD0-"};
109
- styleInject_es.styleInject(css_248z$b);
156
+ const variants$1 = {
157
+ hidden: { opacity: 0, y: -10 },
158
+ visible: { opacity: 1, y: 0 },
159
+ };
160
+ function DataListActionsMenu({ visible = false, position, onRequestClose, children, }) {
161
+ const [ref, setRef] = React.useState();
162
+ useRefocusOnActivator.useRefocusOnActivator(visible);
163
+ const focusTrapRef = useFocusTrap.useFocusTrap(visible);
164
+ useOnKeyDown.useOnKeyDown(onRequestClose, "Escape");
165
+ return ReactDOM.createPortal(React__default["default"].createElement(framerMotion.AnimatePresence, null, visible && (React__default["default"].createElement("div", { ref: focusTrapRef },
166
+ 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$9.menu, style: getPositionCssVars(), onClick: onRequestClose }, children),
167
+ React__default["default"].createElement("button", { className: styles$9.overlay, onClick: onRequestClose, "aria-label": "Close menu" })))), document.body);
168
+ function getPositionCssVars() {
169
+ const { posX, posY } = getPosition();
170
+ return {
171
+ "--actions-menu-x": `${posX}px`,
172
+ "--actions-menu-y": `${posY}px`,
173
+ };
174
+ }
175
+ function getPosition() {
176
+ const rect = ref === null || ref === void 0 ? void 0 : ref.getBoundingClientRect();
177
+ const { width = 0, height = 0 } = rect || {};
178
+ const { x = 0, y = 0 } = position;
179
+ const xIsOffScreen = x + width > window.innerWidth;
180
+ const yIsOffScreen = y + height > window.innerHeight;
181
+ const xOffSet = x + width - window.innerWidth + foundation.tokens["space-base"];
182
+ const yOffSet = y + height - window.innerHeight;
183
+ const newPosX = Math.floor(xIsOffScreen ? x - xOffSet : x);
184
+ const newPosY = Math.floor(yIsOffScreen ? y - yOffSet : y);
185
+ return { posX: newPosX, posY: newPosY };
186
+ }
187
+ }
188
+
189
+ function DataListItemActionsOverflow({ item, actions, }) {
190
+ const [menuPosition, setMenuPosition] = React.useState({ x: 0, y: 0 });
191
+ const [showMenu, setShowMenu] = React.useState(false);
192
+ return (React__default["default"].createElement(React__default["default"].Fragment, null,
193
+ React__default["default"].createElement(Tooltip.Tooltip, { message: "More actions" },
194
+ React__default["default"].createElement(Button.Button, { icon: "more", ariaLabel: "More actions", type: "secondary", variation: "subtle", onClick: handleMoreClick })),
195
+ item && (React__default["default"].createElement(DataListActionsMenu, { visible: showMenu, position: menuPosition, onRequestClose: handleClose }, React.Children.map(actions, action => (React__default["default"].createElement(InternalDataListAction, Object.assign({}, action.props, { item: item }))))))));
196
+ function handleMoreClick(event) {
197
+ setShowMenu(true);
198
+ const rect = event.currentTarget.getBoundingClientRect();
199
+ const posX = rect.x;
200
+ const posY = rect.y + rect.height;
201
+ setMenuPosition({ x: posX, y: posY });
202
+ }
203
+ function handleClose() {
204
+ setShowMenu(false);
205
+ }
206
+ }
207
+
208
+ // This component is meant to capture the props of the DataList.ItemActions
209
+ function DataListItemActions(
210
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
211
+ _) {
212
+ return null;
213
+ }
214
+ const variants = {
215
+ hidden: { opacity: 0, y: 10 },
216
+ visible: { opacity: 1, y: 0 },
217
+ };
218
+ function InternalDataListItemActions({ item, }) {
219
+ const { itemActionComponent } = useDataListContext();
220
+ if (!itemActionComponent)
221
+ return null;
222
+ const { children } = itemActionComponent.props;
223
+ const childrenArray = React.Children.toArray(children).filter(React.isValidElement);
224
+ const exposedActions = getExposedActions(childrenArray);
225
+ childrenArray.splice(0, exposedActions.length);
226
+ return (React__default["default"].createElement(framerMotion.motion.div, { variants: variants, initial: "hidden", animate: "visible", exit: "hidden", transition: {
227
+ duration: TRANSITION_DURATION_IN_SECONDS,
228
+ delay: TRANSITION_DELAY_IN_SECONDS,
229
+ }, className: styles$b.menu, onContextMenu: handleContextMenu },
230
+ exposedActions.map(({ props }) => {
231
+ if (!props.icon)
232
+ return null;
233
+ return (React__default["default"].createElement(Tooltip.Tooltip, { key: props.label, message: props.label },
234
+ React__default["default"].createElement(Button.Button, { icon: props.icon, ariaLabel: props.label, onClick: () => { var _a; return (_a = props.onClick) === null || _a === void 0 ? void 0 : _a.call(props, item); }, type: "secondary", variation: "subtle" })));
235
+ }),
236
+ React__default["default"].createElement(DataListItemActionsOverflow, { actions: childrenArray, item: item })));
237
+ }
238
+ function handleContextMenu(event) {
239
+ event.stopPropagation();
240
+ }
241
+ function getExposedActions(childrenArray) {
242
+ const firstTwoChildren = childrenArray.slice(0, 2);
243
+ return firstTwoChildren.reduce((result, child, i) => {
244
+ const hasIcon = Boolean(child.props.icon);
245
+ const isFirstChild = i === 0;
246
+ if (isFirstChild && hasIcon) {
247
+ return [...result, child];
248
+ }
249
+ const isSecondChild = i === 1;
250
+ const hasFirstChild = result.length === 1;
251
+ if (isSecondChild && hasIcon && hasFirstChild) {
252
+ return [...result, child];
253
+ }
254
+ return result;
255
+ }, []);
256
+ }
257
+
258
+ const DataListLayoutActionsContext = React.createContext({ activeItem: undefined });
259
+ function useDataListLayoutActionsContext() {
260
+ return React.useContext(DataListLayoutActionsContext);
261
+ }
262
+
263
+ function DataListItemInternal({ children, item, }) {
264
+ const { selected, onSelect } = useDataListContext();
265
+ if (selected !== undefined && onSelect) {
266
+ return (React__default["default"].createElement("div", { className: classnames__default["default"](styles__default["default"].selectable, {
267
+ [styles__default["default"].selected]: selected === null || selected === void 0 ? void 0 : selected.length,
268
+ }) },
269
+ children,
270
+ React__default["default"].createElement(Checkbox.Checkbox, { checked: selected === null || selected === void 0 ? void 0 : selected.includes(item.id), onChange: handleChange })));
271
+ }
272
+ return children;
273
+ function handleChange() {
274
+ if (selected === null || selected === void 0 ? void 0 : selected.includes(item.id)) {
275
+ onSelect === null || onSelect === void 0 ? void 0 : onSelect(selected === null || selected === void 0 ? void 0 : selected.filter(id => id !== item.id));
276
+ }
277
+ else if (selected) {
278
+ onSelect === null || onSelect === void 0 ? void 0 : onSelect([...selected, item.id]);
279
+ }
280
+ }
281
+ }
282
+
283
+ function DataListItemClickableInternal({ onClick, url, to, children, }) {
284
+ const { activeItem } = useDataListLayoutActionsContext();
285
+ if (!activeItem)
286
+ return React__default["default"].createElement(React__default["default"].Fragment, null, children);
287
+ if (to) {
288
+ const computedTo = typeof to === "string" ? to : to(activeItem);
289
+ return (React__default["default"].createElement(reactRouterDom.Link, { className: styles__default["default"].listItemClickable, to: computedTo, onClick: handleClick }, children));
290
+ }
291
+ if (url) {
292
+ const href = typeof url === "string" ? url : url(activeItem);
293
+ return (React__default["default"].createElement("a", { className: styles__default["default"].listItemClickable, href: href, onClick: handleClick }, children));
294
+ }
295
+ if (onClick) {
296
+ return (React__default["default"].createElement("button", { className: styles__default["default"].listItemClickable, onClick: handleClick }, children));
297
+ }
298
+ return React__default["default"].createElement(React__default["default"].Fragment, null, children);
299
+ function handleClick() {
300
+ activeItem && (onClick === null || onClick === void 0 ? void 0 : onClick(activeItem));
301
+ }
302
+ }
303
+
304
+ function DataListItemClickable({ children }) {
305
+ const { itemActionComponent } = useDataListContext();
306
+ if (itemActionComponent) {
307
+ const props = itemActionComponent.props;
308
+ return (React__default["default"].createElement(DataListItemClickableInternal, Object.assign({}, props), children));
309
+ }
310
+ return React__default["default"].createElement(React__default["default"].Fragment, null, children);
311
+ }
312
+
313
+ var css_248z$8 = ".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";
314
+ var styles$8 = {"tags":"WRV-UmQmPzo-","tagCount":"liQeWCMenD0-"};
315
+ styleInject_es.styleInject(css_248z$8);
110
316
 
111
317
  function DataListTags({ items }) {
112
318
  const ref = React.useRef(null);
@@ -126,10 +332,10 @@ function DataListTags({ items }) {
126
332
  elements === null || elements === void 0 ? void 0 : elements.forEach(element => observer.unobserve(element));
127
333
  };
128
334
  }, [items]);
129
- return (React__default["default"].createElement("div", { className: styles$b.tags, ref: ref },
335
+ return (React__default["default"].createElement("div", { className: styles$8.tags, ref: ref },
130
336
  items.filter(Boolean).map((tag, index) => (React__default["default"].createElement("div", { key: tag, "data-tag-element": index },
131
337
  React__default["default"].createElement(InlineLabel.InlineLabel, null, tag)))),
132
- Boolean(visibleItems) && (React__default["default"].createElement("div", { className: styles$b.tagCount },
338
+ Boolean(visibleItems) && (React__default["default"].createElement("div", { className: styles$8.tagCount },
133
339
  React__default["default"].createElement(Text.Text, null,
134
340
  "+",
135
341
  visibleItems)))));
@@ -158,44 +364,32 @@ function buildIntersectionThreshold(items) {
158
364
  return thresholds;
159
365
  }
160
366
 
161
- var css_248z$a = ".fLmJZJJqMcE- {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-align: center;\n align-items: center;\n padding: 0;\n border: none;\n background-color: transparent;\n}\n\n.UG8cHUT3Hds- {\n cursor: pointer;\n}\n";
162
- var styles$a = {"headerLabel":"fLmJZJJqMcE-","sortable":"UG8cHUT3Hds-"};
163
- styleInject_es.styleInject(css_248z$a);
367
+ var css_248z$7 = ".fLmJZJJqMcE- {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-align: center;\n align-items: center;\n padding: 0;\n border: none;\n background-color: transparent;\n}\n\n.UG8cHUT3Hds- {\n cursor: pointer;\n}\n";
368
+ var styles$7 = {"headerLabel":"fLmJZJJqMcE-","sortable":"UG8cHUT3Hds-"};
369
+ styleInject_es.styleInject(css_248z$7);
164
370
 
165
- var css_248z$9 = ".AN5egORYy-0- {\n padding-right: calc(16px / 2);\n padding-right: var(--space-small);\n}\n\n.AN5egORYy-0- path {\n fill: rgba(101, 120, 132, 1);\n fill: var(--color-greyBlue);\n transition: all 200ms ease;\n transition: all var(--timing-base) ease;\n}\n\n.AN5egORYy-0- path.F1uTDCK0Sb0- {\n fill: rgb(1, 41, 57);\n fill: var(--color-blue);\n}\n\n.AN5egORYy-0- path._6KYeQXWXLQ8- {\n fill: rgb(193, 201, 206);\n fill: var(--color-greyBlue--lighter);\n}\n";
166
- var styles$9 = {"sortIcon":"AN5egORYy-0-","active":"F1uTDCK0Sb0-","inactive":"_6KYeQXWXLQ8-"};
167
- styleInject_es.styleInject(css_248z$9);
371
+ var css_248z$6 = ".AN5egORYy-0- {\n padding-right: calc(16px / 2);\n padding-right: var(--space-small);\n}\n\n.AN5egORYy-0- path {\n fill: rgba(101, 120, 132, 1);\n fill: var(--color-greyBlue);\n transition: all 200ms ease;\n transition: all var(--timing-base) ease;\n}\n\n.AN5egORYy-0- path.F1uTDCK0Sb0- {\n fill: rgb(1, 41, 57);\n fill: var(--color-blue);\n}\n\n.AN5egORYy-0- path._6KYeQXWXLQ8- {\n fill: rgb(193, 201, 206);\n fill: var(--color-greyBlue--lighter);\n}\n";
372
+ var styles$6 = {"sortIcon":"AN5egORYy-0-","active":"F1uTDCK0Sb0-","inactive":"_6KYeQXWXLQ8-"};
373
+ styleInject_es.styleInject(css_248z$6);
168
374
 
169
375
  const SORTING_ICON_TEST_ID = "ATL-DataList-Sorting-Icon";
170
376
  function DataListSortingArrows({ order }) {
171
- return (React__default["default"].createElement("div", { className: styles$9.sortIcon, "data-testid": SORTING_ICON_TEST_ID },
377
+ return (React__default["default"].createElement("div", { className: styles$6.sortIcon, "data-testid": SORTING_ICON_TEST_ID },
172
378
  React__default["default"].createElement("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg" },
173
379
  React__default["default"].createElement("path", { className: getActiveClassName("asc"), d: "M16.2929 10.6661C15.9024 11.0566 15.2692 11.0566 14.8787 10.6661L12.2891 8.14263L9.70711 10.6661C9.31658 11.0566 8.68342 11.0566 8.29289 10.6661C7.90237 10.2756 7.90237 9.64239 8.29289 9.25186L11.5858 5.95897C11.9763 5.56845 12.6095 5.56845 13 5.95897L16.2929 9.25186C16.6834 9.64239 16.6834 10.2756 16.2929 10.6661Z" }),
174
380
  React__default["default"].createElement("path", { className: getActiveClassName("desc"), d: "M8.29292 13.3339C8.68345 12.9434 9.31661 12.9434 9.70714 13.3339L12.2968 15.8573L14.8787 13.3339C15.2692 12.9434 15.9024 12.9434 16.2929 13.3339C16.6834 13.7244 16.6834 14.3576 16.2929 14.7481L13 18.041C12.6095 18.4315 11.9763 18.4315 11.5858 18.041L8.29292 14.7481C7.9024 14.3576 7.9024 13.7244 8.29292 13.3339Z" }))));
175
381
  function getActiveClassName(targetOrder) {
176
- return order === targetOrder ? styles$9.active : styles$9.inactive;
382
+ return order === targetOrder ? styles$6.active : styles$6.inactive;
177
383
  }
178
384
  }
179
385
 
180
- const defaultValues$1 = {
181
- title: "",
182
- data: [],
183
- headers: {},
184
- children: [],
185
- selected: [],
186
- };
187
- const DataListContext = React.createContext(defaultValues$1);
188
- function useDataListContext() {
189
- return React.useContext(DataListContext);
190
- }
191
-
192
386
  function DataListHeaderTile({ headers, headerKey, }) {
193
387
  const { sorting } = useDataListContext();
194
388
  const isSortable = sorting === null || sorting === void 0 ? void 0 : sorting.sortable.includes(headerKey);
195
389
  const sortingState = sorting === null || sorting === void 0 ? void 0 : sorting.state;
196
390
  const Tag = isSortable ? "button" : "div";
197
- return (React__default["default"].createElement(Tag, { className: classnames__default["default"](styles$a.headerLabel, {
198
- [styles$a.sortable]: isSortable,
391
+ return (React__default["default"].createElement(Tag, { className: classnames__default["default"](styles$7.headerLabel, {
392
+ [styles$7.sortable]: isSortable,
199
393
  }), onClick: handleOnClick },
200
394
  React__default["default"].createElement(Text.Text, { maxLines: "single" }, headers[headerKey]),
201
395
  (sortingState === null || sortingState === void 0 ? void 0 : sortingState.key) === headerKey && (React__default["default"].createElement(DataListSortingArrows, { order: sortingState.order }))));
@@ -234,10 +428,10 @@ function getCompoundComponents(children, type) {
234
428
  return elements;
235
429
  }
236
430
  /**
237
- * Generate the default elements the DataList would use on the data provided.
431
+ * Generate the default element the DataList would use on the data provided.
238
432
  */
239
- function generateListItemElements(data) {
240
- return data.map(item => Object.keys(item).reduce((acc, key) => {
433
+ function generateListItemElement(item) {
434
+ return Object.keys(item).reduce((acc, key) => {
241
435
  const currentItem = item[key];
242
436
  if (!currentItem) {
243
437
  return acc;
@@ -259,7 +453,7 @@ function generateListItemElements(data) {
259
453
  acc[key] = React__default["default"].createElement(Text.Text, { variation: "subdued" }, currentItem);
260
454
  }
261
455
  return acc;
262
- }, {}));
456
+ }, {});
263
457
  }
264
458
  /**
265
459
  * Generate the header elements with the default styling
@@ -272,6 +466,42 @@ function sortSizeProp(sizeProp) {
272
466
  return sizeProp.sort((a, b) => BREAKPOINTS.indexOf(a) - BREAKPOINTS.indexOf(b));
273
467
  }
274
468
 
469
+ function DataListItem({ item, layout, }) {
470
+ const { itemActionComponent } = useDataListContext();
471
+ const { hasInLayoutActions } = useDataListLayoutContext();
472
+ const [showMenu, setShowMenu] = React.useState(false);
473
+ const [contextPosition, setContextPosition] = React.useState();
474
+ const generatedItem = React.useMemo(() => generateListItemElement(item), [item]);
475
+ const contextMenuActions = itemActionComponent === null || itemActionComponent === void 0 ? void 0 : itemActionComponent.props.children;
476
+ const isContextMenuVisible = Boolean(contextPosition);
477
+ const shouldShowContextMenu = showMenu && isContextMenuVisible && Boolean(contextMenuActions);
478
+ return (React__default["default"].createElement(DataListLayoutActionsContext.Provider, { value: { activeItem: item } },
479
+ React__default["default"].createElement("div", { onMouseEnter: handleShowMenu, onMouseLeave: handleHideMenu, onFocus: handleShowMenu, onBlur: handleHideMenu, onContextMenu: handleContextMenu, className: classnames__default["default"](styles__default["default"].listItem, {
480
+ [styles__default["default"].active]: showMenu && isContextMenuVisible,
481
+ }), key: item.id },
482
+ React__default["default"].createElement(DataListItemInternal, { item: item },
483
+ React__default["default"].createElement(DataListItemClickable, null, layout.props.children(generatedItem))),
484
+ React__default["default"].createElement(framerMotion.AnimatePresence, null,
485
+ showMenu && !hasInLayoutActions && (React__default["default"].createElement(InternalDataListItemActions, { item: item })),
486
+ React__default["default"].createElement(DataListActionsMenu, { key: item.id, visible: shouldShowContextMenu, position: contextPosition || { x: 0, y: 0 }, onRequestClose: () => setContextPosition(undefined) }, contextMenuActions &&
487
+ React.Children.map(contextMenuActions, action => (React__default["default"].createElement(InternalDataListAction, Object.assign({ key: item.id }, action.props, { item: item })))))))));
488
+ function handleShowMenu() {
489
+ setShowMenu(true);
490
+ }
491
+ function handleHideMenu() {
492
+ setShowMenu(false);
493
+ }
494
+ function handleContextMenu(event) {
495
+ if (!contextMenuActions || isContextMenuVisible)
496
+ return;
497
+ event.preventDefault();
498
+ setContextPosition({
499
+ x: event.clientX,
500
+ y: event.clientY,
501
+ });
502
+ }
503
+ }
504
+
275
505
  function DataListLayoutInternal({ layouts, renderLayout, mediaMatches, }) {
276
506
  const sizePropsOfLayouts = layouts === null || layouts === void 0 ? void 0 : layouts.map(layout => layout.props.size || "xs");
277
507
  const layoutToRender = layouts === null || layouts === void 0 ? void 0 : layouts.find(layout => {
@@ -304,216 +534,14 @@ function isLayoutVisible({ layoutSize, mediaMatches, sizePropsOfLayouts, }) {
304
534
  return isVisibleBreakpoint && largerLayoutIsNotVisible;
305
535
  }
306
536
 
307
- function DataListItemInternal({ children, item, }) {
308
- const { selected, onSelect } = useDataListContext();
309
- if (selected !== undefined && onSelect) {
310
- return (React__default["default"].createElement("div", { className: classnames__default["default"](styles$e.selectable, {
311
- [styles$e.selected]: selected === null || selected === void 0 ? void 0 : selected.length,
312
- }) },
313
- React__default["default"].createElement(Checkbox.Checkbox, { checked: selected === null || selected === void 0 ? void 0 : selected.includes(item.id), onChange: handleChange }),
314
- children));
315
- }
316
- return children;
317
- function handleChange() {
318
- if (selected === null || selected === void 0 ? void 0 : selected.includes(item.id)) {
319
- onSelect === null || onSelect === void 0 ? void 0 : onSelect(selected === null || selected === void 0 ? void 0 : selected.filter(id => id !== item.id));
320
- }
321
- else if (selected) {
322
- onSelect === null || onSelect === void 0 ? void 0 : onSelect([...selected, item.id]);
323
- }
324
- }
325
- }
326
-
327
- var css_248z$8 = ".jHcHGQ-HDbk- {\n display: -ms-flexbox;\n display: flex;\n position: absolute;\n top: calc((16px / 2) * -1);\n top: calc(calc(16px / 2) * -1);\n top: calc(var(--space-small) * -1);\n right: 0;\n z-index: 6;\n z-index: var(--elevation-menu);\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 padding: calc(16px / 4);\n padding: var(--space-smaller);\n border: calc(16px / 16) solid rgb(225, 225, 225);\n border: var(--border-base) solid var(--color-border);\n border-radius: calc(16px / 2);\n border-radius: var(--radius-larger);\n background-color: rgba(255, 255, 255, 1);\n background-color: var(--color-surface);\n gap: calc(16px / 4);\n gap: var(--space-smaller);\n}\n";
328
- var styles$8 = {"menu":"jHcHGQ-HDbk-"};
329
- styleInject_es.styleInject(css_248z$8);
330
-
331
- var css_248z$7 = ".iyg43v-S9yU- {\n display: -ms-flexbox;\n display: flex;\n width: 100%;\n min-height: 44px;\n padding: calc(16px / 2);\n padding: var(--space-small);\n border: none;\n border-radius: 0;\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 text-align: left;\n background: none;\n cursor: pointer;\n transition: background 200ms ease;\n transition: background var(--timing-base) ease;\n -webkit-appearance: none;\n appearance: none;\n -ms-flex-align: center;\n align-items: center;\n gap: calc(16px / 2);\n gap: var(--space-small);\n}\n\n.iyg43v-S9yU-:hover,\n.iyg43v-S9yU-:focus {\n background-color: rgb(250, 246, 219);\n background-color: var(--color-surface--hover);\n}\n\n.AUJNqz93ZDA- {\n font-weight: 500;\n}\n";
332
- var styles$7 = {"action":"iyg43v-S9yU-","label":"AUJNqz93ZDA-"};
333
- styleInject_es.styleInject(css_248z$7);
334
-
335
- function DataListAction(
336
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
337
- _) {
338
- return null;
339
- }
340
- function InternalDataListAction({ label, icon, destructive, onClick, item, }) {
341
- const color = destructive ? "critical" : "blue";
342
- return (React__default["default"].createElement("button", { className: styles$7.action, onClick: () => onClick === null || onClick === void 0 ? void 0 : onClick(item) },
343
- icon && React__default["default"].createElement(Icon.Icon, { name: icon, color: color }),
344
- React__default["default"].createElement(Typography.Typography, { textColor: color },
345
- React__default["default"].createElement("span", { className: styles$7.label }, label))));
346
- }
347
-
348
- var css_248z$6 = ".aokwZU8jbWU- {\n position: fixed;\n top: 0;\n top: var(--actions-menu-y, 0);\n left: 0;\n left: var(--actions-menu-x, 0);\n z-index: 6;\n z-index: var(--elevation-menu);\n min-width: 150px;\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 padding: calc(16px / 4);\n padding: var(--space-smaller);\n border: calc(16px / 16) solid rgb(225, 225, 225);\n border: var(--border-base) solid var(--color-border);\n border-radius: calc(16px / 2);\n border-radius: var(--radius-larger);\n background-color: rgba(255, 255, 255, 1);\n background-color: var(--color-surface);\n}\n\n.XtVRP97TVSE- {\n position: fixed;\n top: 0;\n left: 0;\n z-index: 6;\n z-index: var(--elevation-menu);\n width: 100%;\n height: 100%;\n}\n";
349
- var styles$6 = {"menu":"aokwZU8jbWU-","overlay":"XtVRP97TVSE-"};
350
- styleInject_es.styleInject(css_248z$6);
351
-
352
- const variants$1 = {
353
- hidden: { opacity: 0, y: -10 },
354
- visible: { opacity: 1, y: 0 },
355
- };
356
- function DataListActionsMenu({ visible = false, position, onRequestClose, children, }) {
357
- const [ref, setRef] = React.useState();
358
- useRefocusOnActivator.useRefocusOnActivator(visible);
359
- const focusTrapRef = useFocusTrap.useFocusTrap(visible);
360
- useOnKeyDown.useOnKeyDown(onRequestClose, "Escape");
361
- return ReactDOM.createPortal(React__default["default"].createElement(framerMotion.AnimatePresence, null, visible && (React__default["default"].createElement(React__default["default"].Fragment, null,
362
- React__default["default"].createElement("div", { className: styles$6.overlay, onClick: onRequestClose }),
363
- 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$6.menu, style: getPositionCssVars(), onClick: onRequestClose },
364
- React__default["default"].createElement("div", { tabIndex: 0, ref: focusTrapRef }, children))))), document.body);
365
- function getPositionCssVars() {
366
- const { posX, posY } = getPosition();
367
- return {
368
- "--actions-menu-x": `${posX}px`,
369
- "--actions-menu-y": `${posY}px`,
370
- };
371
- }
372
- function getPosition() {
373
- const rect = ref === null || ref === void 0 ? void 0 : ref.getBoundingClientRect();
374
- const { width = 0, height = 0 } = rect || {};
375
- const { x = 0, y = 0 } = position;
376
- const xIsOffScreen = x + width > window.innerWidth;
377
- const yIsOffScreen = y + height > window.innerHeight;
378
- const xOffSet = x + width - window.innerWidth + foundation.tokens["space-base"];
379
- const yOffSet = y + height - window.innerHeight;
380
- const newPosX = Math.floor(xIsOffScreen ? x - xOffSet : x);
381
- const newPosY = Math.floor(yIsOffScreen ? y - yOffSet : y);
382
- return { posX: newPosX, posY: newPosY };
383
- }
384
- }
385
-
386
- function DataListItemActionsOverflow({ item, actions, }) {
387
- const [menuPosition, setMenuPosition] = React.useState({ x: 0, y: 0 });
388
- const [showMenu, setShowMenu] = React.useState(false);
389
- return (React__default["default"].createElement(React__default["default"].Fragment, null,
390
- React__default["default"].createElement(Tooltip.Tooltip, { message: "More actions" },
391
- React__default["default"].createElement(Button.Button, { icon: "more", ariaLabel: "More actions", type: "secondary", variation: "subtle", onClick: handleMoreClick })),
392
- item && (React__default["default"].createElement(DataListActionsMenu, { visible: showMenu, position: menuPosition, onRequestClose: handleClose }, React.Children.map(actions, action => (React__default["default"].createElement(InternalDataListAction, Object.assign({}, action.props, { item: item }))))))));
393
- function handleMoreClick(event) {
394
- setShowMenu(true);
395
- const rect = event.currentTarget.getBoundingClientRect();
396
- const posX = rect.x;
397
- const posY = rect.y + rect.height;
398
- setMenuPosition({ x: posX, y: posY });
399
- }
400
- function handleClose() {
401
- setShowMenu(false);
402
- }
403
- }
404
-
405
- // This component is meant to capture the props of the DataList.ItemActions
406
- function DataListItemActions(
407
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
408
- _) {
409
- return null;
410
- }
411
- const variants = {
412
- hidden: { opacity: 0, y: 10 },
413
- visible: { opacity: 1, y: 0 },
414
- };
415
- function InternalDataListItemActions({ item, }) {
416
- const { itemActionComponent } = useDataListContext();
417
- if (!itemActionComponent)
418
- return null;
419
- const { children } = itemActionComponent.props;
420
- const childrenArray = React.Children.toArray(children).filter(React.isValidElement);
421
- const exposedActions = getExposedActions(childrenArray);
422
- childrenArray.splice(0, exposedActions.length);
423
- return (React__default["default"].createElement(framerMotion.motion.div, { variants: variants, initial: "hidden", animate: "visible", exit: "hidden", transition: {
424
- duration: TRANSITION_DURATION_IN_SECONDS,
425
- delay: TRANSITION_DELAY_IN_SECONDS,
426
- }, className: styles$8.menu, onContextMenu: handleContextMenu },
427
- exposedActions.map(({ props }) => {
428
- if (!props.icon)
429
- return null;
430
- return (React__default["default"].createElement(Tooltip.Tooltip, { key: props.label, message: props.label },
431
- React__default["default"].createElement(Button.Button, { icon: props.icon, ariaLabel: props.label, onClick: () => { var _a; return (_a = props.onClick) === null || _a === void 0 ? void 0 : _a.call(props, item); }, type: "secondary", variation: "subtle" })));
432
- }),
433
- React__default["default"].createElement(DataListItemActionsOverflow, { actions: childrenArray, item: item })));
434
- }
435
- function handleContextMenu(event) {
436
- event.stopPropagation();
437
- }
438
- function getExposedActions(childrenArray) {
439
- const firstTwoChildren = childrenArray.slice(0, 2);
440
- return firstTwoChildren.reduce((result, child, i) => {
441
- const hasIcon = Boolean(child.props.icon);
442
- const isFirstChild = i === 0;
443
- if (isFirstChild && hasIcon) {
444
- return [...result, child];
445
- }
446
- const isSecondChild = i === 1;
447
- const hasFirstChild = result.length === 1;
448
- if (isSecondChild && hasIcon && hasFirstChild) {
449
- return [...result, child];
450
- }
451
- return result;
452
- }, []);
453
- }
454
-
455
- const defaultValues = {
456
- isInLayoutProvider: false,
457
- hasInLayoutActions: false,
458
- setHasInLayoutActions: noop__default["default"],
459
- };
460
- const DataListLayoutContext = React.createContext(defaultValues);
461
- function useDataListLayoutContext() {
462
- return React.useContext(DataListLayoutContext);
463
- }
464
-
465
537
  function DataListItems({ layouts, mediaMatches, data, }) {
466
- const { itemActionComponent } = useDataListContext();
467
- const elementData = React.useMemo(() => generateListItemElements(data), [data]);
468
538
  const [hasInLayoutActions, setHasInLayoutActions] = React.useState(false);
469
- const [activeID, setActiveID] = React.useState();
470
- const [activeItem, setActiveItem] = React.useState();
471
- const [contextPosition, setContextPosition] = React.useState();
472
- const contextMenuActions = itemActionComponent === null || itemActionComponent === void 0 ? void 0 : itemActionComponent.props.children;
473
- const isContextMenuVisible = Boolean(contextPosition);
474
539
  return (React__default["default"].createElement(DataListLayoutContext.Provider, { value: {
475
540
  isInLayoutProvider: true,
476
541
  hasInLayoutActions,
477
542
  setHasInLayoutActions,
478
- activeItem,
479
543
  } },
480
- React__default["default"].createElement(DataListLayoutInternal, { layouts: layouts, mediaMatches: mediaMatches, renderLayout: layout => (React__default["default"].createElement(React__default["default"].Fragment, null, elementData.map((child, i) => {
481
- const item = data[i];
482
- const isActive = activeID === item.id;
483
- const shouldShowContextMenu = isActive && isContextMenuVisible && Boolean(contextMenuActions);
484
- return (React__default["default"].createElement("div", {
485
- // Set the active item whenever the element or any of its
486
- // children are clicked
487
- onClick: handleSetActiveItem(item), onMouseEnter: handleSetActiveItem(item), onMouseLeave: handleUnsetActiveItem, onContextMenu: handleContextMenu, className: classnames__default["default"](styles$e.listItem, {
488
- [styles$e.active]: isActive && isContextMenuVisible,
489
- }), key: item.id },
490
- React__default["default"].createElement(DataListItemInternal, { item: data[i] }, layout.props.children(child)),
491
- React__default["default"].createElement(framerMotion.AnimatePresence, null,
492
- activeID === item.id && !hasInLayoutActions && (React__default["default"].createElement(InternalDataListItemActions, { item: item })),
493
- React__default["default"].createElement(DataListActionsMenu, { key: item.id, visible: shouldShowContextMenu, position: contextPosition || { x: 0, y: 0 }, onRequestClose: () => setContextPosition(undefined) }, contextMenuActions &&
494
- React.Children.map(contextMenuActions, action => (React__default["default"].createElement(InternalDataListAction, Object.assign({ key: item.id }, action.props, { item: item }))))))));
495
- }))) })));
496
- function handleSetActiveItem(item) {
497
- return () => {
498
- setActiveID(item.id);
499
- setActiveItem(item);
500
- };
501
- }
502
- function handleUnsetActiveItem() {
503
- if (isContextMenuVisible)
504
- return;
505
- setActiveID(undefined);
506
- setActiveItem(undefined);
507
- }
508
- function handleContextMenu(event) {
509
- if (!contextMenuActions || isContextMenuVisible)
510
- return;
511
- event.preventDefault();
512
- setContextPosition({
513
- x: event.clientX,
514
- y: event.clientY,
515
- });
516
- }
544
+ React__default["default"].createElement(DataListLayoutInternal, { layouts: layouts, mediaMatches: mediaMatches, renderLayout: layout => (React__default["default"].createElement(React__default["default"].Fragment, null, data.map((child, i) => (React__default["default"].createElement(DataListItem, { key: data[i].id, index: i, item: child, layout: layout }))))) })));
517
545
  }
518
546
 
519
547
  function DataListHeaderCheckbox({ children }) {
@@ -849,7 +877,8 @@ styleInject_es.styleInject(css_248z);
849
877
 
850
878
  function DataListLayoutActions() {
851
879
  const { itemActionComponent } = useDataListContext();
852
- const { setHasInLayoutActions, activeItem } = useDataListLayoutContext();
880
+ const { setHasInLayoutActions } = useDataListLayoutContext();
881
+ const { activeItem } = useDataListLayoutActionsContext();
853
882
  const { children: actionsChildren } = (itemActionComponent === null || itemActionComponent === void 0 ? void 0 : itemActionComponent.props) || {};
854
883
  const actions = React.Children.toArray(actionsChildren);
855
884
  const hasActions = actions.length > 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jobber/components",
3
- "version": "4.42.0",
3
+ "version": "4.43.0",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -21,7 +21,7 @@
21
21
  "dependencies": {
22
22
  "@jobber/design": "^0.45.0",
23
23
  "@jobber/formatters": "*",
24
- "@jobber/hooks": "^2.3.0",
24
+ "@jobber/hooks": "^2.4.0",
25
25
  "@popperjs/core": "^2.0.6",
26
26
  "@std-proposal/temporal": "0.0.1",
27
27
  "@tanstack/react-table": "8.5.13",
@@ -84,5 +84,5 @@
84
84
  "> 1%",
85
85
  "IE 10"
86
86
  ],
87
- "gitHead": "685c933bb0a179c249ae5207070afe579efe55b5"
87
+ "gitHead": "f9530a9ef052c5a914c9c9270260b372b720ecf4"
88
88
  }