@trackunit/react-table 0.0.540 → 0.0.545
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 +59 -36
- package/index.esm.js +60 -37
- package/package.json +1 -1
- package/src/ActionSheet/ActionContainerAndOverflow.d.ts +3 -2
- package/src/ActionSheet/ActionSheet.d.ts +6 -2
- package/src/ActionSheet/ActionSheet.variants.d.ts +6 -4
- package/src/ActionSheet/ActionSheetElementUtils.d.ts +14 -8
- package/src/ActionSheet/Actions.d.ts +6 -3
package/index.cjs.js
CHANGED
|
@@ -115,15 +115,13 @@ const cvaActionSheet = cssClassVarianceUtilities.cvaMerge([
|
|
|
115
115
|
"max-w-[80%]",
|
|
116
116
|
"animate-fade-in-fast",
|
|
117
117
|
"grid",
|
|
118
|
-
"grid-
|
|
119
|
-
"grid-cols-[min-content,1fr,min-content]",
|
|
120
|
-
"sm:grid-cols-[min-content,1fr,min-content]",
|
|
118
|
+
"grid-cols-[min-content,1fr]",
|
|
119
|
+
"sm:grid-cols-[min-content,min-content,1fr,min-content]",
|
|
121
120
|
"sm:grid-rows-1",
|
|
122
121
|
"p-2",
|
|
123
122
|
"bg-primary-600",
|
|
124
123
|
"gap-1",
|
|
125
124
|
"rounded-2xl",
|
|
126
|
-
"items-center",
|
|
127
125
|
"z-top",
|
|
128
126
|
"shadow-2xl",
|
|
129
127
|
"fixed",
|
|
@@ -131,31 +129,41 @@ const cvaActionSheet = cssClassVarianceUtilities.cvaMerge([
|
|
|
131
129
|
"left-1/2",
|
|
132
130
|
"-translate-x-1/2",
|
|
133
131
|
]);
|
|
132
|
+
const cvaDivider = cssClassVarianceUtilities.cvaMerge(["border-blue-500", "row-start-2", "col-span-4", "sm:hidden", "min-h-px"]);
|
|
134
133
|
const cvaActionContainerAndOverflow = cssClassVarianceUtilities.cvaMerge([
|
|
135
|
-
"
|
|
134
|
+
"row-start-3",
|
|
135
|
+
"col-span-full",
|
|
136
136
|
"flex",
|
|
137
|
-
"flex-row
|
|
138
|
-
"flex-nowrap",
|
|
139
|
-
"justify-end",
|
|
137
|
+
"flex-row",
|
|
140
138
|
"gap-2",
|
|
141
139
|
"overflow-hidden",
|
|
142
|
-
"sm:
|
|
143
|
-
"sm:
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
const cvaActionSpinner = cssClassVarianceUtilities.cvaMerge([], {
|
|
140
|
+
"sm:row-start-1",
|
|
141
|
+
"sm:col-span-3",
|
|
142
|
+
"sm:justify-end",
|
|
143
|
+
], {
|
|
147
144
|
variants: {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
secondary: ["h-3.5", "w-3.5"],
|
|
152
|
-
"secondary-danger": ["h-3.5", "w-3.5"],
|
|
153
|
-
ghost: [],
|
|
154
|
-
"ghost-neutral": [],
|
|
145
|
+
isDropdown: {
|
|
146
|
+
true: [],
|
|
147
|
+
false: ["col-span-2"],
|
|
155
148
|
},
|
|
156
149
|
},
|
|
157
|
-
|
|
158
|
-
|
|
150
|
+
});
|
|
151
|
+
const cvaMoreContainer = cssClassVarianceUtilities.cvaMerge([
|
|
152
|
+
"row-start-4",
|
|
153
|
+
"col-span-full",
|
|
154
|
+
"sm:col-span-1",
|
|
155
|
+
"flex",
|
|
156
|
+
"flex-row",
|
|
157
|
+
"justify-between",
|
|
158
|
+
"gap-2",
|
|
159
|
+
"sm:row-start-1",
|
|
160
|
+
"sm:col-span-3",
|
|
161
|
+
], {
|
|
162
|
+
variants: {
|
|
163
|
+
isDropdown: {
|
|
164
|
+
true: [],
|
|
165
|
+
false: ["row-start-3", "col-span-2", "place-self-end"],
|
|
166
|
+
},
|
|
159
167
|
},
|
|
160
168
|
});
|
|
161
169
|
|
|
@@ -165,16 +173,15 @@ const cvaActionSpinner = cssClassVarianceUtilities.cvaMerge([], {
|
|
|
165
173
|
*
|
|
166
174
|
* @param {ActionButtonProps} props - The properties for the action button.
|
|
167
175
|
* @param {ActionModel} props.action - The action model defining what action to perform.
|
|
168
|
-
* @param {ReactNode} props.children - The children to render inside the button.
|
|
169
176
|
* @param {string} [props.id] - The optional ID for the button.
|
|
170
177
|
* @param {...any} [props.rest] - Any additional button properties.
|
|
171
178
|
* @returns {JSX.Element} - The action button component.
|
|
172
179
|
*/
|
|
173
|
-
const ActionButton = ({ action,
|
|
180
|
+
const ActionButton = ({ action, id, ...rest }) => {
|
|
174
181
|
if (action.type === "route") {
|
|
175
|
-
return (jsxRuntime.jsx(reactComponents.Button, { asChild: true, id: id,
|
|
182
|
+
return (jsxRuntime.jsx(reactComponents.Button, { asChild: true, id: id, loading: action.loading, prefix: jsxRuntime.jsx(ActionIcon, { action: action }), ...rest, children: jsxRuntime.jsx(reactRouter.Link, { to: action.url, children: action.label }) }));
|
|
176
183
|
}
|
|
177
|
-
return (jsxRuntime.jsx(reactComponents.Button, { id: id, onClick: e => action.method(e),
|
|
184
|
+
return (jsxRuntime.jsx(reactComponents.Button, { id: id, loading: action.loading, onClick: e => action.method(e), prefix: jsxRuntime.jsx(ActionIcon, { action: action }), ...rest, children: action.label }));
|
|
178
185
|
};
|
|
179
186
|
/**
|
|
180
187
|
* Converts an action model to a MenuItem component.
|
|
@@ -195,7 +202,7 @@ const actionDataToMenuItem = (action, dataTestId) => {
|
|
|
195
202
|
key: action.label,
|
|
196
203
|
dataTestId,
|
|
197
204
|
};
|
|
198
|
-
const item = (jsxRuntime.jsx(reactComponents.MenuItem, { props, className: "flex justify-center", dataTestId: `${dataTestId}-action-label`, label: action.label, onClick: "method" in action ? action.method : undefined, prefix: jsxRuntime.jsx(reactComponents.Icon, { "data-testid": "action-icon", forwardedRef: action.forwardedRef, name: action.icon, size: action.size, style: action.style }), stopPropagation: false }, action.label));
|
|
205
|
+
const item = (jsxRuntime.jsx(reactComponents.MenuItem, { props, className: "flex justify-center", dataTestId: `${dataTestId}-action-label`, label: action.label, onClick: "method" in action ? action.method : undefined, prefix: action.icon ? (jsxRuntime.jsx(reactComponents.Icon, { "data-testid": "action-icon", forwardedRef: action.forwardedRef, name: action.icon, size: action.size, style: action.style })) : null, stopPropagation: false }, action.label));
|
|
199
206
|
if ("url" in action) {
|
|
200
207
|
return (jsxRuntime.jsx(reactRouter.Link, { id: action.id, to: action.url, children: item }, action.label));
|
|
201
208
|
}
|
|
@@ -210,7 +217,18 @@ const actionDataToMenuItem = (action, dataTestId) => {
|
|
|
210
217
|
* @param {string} [dataTestId] - Optional data test ID.
|
|
211
218
|
* @returns {JSX.Element} - The ActionButton component for the given action.
|
|
212
219
|
*/
|
|
213
|
-
const actionDataToActionButton = (action
|
|
220
|
+
const actionDataToActionButton = (action) => (jsxRuntime.jsx(ActionButton, { action: action, className: "max-w-max flex-shrink-0", dataTestId: action.dataTestId || action.id, disabled: action.loading, id: action.id }, action.id));
|
|
221
|
+
/**
|
|
222
|
+
* Renders the icon for an action button.
|
|
223
|
+
* Should not be used outside the ActionSheet component.
|
|
224
|
+
*
|
|
225
|
+
* @param {InnerActionButtonProps} props - The properties for the action icon.
|
|
226
|
+
* @param {ActionModel} props.action - The action model defining what action to perform.
|
|
227
|
+
* @returns {JSX.Element | null} - The icon for the action button, or null if no icon is defined.
|
|
228
|
+
*/
|
|
229
|
+
const ActionIcon = ({ action }) => {
|
|
230
|
+
return action.icon ? (jsxRuntime.jsx(reactComponents.Icon, { color: "white", "data-testid": "action-icon", forwardedRef: action.forwardedRef, name: action.icon, size: "small", style: action.style })) : null;
|
|
231
|
+
};
|
|
214
232
|
|
|
215
233
|
/**
|
|
216
234
|
* `ActionContainerAndOverflow` renders a set of actions and a MoreMenu for overflow.
|
|
@@ -222,8 +240,8 @@ const actionDataToActionButton = (action, dataTestId) => (jsxRuntime.jsxs(Action
|
|
|
222
240
|
* @param {string} [props.dataTestId] - Data test id for the component, useful in testing.
|
|
223
241
|
* @returns {ReactElement} The rendered component.
|
|
224
242
|
*/
|
|
225
|
-
const ActionContainerAndOverflow = ({ actions, moreActions, dataTestId }) => {
|
|
226
|
-
const children = React.useMemo(() => actions.map(action => actionDataToActionButton(action
|
|
243
|
+
const ActionContainerAndOverflow = ({ actions, dropdownActions, moreActions, dataTestId, }) => {
|
|
244
|
+
const children = React.useMemo(() => actions.map(action => actionDataToActionButton(action)), [actions]);
|
|
227
245
|
const { overflowContainerRef, itemOverflowMap } = reactComponents.useOverflowItems({
|
|
228
246
|
children,
|
|
229
247
|
childUniqueIdentifierAttribute: "id",
|
|
@@ -236,13 +254,17 @@ const ActionContainerAndOverflow = ({ actions, moreActions, dataTestId }) => {
|
|
|
236
254
|
return "visible";
|
|
237
255
|
};
|
|
238
256
|
const overflowItemCount = sharedUtils.objectValues(itemOverflowMap).filter(isOverflowing => isOverflowing).length;
|
|
239
|
-
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { className: cvaActionContainerAndOverflow(), ref: overflowContainerRef, children: React.Children.map(children, child => {
|
|
257
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { className: cvaActionContainerAndOverflow({ isDropdown: dropdownActions !== undefined }), ref: overflowContainerRef, children: React.Children.map(children, child => {
|
|
240
258
|
return React.cloneElement(child, {
|
|
241
259
|
className: `${child.props.className} ${itemVisibilityClassName(child.props.id)}`,
|
|
242
260
|
});
|
|
243
|
-
}) }),
|
|
244
|
-
|
|
245
|
-
|
|
261
|
+
}) }), jsxRuntime.jsxs("div", { className: cvaMoreContainer({ isDropdown: dropdownActions !== undefined }), children: [dropdownActions
|
|
262
|
+
? dropdownActions.map(action => {
|
|
263
|
+
return (jsxRuntime.jsx(reactComponents.MoreMenu, { className: "p-0", customButton: jsxRuntime.jsx(reactComponents.Button, { dataTestId: action.dataTestId, id: action.id, loading: action.loading, onClick: action.method, prefix: jsxRuntime.jsx(ActionIcon, { action: action }), children: action.label }), dataTestId: `${dataTestId}-dropdown-more-menu`, popoverProps: { placement: "top-end" }, children: action.dropdown }, action.id));
|
|
264
|
+
})
|
|
265
|
+
: null, React.Children.count(moreActions) > 0 || overflowItemCount ? (jsxRuntime.jsx(reactComponents.MoreMenu, { className: "p-0", dataTestId: `${dataTestId}-more-menu`, iconButtonProps: { variant: "primary" }, iconProps: { color: "white", name: "EllipsisHorizontal" }, popoverProps: { placement: "top-end" }, children: close => (jsxRuntime.jsxs(reactComponents.MenuList, { className: "relative -right-2", onClick: close, children: [moreActions ? moreActions : null, actions.map(action => {
|
|
266
|
+
return itemOverflowMap[action.id] ? actionDataToMenuItem(action, dataTestId) : null;
|
|
267
|
+
})] })) })) : null] })] }));
|
|
246
268
|
};
|
|
247
269
|
|
|
248
270
|
/**
|
|
@@ -253,10 +275,11 @@ const ActionContainerAndOverflow = ({ actions, moreActions, dataTestId }) => {
|
|
|
253
275
|
* @param {ActionSheetProps} props - The props for the ActionSheet component
|
|
254
276
|
* @returns {JSX.Element} ActionSheet component
|
|
255
277
|
*/
|
|
256
|
-
const ActionSheet = ({ actions, moreActions = [], selections, resetSelection, className, dataTestId, }) => {
|
|
278
|
+
const ActionSheet = ({ actions, dropdownActions, moreActions = [], selections, resetSelection, className, dataTestId, }) => {
|
|
257
279
|
const [t] = useTranslation();
|
|
258
|
-
return (jsxRuntime.jsxs("div", { className: cvaActionSheet({ className }), "data-testid": dataTestId, children: [jsxRuntime.
|
|
280
|
+
return (jsxRuntime.jsxs("div", { className: cvaActionSheet({ className }), "data-testid": dataTestId, children: [jsxRuntime.jsx(reactComponents.Button, { className: "row-start-1", dataTestId: "XButton", onClick: resetSelection, prefix: jsxRuntime.jsx(reactComponents.Icon, { color: "white", "data-testid": "close-icon", name: "XMark", size: "small" }), children: t("table.actionsheet.selected", { count: selections.length }) }), jsxRuntime.jsx(reactComponents.Spacer, { border: true, className: cvaDivider() }), jsxRuntime.jsx(ActionContainerAndOverflow, { dataTestId,
|
|
259
281
|
actions,
|
|
282
|
+
dropdownActions,
|
|
260
283
|
moreActions: moreActions.map(action => actionDataToMenuItem(action, dataTestId)) })] }));
|
|
261
284
|
};
|
|
262
285
|
|
package/index.esm.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import { registerTranslations, useNamespaceTranslation } from '@trackunit/i18n-library-translation';
|
|
3
|
-
import { MenuItem, Icon,
|
|
3
|
+
import { MenuItem, Icon, Button, useOverflowItems, MoreMenu, MenuList, Spacer, Card, Text, cvaInteractableItem, Spinner, EmptyState, Tooltip, Popover, PopoverTrigger, PopoverContent } from '@trackunit/react-components';
|
|
4
4
|
import { objectValues, nonNullable, objectKeys, objectEntries } from '@trackunit/shared-utils';
|
|
5
5
|
import * as React from 'react';
|
|
6
6
|
import { useMemo, Children, cloneElement, useRef, useEffect, useState, useCallback } from 'react';
|
|
@@ -96,15 +96,13 @@ const cvaActionSheet = cvaMerge([
|
|
|
96
96
|
"max-w-[80%]",
|
|
97
97
|
"animate-fade-in-fast",
|
|
98
98
|
"grid",
|
|
99
|
-
"grid-
|
|
100
|
-
"grid-cols-[min-content,1fr,min-content]",
|
|
101
|
-
"sm:grid-cols-[min-content,1fr,min-content]",
|
|
99
|
+
"grid-cols-[min-content,1fr]",
|
|
100
|
+
"sm:grid-cols-[min-content,min-content,1fr,min-content]",
|
|
102
101
|
"sm:grid-rows-1",
|
|
103
102
|
"p-2",
|
|
104
103
|
"bg-primary-600",
|
|
105
104
|
"gap-1",
|
|
106
105
|
"rounded-2xl",
|
|
107
|
-
"items-center",
|
|
108
106
|
"z-top",
|
|
109
107
|
"shadow-2xl",
|
|
110
108
|
"fixed",
|
|
@@ -112,31 +110,41 @@ const cvaActionSheet = cvaMerge([
|
|
|
112
110
|
"left-1/2",
|
|
113
111
|
"-translate-x-1/2",
|
|
114
112
|
]);
|
|
113
|
+
const cvaDivider = cvaMerge(["border-blue-500", "row-start-2", "col-span-4", "sm:hidden", "min-h-px"]);
|
|
115
114
|
const cvaActionContainerAndOverflow = cvaMerge([
|
|
116
|
-
"
|
|
115
|
+
"row-start-3",
|
|
116
|
+
"col-span-full",
|
|
117
117
|
"flex",
|
|
118
|
-
"flex-row
|
|
119
|
-
"flex-nowrap",
|
|
120
|
-
"justify-end",
|
|
118
|
+
"flex-row",
|
|
121
119
|
"gap-2",
|
|
122
120
|
"overflow-hidden",
|
|
123
|
-
"sm:
|
|
124
|
-
"sm:
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
const cvaActionSpinner = cvaMerge([], {
|
|
121
|
+
"sm:row-start-1",
|
|
122
|
+
"sm:col-span-3",
|
|
123
|
+
"sm:justify-end",
|
|
124
|
+
], {
|
|
128
125
|
variants: {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
secondary: ["h-3.5", "w-3.5"],
|
|
133
|
-
"secondary-danger": ["h-3.5", "w-3.5"],
|
|
134
|
-
ghost: [],
|
|
135
|
-
"ghost-neutral": [],
|
|
126
|
+
isDropdown: {
|
|
127
|
+
true: [],
|
|
128
|
+
false: ["col-span-2"],
|
|
136
129
|
},
|
|
137
130
|
},
|
|
138
|
-
|
|
139
|
-
|
|
131
|
+
});
|
|
132
|
+
const cvaMoreContainer = cvaMerge([
|
|
133
|
+
"row-start-4",
|
|
134
|
+
"col-span-full",
|
|
135
|
+
"sm:col-span-1",
|
|
136
|
+
"flex",
|
|
137
|
+
"flex-row",
|
|
138
|
+
"justify-between",
|
|
139
|
+
"gap-2",
|
|
140
|
+
"sm:row-start-1",
|
|
141
|
+
"sm:col-span-3",
|
|
142
|
+
], {
|
|
143
|
+
variants: {
|
|
144
|
+
isDropdown: {
|
|
145
|
+
true: [],
|
|
146
|
+
false: ["row-start-3", "col-span-2", "place-self-end"],
|
|
147
|
+
},
|
|
140
148
|
},
|
|
141
149
|
});
|
|
142
150
|
|
|
@@ -146,16 +154,15 @@ const cvaActionSpinner = cvaMerge([], {
|
|
|
146
154
|
*
|
|
147
155
|
* @param {ActionButtonProps} props - The properties for the action button.
|
|
148
156
|
* @param {ActionModel} props.action - The action model defining what action to perform.
|
|
149
|
-
* @param {ReactNode} props.children - The children to render inside the button.
|
|
150
157
|
* @param {string} [props.id] - The optional ID for the button.
|
|
151
158
|
* @param {...any} [props.rest] - Any additional button properties.
|
|
152
159
|
* @returns {JSX.Element} - The action button component.
|
|
153
160
|
*/
|
|
154
|
-
const ActionButton = ({ action,
|
|
161
|
+
const ActionButton = ({ action, id, ...rest }) => {
|
|
155
162
|
if (action.type === "route") {
|
|
156
|
-
return (jsx(Button, { asChild: true, id: id,
|
|
163
|
+
return (jsx(Button, { asChild: true, id: id, loading: action.loading, prefix: jsx(ActionIcon, { action: action }), ...rest, children: jsx(Link, { to: action.url, children: action.label }) }));
|
|
157
164
|
}
|
|
158
|
-
return (jsx(Button, { id: id, onClick: e => action.method(e),
|
|
165
|
+
return (jsx(Button, { id: id, loading: action.loading, onClick: e => action.method(e), prefix: jsx(ActionIcon, { action: action }), ...rest, children: action.label }));
|
|
159
166
|
};
|
|
160
167
|
/**
|
|
161
168
|
* Converts an action model to a MenuItem component.
|
|
@@ -176,7 +183,7 @@ const actionDataToMenuItem = (action, dataTestId) => {
|
|
|
176
183
|
key: action.label,
|
|
177
184
|
dataTestId,
|
|
178
185
|
};
|
|
179
|
-
const item = (jsx(MenuItem, { props, className: "flex justify-center", dataTestId: `${dataTestId}-action-label`, label: action.label, onClick: "method" in action ? action.method : undefined, prefix: jsx(Icon, { "data-testid": "action-icon", forwardedRef: action.forwardedRef, name: action.icon, size: action.size, style: action.style }), stopPropagation: false }, action.label));
|
|
186
|
+
const item = (jsx(MenuItem, { props, className: "flex justify-center", dataTestId: `${dataTestId}-action-label`, label: action.label, onClick: "method" in action ? action.method : undefined, prefix: action.icon ? (jsx(Icon, { "data-testid": "action-icon", forwardedRef: action.forwardedRef, name: action.icon, size: action.size, style: action.style })) : null, stopPropagation: false }, action.label));
|
|
180
187
|
if ("url" in action) {
|
|
181
188
|
return (jsx(Link, { id: action.id, to: action.url, children: item }, action.label));
|
|
182
189
|
}
|
|
@@ -191,7 +198,18 @@ const actionDataToMenuItem = (action, dataTestId) => {
|
|
|
191
198
|
* @param {string} [dataTestId] - Optional data test ID.
|
|
192
199
|
* @returns {JSX.Element} - The ActionButton component for the given action.
|
|
193
200
|
*/
|
|
194
|
-
const actionDataToActionButton = (action
|
|
201
|
+
const actionDataToActionButton = (action) => (jsx(ActionButton, { action: action, className: "max-w-max flex-shrink-0", dataTestId: action.dataTestId || action.id, disabled: action.loading, id: action.id }, action.id));
|
|
202
|
+
/**
|
|
203
|
+
* Renders the icon for an action button.
|
|
204
|
+
* Should not be used outside the ActionSheet component.
|
|
205
|
+
*
|
|
206
|
+
* @param {InnerActionButtonProps} props - The properties for the action icon.
|
|
207
|
+
* @param {ActionModel} props.action - The action model defining what action to perform.
|
|
208
|
+
* @returns {JSX.Element | null} - The icon for the action button, or null if no icon is defined.
|
|
209
|
+
*/
|
|
210
|
+
const ActionIcon = ({ action }) => {
|
|
211
|
+
return action.icon ? (jsx(Icon, { color: "white", "data-testid": "action-icon", forwardedRef: action.forwardedRef, name: action.icon, size: "small", style: action.style })) : null;
|
|
212
|
+
};
|
|
195
213
|
|
|
196
214
|
/**
|
|
197
215
|
* `ActionContainerAndOverflow` renders a set of actions and a MoreMenu for overflow.
|
|
@@ -203,8 +221,8 @@ const actionDataToActionButton = (action, dataTestId) => (jsxs(ActionButton, { a
|
|
|
203
221
|
* @param {string} [props.dataTestId] - Data test id for the component, useful in testing.
|
|
204
222
|
* @returns {ReactElement} The rendered component.
|
|
205
223
|
*/
|
|
206
|
-
const ActionContainerAndOverflow = ({ actions, moreActions, dataTestId }) => {
|
|
207
|
-
const children = useMemo(() => actions.map(action => actionDataToActionButton(action
|
|
224
|
+
const ActionContainerAndOverflow = ({ actions, dropdownActions, moreActions, dataTestId, }) => {
|
|
225
|
+
const children = useMemo(() => actions.map(action => actionDataToActionButton(action)), [actions]);
|
|
208
226
|
const { overflowContainerRef, itemOverflowMap } = useOverflowItems({
|
|
209
227
|
children,
|
|
210
228
|
childUniqueIdentifierAttribute: "id",
|
|
@@ -217,13 +235,17 @@ const ActionContainerAndOverflow = ({ actions, moreActions, dataTestId }) => {
|
|
|
217
235
|
return "visible";
|
|
218
236
|
};
|
|
219
237
|
const overflowItemCount = objectValues(itemOverflowMap).filter(isOverflowing => isOverflowing).length;
|
|
220
|
-
return (jsxs(Fragment, { children: [jsx("div", { className: cvaActionContainerAndOverflow(), ref: overflowContainerRef, children: Children.map(children, child => {
|
|
238
|
+
return (jsxs(Fragment, { children: [jsx("div", { className: cvaActionContainerAndOverflow({ isDropdown: dropdownActions !== undefined }), ref: overflowContainerRef, children: Children.map(children, child => {
|
|
221
239
|
return cloneElement(child, {
|
|
222
240
|
className: `${child.props.className} ${itemVisibilityClassName(child.props.id)}`,
|
|
223
241
|
});
|
|
224
|
-
}) }),
|
|
225
|
-
|
|
226
|
-
|
|
242
|
+
}) }), jsxs("div", { className: cvaMoreContainer({ isDropdown: dropdownActions !== undefined }), children: [dropdownActions
|
|
243
|
+
? dropdownActions.map(action => {
|
|
244
|
+
return (jsx(MoreMenu, { className: "p-0", customButton: jsx(Button, { dataTestId: action.dataTestId, id: action.id, loading: action.loading, onClick: action.method, prefix: jsx(ActionIcon, { action: action }), children: action.label }), dataTestId: `${dataTestId}-dropdown-more-menu`, popoverProps: { placement: "top-end" }, children: action.dropdown }, action.id));
|
|
245
|
+
})
|
|
246
|
+
: null, Children.count(moreActions) > 0 || overflowItemCount ? (jsx(MoreMenu, { className: "p-0", dataTestId: `${dataTestId}-more-menu`, iconButtonProps: { variant: "primary" }, iconProps: { color: "white", name: "EllipsisHorizontal" }, popoverProps: { placement: "top-end" }, children: close => (jsxs(MenuList, { className: "relative -right-2", onClick: close, children: [moreActions ? moreActions : null, actions.map(action => {
|
|
247
|
+
return itemOverflowMap[action.id] ? actionDataToMenuItem(action, dataTestId) : null;
|
|
248
|
+
})] })) })) : null] })] }));
|
|
227
249
|
};
|
|
228
250
|
|
|
229
251
|
/**
|
|
@@ -234,10 +256,11 @@ const ActionContainerAndOverflow = ({ actions, moreActions, dataTestId }) => {
|
|
|
234
256
|
* @param {ActionSheetProps} props - The props for the ActionSheet component
|
|
235
257
|
* @returns {JSX.Element} ActionSheet component
|
|
236
258
|
*/
|
|
237
|
-
const ActionSheet = ({ actions, moreActions = [], selections, resetSelection, className, dataTestId, }) => {
|
|
259
|
+
const ActionSheet = ({ actions, dropdownActions, moreActions = [], selections, resetSelection, className, dataTestId, }) => {
|
|
238
260
|
const [t] = useTranslation();
|
|
239
|
-
return (jsxs("div", { className: cvaActionSheet({ className }), "data-testid": dataTestId, children: [
|
|
261
|
+
return (jsxs("div", { className: cvaActionSheet({ className }), "data-testid": dataTestId, children: [jsx(Button, { className: "row-start-1", dataTestId: "XButton", onClick: resetSelection, prefix: jsx(Icon, { color: "white", "data-testid": "close-icon", name: "XMark", size: "small" }), children: t("table.actionsheet.selected", { count: selections.length }) }), jsx(Spacer, { border: true, className: cvaDivider() }), jsx(ActionContainerAndOverflow, { dataTestId,
|
|
240
262
|
actions,
|
|
263
|
+
dropdownActions,
|
|
241
264
|
moreActions: moreActions.map(action => actionDataToMenuItem(action, dataTestId)) })] }));
|
|
242
265
|
};
|
|
243
266
|
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { CommonProps, SidebarItemProps } from "@trackunit/react-components";
|
|
2
2
|
import { ReactElement } from "react";
|
|
3
|
-
import { ActionModel } from "./Actions";
|
|
3
|
+
import { ActionModel, DropdownModel } from "./Actions";
|
|
4
4
|
interface ActionContainerAndOverflowProps extends CommonProps {
|
|
5
5
|
actions: ActionModel[];
|
|
6
|
+
dropdownActions?: DropdownModel[];
|
|
6
7
|
moreActions?: ReactElement<SidebarItemProps>[] | ReactElement<SidebarItemProps>;
|
|
7
8
|
}
|
|
8
9
|
/**
|
|
@@ -15,5 +16,5 @@ interface ActionContainerAndOverflowProps extends CommonProps {
|
|
|
15
16
|
* @param {string} [props.dataTestId] - Data test id for the component, useful in testing.
|
|
16
17
|
* @returns {ReactElement} The rendered component.
|
|
17
18
|
*/
|
|
18
|
-
export declare const ActionContainerAndOverflow: ({ actions, moreActions, dataTestId }: ActionContainerAndOverflowProps) => import("react/jsx-runtime").JSX.Element;
|
|
19
|
+
export declare const ActionContainerAndOverflow: ({ actions, dropdownActions, moreActions, dataTestId, }: ActionContainerAndOverflowProps) => import("react/jsx-runtime").JSX.Element;
|
|
19
20
|
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CommonProps } from "@trackunit/react-components";
|
|
2
|
-
import { ActionModel } from "./Actions";
|
|
2
|
+
import { ActionModel, DropdownModel } from "./Actions";
|
|
3
3
|
export interface ActionSheetProps extends CommonProps {
|
|
4
4
|
/**
|
|
5
5
|
* Actions to be displayed in the ActionSheet as primary actions (normally visible)
|
|
@@ -9,6 +9,10 @@ export interface ActionSheetProps extends CommonProps {
|
|
|
9
9
|
* Secondary Actions to be displayed in the ActionSheet via the more menu
|
|
10
10
|
*/
|
|
11
11
|
moreActions?: ActionModel[];
|
|
12
|
+
/**
|
|
13
|
+
* Actions to be displayed as primary actions with capability to pass MenuList as dropdown
|
|
14
|
+
*/
|
|
15
|
+
dropdownActions?: DropdownModel[];
|
|
12
16
|
/**
|
|
13
17
|
* array of selected element-ids is used for calculating the number of selected elements - and available for eventhandlers.
|
|
14
18
|
*/
|
|
@@ -26,4 +30,4 @@ export interface ActionSheetProps extends CommonProps {
|
|
|
26
30
|
* @param {ActionSheetProps} props - The props for the ActionSheet component
|
|
27
31
|
* @returns {JSX.Element} ActionSheet component
|
|
28
32
|
*/
|
|
29
|
-
export declare const ActionSheet: ({ actions, moreActions, selections, resetSelection, className, dataTestId, }: ActionSheetProps) => import("react/jsx-runtime").JSX.Element;
|
|
33
|
+
export declare const ActionSheet: ({ actions, dropdownActions, moreActions, selections, resetSelection, className, dataTestId, }: ActionSheetProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export declare const cvaActionSheet: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
|
|
2
|
-
export declare const
|
|
3
|
-
export declare const
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
export declare const cvaDivider: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
|
|
3
|
+
export declare const cvaActionContainerAndOverflow: (props?: ({
|
|
4
|
+
isDropdown?: boolean | null | undefined;
|
|
5
|
+
} & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
|
|
6
|
+
export declare const cvaMoreContainer: (props?: ({
|
|
7
|
+
isDropdown?: boolean | null | undefined;
|
|
6
8
|
} & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
|
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
import { ButtonCommonProps } from "@trackunit/react-components";
|
|
2
|
-
import { ReactNode } from "react";
|
|
3
2
|
import { ActionModel } from "./Actions";
|
|
4
3
|
interface ActionButtonProps extends ButtonCommonProps {
|
|
5
4
|
/**
|
|
6
5
|
* The action model defining what the action.
|
|
7
6
|
*/
|
|
8
7
|
action: ActionModel;
|
|
9
|
-
/**
|
|
10
|
-
* The children to render inside the button.
|
|
11
|
-
*/
|
|
12
|
-
children: ReactNode;
|
|
13
8
|
}
|
|
14
9
|
/**
|
|
15
10
|
* The button to show in the ActionSheet.
|
|
@@ -17,12 +12,11 @@ interface ActionButtonProps extends ButtonCommonProps {
|
|
|
17
12
|
*
|
|
18
13
|
* @param {ActionButtonProps} props - The properties for the action button.
|
|
19
14
|
* @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
15
|
* @param {string} [props.id] - The optional ID for the button.
|
|
22
16
|
* @param {...any} [props.rest] - Any additional button properties.
|
|
23
17
|
* @returns {JSX.Element} - The action button component.
|
|
24
18
|
*/
|
|
25
|
-
export declare const ActionButton: ({ action,
|
|
19
|
+
export declare const ActionButton: ({ action, id, ...rest }: ActionButtonProps) => import("react/jsx-runtime").JSX.Element;
|
|
26
20
|
/**
|
|
27
21
|
* Converts an action model to a MenuItem component.
|
|
28
22
|
* These should be shown in the more menu.
|
|
@@ -42,5 +36,17 @@ export declare const actionDataToMenuItem: (action: ActionModel, dataTestId?: st
|
|
|
42
36
|
* @param {string} [dataTestId] - Optional data test ID.
|
|
43
37
|
* @returns {JSX.Element} - The ActionButton component for the given action.
|
|
44
38
|
*/
|
|
45
|
-
export declare const actionDataToActionButton: (action: ActionModel
|
|
39
|
+
export declare const actionDataToActionButton: (action: ActionModel) => import("react/jsx-runtime").JSX.Element;
|
|
40
|
+
interface InnerActionButtonProps {
|
|
41
|
+
action: ActionModel;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Renders the icon for an action button.
|
|
45
|
+
* Should not be used outside the ActionSheet component.
|
|
46
|
+
*
|
|
47
|
+
* @param {InnerActionButtonProps} props - The properties for the action icon.
|
|
48
|
+
* @param {ActionModel} props.action - The action model defining what action to perform.
|
|
49
|
+
* @returns {JSX.Element | null} - The icon for the action button, or null if no icon is defined.
|
|
50
|
+
*/
|
|
51
|
+
export declare const ActionIcon: ({ action }: InnerActionButtonProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
46
52
|
export {};
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
import { IconProps
|
|
1
|
+
import { IconProps } from "@trackunit/react-components";
|
|
2
2
|
import { IconName } from "@trackunit/ui-icons";
|
|
3
|
+
import { ReactNode } from "react";
|
|
3
4
|
type IconExposedProp = Omit<IconProps, "color" | "onclick" | "type" | "name">;
|
|
4
5
|
export type ActionModel = (MethodAction | RouteAction) & CommonAction;
|
|
6
|
+
export type DropdownModel = MethodAction & CommonAction & {
|
|
7
|
+
dropdown: ReactNode;
|
|
8
|
+
};
|
|
5
9
|
export type MethodAction = {
|
|
6
10
|
type: "method";
|
|
7
11
|
method: (e: React.MouseEvent) => void;
|
|
@@ -14,8 +18,7 @@ export type RouteAction = {
|
|
|
14
18
|
export interface CommonAction extends IconExposedProp {
|
|
15
19
|
id: string;
|
|
16
20
|
label: string;
|
|
17
|
-
icon
|
|
18
|
-
size?: Size;
|
|
21
|
+
icon?: IconName;
|
|
19
22
|
forwardedRef?: React.RefObject<HTMLSpanElement>;
|
|
20
23
|
style?: Record<string, string>;
|
|
21
24
|
loading?: boolean;
|