@transferwise/components 0.0.0-experimental-029bd71 → 0.0.0-experimental-bb32303
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/build/button/Button.js.map +1 -1
- package/build/button/Button.mjs.map +1 -1
- package/build/button/legacyUtils/legacyUtils.js.map +1 -1
- package/build/button/legacyUtils/legacyUtils.mjs.map +1 -1
- package/build/i18n/en.json +0 -5
- package/build/i18n/en.json.js +0 -5
- package/build/i18n/en.json.js.map +1 -1
- package/build/i18n/en.json.mjs +0 -5
- package/build/i18n/en.json.mjs.map +1 -1
- package/build/main.css +0 -300
- package/build/styles/main.css +0 -300
- package/build/types/button/Button.d.ts +1 -1
- package/build/types/button/Button.d.ts.map +1 -1
- package/build/types/button/legacyUtils/legacyUtils.d.ts +2 -2
- package/build/types/button/legacyUtils/legacyUtils.d.ts.map +1 -1
- package/build/types/test-utils/index.d.ts +158 -0
- package/build/types/test-utils/index.d.ts.map +1 -0
- package/build/types/test-utils/jest.setup.d.ts +2 -0
- package/build/types/test-utils/jest.setup.d.ts.map +1 -0
- package/package.json +5 -4
- package/src/button/{Button.spec.js → Button.spec.tsx} +3 -2
- package/src/button/Button.tsx +1 -1
- package/src/button/legacyUtils/{legacyUtils.spec.js → legacyUtils.spec.tsx} +1 -1
- package/src/button/legacyUtils/legacyUtils.ts +2 -2
- package/src/i18n/en.json +0 -5
- package/src/main.css +0 -300
- package/src/main.less +0 -1
- package/src/modal/{Modal.rtl.spec.js → Modal.rtl.spec.tsx} +8 -7
- package/src/slidingPanel/SlidingPanel.spec.js +1 -1
- package/src/ssr.spec.tsx +264 -0
- package/src/test-utils/{index.js → index.tsx} +11 -6
- package/src/test-utils/{jest.setup.js → jest.setup.ts} +13 -8
- package/build/styles/table/Table.css +0 -300
- package/build/types/table/Table.d.ts +0 -23
- package/build/types/table/Table.d.ts.map +0 -1
- package/build/types/table/Table.messages.d.ts +0 -24
- package/build/types/table/Table.messages.d.ts.map +0 -1
- package/build/types/table/TableCell.d.ts +0 -44
- package/build/types/table/TableCell.d.ts.map +0 -1
- package/build/types/table/TableHeader.d.ts +0 -13
- package/build/types/table/TableHeader.d.ts.map +0 -1
- package/build/types/table/TableRow.d.ts +0 -17
- package/build/types/table/TableRow.d.ts.map +0 -1
- package/build/types/table/TableStatusText.d.ts +0 -9
- package/build/types/table/TableStatusText.d.ts.map +0 -1
- package/build/types/table/index.d.ts +0 -6
- package/build/types/table/index.d.ts.map +0 -1
- package/src/ssr.spec.js +0 -256
- package/src/table/Table.css +0 -300
- package/src/table/Table.less +0 -361
- package/src/table/Table.messages.ts +0 -24
- package/src/table/Table.spec.tsx +0 -88
- package/src/table/Table.story.tsx +0 -359
- package/src/table/Table.tsx +0 -166
- package/src/table/TableCell.spec.tsx +0 -304
- package/src/table/TableCell.tsx +0 -170
- package/src/table/TableHeader.spec.tsx +0 -55
- package/src/table/TableHeader.tsx +0 -75
- package/src/table/TableRow.spec.tsx +0 -117
- package/src/table/TableRow.tsx +0 -70
- package/src/table/TableStatusText.spec.tsx +0 -53
- package/src/table/TableStatusText.tsx +0 -36
- package/src/table/index.ts +0 -11
- /package/src/button/__snapshots__/{Button.spec.js.snap → Button.spec.tsx.snap} +0 -0
- /package/src/dimmer/{Dimmer.rtl.spec.js → Dimmer.rtl.spec.tsx} +0 -0
- /package/src/info/{Info.spec.js → Info.spec.jsx} +0 -0
|
@@ -1,304 +0,0 @@
|
|
|
1
|
-
import { render, screen } from '@testing-library/react';
|
|
2
|
-
import '@testing-library/jest-dom';
|
|
3
|
-
import TableCell, {
|
|
4
|
-
TableCellCurrency,
|
|
5
|
-
TableCellLeading,
|
|
6
|
-
TableCellStatus,
|
|
7
|
-
TableCellText,
|
|
8
|
-
} from './TableCell';
|
|
9
|
-
import { IntlProvider } from 'react-intl';
|
|
10
|
-
import { mockMatchMedia } from '../test-utils';
|
|
11
|
-
|
|
12
|
-
mockMatchMedia();
|
|
13
|
-
|
|
14
|
-
describe('TableCell Component', () => {
|
|
15
|
-
const cellContentMocks = {
|
|
16
|
-
leading: {
|
|
17
|
-
type: 'leading',
|
|
18
|
-
primaryText: 'Alice Johnson',
|
|
19
|
-
secondaryText: 'Frontend Developer',
|
|
20
|
-
avatar: {
|
|
21
|
-
fullName: 'Alice Johnson',
|
|
22
|
-
},
|
|
23
|
-
} satisfies TableCellLeading,
|
|
24
|
-
text: {
|
|
25
|
-
type: 'text',
|
|
26
|
-
text: 'JP, Tokyo',
|
|
27
|
-
} satisfies TableCellText,
|
|
28
|
-
currency: {
|
|
29
|
-
type: 'currency',
|
|
30
|
-
primaryCurrency: {
|
|
31
|
-
value: '56789.01',
|
|
32
|
-
currency: 'jpy',
|
|
33
|
-
},
|
|
34
|
-
secondaryCurrency: {
|
|
35
|
-
value: '51000.00',
|
|
36
|
-
currency: 'gbp',
|
|
37
|
-
},
|
|
38
|
-
} satisfies TableCellCurrency,
|
|
39
|
-
status: {
|
|
40
|
-
type: 'status',
|
|
41
|
-
primaryText: 'Overdue',
|
|
42
|
-
secondaryText: '6 days ago',
|
|
43
|
-
sentiment: 'pending',
|
|
44
|
-
} satisfies TableCellStatus,
|
|
45
|
-
custom: <div>Custom content</div>,
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
const renderWithIntl = (component: React.ReactElement) => {
|
|
49
|
-
return render(<IntlProvider locale="en">{component}</IntlProvider>);
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
it('renders without content', () => {
|
|
53
|
-
renderWithIntl(<TableCell />);
|
|
54
|
-
expect(screen.getByRole('cell')).toBeInTheDocument();
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
it('applies `right` alignment class', () => {
|
|
58
|
-
renderWithIntl(<TableCell alignment="right" />);
|
|
59
|
-
expect(screen.getByRole('cell')).toHaveClass('np-table-cell--right');
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
it('applies reversed class for cell with image and `right` alignment', () => {
|
|
63
|
-
renderWithIntl(<TableCell cell={cellContentMocks.currency} alignment="right" />);
|
|
64
|
-
expect(screen.getByTestId('np-table-content')).toHaveClass('np-table-content--reversed');
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
it('applies custom class', () => {
|
|
68
|
-
renderWithIntl(<TableCell className="custom-class" />);
|
|
69
|
-
expect(screen.getByRole('cell')).toHaveClass('custom-class');
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
it('renders with spanned columns', () => {
|
|
73
|
-
renderWithIntl(<TableCell colSpan={2} />);
|
|
74
|
-
expect(screen.getByRole('cell')).toHaveAttribute('colSpan', '2');
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
it('renders with `children` as a content', () => {
|
|
78
|
-
renderWithIntl(<TableCell>{cellContentMocks.custom}</TableCell>);
|
|
79
|
-
expect(screen.getByText('Custom content')).toBeInTheDocument();
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
it('renders `text` cell type', () => {
|
|
83
|
-
renderWithIntl(<TableCell cell={{ ...cellContentMocks.text }} />);
|
|
84
|
-
expect(screen.getByText('JP, Tokyo')).toBeInTheDocument();
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it('renders `text` cell type with error', () => {
|
|
88
|
-
renderWithIntl(<TableCell cell={{ ...cellContentMocks.text, status: 'error' }} />);
|
|
89
|
-
expect(screen.getByText('JP, Tokyo')).toHaveClass('np-table-content--error');
|
|
90
|
-
expect(screen.getByTestId('alert-icon')).toBeInTheDocument();
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
it('renders `text` cell type with success', () => {
|
|
94
|
-
renderWithIntl(<TableCell cell={{ ...cellContentMocks.text, status: 'success' }} />);
|
|
95
|
-
expect(screen.getByText('JP, Tokyo')).toHaveClass('np-table-content--success');
|
|
96
|
-
expect(screen.getByTestId('check-icon')).toBeInTheDocument();
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
it('renders `leading` cell type with initials avatar when `fullName` is provided', () => {
|
|
100
|
-
renderWithIntl(<TableCell cell={{ ...cellContentMocks.leading }} />);
|
|
101
|
-
expect(screen.getByText('AJ')).toBeInTheDocument();
|
|
102
|
-
expect(screen.getByText('Alice Johnson')).toBeInTheDocument();
|
|
103
|
-
expect(screen.getByText('Frontend Developer')).toBeInTheDocument();
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
it('renders `leading` cell type without media content when `fullName` is not provided', () => {
|
|
107
|
-
renderWithIntl(
|
|
108
|
-
<TableCell
|
|
109
|
-
cell={{
|
|
110
|
-
...cellContentMocks.leading,
|
|
111
|
-
avatar: { fullName: undefined },
|
|
112
|
-
}}
|
|
113
|
-
/>,
|
|
114
|
-
);
|
|
115
|
-
expect(screen.queryByText('AJ')).not.toBeInTheDocument();
|
|
116
|
-
expect(screen.getByText('Alice Johnson')).toBeInTheDocument();
|
|
117
|
-
expect(screen.getByText('Frontend Developer')).toBeInTheDocument();
|
|
118
|
-
expect(screen.queryByTestId('np-table-content-media')).not.toBeInTheDocument();
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
it('renders `leading` cell without primary text if is not provided', () => {
|
|
122
|
-
renderWithIntl(
|
|
123
|
-
<TableCell
|
|
124
|
-
cell={{
|
|
125
|
-
...cellContentMocks.leading,
|
|
126
|
-
primaryText: undefined,
|
|
127
|
-
}}
|
|
128
|
-
/>,
|
|
129
|
-
);
|
|
130
|
-
expect(screen.getByText('AJ')).toBeInTheDocument();
|
|
131
|
-
expect(screen.queryByText('Alice Johnson')).not.toBeInTheDocument();
|
|
132
|
-
expect(screen.getByText('Frontend Developer')).toBeInTheDocument();
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
it('renders `leading` cell without secondary text if it is not provided', () => {
|
|
136
|
-
renderWithIntl(
|
|
137
|
-
<TableCell
|
|
138
|
-
cell={{
|
|
139
|
-
...cellContentMocks.leading,
|
|
140
|
-
secondaryText: undefined,
|
|
141
|
-
}}
|
|
142
|
-
/>,
|
|
143
|
-
);
|
|
144
|
-
expect(screen.getByText('AJ')).toBeInTheDocument();
|
|
145
|
-
expect(screen.getByText('Alice Johnson')).toBeInTheDocument();
|
|
146
|
-
expect(screen.queryByText('Frontend Developer')).not.toBeInTheDocument();
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
it('applies an `error` class, renders an `alert-icon` for `leading` cell type with `error` status', () => {
|
|
150
|
-
renderWithIntl(
|
|
151
|
-
<TableCell
|
|
152
|
-
cell={{
|
|
153
|
-
...cellContentMocks.leading,
|
|
154
|
-
status: 'error',
|
|
155
|
-
}}
|
|
156
|
-
/>,
|
|
157
|
-
);
|
|
158
|
-
expect(screen.getByText('Alice Johnson')).toBeInTheDocument();
|
|
159
|
-
expect(screen.getByText('Alice Johnson')).toHaveClass('np-table-content--error');
|
|
160
|
-
expect(screen.getByTestId('alert-icon')).toBeInTheDocument();
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
it('applies a `success` class, renders an `check-icon` for `leading` cell type with `success` status', () => {
|
|
164
|
-
renderWithIntl(
|
|
165
|
-
<TableCell
|
|
166
|
-
cell={{
|
|
167
|
-
...cellContentMocks.leading,
|
|
168
|
-
status: 'success',
|
|
169
|
-
}}
|
|
170
|
-
/>,
|
|
171
|
-
);
|
|
172
|
-
expect(screen.getByText('Alice Johnson')).toBeInTheDocument();
|
|
173
|
-
expect(screen.getByText('Alice Johnson')).toHaveClass('np-table-content--success');
|
|
174
|
-
expect(screen.getByTestId('check-icon')).toBeInTheDocument();
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
it('renders `currency` cell type', () => {
|
|
178
|
-
renderWithIntl(<TableCell cell={{ ...cellContentMocks.currency }} alignment="right" />);
|
|
179
|
-
expect(screen.getByTestId('np-table-content-media')).toBeInTheDocument();
|
|
180
|
-
expect(screen.getByText('56,789 JPY')).toBeInTheDocument();
|
|
181
|
-
expect(screen.getByText('51,000.00 GBP')).toBeInTheDocument();
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
it('renders `currency` cell without media content when currency value of `primaryCurrency` is not provided', () => {
|
|
185
|
-
renderWithIntl(
|
|
186
|
-
<TableCell
|
|
187
|
-
cell={{
|
|
188
|
-
...cellContentMocks.currency,
|
|
189
|
-
primaryCurrency: {
|
|
190
|
-
value: cellContentMocks.currency.primaryCurrency.value,
|
|
191
|
-
currency: '',
|
|
192
|
-
},
|
|
193
|
-
}}
|
|
194
|
-
alignment="right"
|
|
195
|
-
/>,
|
|
196
|
-
);
|
|
197
|
-
expect(screen.queryByRole('presentation')).not.toBeInTheDocument();
|
|
198
|
-
expect(screen.getByText('56,789.01')).toBeInTheDocument();
|
|
199
|
-
expect(screen.getByText('51,000.00 GBP')).toBeInTheDocument();
|
|
200
|
-
expect(screen.queryByTestId('np-table-content-media')).not.toBeInTheDocument();
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
it('renders `currency` cell without primary currency when it is not provided', () => {
|
|
204
|
-
renderWithIntl(
|
|
205
|
-
<TableCell
|
|
206
|
-
cell={{
|
|
207
|
-
...cellContentMocks.currency,
|
|
208
|
-
primaryCurrency: undefined,
|
|
209
|
-
}}
|
|
210
|
-
alignment="right"
|
|
211
|
-
/>,
|
|
212
|
-
);
|
|
213
|
-
expect(screen.queryByText('56,789 JPY')).not.toBeInTheDocument();
|
|
214
|
-
expect(screen.getByText('51,000.00 GBP')).toBeInTheDocument();
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
it('renders `currency` cell without secondary currency when it is not provided', () => {
|
|
218
|
-
renderWithIntl(
|
|
219
|
-
<TableCell
|
|
220
|
-
cell={{
|
|
221
|
-
...cellContentMocks.currency,
|
|
222
|
-
secondaryCurrency: undefined,
|
|
223
|
-
}}
|
|
224
|
-
alignment="right"
|
|
225
|
-
/>,
|
|
226
|
-
);
|
|
227
|
-
expect(screen.getByText('56,789 JPY')).toBeInTheDocument();
|
|
228
|
-
expect(screen.queryByText('51,000.00 GBP')).not.toBeInTheDocument();
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
it('renders `currency` cell with error content', () => {
|
|
232
|
-
renderWithIntl(
|
|
233
|
-
<TableCell
|
|
234
|
-
cell={{
|
|
235
|
-
...cellContentMocks.currency,
|
|
236
|
-
status: 'error',
|
|
237
|
-
}}
|
|
238
|
-
alignment="right"
|
|
239
|
-
/>,
|
|
240
|
-
);
|
|
241
|
-
expect(screen.getByText('56,789 JPY')).toBeInTheDocument();
|
|
242
|
-
expect(screen.getByText('56,789 JPY')).toHaveClass('np-table-content--error');
|
|
243
|
-
expect(screen.getByTestId('alert-icon')).toBeInTheDocument();
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
it('renders `currency` cell with `success` content', () => {
|
|
247
|
-
renderWithIntl(
|
|
248
|
-
<TableCell
|
|
249
|
-
cell={{
|
|
250
|
-
...cellContentMocks.currency,
|
|
251
|
-
status: 'success',
|
|
252
|
-
}}
|
|
253
|
-
alignment="right"
|
|
254
|
-
/>,
|
|
255
|
-
);
|
|
256
|
-
expect(screen.getByText('56,789 JPY')).toBeInTheDocument();
|
|
257
|
-
expect(screen.getByText('56,789 JPY')).toHaveClass('np-table-content--success');
|
|
258
|
-
expect(screen.getByTestId('check-icon')).toBeInTheDocument();
|
|
259
|
-
});
|
|
260
|
-
|
|
261
|
-
it('renders a `status` cell type content', () => {
|
|
262
|
-
renderWithIntl(<TableCell cell={{ ...cellContentMocks.status }} />);
|
|
263
|
-
expect(screen.getByTestId('status-icon')).toBeInTheDocument();
|
|
264
|
-
expect(screen.getByTestId('status-icon')).toHaveClass('pending');
|
|
265
|
-
expect(screen.getByText('Overdue')).toBeInTheDocument();
|
|
266
|
-
expect(screen.getByText('6 days ago')).toBeInTheDocument();
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
it('renders an `info-icon` for `status` cell type if `sentiment` is not provided', () => {
|
|
270
|
-
renderWithIntl(
|
|
271
|
-
<TableCell
|
|
272
|
-
cell={{
|
|
273
|
-
...cellContentMocks.status,
|
|
274
|
-
sentiment: undefined,
|
|
275
|
-
}}
|
|
276
|
-
/>,
|
|
277
|
-
);
|
|
278
|
-
expect(screen.getByTestId('info-icon')).toBeInTheDocument();
|
|
279
|
-
});
|
|
280
|
-
|
|
281
|
-
it('renders `status` cell type without `primary` text if it is not provided', () => {
|
|
282
|
-
renderWithIntl(
|
|
283
|
-
<TableCell
|
|
284
|
-
cell={{
|
|
285
|
-
...cellContentMocks.status,
|
|
286
|
-
primaryText: undefined,
|
|
287
|
-
}}
|
|
288
|
-
/>,
|
|
289
|
-
);
|
|
290
|
-
expect(screen.queryByText('Overdue')).not.toBeInTheDocument();
|
|
291
|
-
});
|
|
292
|
-
|
|
293
|
-
it('renders `status` cell type without `secondary` text if it is not provided', () => {
|
|
294
|
-
renderWithIntl(
|
|
295
|
-
<TableCell
|
|
296
|
-
cell={{
|
|
297
|
-
...cellContentMocks.status,
|
|
298
|
-
secondaryText: undefined,
|
|
299
|
-
}}
|
|
300
|
-
/>,
|
|
301
|
-
);
|
|
302
|
-
expect(screen.queryByText('6 days ago')).not.toBeInTheDocument();
|
|
303
|
-
});
|
|
304
|
-
});
|
package/src/table/TableCell.tsx
DELETED
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
import TableStatusText from './TableStatusText';
|
|
2
|
-
import Avatar, { AvatarType } from '../avatar';
|
|
3
|
-
import StatusIcon from '../statusIcon';
|
|
4
|
-
import { Flag } from '@wise/art';
|
|
5
|
-
import { formatMoney } from '@transferwise/formatting';
|
|
6
|
-
import { useIntl } from 'react-intl';
|
|
7
|
-
import React from 'react';
|
|
8
|
-
import { clsx } from 'clsx';
|
|
9
|
-
import { getInitials } from '../common';
|
|
10
|
-
import Image from '../image';
|
|
11
|
-
|
|
12
|
-
interface TableCellTypeProp {
|
|
13
|
-
type: 'leading' | 'text' | 'currency' | 'status';
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
// `Leading` and `Status` cell types have 2 text fields: `primaryText` and `secondaryText`
|
|
17
|
-
interface TableCellTextProps {
|
|
18
|
-
primaryText?: string;
|
|
19
|
-
secondaryText?: string;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// `Leading`, `Text` and `Currency` cells' types can have a status indicator with `error` or `success` values
|
|
23
|
-
interface TableCellStatusProp {
|
|
24
|
-
status?: 'error' | 'success';
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface TableCellLeading
|
|
28
|
-
extends TableCellTypeProp,
|
|
29
|
-
TableCellTextProps,
|
|
30
|
-
TableCellStatusProp {
|
|
31
|
-
avatar?: {
|
|
32
|
-
src?: string;
|
|
33
|
-
fullName?: string;
|
|
34
|
-
backgroundColorSeed?: string;
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export interface TableCellText extends TableCellTypeProp, TableCellStatusProp {
|
|
39
|
-
text?: string;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
interface Currency {
|
|
43
|
-
value: string | number;
|
|
44
|
-
currency: string;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export interface TableCellCurrency extends TableCellTypeProp, TableCellStatusProp {
|
|
48
|
-
primaryCurrency?: Currency;
|
|
49
|
-
secondaryCurrency?: Currency;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export interface TableCellStatus extends TableCellTypeProp, TableCellTextProps {
|
|
53
|
-
sentiment?: 'negative' | 'neutral' | 'positive' | 'warning' | 'pending';
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export interface TableCellType {
|
|
57
|
-
cell?: TableCellLeading & TableCellText & TableCellCurrency & TableCellStatus;
|
|
58
|
-
alignment?: 'right';
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// These properties should be exported only on the lib level to prevent visual issues because of incorrect usage.
|
|
62
|
-
export interface TableCellProps extends TableCellType {
|
|
63
|
-
className?: string;
|
|
64
|
-
colSpan?: number;
|
|
65
|
-
children?: React.ReactNode;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const TableCell = ({ cell, alignment, className, colSpan, children }: TableCellProps) => {
|
|
69
|
-
const { locale } = useIntl();
|
|
70
|
-
|
|
71
|
-
const getContentMedia = () => {
|
|
72
|
-
let mediaContent = null;
|
|
73
|
-
|
|
74
|
-
if (cell?.type === 'leading' && (cell?.avatar?.src || cell?.avatar?.fullName)) {
|
|
75
|
-
const avatarType = cell?.avatar?.src ? AvatarType.THUMBNAIL : AvatarType.INITIALS;
|
|
76
|
-
|
|
77
|
-
mediaContent = (
|
|
78
|
-
<Avatar size={40} type={avatarType} backgroundColorSeed={cell?.avatar?.backgroundColorSeed}>
|
|
79
|
-
{avatarType === AvatarType.INITIALS &&
|
|
80
|
-
cell?.avatar?.fullName &&
|
|
81
|
-
getInitials(cell?.avatar?.fullName)}
|
|
82
|
-
{cell?.avatar?.src && <Image src={cell?.avatar?.src} alt="" />}
|
|
83
|
-
</Avatar>
|
|
84
|
-
);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
if (cell?.type === 'currency' && cell?.primaryCurrency?.currency) {
|
|
88
|
-
mediaContent = (
|
|
89
|
-
<Flag code={cell?.primaryCurrency?.currency?.toLowerCase()} intrinsicSize={24} />
|
|
90
|
-
);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (cell?.type === 'status') {
|
|
94
|
-
mediaContent = <StatusIcon size="md" sentiment={cell?.sentiment ?? 'neutral'} />;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
if (mediaContent) {
|
|
98
|
-
return (
|
|
99
|
-
<div
|
|
100
|
-
aria-hidden="true"
|
|
101
|
-
className="np-table-content-media"
|
|
102
|
-
data-testid="np-table-content-media"
|
|
103
|
-
>
|
|
104
|
-
{mediaContent}
|
|
105
|
-
</div>
|
|
106
|
-
);
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
const formatCurrencyValue = (currency?: Currency) => {
|
|
111
|
-
if (currency) {
|
|
112
|
-
return formatMoney(Number(currency.value), currency.currency, locale, {
|
|
113
|
-
alwaysShowDecimals: true,
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
return '';
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
return (
|
|
121
|
-
<td
|
|
122
|
-
className={clsx(
|
|
123
|
-
'np-table-cell',
|
|
124
|
-
cell?.type ? `np-table-cell--${cell?.type}` : '',
|
|
125
|
-
className,
|
|
126
|
-
{
|
|
127
|
-
'np-table-cell--right': alignment === 'right',
|
|
128
|
-
},
|
|
129
|
-
)}
|
|
130
|
-
colSpan={colSpan}
|
|
131
|
-
>
|
|
132
|
-
{cell?.type === 'text' && cell?.text && (
|
|
133
|
-
<TableStatusText text={cell?.text} status={cell?.status} />
|
|
134
|
-
)}
|
|
135
|
-
{cell?.type && ['leading', 'currency', 'status'].includes(cell?.type) && (
|
|
136
|
-
<div
|
|
137
|
-
className={clsx('np-table-content', {
|
|
138
|
-
'np-table-content--reversed': alignment === 'right',
|
|
139
|
-
})}
|
|
140
|
-
data-testid="np-table-content"
|
|
141
|
-
>
|
|
142
|
-
{getContentMedia()}
|
|
143
|
-
<div className="np-table-content-body">
|
|
144
|
-
{(cell?.primaryCurrency ?? cell?.primaryText) && (
|
|
145
|
-
<TableStatusText
|
|
146
|
-
text={
|
|
147
|
-
cell?.type === 'currency'
|
|
148
|
-
? formatCurrencyValue(cell?.primaryCurrency)
|
|
149
|
-
: (cell?.primaryText ?? '')
|
|
150
|
-
}
|
|
151
|
-
status={cell?.type !== 'status' ? cell?.status : undefined}
|
|
152
|
-
typography="default-bold"
|
|
153
|
-
/>
|
|
154
|
-
)}
|
|
155
|
-
{(cell?.secondaryCurrency ?? cell?.secondaryText) && (
|
|
156
|
-
<div className="np-table-text-secondary">
|
|
157
|
-
{cell?.type === 'currency'
|
|
158
|
-
? formatCurrencyValue(cell?.secondaryCurrency)
|
|
159
|
-
: cell?.secondaryText}
|
|
160
|
-
</div>
|
|
161
|
-
)}
|
|
162
|
-
</div>
|
|
163
|
-
</div>
|
|
164
|
-
)}
|
|
165
|
-
{children}
|
|
166
|
-
</td>
|
|
167
|
-
);
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
export default TableCell;
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { render, screen } from '@testing-library/react';
|
|
2
|
-
import TableHeader, { TableHeaderProps } from './TableHeader';
|
|
3
|
-
import { IntlProvider } from 'react-intl';
|
|
4
|
-
|
|
5
|
-
describe('TableHeader Component', () => {
|
|
6
|
-
const renderComponent = (props: Partial<TableHeaderProps> = {}) => {
|
|
7
|
-
const defaultProps = {
|
|
8
|
-
header: '',
|
|
9
|
-
} satisfies TableHeaderProps;
|
|
10
|
-
return render(
|
|
11
|
-
<IntlProvider locale="en">
|
|
12
|
-
<TableHeader {...defaultProps} {...props} />
|
|
13
|
-
</IntlProvider>,
|
|
14
|
-
);
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
it('should render header', () => {
|
|
18
|
-
const { container } = renderComponent();
|
|
19
|
-
expect(container).toBeInTheDocument();
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
it('should render header text when provided', () => {
|
|
23
|
-
const headerText = 'Test Header';
|
|
24
|
-
renderComponent({ header: headerText });
|
|
25
|
-
expect(screen.getByText(headerText)).toBeInTheDocument();
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it('should apply custom className', () => {
|
|
29
|
-
const className = 'custom-class';
|
|
30
|
-
renderComponent({ className });
|
|
31
|
-
expect(screen.getByRole('columnheader')).toHaveClass(className);
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it('should align text to the right when alignment is set to right', () => {
|
|
35
|
-
renderComponent({ alignment: 'right' });
|
|
36
|
-
expect(screen.getByRole('columnheader')).toHaveClass('np-table-header--right');
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
it("should show error class when status equals 'error'", () => {
|
|
40
|
-
renderComponent({ status: 'error' });
|
|
41
|
-
expect(screen.getByRole('columnheader')).toHaveClass('np-table-header--error');
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it('should render empty header content when header is not provided', () => {
|
|
45
|
-
renderComponent();
|
|
46
|
-
expect(screen.getByTestId('np-table-empty-header').innerHTML).toBe(' ');
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
it('should render header with error status when status is `error`', () => {
|
|
50
|
-
const headerText = 'Test Header';
|
|
51
|
-
renderComponent({ header: headerText, status: 'error' });
|
|
52
|
-
expect(screen.getByText(headerText)).toHaveClass('np-table-content--error');
|
|
53
|
-
expect(screen.getByTestId('alert-icon')).toBeInTheDocument();
|
|
54
|
-
});
|
|
55
|
-
});
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { useIntl } from 'react-intl';
|
|
2
|
-
import messages from './Table.messages';
|
|
3
|
-
import TableStatusText from './TableStatusText';
|
|
4
|
-
import { clsx } from 'clsx';
|
|
5
|
-
|
|
6
|
-
export interface TableHeaderType {
|
|
7
|
-
header?: string;
|
|
8
|
-
className?: string;
|
|
9
|
-
alignment?: 'right';
|
|
10
|
-
status?: 'error';
|
|
11
|
-
width?: string;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export interface TableHeaderProps extends TableHeaderType {
|
|
15
|
-
isActionHeader?: boolean;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const TableHeader = ({
|
|
19
|
-
header,
|
|
20
|
-
className,
|
|
21
|
-
alignment,
|
|
22
|
-
status,
|
|
23
|
-
width,
|
|
24
|
-
isActionHeader = false,
|
|
25
|
-
}: TableHeaderProps) => {
|
|
26
|
-
const { formatMessage } = useIntl();
|
|
27
|
-
|
|
28
|
-
const getHeaderContent = () => {
|
|
29
|
-
if (isActionHeader) {
|
|
30
|
-
// `Action` header doesn't have visual text content, but it has the header, which is visible for screen readers only
|
|
31
|
-
return (
|
|
32
|
-
<TableStatusText
|
|
33
|
-
text={formatMessage(messages.actionHeader)}
|
|
34
|
-
className={`np-table-header-content${isActionHeader ? ' sr-only' : ''}`}
|
|
35
|
-
/>
|
|
36
|
-
);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (header) {
|
|
40
|
-
return (
|
|
41
|
-
<TableStatusText
|
|
42
|
-
text={header}
|
|
43
|
-
className={`np-table-header-content${isActionHeader ? ' sr-only' : ''}`}
|
|
44
|
-
status={status}
|
|
45
|
-
typography="default-bold"
|
|
46
|
-
/>
|
|
47
|
-
);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// If headers are empty, we still should render empty headers to keep visual consistency
|
|
51
|
-
return (
|
|
52
|
-
<div
|
|
53
|
-
className="np-table-header-content np-text-body-default-bold"
|
|
54
|
-
data-testid="np-table-empty-header"
|
|
55
|
-
>
|
|
56
|
-
|
|
57
|
-
</div>
|
|
58
|
-
);
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
return (
|
|
62
|
-
<th
|
|
63
|
-
className={clsx('np-table-header', className, {
|
|
64
|
-
'np-table-header--right': alignment === 'right',
|
|
65
|
-
'np-table-header--error': status === 'error',
|
|
66
|
-
'np-table-header--action': isActionHeader,
|
|
67
|
-
})}
|
|
68
|
-
style={{ minWidth: width, width }}
|
|
69
|
-
>
|
|
70
|
-
{getHeaderContent()}
|
|
71
|
-
</th>
|
|
72
|
-
);
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
export default TableHeader;
|