@coveord/plasma-mantine 51.2.0 → 52.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +3 -3
- package/.turbo/turbo-test.log +30 -29
- package/dist/.tsbuildinfo +1 -1
- package/dist/cjs/components/code-editor/CodeEditor.js +3 -21
- package/dist/cjs/components/code-editor/CodeEditor.js.map +1 -1
- package/dist/cjs/components/collection/Collection.js +6 -3
- package/dist/cjs/components/collection/Collection.js.map +1 -1
- package/dist/cjs/components/collection/CollectionItem.js +1 -1
- package/dist/cjs/components/collection/CollectionItem.js.map +1 -1
- package/dist/cjs/components/copyToClipboard/CopyToClipboard.js +60 -0
- package/dist/cjs/components/copyToClipboard/CopyToClipboard.js.map +1 -0
- package/dist/cjs/components/copyToClipboard/index.js +8 -0
- package/dist/cjs/components/copyToClipboard/index.js.map +1 -0
- package/dist/cjs/components/index.js +1 -0
- package/dist/cjs/components/index.js.map +1 -1
- package/dist/cjs/components/modal-wizard/ModalWizard.js +2 -2
- package/dist/cjs/components/modal-wizard/ModalWizard.js.map +1 -1
- package/dist/cjs/components/table/Table.js +43 -35
- package/dist/cjs/components/table/Table.js.map +1 -1
- package/dist/cjs/components/table/TableConsumer.js +19 -0
- package/dist/cjs/components/table/TableConsumer.js.map +1 -0
- package/dist/cjs/index.js +3 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/definitions/components/code-editor/CodeEditor.d.ts.map +1 -1
- package/dist/definitions/components/collection/Collection.d.ts +10 -0
- package/dist/definitions/components/collection/Collection.d.ts.map +1 -1
- package/dist/definitions/components/copyToClipboard/CopyToClipboard.d.ts +15 -0
- package/dist/definitions/components/copyToClipboard/CopyToClipboard.d.ts.map +1 -0
- package/dist/definitions/components/copyToClipboard/index.d.ts +2 -0
- package/dist/definitions/components/copyToClipboard/index.d.ts.map +1 -0
- package/dist/definitions/components/index.d.ts +1 -0
- package/dist/definitions/components/index.d.ts.map +1 -1
- package/dist/definitions/components/modal-wizard/ModalWizard.d.ts +2 -2
- package/dist/definitions/components/modal-wizard/ModalWizard.d.ts.map +1 -1
- package/dist/definitions/components/table/Table.d.ts.map +1 -1
- package/dist/definitions/components/table/Table.types.d.ts +2 -0
- package/dist/definitions/components/table/Table.types.d.ts.map +1 -1
- package/dist/definitions/components/table/TableConsumer.d.ts +5 -0
- package/dist/definitions/components/table/TableConsumer.d.ts.map +1 -0
- package/dist/definitions/index.d.ts +1 -1
- package/dist/definitions/index.d.ts.map +1 -1
- package/dist/esm/components/code-editor/CodeEditor.js +4 -22
- package/dist/esm/components/code-editor/CodeEditor.js.map +1 -1
- package/dist/esm/components/collection/Collection.js +7 -4
- package/dist/esm/components/collection/Collection.js.map +1 -1
- package/dist/esm/components/collection/CollectionItem.js +1 -1
- package/dist/esm/components/collection/CollectionItem.js.map +1 -1
- package/dist/esm/components/copyToClipboard/CopyToClipboard.js +49 -0
- package/dist/esm/components/copyToClipboard/CopyToClipboard.js.map +1 -0
- package/dist/esm/components/copyToClipboard/index.js +3 -0
- package/dist/esm/components/copyToClipboard/index.js.map +1 -0
- package/dist/esm/components/index.js +1 -0
- package/dist/esm/components/index.js.map +1 -1
- package/dist/esm/components/modal-wizard/ModalWizard.js +2 -2
- package/dist/esm/components/modal-wizard/ModalWizard.js.map +1 -1
- package/dist/esm/components/table/Table.js +43 -35
- package/dist/esm/components/table/Table.js.map +1 -1
- package/dist/esm/components/table/Table.types.js.map +1 -1
- package/dist/esm/components/table/TableConsumer.js +9 -0
- package/dist/esm/components/table/TableConsumer.js.map +1 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/package.json +16 -16
- package/src/components/code-editor/CodeEditor.tsx +2 -13
- package/src/components/collection/Collection.tsx +15 -4
- package/src/components/collection/CollectionItem.tsx +1 -1
- package/src/components/copyToClipboard/CopyToClipboard.tsx +52 -0
- package/src/components/copyToClipboard/__tests__/CopyToClipboard.spec.tsx +25 -0
- package/src/components/copyToClipboard/index.ts +1 -0
- package/src/components/index.ts +1 -0
- package/src/components/modal-wizard/ModalWizard.tsx +4 -4
- package/src/components/modal-wizard/__tests__/ModalWizard.spec.tsx +10 -0
- package/src/components/table/Table.tsx +4 -0
- package/src/components/table/Table.types.ts +3 -1
- package/src/components/table/TableConsumer.tsx +3 -0
- package/src/components/table/__tests__/Table.spec.tsx +25 -0
- package/src/index.ts +2 -0
|
@@ -12,8 +12,8 @@ import {
|
|
|
12
12
|
useComponentDefaultProps,
|
|
13
13
|
} from '@mantine/core';
|
|
14
14
|
import {ReorderPayload} from '@mantine/form/lib/types';
|
|
15
|
-
import {useDidUpdate
|
|
16
|
-
import {ReactNode} from 'react';
|
|
15
|
+
import {useDidUpdate} from '@mantine/hooks';
|
|
16
|
+
import {ReactNode, useId} from 'react';
|
|
17
17
|
import {DragDropContext, Droppable} from 'react-beautiful-dnd';
|
|
18
18
|
|
|
19
19
|
import {Button} from '../button';
|
|
@@ -40,6 +40,16 @@ interface CollectionProps<T>
|
|
|
40
40
|
* @default []
|
|
41
41
|
*/
|
|
42
42
|
value?: T[];
|
|
43
|
+
/**
|
|
44
|
+
* Defines how each item is uniquely identified. It is highly recommended that you specify this prop to an ID that makes sense.
|
|
45
|
+
*
|
|
46
|
+
* This method is required when using this component with ReactHookForm.
|
|
47
|
+
*
|
|
48
|
+
* @see {@link https://react-hook-form.com/api/usefieldarray/} for using a collection with ReactHookForm.
|
|
49
|
+
*
|
|
50
|
+
* @param originalItem The original item
|
|
51
|
+
*/
|
|
52
|
+
getItemId?: (originalItem: T) => string;
|
|
43
53
|
/**
|
|
44
54
|
* Unused, has no effect
|
|
45
55
|
*/
|
|
@@ -146,6 +156,7 @@ export const Collection = <T,>(props: CollectionProps<T>) => {
|
|
|
146
156
|
descriptionProps,
|
|
147
157
|
error,
|
|
148
158
|
errorProps,
|
|
159
|
+
getItemId,
|
|
149
160
|
|
|
150
161
|
// Style props
|
|
151
162
|
classNames,
|
|
@@ -156,7 +167,7 @@ export const Collection = <T,>(props: CollectionProps<T>) => {
|
|
|
156
167
|
...others
|
|
157
168
|
} = useComponentDefaultProps('Collection', defaultProps as CollectionProps<T>, props);
|
|
158
169
|
const {classes, cx} = useStyles(null, {classNames, name: 'Collection', styles, unstyled});
|
|
159
|
-
const collectionID = useId(
|
|
170
|
+
const collectionID = useId();
|
|
160
171
|
|
|
161
172
|
const hasOnlyOneItem = value.length === 1;
|
|
162
173
|
|
|
@@ -188,7 +199,7 @@ export const Collection = <T,>(props: CollectionProps<T>) => {
|
|
|
188
199
|
|
|
189
200
|
const items = value.map((item, index) => (
|
|
190
201
|
<CollectionItem
|
|
191
|
-
key={index}
|
|
202
|
+
key={(getItemId?.(item) ?? index) as string}
|
|
192
203
|
disabled={disabled}
|
|
193
204
|
draggable={draggable}
|
|
194
205
|
index={index}
|
|
@@ -62,7 +62,7 @@ const DraggableCollectionItem: FunctionComponent<PropsWithChildren<CollectionIte
|
|
|
62
62
|
const removeButton = removable && onRemove ? <RemoveButton onClick={onRemove} /> : null;
|
|
63
63
|
|
|
64
64
|
return (
|
|
65
|
-
<Draggable index={index} draggableId={index.toString()}>
|
|
65
|
+
<Draggable key={index} index={index} draggableId={index.toString()}>
|
|
66
66
|
{(provided, {isDragging}) => (
|
|
67
67
|
<Group
|
|
68
68
|
ref={provided.innerRef}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import {CheckSize24Px, CopySize24Px} from '@coveord/plasma-react-icons';
|
|
4
|
+
import {TextInput, CopyButton, Tooltip, ActionIcon, createStyles} from '@mantine/core';
|
|
5
|
+
|
|
6
|
+
export interface CopyToClipboardProps {
|
|
7
|
+
/**
|
|
8
|
+
* The value to be copied to the clipboard.
|
|
9
|
+
*/
|
|
10
|
+
value: string;
|
|
11
|
+
/**
|
|
12
|
+
* Whether to display the string to be copied alongside the button.
|
|
13
|
+
*
|
|
14
|
+
* @default false
|
|
15
|
+
*/
|
|
16
|
+
withLabel?: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const useStyles = createStyles((theme) => ({
|
|
20
|
+
input: {
|
|
21
|
+
color: theme.colors.gray[7],
|
|
22
|
+
},
|
|
23
|
+
}));
|
|
24
|
+
|
|
25
|
+
const CopyToClipboardButton: React.FunctionComponent<{value: string}> = ({value}) => (
|
|
26
|
+
<CopyButton value={value} timeout={2000}>
|
|
27
|
+
{({copied, copy}) => (
|
|
28
|
+
<Tooltip label={copied ? 'Copied' : 'Copy'} withArrow position="top">
|
|
29
|
+
<ActionIcon color={copied ? 'teal' : 'gray'} onClick={copy}>
|
|
30
|
+
{copied ? <CheckSize24Px /> : <CopySize24Px />}
|
|
31
|
+
</ActionIcon>
|
|
32
|
+
</Tooltip>
|
|
33
|
+
)}
|
|
34
|
+
</CopyButton>
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
export const CopyToClipboard: React.FunctionComponent<CopyToClipboardProps> = ({value, withLabel}) => {
|
|
38
|
+
const {classes} = useStyles();
|
|
39
|
+
|
|
40
|
+
return withLabel ? (
|
|
41
|
+
<TextInput
|
|
42
|
+
classNames={{
|
|
43
|
+
input: classes.input,
|
|
44
|
+
}}
|
|
45
|
+
value={value}
|
|
46
|
+
readOnly
|
|
47
|
+
rightSection={<CopyToClipboardButton value={value} />}
|
|
48
|
+
/>
|
|
49
|
+
) : (
|
|
50
|
+
<CopyToClipboardButton value={value} />
|
|
51
|
+
);
|
|
52
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {render, screen} from '@test-utils';
|
|
2
|
+
|
|
3
|
+
import {CopyToClipboard} from '../CopyToClipboard';
|
|
4
|
+
|
|
5
|
+
describe('CopyToClipboard', () => {
|
|
6
|
+
it('should display only a button by default', () => {
|
|
7
|
+
const testValue = 'text value';
|
|
8
|
+
render(<CopyToClipboard value={testValue} />);
|
|
9
|
+
|
|
10
|
+
expect(screen.getByRole('button', {name: /copy/i})).toBeVisible();
|
|
11
|
+
expect(screen.queryByDisplayValue(testValue)).not.toBeInTheDocument();
|
|
12
|
+
expect(document.querySelector('input')).not.toBeInTheDocument();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
describe('when "isLabel" is true', () => {
|
|
16
|
+
it('should display an input element', () => {
|
|
17
|
+
const testValue = 'text value';
|
|
18
|
+
render(<CopyToClipboard value={testValue} withLabel />);
|
|
19
|
+
|
|
20
|
+
expect(screen.getByDisplayValue(testValue)).toBeVisible();
|
|
21
|
+
expect(screen.getByRole('button', {name: /copy/i})).toBeVisible();
|
|
22
|
+
expect(document.querySelector('input')).toBeInTheDocument();
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './CopyToClipboard';
|
package/src/components/index.ts
CHANGED
|
@@ -54,12 +54,12 @@ export interface ModalWizardProps
|
|
|
54
54
|
/**
|
|
55
55
|
* A callback function that is executed when the user clicks on the next button
|
|
56
56
|
*/
|
|
57
|
-
onNext?: () => unknown;
|
|
57
|
+
onNext?: (newStep: number) => unknown;
|
|
58
58
|
|
|
59
59
|
/**
|
|
60
60
|
* A callback function that is executed when the user clicks on the previous button
|
|
61
61
|
*/
|
|
62
|
-
onPrevious?: () => unknown;
|
|
62
|
+
onPrevious?: (newStep: number) => unknown;
|
|
63
63
|
|
|
64
64
|
/**
|
|
65
65
|
* A function that is executed when user completes all the steps.
|
|
@@ -210,7 +210,7 @@ export const ModalWizard: ModalWizardType = ({
|
|
|
210
210
|
if (isFirstStep) {
|
|
211
211
|
handleClose(true);
|
|
212
212
|
} else {
|
|
213
|
-
onPrevious?.();
|
|
213
|
+
onPrevious?.(currentStepIndex - 1);
|
|
214
214
|
setCurrentStepIndex(currentStepIndex - 1);
|
|
215
215
|
}
|
|
216
216
|
}}
|
|
@@ -224,7 +224,7 @@ export const ModalWizard: ModalWizardType = ({
|
|
|
224
224
|
if (isLastStep) {
|
|
225
225
|
onFinish?.() ?? handleClose(false);
|
|
226
226
|
} else {
|
|
227
|
-
onNext?.();
|
|
227
|
+
onNext?.(currentStepIndex + 1);
|
|
228
228
|
setCurrentStepIndex(currentStepIndex + 1);
|
|
229
229
|
}
|
|
230
230
|
}}
|
|
@@ -34,6 +34,8 @@ describe('ModalWizard', () => {
|
|
|
34
34
|
];
|
|
35
35
|
|
|
36
36
|
const isDirty = () => false;
|
|
37
|
+
const onNextSpy = vi.fn();
|
|
38
|
+
const onPreviousSpy = vi.fn();
|
|
37
39
|
|
|
38
40
|
render(
|
|
39
41
|
<ModalWizard
|
|
@@ -41,6 +43,8 @@ describe('ModalWizard', () => {
|
|
|
41
43
|
handleDirtyState={() => confirm('Are you sure you want to close?')}
|
|
42
44
|
opened={true}
|
|
43
45
|
onClose={undefined}
|
|
46
|
+
onNext={onNextSpy}
|
|
47
|
+
onPrevious={onPreviousSpy}
|
|
44
48
|
>
|
|
45
49
|
{modelSteps.map((model_item) => (
|
|
46
50
|
<ModalWizard.Step
|
|
@@ -75,6 +79,8 @@ describe('ModalWizard', () => {
|
|
|
75
79
|
|
|
76
80
|
await user.click(nextButton);
|
|
77
81
|
|
|
82
|
+
expect(onNextSpy).toHaveBeenCalledWith(1);
|
|
83
|
+
|
|
78
84
|
expect(
|
|
79
85
|
screen.getByRole('heading', {
|
|
80
86
|
name: /current step is: 2/i,
|
|
@@ -102,6 +108,8 @@ describe('ModalWizard', () => {
|
|
|
102
108
|
|
|
103
109
|
await user.click(nextButton);
|
|
104
110
|
|
|
111
|
+
expect(onNextSpy).toHaveBeenCalledWith(2);
|
|
112
|
+
|
|
105
113
|
expect(
|
|
106
114
|
screen.getByRole('heading', {
|
|
107
115
|
name: /current step is: 3/i,
|
|
@@ -135,6 +143,8 @@ describe('ModalWizard', () => {
|
|
|
135
143
|
})
|
|
136
144
|
);
|
|
137
145
|
|
|
146
|
+
expect(onNextSpy).toHaveBeenCalledWith(1);
|
|
147
|
+
|
|
138
148
|
expect(
|
|
139
149
|
screen.getByRole('heading', {
|
|
140
150
|
name: /current step is: 2/i,
|
|
@@ -26,6 +26,7 @@ import {TableHeader} from './TableHeader';
|
|
|
26
26
|
import {TablePagination} from './TablePagination';
|
|
27
27
|
import {TablePerPage} from './TablePerPage';
|
|
28
28
|
import {TablePredicate} from './TablePredicate';
|
|
29
|
+
import {TableConsumer} from './TableConsumer';
|
|
29
30
|
import {TableSelectableColumn} from './TableSelectableColumn';
|
|
30
31
|
import {Th} from './Th';
|
|
31
32
|
import {useRowSelection} from './useRowSelection';
|
|
@@ -55,6 +56,7 @@ export const Table: TableType = <T,>({
|
|
|
55
56
|
const convertedChildren = Children.toArray(children) as ReactElement[];
|
|
56
57
|
const header = convertedChildren.find((child) => child.type === TableHeader);
|
|
57
58
|
const footer = convertedChildren.find((child) => child.type === TableFooter);
|
|
59
|
+
const consumer = convertedChildren.find((child) => child.type === TableConsumer);
|
|
58
60
|
|
|
59
61
|
const {predicates, dateRange, ...initialStateWithoutForm} = initialState;
|
|
60
62
|
const form = useForm<TableFormType>({
|
|
@@ -189,6 +191,7 @@ export const Table: TableType = <T,>({
|
|
|
189
191
|
getPageCount: table.getPageCount,
|
|
190
192
|
}}
|
|
191
193
|
>
|
|
194
|
+
{consumer}
|
|
192
195
|
{!rows.length && !isFiltered && !loading ? (
|
|
193
196
|
noDataChildren
|
|
194
197
|
) : (
|
|
@@ -235,3 +238,4 @@ Table.Predicate = TablePredicate;
|
|
|
235
238
|
Table.CollapsibleColumn = TableCollapsibleColumn;
|
|
236
239
|
Table.AccordionColumn = TableAccordionColumn;
|
|
237
240
|
Table.DateRangePicker = TableDateRangePicker;
|
|
241
|
+
Table.Consumer = TableConsumer;
|
|
@@ -7,8 +7,8 @@ import {
|
|
|
7
7
|
TableState as TanstackTableState,
|
|
8
8
|
} from '@tanstack/table-core';
|
|
9
9
|
import {Dispatch, ReactElement, ReactNode, RefObject} from 'react';
|
|
10
|
-
import {DateRangePickerValue} from '../date-range-picker/DateRangePickerInlineCalendar';
|
|
11
10
|
|
|
11
|
+
import {DateRangePickerValue} from '../date-range-picker/DateRangePickerInlineCalendar';
|
|
12
12
|
import {TableActions} from './TableActions';
|
|
13
13
|
import {TableAccordionColumn, TableCollapsibleColumn} from './TableCollapsibleColumn';
|
|
14
14
|
import {TableDateRangePicker} from './TableDateRangePicker';
|
|
@@ -18,6 +18,7 @@ import {TableHeader} from './TableHeader';
|
|
|
18
18
|
import {TablePagination} from './TablePagination';
|
|
19
19
|
import {TablePerPage} from './TablePerPage';
|
|
20
20
|
import {TablePredicate} from './TablePredicate';
|
|
21
|
+
import {TableConsumer} from './TableConsumer';
|
|
21
22
|
|
|
22
23
|
export type RowSelectionWithData<TData> = Record<string, TData>;
|
|
23
24
|
export interface RowSelectionState<TData> {
|
|
@@ -206,4 +207,5 @@ export interface TableType {
|
|
|
206
207
|
DateRangePicker: typeof TableDateRangePicker;
|
|
207
208
|
CollapsibleColumn: typeof TableCollapsibleColumn;
|
|
208
209
|
AccordionColumn: typeof TableAccordionColumn;
|
|
210
|
+
Consumer: typeof TableConsumer;
|
|
209
211
|
}
|
|
@@ -137,6 +137,31 @@ describe('Table', () => {
|
|
|
137
137
|
expect(screen.queryByTestId('empty-state')).not.toBeInTheDocument();
|
|
138
138
|
});
|
|
139
139
|
|
|
140
|
+
it('updates the table when a component in Table.Consumer triggers a change', async () => {
|
|
141
|
+
const user = userEvent.setup();
|
|
142
|
+
const spy = vi.fn();
|
|
143
|
+
const Fixture = () => {
|
|
144
|
+
const {onChange} = useTable();
|
|
145
|
+
return <button onClick={() => onChange()}>Click me</button>;
|
|
146
|
+
};
|
|
147
|
+
render(
|
|
148
|
+
<Table onChange={spy} data={[{id: '🆔', firstName: 'first', lastName: 'last'}]} columns={columns}>
|
|
149
|
+
<Table.Consumer>
|
|
150
|
+
<Fixture />
|
|
151
|
+
</Table.Consumer>
|
|
152
|
+
</Table>
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
expect(screen.getByRole('button', {name: 'Click me'})).toBeVisible();
|
|
156
|
+
expect(spy).not.toHaveBeenCalled();
|
|
157
|
+
|
|
158
|
+
await user.click(screen.getByRole('button', {name: 'Click me'}));
|
|
159
|
+
|
|
160
|
+
await waitFor(() => {
|
|
161
|
+
expect(spy).toHaveBeenCalledTimes(1);
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
|
|
140
165
|
describe('shows a loading animation', () => {
|
|
141
166
|
const doRender = (props: Omit<TableProps<RowData>, 'columns'>) => {
|
|
142
167
|
const NoData = () => {
|