@jobber/components 4.42.0 → 4.42.1

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.
@@ -148,9 +148,8 @@ export interface DataListContextProps<T extends DataListObject> extends DataList
148
148
  readonly layoutComponents?: ReactElement<DataListLayoutProps<T>>[];
149
149
  readonly itemActionComponent?: ReactElement<DataListItemActionsProps<T>>;
150
150
  }
151
- export interface DataListLayoutContextProps<T extends DataListObject> {
151
+ export interface DataListLayoutContextProps {
152
152
  readonly isInLayoutProvider: boolean;
153
- readonly activeItem?: T;
154
153
  /**
155
154
  * Determine if the consumer of the DataList manually added an action to the
156
155
  * layout. This is used to determine if the DataList should render the
@@ -159,6 +158,9 @@ export interface DataListLayoutContextProps<T extends DataListObject> {
159
158
  readonly hasInLayoutActions: boolean;
160
159
  readonly setHasInLayoutActions: (state: boolean) => void;
161
160
  }
161
+ export interface DataListLayoutActionsContextProps<T extends DataListObject> {
162
+ readonly activeItem?: T;
163
+ }
162
164
  type Fragment<T> = T | T[];
163
165
  export interface DataListItemActionsProps<T extends DataListObject> {
164
166
  /**
@@ -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 @@
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(): DataListLayoutActionsContextProps<DataListObject>;
@@ -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 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
- var Typography = require('../Typography-fd6f932a.js');
12
+ var noop = require('lodash/noop');
21
13
  require('react-router-dom');
22
14
  var Button = require('../Button-fd8413b2.js');
15
+ var design = require('@jobber/design');
16
+ var Typography = require('../Typography-fd6f932a.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,8 +51,9 @@ 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
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.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";
@@ -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: 6;\n z-index: var(--elevation-menu);\n width: 100%;\n height: 100%;\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,137 @@ 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(React__default["default"].Fragment, null,
166
+ React__default["default"].createElement("div", { className: styles$9.overlay, onClick: onRequestClose }),
167
+ 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 },
168
+ React__default["default"].createElement("div", { tabIndex: 0, ref: focusTrapRef }, children))))), document.body);
169
+ function getPositionCssVars() {
170
+ const { posX, posY } = getPosition();
171
+ return {
172
+ "--actions-menu-x": `${posX}px`,
173
+ "--actions-menu-y": `${posY}px`,
174
+ };
175
+ }
176
+ function getPosition() {
177
+ const rect = ref === null || ref === void 0 ? void 0 : ref.getBoundingClientRect();
178
+ const { width = 0, height = 0 } = rect || {};
179
+ const { x = 0, y = 0 } = position;
180
+ const xIsOffScreen = x + width > window.innerWidth;
181
+ const yIsOffScreen = y + height > window.innerHeight;
182
+ const xOffSet = x + width - window.innerWidth + foundation.tokens["space-base"];
183
+ const yOffSet = y + height - window.innerHeight;
184
+ const newPosX = Math.floor(xIsOffScreen ? x - xOffSet : x);
185
+ const newPosY = Math.floor(yIsOffScreen ? y - yOffSet : y);
186
+ return { posX: newPosX, posY: newPosY };
187
+ }
188
+ }
189
+
190
+ function DataListItemActionsOverflow({ item, actions, }) {
191
+ const [menuPosition, setMenuPosition] = React.useState({ x: 0, y: 0 });
192
+ const [showMenu, setShowMenu] = React.useState(false);
193
+ return (React__default["default"].createElement(React__default["default"].Fragment, null,
194
+ React__default["default"].createElement(Tooltip.Tooltip, { message: "More actions" },
195
+ React__default["default"].createElement(Button.Button, { icon: "more", ariaLabel: "More actions", type: "secondary", variation: "subtle", onClick: handleMoreClick })),
196
+ 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 }))))))));
197
+ function handleMoreClick(event) {
198
+ setShowMenu(true);
199
+ const rect = event.currentTarget.getBoundingClientRect();
200
+ const posX = rect.x;
201
+ const posY = rect.y + rect.height;
202
+ setMenuPosition({ x: posX, y: posY });
203
+ }
204
+ function handleClose() {
205
+ setShowMenu(false);
206
+ }
207
+ }
208
+
209
+ // This component is meant to capture the props of the DataList.ItemActions
210
+ function DataListItemActions(
211
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
212
+ _) {
213
+ return null;
214
+ }
215
+ const variants = {
216
+ hidden: { opacity: 0, y: 10 },
217
+ visible: { opacity: 1, y: 0 },
218
+ };
219
+ function InternalDataListItemActions({ item, }) {
220
+ const { itemActionComponent } = useDataListContext();
221
+ if (!itemActionComponent)
222
+ return null;
223
+ const { children } = itemActionComponent.props;
224
+ const childrenArray = React.Children.toArray(children).filter(React.isValidElement);
225
+ const exposedActions = getExposedActions(childrenArray);
226
+ childrenArray.splice(0, exposedActions.length);
227
+ return (React__default["default"].createElement(framerMotion.motion.div, { variants: variants, initial: "hidden", animate: "visible", exit: "hidden", transition: {
228
+ duration: TRANSITION_DURATION_IN_SECONDS,
229
+ delay: TRANSITION_DELAY_IN_SECONDS,
230
+ }, className: styles$b.menu, onContextMenu: handleContextMenu },
231
+ exposedActions.map(({ props }) => {
232
+ if (!props.icon)
233
+ return null;
234
+ return (React__default["default"].createElement(Tooltip.Tooltip, { key: props.label, message: props.label },
235
+ 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" })));
236
+ }),
237
+ React__default["default"].createElement(DataListItemActionsOverflow, { actions: childrenArray, item: item })));
238
+ }
239
+ function handleContextMenu(event) {
240
+ event.stopPropagation();
241
+ }
242
+ function getExposedActions(childrenArray) {
243
+ const firstTwoChildren = childrenArray.slice(0, 2);
244
+ return firstTwoChildren.reduce((result, child, i) => {
245
+ const hasIcon = Boolean(child.props.icon);
246
+ const isFirstChild = i === 0;
247
+ if (isFirstChild && hasIcon) {
248
+ return [...result, child];
249
+ }
250
+ const isSecondChild = i === 1;
251
+ const hasFirstChild = result.length === 1;
252
+ if (isSecondChild && hasIcon && hasFirstChild) {
253
+ return [...result, child];
254
+ }
255
+ return result;
256
+ }, []);
257
+ }
258
+
259
+ const DataListLayoutActionsContext = React.createContext({ activeItem: undefined });
260
+ function useDataListLayoutActionsContext() {
261
+ return React.useContext(DataListLayoutActionsContext);
262
+ }
263
+
264
+ function DataListItemInternal({ children, item, }) {
265
+ const { selected, onSelect } = useDataListContext();
266
+ if (selected !== undefined && onSelect) {
267
+ return (React__default["default"].createElement("div", { className: classnames__default["default"](styles__default["default"].selectable, {
268
+ [styles__default["default"].selected]: selected === null || selected === void 0 ? void 0 : selected.length,
269
+ }) },
270
+ React__default["default"].createElement(Checkbox.Checkbox, { checked: selected === null || selected === void 0 ? void 0 : selected.includes(item.id), onChange: handleChange }),
271
+ children));
272
+ }
273
+ return children;
274
+ function handleChange() {
275
+ if (selected === null || selected === void 0 ? void 0 : selected.includes(item.id)) {
276
+ onSelect === null || onSelect === void 0 ? void 0 : onSelect(selected === null || selected === void 0 ? void 0 : selected.filter(id => id !== item.id));
277
+ }
278
+ else if (selected) {
279
+ onSelect === null || onSelect === void 0 ? void 0 : onSelect([...selected, item.id]);
280
+ }
281
+ }
282
+ }
283
+
284
+ 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";
285
+ var styles$8 = {"tags":"WRV-UmQmPzo-","tagCount":"liQeWCMenD0-"};
286
+ styleInject_es.styleInject(css_248z$8);
110
287
 
111
288
  function DataListTags({ items }) {
112
289
  const ref = React.useRef(null);
@@ -126,10 +303,10 @@ function DataListTags({ items }) {
126
303
  elements === null || elements === void 0 ? void 0 : elements.forEach(element => observer.unobserve(element));
127
304
  };
128
305
  }, [items]);
129
- return (React__default["default"].createElement("div", { className: styles$b.tags, ref: ref },
306
+ return (React__default["default"].createElement("div", { className: styles$8.tags, ref: ref },
130
307
  items.filter(Boolean).map((tag, index) => (React__default["default"].createElement("div", { key: tag, "data-tag-element": index },
131
308
  React__default["default"].createElement(InlineLabel.InlineLabel, null, tag)))),
132
- Boolean(visibleItems) && (React__default["default"].createElement("div", { className: styles$b.tagCount },
309
+ Boolean(visibleItems) && (React__default["default"].createElement("div", { className: styles$8.tagCount },
133
310
  React__default["default"].createElement(Text.Text, null,
134
311
  "+",
135
312
  visibleItems)))));
@@ -158,44 +335,32 @@ function buildIntersectionThreshold(items) {
158
335
  return thresholds;
159
336
  }
160
337
 
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);
338
+ 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";
339
+ var styles$7 = {"headerLabel":"fLmJZJJqMcE-","sortable":"UG8cHUT3Hds-"};
340
+ styleInject_es.styleInject(css_248z$7);
164
341
 
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);
342
+ 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";
343
+ var styles$6 = {"sortIcon":"AN5egORYy-0-","active":"F1uTDCK0Sb0-","inactive":"_6KYeQXWXLQ8-"};
344
+ styleInject_es.styleInject(css_248z$6);
168
345
 
169
346
  const SORTING_ICON_TEST_ID = "ATL-DataList-Sorting-Icon";
170
347
  function DataListSortingArrows({ order }) {
171
- return (React__default["default"].createElement("div", { className: styles$9.sortIcon, "data-testid": SORTING_ICON_TEST_ID },
348
+ return (React__default["default"].createElement("div", { className: styles$6.sortIcon, "data-testid": SORTING_ICON_TEST_ID },
172
349
  React__default["default"].createElement("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg" },
173
350
  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
351
  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
352
  function getActiveClassName(targetOrder) {
176
- return order === targetOrder ? styles$9.active : styles$9.inactive;
353
+ return order === targetOrder ? styles$6.active : styles$6.inactive;
177
354
  }
178
355
  }
179
356
 
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
357
  function DataListHeaderTile({ headers, headerKey, }) {
193
358
  const { sorting } = useDataListContext();
194
359
  const isSortable = sorting === null || sorting === void 0 ? void 0 : sorting.sortable.includes(headerKey);
195
360
  const sortingState = sorting === null || sorting === void 0 ? void 0 : sorting.state;
196
361
  const Tag = isSortable ? "button" : "div";
197
- return (React__default["default"].createElement(Tag, { className: classnames__default["default"](styles$a.headerLabel, {
198
- [styles$a.sortable]: isSortable,
362
+ return (React__default["default"].createElement(Tag, { className: classnames__default["default"](styles$7.headerLabel, {
363
+ [styles$7.sortable]: isSortable,
199
364
  }), onClick: handleOnClick },
200
365
  React__default["default"].createElement(Text.Text, { maxLines: "single" }, headers[headerKey]),
201
366
  (sortingState === null || sortingState === void 0 ? void 0 : sortingState.key) === headerKey && (React__default["default"].createElement(DataListSortingArrows, { order: sortingState.order }))));
@@ -234,10 +399,10 @@ function getCompoundComponents(children, type) {
234
399
  return elements;
235
400
  }
236
401
  /**
237
- * Generate the default elements the DataList would use on the data provided.
402
+ * Generate the default element the DataList would use on the data provided.
238
403
  */
239
- function generateListItemElements(data) {
240
- return data.map(item => Object.keys(item).reduce((acc, key) => {
404
+ function generateListItemElement(item) {
405
+ return Object.keys(item).reduce((acc, key) => {
241
406
  const currentItem = item[key];
242
407
  if (!currentItem) {
243
408
  return acc;
@@ -259,7 +424,7 @@ function generateListItemElements(data) {
259
424
  acc[key] = React__default["default"].createElement(Text.Text, { variation: "subdued" }, currentItem);
260
425
  }
261
426
  return acc;
262
- }, {}));
427
+ }, {});
263
428
  }
264
429
  /**
265
430
  * Generate the header elements with the default styling
@@ -272,6 +437,41 @@ function sortSizeProp(sizeProp) {
272
437
  return sizeProp.sort((a, b) => BREAKPOINTS.indexOf(a) - BREAKPOINTS.indexOf(b));
273
438
  }
274
439
 
440
+ function DataListItem({ item, layout, }) {
441
+ const { itemActionComponent } = useDataListContext();
442
+ const { hasInLayoutActions } = useDataListLayoutContext();
443
+ const [showMenu, setShowMenu] = React.useState(false);
444
+ const [contextPosition, setContextPosition] = React.useState();
445
+ const generatedItem = React.useMemo(() => generateListItemElement(item), [item]);
446
+ const contextMenuActions = itemActionComponent === null || itemActionComponent === void 0 ? void 0 : itemActionComponent.props.children;
447
+ const isContextMenuVisible = Boolean(contextPosition);
448
+ const shouldShowContextMenu = showMenu && isContextMenuVisible && Boolean(contextMenuActions);
449
+ return (React__default["default"].createElement(DataListLayoutActionsContext.Provider, { value: { activeItem: item } },
450
+ React__default["default"].createElement("div", { onMouseEnter: handleShowMenu, onMouseLeave: handleHideMenu, onContextMenu: handleContextMenu, className: classnames__default["default"](styles__default["default"].listItem, {
451
+ [styles__default["default"].active]: showMenu && isContextMenuVisible,
452
+ }), key: item.id },
453
+ React__default["default"].createElement(DataListItemInternal, { item: item }, layout.props.children(generatedItem)),
454
+ React__default["default"].createElement(framerMotion.AnimatePresence, null,
455
+ showMenu && !hasInLayoutActions && (React__default["default"].createElement(InternalDataListItemActions, { item: item })),
456
+ React__default["default"].createElement(DataListActionsMenu, { key: item.id, visible: shouldShowContextMenu, position: contextPosition || { x: 0, y: 0 }, onRequestClose: () => setContextPosition(undefined) }, contextMenuActions &&
457
+ React.Children.map(contextMenuActions, action => (React__default["default"].createElement(InternalDataListAction, Object.assign({ key: item.id }, action.props, { item: item })))))))));
458
+ function handleShowMenu() {
459
+ setShowMenu(true);
460
+ }
461
+ function handleHideMenu() {
462
+ setShowMenu(false);
463
+ }
464
+ function handleContextMenu(event) {
465
+ if (!contextMenuActions || isContextMenuVisible)
466
+ return;
467
+ event.preventDefault();
468
+ setContextPosition({
469
+ x: event.clientX,
470
+ y: event.clientY,
471
+ });
472
+ }
473
+ }
474
+
275
475
  function DataListLayoutInternal({ layouts, renderLayout, mediaMatches, }) {
276
476
  const sizePropsOfLayouts = layouts === null || layouts === void 0 ? void 0 : layouts.map(layout => layout.props.size || "xs");
277
477
  const layoutToRender = layouts === null || layouts === void 0 ? void 0 : layouts.find(layout => {
@@ -304,216 +504,14 @@ function isLayoutVisible({ layoutSize, mediaMatches, sizePropsOfLayouts, }) {
304
504
  return isVisibleBreakpoint && largerLayoutIsNotVisible;
305
505
  }
306
506
 
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
507
  function DataListItems({ layouts, mediaMatches, data, }) {
466
- const { itemActionComponent } = useDataListContext();
467
- const elementData = React.useMemo(() => generateListItemElements(data), [data]);
468
508
  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
509
  return (React__default["default"].createElement(DataListLayoutContext.Provider, { value: {
475
510
  isInLayoutProvider: true,
476
511
  hasInLayoutActions,
477
512
  setHasInLayoutActions,
478
- activeItem,
479
513
  } },
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
- }
514
+ 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
515
  }
518
516
 
519
517
  function DataListHeaderCheckbox({ children }) {
@@ -849,7 +847,8 @@ styleInject_es.styleInject(css_248z);
849
847
 
850
848
  function DataListLayoutActions() {
851
849
  const { itemActionComponent } = useDataListContext();
852
- const { setHasInLayoutActions, activeItem } = useDataListLayoutContext();
850
+ const { setHasInLayoutActions } = useDataListLayoutContext();
851
+ const { activeItem } = useDataListLayoutActionsContext();
853
852
  const { children: actionsChildren } = (itemActionComponent === null || itemActionComponent === void 0 ? void 0 : itemActionComponent.props) || {};
854
853
  const actions = React.Children.toArray(actionsChildren);
855
854
  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.42.1",
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": "685c933bb0a179c249ae5207070afe579efe55b5"
87
+ "gitHead": "e46abe091488d7bacf653ac8fd7ffb73b575e8aa"
88
88
  }