@trackunit/react-table 0.0.83 → 0.0.85

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.cjs.js CHANGED
@@ -6,8 +6,8 @@ var jsxRuntime = require('react/jsx-runtime');
6
6
  var i18nLibraryTranslation = require('@trackunit/i18n-library-translation');
7
7
  var reactComponents = require('@trackunit/react-components');
8
8
  var React = require('react');
9
- var reactRouterDom = require('react-router-dom');
10
9
  var cssClassVarianceUtilities = require('@trackunit/css-class-variance-utilities');
10
+ var reactRouterDom = require('react-router-dom');
11
11
  var reactTableBaseComponents = require('@trackunit/react-table-base-components');
12
12
  var reactDom = require('react-dom');
13
13
  var reactFormComponents = require('@trackunit/react-form-components');
@@ -34,7 +34,7 @@ function _interopNamespace(e) {
34
34
  var React__namespace = /*#__PURE__*/_interopNamespace(React);
35
35
 
36
36
  var defaultTranslations = {
37
- "table.actionsheet.selected": "selected",
37
+ "table.actionsheet.selected": "{{count}} selected",
38
38
  "layout.actions.reset": "Reset",
39
39
  "table.pagination.of": "of {{count}}",
40
40
  "table.pagination.full": "Showing {{count}} of {{total}} results",
@@ -106,6 +106,40 @@ const setupLibraryTranslations = () => {
106
106
  i18nLibraryTranslation.registerTranslations(translations);
107
107
  };
108
108
 
109
+ const cvaActionSheet = cssClassVarianceUtilities.cvaMerge([
110
+ "w-[760px]",
111
+ "max-w-[80%]",
112
+ "animate-fade-in-fast",
113
+ "grid",
114
+ "grid-rows-2",
115
+ "grid-cols-[min-content,1fr,min-content]",
116
+ "sm:grid-cols-[min-content,1fr,min-content]",
117
+ "sm:grid-rows-1",
118
+ "p-2",
119
+ "bg-blue-600",
120
+ "gap-1",
121
+ "rounded-2xl",
122
+ "h-min",
123
+ "items-center",
124
+ "z-top",
125
+ "shadow-2xl",
126
+ "fixed",
127
+ "bottom-24",
128
+ "left-1/2",
129
+ "-translate-x-1/2",
130
+ ]);
131
+ const cvaActionContainerAndOverflow = cssClassVarianceUtilities.cvaMerge([
132
+ "col-span-2",
133
+ "flex",
134
+ "flex-row-reverse",
135
+ "flex-nowrap",
136
+ "justify-end",
137
+ "gap-2",
138
+ "overflow-hidden",
139
+ "sm:col-span-1",
140
+ "sm:flex-row",
141
+ ]);
142
+
109
143
  /******************************************************************************
110
144
  Copyright (c) Microsoft Corporation.
111
145
 
@@ -133,31 +167,93 @@ function __rest(s, e) {
133
167
  return t;
134
168
  }
135
169
 
136
- const cvaActionSheet = cssClassVarianceUtilities.cvaMerge([
137
- "animate-fade-in-fast",
138
- "grid",
139
- "!p-2",
140
- "bg-blue-600",
141
- "grid-flow-col",
142
- "min-w-20",
143
- "gap-1",
144
- "rounded-2xl",
145
- "items-center",
146
- "z-top",
147
- "shadow-md",
148
- "fixed",
149
- "bottom-24",
150
- "left-1/2",
151
- "-translate-x-1/2",
152
- ]);
153
-
170
+ /**
171
+ * The button to show in the ActionSheet.
172
+ * Should not be used outside the ActionSheet component.
173
+ *
174
+ * @param {ActionButtonProps} props - The properties for the action button.
175
+ * @param {ActionModel} props.action - The action model defining what action to perform.
176
+ * @param {ReactNode} props.children - The children to render inside the button.
177
+ * @param {string} [props.id] - The optional ID for the button.
178
+ * @param {...any} [props.rest] - Any additional button properties.
179
+ * @returns {JSX.Element} - The action button component.
180
+ */
154
181
  const ActionButton = (_a) => {
155
- var { action, children } = _a, rest = __rest(_a, ["action", "children"]);
182
+ var { action, children, id } = _a, rest = __rest(_a, ["action", "children", "id"]);
156
183
  if (action.type === "route") {
157
- return (jsxRuntime.jsx(reactComponents.Button, Object.assign({ renderAs: reactRouterDom.Link, to: action.url, variant: "transparent", color: "secondary" }, rest, { children: children })));
184
+ return (jsxRuntime.jsx(reactComponents.Button, Object.assign({ renderAs: reactRouterDom.Link, to: action.url, variant: "transparent", color: "secondary", id: id }, rest, { children: children })));
185
+ }
186
+ return (jsxRuntime.jsx(reactComponents.Button, Object.assign({ onClick: action.method, variant: "transparent", color: "secondary", id: id }, rest, { children: children })));
187
+ };
188
+ /**
189
+ * Converts an action model to a MenuItem component.
190
+ * These should be shown in the more menu.
191
+ * Should not be used outside the ActionSheet component.
192
+ *
193
+ * @param {ActionModel} action - The action model to convert.
194
+ * @param {string} [dataTestId] - Optional data test ID.
195
+ * @returns {JSX.Element} - The MenuItem component for the given action.
196
+ */
197
+ const actionDataToMenuItem = (action, dataTestId) => {
198
+ const props = "url" in action
199
+ ? {
200
+ dataTestId,
201
+ }
202
+ : {
203
+ id: action.id,
204
+ key: action.label,
205
+ dataTestId,
206
+ };
207
+ const item = (jsxRuntime.jsx(reactComponents.MenuItem, { props, onClick: "method" in action ? action.method : undefined, dataTestId: `${dataTestId}-action-label`, className: "flex justify-center", label: action.label, prefix: jsxRuntime.jsx(reactComponents.Icon, { name: action.icon, size: action.size, "data-testid": "action-icon", forwardedRef: action.forwardedRef, style: action.style }) }, action.label));
208
+ if ("url" in action) {
209
+ return (jsxRuntime.jsx(reactRouterDom.Link, { id: action.id, to: action.url, children: item }, action.label));
158
210
  }
159
- return (jsxRuntime.jsx(reactComponents.Button, Object.assign({ onClick: action.method, variant: "transparent", color: "secondary" }, rest, { children: children })));
211
+ return item;
160
212
  };
213
+ /**
214
+ * Converts an action model to an ActionButton component.
215
+ * These should be shown in the ActionSheet.
216
+ * Should not be used outside the ActionSheet component.
217
+ *
218
+ * @param {ActionModel} action - The action model to convert.
219
+ * @param {string} [dataTestId] - Optional data test ID.
220
+ * @returns {JSX.Element} - The ActionButton component for the given action.
221
+ */
222
+ const actionDataToActionButton = (action, dataTestId) => (jsxRuntime.jsxs(ActionButton, { action: action, dataTestId: action.label, className: "max-w-max flex-shrink-0", id: action.id, children: [jsxRuntime.jsx(reactComponents.Icon, { name: action.icon, color: "white", size: action.size, "data-testid": "action-icon", forwardedRef: action.forwardedRef, style: action.style }), jsxRuntime.jsx(reactComponents.Text, { dataTestId: `${dataTestId}-action-label`, className: "!text-base text-white", children: action.label })] }, action.id));
223
+
224
+ /**
225
+ * `ActionContainerAndOverflow` renders a set of actions and a MoreMenu for overflow.
226
+ * It makes use of the `useOverflowItems` hook to determine which items should go into the overflow menu.
227
+ *
228
+ * @param {object} props - Props for the component.
229
+ * @param {ActionModel[]} props.actions - Array of action models to be rendered.
230
+ * @param {ReactElement<SidebarItemProps>[] | ReactElement<SidebarItemProps>} props.moreActions - Additional actions that can be rendered in the MoreMenu.
231
+ * @param {string} [props.dataTestId] - Data test id for the component, useful in testing.
232
+ * @returns {ReactElement} The rendered component.
233
+ */
234
+ const ActionContainerAndOverflow = ({ actions, moreActions, dataTestId }) => {
235
+ const children = React.useMemo(() => actions && actions.map(action => action && actionDataToActionButton(action, dataTestId)), [actions, dataTestId]);
236
+ const { overflowContainerRef, itemOverflowMap } = reactComponents.useOverflowItems({
237
+ children,
238
+ childUniqueIdentifierAttribute: "id",
239
+ threshold: 1,
240
+ });
241
+ const itemVisibilityClassName = (id) => {
242
+ if (itemOverflowMap[id]) {
243
+ return "invisible";
244
+ }
245
+ return "visible";
246
+ };
247
+ const overflowItemCount = Object.values(itemOverflowMap).filter(isOverflowing => isOverflowing).length;
248
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { className: cvaActionContainerAndOverflow(), ref: overflowContainerRef, children: React.Children.map(children, child => {
249
+ return React.cloneElement(child, {
250
+ className: `${child.props.className} ${itemVisibilityClassName(child.props.id)}`,
251
+ });
252
+ }) }), React.Children.count(moreActions) > 0 || overflowItemCount ? (jsxRuntime.jsx(reactComponents.MoreMenu, { popoverProps: { placement: "top-end" }, className: "p-0", iconButtonProps: { variant: "transparent", circular: true }, iconProps: { color: "white", name: "EllipsisHorizontal" }, dataTestId: `${dataTestId}-more-menu`, children: jsxRuntime.jsxs(reactComponents.MenuList, { className: "relative -right-2", children: [moreActions ? moreActions : null, actions.map(action => {
253
+ return itemOverflowMap[action.id] ? actionDataToMenuItem(action, dataTestId) : null;
254
+ })] }) })) : null] }));
255
+ };
256
+
161
257
  /**
162
258
  * The Action Sheet appears when one or more items are selected from a table.
163
259
  * It primarily accommodates 1-3 main actions that represent the most crucial and frequently accessed functions on the specific page.
@@ -168,25 +264,9 @@ const ActionButton = (_a) => {
168
264
  */
169
265
  const ActionSheet = ({ actions, moreActions = [], selections, resetSelection, className, dataTestId, }) => {
170
266
  const [t] = useTranslation();
171
- const containerProps = reactComponents.useContainerProps({ dataTestId, className });
172
- const [smallScreen, setSmallScreen] = React.useState(window.innerWidth < 1024);
173
- const wrapperSmallScreen = () => setSmallScreen(window.innerWidth < 1024);
174
- React.useEffect(() => {
175
- window.addEventListener("resize", wrapperSmallScreen);
176
- return () => window.removeEventListener("resize", wrapperSmallScreen);
177
- }, []);
178
- const filteredActions = actions.filter(action => action !== undefined);
179
- const actionsFilteredForScreenSize = smallScreen ? [filteredActions[0]] : filteredActions;
180
- const moreActionsFilteredForScreenSize = smallScreen ? moreActions === null || moreActions === void 0 ? void 0 : moreActions.concat(filteredActions.slice(1)) : moreActions;
181
- const actionDataToActionButton = (action, moreAction = false) => (jsxRuntime.jsxs(ActionButton, { action: action, dataTestId: action.label, className: "lg:mr-3", children: [jsxRuntime.jsx(reactComponents.Icon, { name: action.icon, color: moreAction ? "neutral" : "white", size: action.size, "data-testid": "action-icon", forwardedRef: action.forwardedRef, style: action.style }), jsxRuntime.jsx(reactComponents.Text, { dataTestId: `${containerProps["data-testid"]}-action-label`, className: `${moreAction ? "text-inherit" : "!text-white"} !text-base`, children: action.label })] }, action.label));
182
- const actionDataToMenuItem = (action) => {
183
- const item = (jsxRuntime.jsx(reactComponents.MenuItem, { onClick: "method" in action ? action.method : undefined, dataTestId: `${containerProps["data-testid"]}-action-label`, label: action.label, className: "lg:mr-3", prefix: jsxRuntime.jsx(reactComponents.Icon, { name: action.icon, size: action.size, "data-testid": "action-icon", forwardedRef: action.forwardedRef, style: action.style }) }, action.label));
184
- if ("url" in action) {
185
- return jsxRuntime.jsx(reactRouterDom.Link, { to: action.url, children: item });
186
- }
187
- return item;
188
- };
189
- return (jsxRuntime.jsxs("div", { className: cvaActionSheet({ className: containerProps.className }), "data-testid": containerProps["data-testid"], children: [jsxRuntime.jsx(reactComponents.IconButton, { icon: jsxRuntime.jsx(reactComponents.Icon, { name: "XMark", size: "small", color: "white", "data-testid": "close-icon" }), onClick: resetSelection, color: "secondary", variant: "transparent", circular: true, dataTestId: "XButton" }), jsxRuntime.jsxs(reactComponents.Text, { size: "large", className: "!lg:mr-28 !mr-4 w-max !text-white", children: [selections === null || selections === void 0 ? void 0 : selections.length, " ", t("table.actionsheet.selected")] }), actionsFilteredForScreenSize.map(action => action && actionDataToActionButton(action)), moreActionsFilteredForScreenSize && moreActionsFilteredForScreenSize.length > 0 && (jsxRuntime.jsx(reactComponents.MoreMenu, { popoverProps: { placement: "top-end" }, className: "p-0", iconButtonProps: { variant: "transparent", circular: true }, iconProps: { color: "white", name: "EllipsisHorizontal" }, dataTestId: `${containerProps["data-testid"]}-more-menu`, children: jsxRuntime.jsx(reactComponents.MenuList, { className: "relative -right-2", children: moreActionsFilteredForScreenSize.map(action => actionDataToMenuItem(action)) }) }))] }));
267
+ return (jsxRuntime.jsxs("div", { className: cvaActionSheet({ className }), "data-testid": dataTestId, children: [jsxRuntime.jsxs(reactComponents.Text, { size: "large", className: "border-primary-500 col-span-3 w-full border-b text-white sm:col-span-1 sm:w-max sm:border-0", children: [jsxRuntime.jsx(reactComponents.IconButton, { icon: jsxRuntime.jsx(reactComponents.Icon, { name: "XMark", size: "small", color: "white", "data-testid": "close-icon" }), onClick: resetSelection, color: "secondary", variant: "transparent", circular: true, dataTestId: "XButton" }), t("table.actionsheet.selected", { count: selections === null || selections === void 0 ? void 0 : selections.length })] }), jsxRuntime.jsx(ActionContainerAndOverflow, { dataTestId,
268
+ actions,
269
+ moreActions: moreActions.map(action => actionDataToMenuItem(action, dataTestId)) })] }));
190
270
  };
191
271
 
192
272
  /**
package/index.esm.js CHANGED
@@ -1,17 +1,17 @@
1
- import { jsxs, jsx } from 'react/jsx-runtime';
1
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import { registerTranslations, useNamespaceTranslation } from '@trackunit/i18n-library-translation';
3
- import { useContainerProps, IconButton, Icon, Text, MoreMenu, MenuList, MenuItem, Button, Card, EmptyState, Spinner, Tooltip, Popover, PopoverTrigger, PopoverContent } from '@trackunit/react-components';
3
+ import { MenuItem, Icon, Text, Button, useOverflowItems, MoreMenu, MenuList, IconButton, Card, EmptyState, Spinner, Tooltip, Popover, PopoverTrigger, PopoverContent } from '@trackunit/react-components';
4
4
  import * as React from 'react';
5
- import { useState, useEffect, useCallback, useRef, createContext, memo as memo$2, isValidElement, cloneElement, useLayoutEffect, useMemo, useContext } from 'react';
6
- import { Link } from 'react-router-dom';
5
+ import { useMemo, Children, cloneElement, useCallback, useEffect, useRef, createContext, memo as memo$2, isValidElement, useLayoutEffect, useContext, useState } from 'react';
7
6
  import { cvaMerge } from '@trackunit/css-class-variance-utilities';
7
+ import { Link } from 'react-router-dom';
8
8
  import { TableRoot, Thead, Tr, Th, SortIndicator, ResizeHandle, Tbody, Td } from '@trackunit/react-table-base-components';
9
9
  import { flushSync } from 'react-dom';
10
10
  import { Toggle, RadioGroup, RadioItem } from '@trackunit/react-form-components';
11
11
  import { SortOrder, validateStringAsAssetSortByProperty } from '@trackunit/react-core-contexts-api';
12
12
 
13
13
  var defaultTranslations = {
14
- "table.actionsheet.selected": "selected",
14
+ "table.actionsheet.selected": "{{count}} selected",
15
15
  "layout.actions.reset": "Reset",
16
16
  "table.pagination.of": "of {{count}}",
17
17
  "table.pagination.full": "Showing {{count}} of {{total}} results",
@@ -83,6 +83,40 @@ const setupLibraryTranslations = () => {
83
83
  registerTranslations(translations);
84
84
  };
85
85
 
86
+ const cvaActionSheet = cvaMerge([
87
+ "w-[760px]",
88
+ "max-w-[80%]",
89
+ "animate-fade-in-fast",
90
+ "grid",
91
+ "grid-rows-2",
92
+ "grid-cols-[min-content,1fr,min-content]",
93
+ "sm:grid-cols-[min-content,1fr,min-content]",
94
+ "sm:grid-rows-1",
95
+ "p-2",
96
+ "bg-blue-600",
97
+ "gap-1",
98
+ "rounded-2xl",
99
+ "h-min",
100
+ "items-center",
101
+ "z-top",
102
+ "shadow-2xl",
103
+ "fixed",
104
+ "bottom-24",
105
+ "left-1/2",
106
+ "-translate-x-1/2",
107
+ ]);
108
+ const cvaActionContainerAndOverflow = cvaMerge([
109
+ "col-span-2",
110
+ "flex",
111
+ "flex-row-reverse",
112
+ "flex-nowrap",
113
+ "justify-end",
114
+ "gap-2",
115
+ "overflow-hidden",
116
+ "sm:col-span-1",
117
+ "sm:flex-row",
118
+ ]);
119
+
86
120
  /******************************************************************************
87
121
  Copyright (c) Microsoft Corporation.
88
122
 
@@ -110,31 +144,93 @@ function __rest(s, e) {
110
144
  return t;
111
145
  }
112
146
 
113
- const cvaActionSheet = cvaMerge([
114
- "animate-fade-in-fast",
115
- "grid",
116
- "!p-2",
117
- "bg-blue-600",
118
- "grid-flow-col",
119
- "min-w-20",
120
- "gap-1",
121
- "rounded-2xl",
122
- "items-center",
123
- "z-top",
124
- "shadow-md",
125
- "fixed",
126
- "bottom-24",
127
- "left-1/2",
128
- "-translate-x-1/2",
129
- ]);
130
-
147
+ /**
148
+ * The button to show in the ActionSheet.
149
+ * Should not be used outside the ActionSheet component.
150
+ *
151
+ * @param {ActionButtonProps} props - The properties for the action button.
152
+ * @param {ActionModel} props.action - The action model defining what action to perform.
153
+ * @param {ReactNode} props.children - The children to render inside the button.
154
+ * @param {string} [props.id] - The optional ID for the button.
155
+ * @param {...any} [props.rest] - Any additional button properties.
156
+ * @returns {JSX.Element} - The action button component.
157
+ */
131
158
  const ActionButton = (_a) => {
132
- var { action, children } = _a, rest = __rest(_a, ["action", "children"]);
159
+ var { action, children, id } = _a, rest = __rest(_a, ["action", "children", "id"]);
133
160
  if (action.type === "route") {
134
- return (jsx(Button, Object.assign({ renderAs: Link, to: action.url, variant: "transparent", color: "secondary" }, rest, { children: children })));
161
+ return (jsx(Button, Object.assign({ renderAs: Link, to: action.url, variant: "transparent", color: "secondary", id: id }, rest, { children: children })));
162
+ }
163
+ return (jsx(Button, Object.assign({ onClick: action.method, variant: "transparent", color: "secondary", id: id }, rest, { children: children })));
164
+ };
165
+ /**
166
+ * Converts an action model to a MenuItem component.
167
+ * These should be shown in the more menu.
168
+ * Should not be used outside the ActionSheet component.
169
+ *
170
+ * @param {ActionModel} action - The action model to convert.
171
+ * @param {string} [dataTestId] - Optional data test ID.
172
+ * @returns {JSX.Element} - The MenuItem component for the given action.
173
+ */
174
+ const actionDataToMenuItem = (action, dataTestId) => {
175
+ const props = "url" in action
176
+ ? {
177
+ dataTestId,
178
+ }
179
+ : {
180
+ id: action.id,
181
+ key: action.label,
182
+ dataTestId,
183
+ };
184
+ const item = (jsx(MenuItem, { props, onClick: "method" in action ? action.method : undefined, dataTestId: `${dataTestId}-action-label`, className: "flex justify-center", label: action.label, prefix: jsx(Icon, { name: action.icon, size: action.size, "data-testid": "action-icon", forwardedRef: action.forwardedRef, style: action.style }) }, action.label));
185
+ if ("url" in action) {
186
+ return (jsx(Link, { id: action.id, to: action.url, children: item }, action.label));
135
187
  }
136
- return (jsx(Button, Object.assign({ onClick: action.method, variant: "transparent", color: "secondary" }, rest, { children: children })));
188
+ return item;
137
189
  };
190
+ /**
191
+ * Converts an action model to an ActionButton component.
192
+ * These should be shown in the ActionSheet.
193
+ * Should not be used outside the ActionSheet component.
194
+ *
195
+ * @param {ActionModel} action - The action model to convert.
196
+ * @param {string} [dataTestId] - Optional data test ID.
197
+ * @returns {JSX.Element} - The ActionButton component for the given action.
198
+ */
199
+ const actionDataToActionButton = (action, dataTestId) => (jsxs(ActionButton, { action: action, dataTestId: action.label, className: "max-w-max flex-shrink-0", id: action.id, children: [jsx(Icon, { name: action.icon, color: "white", size: action.size, "data-testid": "action-icon", forwardedRef: action.forwardedRef, style: action.style }), jsx(Text, { dataTestId: `${dataTestId}-action-label`, className: "!text-base text-white", children: action.label })] }, action.id));
200
+
201
+ /**
202
+ * `ActionContainerAndOverflow` renders a set of actions and a MoreMenu for overflow.
203
+ * It makes use of the `useOverflowItems` hook to determine which items should go into the overflow menu.
204
+ *
205
+ * @param {object} props - Props for the component.
206
+ * @param {ActionModel[]} props.actions - Array of action models to be rendered.
207
+ * @param {ReactElement<SidebarItemProps>[] | ReactElement<SidebarItemProps>} props.moreActions - Additional actions that can be rendered in the MoreMenu.
208
+ * @param {string} [props.dataTestId] - Data test id for the component, useful in testing.
209
+ * @returns {ReactElement} The rendered component.
210
+ */
211
+ const ActionContainerAndOverflow = ({ actions, moreActions, dataTestId }) => {
212
+ const children = useMemo(() => actions && actions.map(action => action && actionDataToActionButton(action, dataTestId)), [actions, dataTestId]);
213
+ const { overflowContainerRef, itemOverflowMap } = useOverflowItems({
214
+ children,
215
+ childUniqueIdentifierAttribute: "id",
216
+ threshold: 1,
217
+ });
218
+ const itemVisibilityClassName = (id) => {
219
+ if (itemOverflowMap[id]) {
220
+ return "invisible";
221
+ }
222
+ return "visible";
223
+ };
224
+ const overflowItemCount = Object.values(itemOverflowMap).filter(isOverflowing => isOverflowing).length;
225
+ return (jsxs(Fragment, { children: [jsx("div", { className: cvaActionContainerAndOverflow(), ref: overflowContainerRef, children: Children.map(children, child => {
226
+ return cloneElement(child, {
227
+ className: `${child.props.className} ${itemVisibilityClassName(child.props.id)}`,
228
+ });
229
+ }) }), Children.count(moreActions) > 0 || overflowItemCount ? (jsx(MoreMenu, { popoverProps: { placement: "top-end" }, className: "p-0", iconButtonProps: { variant: "transparent", circular: true }, iconProps: { color: "white", name: "EllipsisHorizontal" }, dataTestId: `${dataTestId}-more-menu`, children: jsxs(MenuList, { className: "relative -right-2", children: [moreActions ? moreActions : null, actions.map(action => {
230
+ return itemOverflowMap[action.id] ? actionDataToMenuItem(action, dataTestId) : null;
231
+ })] }) })) : null] }));
232
+ };
233
+
138
234
  /**
139
235
  * The Action Sheet appears when one or more items are selected from a table.
140
236
  * It primarily accommodates 1-3 main actions that represent the most crucial and frequently accessed functions on the specific page.
@@ -145,25 +241,9 @@ const ActionButton = (_a) => {
145
241
  */
146
242
  const ActionSheet = ({ actions, moreActions = [], selections, resetSelection, className, dataTestId, }) => {
147
243
  const [t] = useTranslation();
148
- const containerProps = useContainerProps({ dataTestId, className });
149
- const [smallScreen, setSmallScreen] = useState(window.innerWidth < 1024);
150
- const wrapperSmallScreen = () => setSmallScreen(window.innerWidth < 1024);
151
- useEffect(() => {
152
- window.addEventListener("resize", wrapperSmallScreen);
153
- return () => window.removeEventListener("resize", wrapperSmallScreen);
154
- }, []);
155
- const filteredActions = actions.filter(action => action !== undefined);
156
- const actionsFilteredForScreenSize = smallScreen ? [filteredActions[0]] : filteredActions;
157
- const moreActionsFilteredForScreenSize = smallScreen ? moreActions === null || moreActions === void 0 ? void 0 : moreActions.concat(filteredActions.slice(1)) : moreActions;
158
- const actionDataToActionButton = (action, moreAction = false) => (jsxs(ActionButton, { action: action, dataTestId: action.label, className: "lg:mr-3", children: [jsx(Icon, { name: action.icon, color: moreAction ? "neutral" : "white", size: action.size, "data-testid": "action-icon", forwardedRef: action.forwardedRef, style: action.style }), jsx(Text, { dataTestId: `${containerProps["data-testid"]}-action-label`, className: `${moreAction ? "text-inherit" : "!text-white"} !text-base`, children: action.label })] }, action.label));
159
- const actionDataToMenuItem = (action) => {
160
- const item = (jsx(MenuItem, { onClick: "method" in action ? action.method : undefined, dataTestId: `${containerProps["data-testid"]}-action-label`, label: action.label, className: "lg:mr-3", prefix: jsx(Icon, { name: action.icon, size: action.size, "data-testid": "action-icon", forwardedRef: action.forwardedRef, style: action.style }) }, action.label));
161
- if ("url" in action) {
162
- return jsx(Link, { to: action.url, children: item });
163
- }
164
- return item;
165
- };
166
- return (jsxs("div", { className: cvaActionSheet({ className: containerProps.className }), "data-testid": containerProps["data-testid"], children: [jsx(IconButton, { icon: jsx(Icon, { name: "XMark", size: "small", color: "white", "data-testid": "close-icon" }), onClick: resetSelection, color: "secondary", variant: "transparent", circular: true, dataTestId: "XButton" }), jsxs(Text, { size: "large", className: "!lg:mr-28 !mr-4 w-max !text-white", children: [selections === null || selections === void 0 ? void 0 : selections.length, " ", t("table.actionsheet.selected")] }), actionsFilteredForScreenSize.map(action => action && actionDataToActionButton(action)), moreActionsFilteredForScreenSize && moreActionsFilteredForScreenSize.length > 0 && (jsx(MoreMenu, { popoverProps: { placement: "top-end" }, className: "p-0", iconButtonProps: { variant: "transparent", circular: true }, iconProps: { color: "white", name: "EllipsisHorizontal" }, dataTestId: `${containerProps["data-testid"]}-more-menu`, children: jsx(MenuList, { className: "relative -right-2", children: moreActionsFilteredForScreenSize.map(action => actionDataToMenuItem(action)) }) }))] }));
244
+ return (jsxs("div", { className: cvaActionSheet({ className }), "data-testid": dataTestId, children: [jsxs(Text, { size: "large", className: "border-primary-500 col-span-3 w-full border-b text-white sm:col-span-1 sm:w-max sm:border-0", children: [jsx(IconButton, { icon: jsx(Icon, { name: "XMark", size: "small", color: "white", "data-testid": "close-icon" }), onClick: resetSelection, color: "secondary", variant: "transparent", circular: true, dataTestId: "XButton" }), t("table.actionsheet.selected", { count: selections === null || selections === void 0 ? void 0 : selections.length })] }), jsx(ActionContainerAndOverflow, { dataTestId,
245
+ actions,
246
+ moreActions: moreActions.map(action => actionDataToMenuItem(action, dataTestId)) })] }));
167
247
  };
168
248
 
169
249
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trackunit/react-table",
3
- "version": "0.0.83",
3
+ "version": "0.0.85",
4
4
  "repository": "https://github.com/Trackunit/manager",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "engines": {
@@ -13,11 +13,11 @@
13
13
  "@trackunit/css-core": "0.0.99",
14
14
  "@trackunit/i18n-library-translation": "0.0.89",
15
15
  "@trackunit/iris-app-api": "0.0.126",
16
- "@trackunit/react-components": "0.1.189",
16
+ "@trackunit/react-components": "0.1.190",
17
17
  "@trackunit/react-core-contexts-api": "0.2.68",
18
18
  "@trackunit/react-core-contexts-test": "0.1.125",
19
- "@trackunit/react-form-components": "0.0.189",
20
- "@trackunit/react-table-base-components": "0.0.66",
19
+ "@trackunit/react-form-components": "0.0.191",
20
+ "@trackunit/react-table-base-components": "0.0.68",
21
21
  "@trackunit/shared-utils": "0.0.15",
22
22
  "@trackunit/ui-icons": "0.0.78",
23
23
  "immutability-helper": "3.1.1",
@@ -0,0 +1,19 @@
1
+ import { CommonProps, SidebarItemProps } from "@trackunit/react-components";
2
+ import { ReactElement } from "react";
3
+ import { ActionModel } from "./Actions";
4
+ interface ActionContainerAndOverflowProps extends CommonProps {
5
+ actions: ActionModel[];
6
+ moreActions?: ReactElement<SidebarItemProps>[] | ReactElement<SidebarItemProps>;
7
+ }
8
+ /**
9
+ * `ActionContainerAndOverflow` renders a set of actions and a MoreMenu for overflow.
10
+ * It makes use of the `useOverflowItems` hook to determine which items should go into the overflow menu.
11
+ *
12
+ * @param {object} props - Props for the component.
13
+ * @param {ActionModel[]} props.actions - Array of action models to be rendered.
14
+ * @param {ReactElement<SidebarItemProps>[] | ReactElement<SidebarItemProps>} props.moreActions - Additional actions that can be rendered in the MoreMenu.
15
+ * @param {string} [props.dataTestId] - Data test id for the component, useful in testing.
16
+ * @returns {ReactElement} The rendered component.
17
+ */
18
+ export declare const ActionContainerAndOverflow: ({ actions, moreActions, dataTestId }: ActionContainerAndOverflowProps) => JSX.Element;
19
+ export {};
@@ -5,7 +5,7 @@ export interface ActionSheetProps extends CommonProps {
5
5
  /**
6
6
  * Actions to be displayed in the ActionSheet as primary actions (normally visible)
7
7
  */
8
- actions: readonly [ActionModel, ActionModel?, ActionModel?, ActionModel?];
8
+ actions: ActionModel[];
9
9
  /**
10
10
  * Secondary Actions to be displayed in the ActionSheet via the more menu
11
11
  */
@@ -1 +1,2 @@
1
1
  export declare const cvaActionSheet: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
2
+ export declare const cvaActionContainerAndOverflow: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
@@ -0,0 +1,46 @@
1
+ import { ButtonCommonProps } from "@trackunit/react-components";
2
+ import { ReactNode } from "react";
3
+ import { ActionModel } from "./Actions";
4
+ interface ActionButtonProps extends ButtonCommonProps {
5
+ /**
6
+ * The action model defining what the action.
7
+ */
8
+ action: ActionModel;
9
+ /**
10
+ * The children to render inside the button.
11
+ */
12
+ children: ReactNode;
13
+ }
14
+ /**
15
+ * The button to show in the ActionSheet.
16
+ * Should not be used outside the ActionSheet component.
17
+ *
18
+ * @param {ActionButtonProps} props - The properties for the action button.
19
+ * @param {ActionModel} props.action - The action model defining what action to perform.
20
+ * @param {ReactNode} props.children - The children to render inside the button.
21
+ * @param {string} [props.id] - The optional ID for the button.
22
+ * @param {...any} [props.rest] - Any additional button properties.
23
+ * @returns {JSX.Element} - The action button component.
24
+ */
25
+ export declare const ActionButton: ({ action, children, id, ...rest }: ActionButtonProps) => JSX.Element;
26
+ /**
27
+ * Converts an action model to a MenuItem component.
28
+ * These should be shown in the more menu.
29
+ * Should not be used outside the ActionSheet component.
30
+ *
31
+ * @param {ActionModel} action - The action model to convert.
32
+ * @param {string} [dataTestId] - Optional data test ID.
33
+ * @returns {JSX.Element} - The MenuItem component for the given action.
34
+ */
35
+ export declare const actionDataToMenuItem: (action: ActionModel, dataTestId?: string) => JSX.Element;
36
+ /**
37
+ * Converts an action model to an ActionButton component.
38
+ * These should be shown in the ActionSheet.
39
+ * Should not be used outside the ActionSheet component.
40
+ *
41
+ * @param {ActionModel} action - The action model to convert.
42
+ * @param {string} [dataTestId] - Optional data test ID.
43
+ * @returns {JSX.Element} - The ActionButton component for the given action.
44
+ */
45
+ export declare const actionDataToActionButton: (action: ActionModel, dataTestId?: string) => JSX.Element;
46
+ export {};
@@ -12,6 +12,7 @@ export type RouteAction = {
12
12
  url: string;
13
13
  };
14
14
  export interface CommonAction extends IconExposedProp {
15
+ id: string;
15
16
  label: string;
16
17
  icon: IconName;
17
18
  size?: Size;