@transferwise/components 0.0.0-experimental-029bd71 → 0.0.0-experimental-339e531

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.
Files changed (66) hide show
  1. package/build/button/Button.js.map +1 -1
  2. package/build/button/Button.mjs.map +1 -1
  3. package/build/button/legacyUtils/legacyUtils.js.map +1 -1
  4. package/build/button/legacyUtils/legacyUtils.mjs.map +1 -1
  5. package/build/i18n/en.json +0 -5
  6. package/build/i18n/en.json.js +0 -5
  7. package/build/i18n/en.json.js.map +1 -1
  8. package/build/i18n/en.json.mjs +0 -5
  9. package/build/i18n/en.json.mjs.map +1 -1
  10. package/build/main.css +0 -300
  11. package/build/styles/main.css +0 -300
  12. package/build/types/button/Button.d.ts +1 -1
  13. package/build/types/button/Button.d.ts.map +1 -1
  14. package/build/types/button/legacyUtils/legacyUtils.d.ts +2 -2
  15. package/build/types/button/legacyUtils/legacyUtils.d.ts.map +1 -1
  16. package/build/types/test-utils/index.d.ts +158 -0
  17. package/build/types/test-utils/index.d.ts.map +1 -0
  18. package/build/types/test-utils/jest.setup.d.ts +2 -0
  19. package/build/types/test-utils/jest.setup.d.ts.map +1 -0
  20. package/package.json +4 -3
  21. package/src/button/{Button.spec.js → Button.spec.tsx} +3 -2
  22. package/src/button/Button.tsx +1 -1
  23. package/src/button/legacyUtils/{legacyUtils.spec.js → legacyUtils.spec.tsx} +1 -1
  24. package/src/button/legacyUtils/legacyUtils.ts +2 -2
  25. package/src/i18n/en.json +0 -5
  26. package/src/main.css +0 -300
  27. package/src/main.less +0 -1
  28. package/src/modal/{Modal.rtl.spec.js → Modal.rtl.spec.tsx} +8 -7
  29. package/src/slidingPanel/SlidingPanel.spec.js +1 -1
  30. package/src/ssr.spec.tsx +264 -0
  31. package/src/test-utils/{index.js → index.tsx} +11 -6
  32. package/src/test-utils/{jest.setup.js → jest.setup.ts} +13 -8
  33. package/build/styles/table/Table.css +0 -300
  34. package/build/types/table/Table.d.ts +0 -23
  35. package/build/types/table/Table.d.ts.map +0 -1
  36. package/build/types/table/Table.messages.d.ts +0 -24
  37. package/build/types/table/Table.messages.d.ts.map +0 -1
  38. package/build/types/table/TableCell.d.ts +0 -44
  39. package/build/types/table/TableCell.d.ts.map +0 -1
  40. package/build/types/table/TableHeader.d.ts +0 -13
  41. package/build/types/table/TableHeader.d.ts.map +0 -1
  42. package/build/types/table/TableRow.d.ts +0 -17
  43. package/build/types/table/TableRow.d.ts.map +0 -1
  44. package/build/types/table/TableStatusText.d.ts +0 -9
  45. package/build/types/table/TableStatusText.d.ts.map +0 -1
  46. package/build/types/table/index.d.ts +0 -6
  47. package/build/types/table/index.d.ts.map +0 -1
  48. package/src/ssr.spec.js +0 -256
  49. package/src/table/Table.css +0 -300
  50. package/src/table/Table.less +0 -361
  51. package/src/table/Table.messages.ts +0 -24
  52. package/src/table/Table.spec.tsx +0 -88
  53. package/src/table/Table.story.tsx +0 -359
  54. package/src/table/Table.tsx +0 -166
  55. package/src/table/TableCell.spec.tsx +0 -304
  56. package/src/table/TableCell.tsx +0 -170
  57. package/src/table/TableHeader.spec.tsx +0 -55
  58. package/src/table/TableHeader.tsx +0 -75
  59. package/src/table/TableRow.spec.tsx +0 -117
  60. package/src/table/TableRow.tsx +0 -70
  61. package/src/table/TableStatusText.spec.tsx +0 -53
  62. package/src/table/TableStatusText.tsx +0 -36
  63. package/src/table/index.ts +0 -11
  64. /package/src/button/__snapshots__/{Button.spec.js.snap → Button.spec.tsx.snap} +0 -0
  65. /package/src/dimmer/{Dimmer.rtl.spec.js → Dimmer.rtl.spec.tsx} +0 -0
  66. /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
- });
@@ -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('&nbsp;');
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
- &nbsp;
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;