@hyphen/hyphen-components 8.0.1 → 9.0.0-beta.1
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/dist/css/utilities.css +1 -1
- package/dist/css/utilities.css.map +1 -1
- package/dist/hyphen-components.cjs.development.js +353 -313
- package/dist/hyphen-components.cjs.development.js.map +1 -1
- package/dist/hyphen-components.cjs.production.min.js +2 -2
- package/dist/hyphen-components.cjs.production.min.js.map +1 -1
- package/dist/hyphen-components.esm.js +357 -314
- package/dist/hyphen-components.esm.js.map +1 -1
- package/dist/index.d.ts +222 -212
- package/package.json +6 -5
- package/src/components/Alert/Alert.tsx +5 -6
- package/src/components/Badge/Badge.test.tsx +12 -0
- package/src/components/Badge/Badge.tsx +52 -20
- package/src/components/Box/Box.mdx +1 -1
- package/src/components/Box/Box.stories.tsx +1 -1
- package/src/components/Box/Box.test.tsx +24 -1
- package/src/components/Box/Box.tsx +108 -82
- package/src/components/Card/Card.tsx +5 -1
- package/src/components/Card/components/CardFooter/CardFooter.tsx +0 -4
- package/src/components/Card/components/CardHeader/CardHeader.tsx +4 -1
- package/src/components/Card/components/CardSection/CardSection.tsx +4 -5
- package/src/components/CheckboxInput/CheckboxInput.test.tsx +17 -0
- package/src/components/CheckboxInput/CheckboxInput.tsx +15 -4
- package/src/components/CheckboxInput/components/Checkbox.test.tsx +36 -0
- package/src/components/CheckboxInput/components/Checkbox.tsx +8 -2
- package/src/components/Details/Details.test.tsx +8 -0
- package/src/components/Details/Details.tsx +5 -2
- package/src/components/Details/DetailsSummary.tsx +4 -1
- package/src/components/Drawer/Drawer.test.tsx +8 -0
- package/src/components/Drawer/Drawer.tsx +1 -1
- package/src/components/FormLabel/FormLabel.tsx +6 -3
- package/src/components/Formik/FormikCheckboxInput/FormikCheckboxInput.test.tsx +9 -0
- package/src/components/Formik/FormikCheckboxInput/FormikCheckboxInput.tsx +1 -0
- package/src/components/Formik/FormikSelectInput/FormikSelectInput.tsx +21 -11
- package/src/components/Formik/FormikSelectInputNative/FormikSelectInputNative.tsx +1 -1
- package/src/components/Formik/FormikTimePicker/FormikTimePicker.tsx +1 -1
- package/src/components/Heading/Heading.tsx +5 -6
- package/src/components/Icon/Icon.test.tsx +8 -0
- package/src/components/Icon/Icon.tsx +6 -7
- package/src/components/Modal/Modal.test.tsx +31 -1
- package/src/components/Modal/Modal.tsx +13 -7
- package/src/components/Popover/Popover.test.tsx +3 -4
- package/src/components/RadioGroup/RadioGroup.tsx +11 -6
- package/src/components/RadioGroup/RadioInput/RadioInputIcon.tsx +0 -4
- package/src/components/SelectInput/SelectInput.test.tsx +18 -0
- package/src/components/SelectInput/SelectInput.tsx +47 -27
- package/src/components/SelectInputInset/SelectInputInset.tsx +8 -9
- package/src/components/SelectInputNative/SelectInputNative.test.tsx +24 -0
- package/src/components/SelectInputNative/SelectInputNative.tsx +79 -14
- package/src/components/Switch/Switch.tsx +1 -1
- package/src/components/Table/Table.mdx +21 -1
- package/src/components/Table/Table.stories.tsx +5 -1
- package/src/components/Table/Table.tsx +7 -7
- package/src/components/Table/TableBody/TableBody.test.tsx +89 -1
- package/src/components/Table/TableBody/TableBody.tsx +23 -8
- package/src/components/Table/TableHead/TableHead.tsx +6 -6
- package/src/components/Table/TableHead/TableHeaderCell/TableHeaderCell.tsx +6 -6
- package/src/components/Table/common/TableRow/TableRow.test.tsx +17 -1
- package/src/components/Table/common/TableRow/TableRow.tsx +30 -10
- package/src/components/TextInput/TextInput.tsx +10 -8
- package/src/components/TextInputInset/TextInputInset.tsx +5 -6
- package/src/components/TextareaInput/TextareaInput.tsx +4 -5
- package/src/components/TextareaInputInset/TextareaInputInset.tsx +10 -17
- package/src/components/Toast/Toast.stories.tsx +5 -1
- package/src/lib/getColumnKeys.ts +5 -3
- package/src/types/index.ts +6 -7
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from 'react';
|
|
2
2
|
import classNames from 'classnames';
|
|
3
3
|
import styles from './TableBody.module.scss';
|
|
4
4
|
import { Column, Row } from '../../../types';
|
|
5
5
|
import { TableRow } from '../common/TableRow/TableRow';
|
|
6
6
|
|
|
7
|
-
export interface TableBodyProps {
|
|
7
|
+
export interface TableBodyProps<TRow extends object = Row> {
|
|
8
8
|
/**
|
|
9
9
|
* The table columns to be rendered
|
|
10
10
|
*/
|
|
11
|
-
columns: Column[];
|
|
11
|
+
columns: Column<TRow>[];
|
|
12
12
|
/**
|
|
13
13
|
* The unique key to identify a React node for each row.
|
|
14
14
|
*/
|
|
15
|
-
rowKey:
|
|
15
|
+
rowKey: Extract<keyof TRow, string>;
|
|
16
16
|
/**
|
|
17
17
|
* The table rows to be rendered
|
|
18
18
|
*/
|
|
19
|
-
rows:
|
|
19
|
+
rows: TRow[];
|
|
20
20
|
/**
|
|
21
21
|
* Text alignment for all table cells. Can be superseded by passing the same prop into the `Column` object
|
|
22
22
|
* for a specific column.
|
|
@@ -54,9 +54,10 @@ export interface TableBodyProps {
|
|
|
54
54
|
truncateOverflow?: boolean;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
export const TableBody
|
|
57
|
+
export const TableBody = <TRow extends object = Row,>({
|
|
58
58
|
columns,
|
|
59
59
|
rows,
|
|
60
|
+
rowKey,
|
|
60
61
|
align = 'left',
|
|
61
62
|
className = '',
|
|
62
63
|
emptyCellPlaceholder = '',
|
|
@@ -65,7 +66,7 @@ export const TableBody: FC<TableBodyProps> = ({
|
|
|
65
66
|
isCompact = false,
|
|
66
67
|
isStriped = false,
|
|
67
68
|
truncateOverflow = false,
|
|
68
|
-
}) => {
|
|
69
|
+
}: TableBodyProps<TRow>) => {
|
|
69
70
|
const tableBodyClasses = classNames(
|
|
70
71
|
styles['table-body'],
|
|
71
72
|
{
|
|
@@ -75,6 +76,20 @@ export const TableBody: FC<TableBodyProps> = ({
|
|
|
75
76
|
className
|
|
76
77
|
);
|
|
77
78
|
|
|
79
|
+
const getRowKey = (row: TRow, rowIndex: number): string => {
|
|
80
|
+
const keyValue = row?.[rowKey];
|
|
81
|
+
|
|
82
|
+
if (
|
|
83
|
+
typeof keyValue === 'string' ||
|
|
84
|
+
typeof keyValue === 'number' ||
|
|
85
|
+
typeof keyValue === 'bigint'
|
|
86
|
+
) {
|
|
87
|
+
return `row-key-${String(keyValue)}`;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return `row-index-${rowIndex}`;
|
|
91
|
+
};
|
|
92
|
+
|
|
78
93
|
return (
|
|
79
94
|
<tbody className={tableBodyClasses}>
|
|
80
95
|
{rows.map((row, rowIndex) => (
|
|
@@ -83,7 +98,7 @@ export const TableBody: FC<TableBodyProps> = ({
|
|
|
83
98
|
row={row}
|
|
84
99
|
rowIndex={rowIndex}
|
|
85
100
|
align={align}
|
|
86
|
-
key={rowIndex}
|
|
101
|
+
key={getRowKey(row, rowIndex)}
|
|
87
102
|
emptyCellPlaceholder={emptyCellPlaceholder}
|
|
88
103
|
truncateOverflow={truncateOverflow}
|
|
89
104
|
isBorderless={isBorderless}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from 'react';
|
|
2
2
|
import classNames from 'classnames';
|
|
3
|
-
import { Column, EventWithColumnKey } from '../../../types';
|
|
3
|
+
import { Column, EventWithColumnKey, Row } from '../../../types';
|
|
4
4
|
import { TableRow } from '../common/TableRow/TableRow';
|
|
5
5
|
|
|
6
|
-
export interface TableHeadProps {
|
|
6
|
+
export interface TableHeadProps<TRow extends object = Row> {
|
|
7
7
|
/**
|
|
8
8
|
* The table columns to be rendered
|
|
9
9
|
*/
|
|
10
|
-
columns: Column[];
|
|
10
|
+
columns: Column<TRow>[];
|
|
11
11
|
/**
|
|
12
12
|
* Text alignment for all table cells. Can be superseded by passing the same prop into the `Column` object
|
|
13
13
|
* for a specific column.
|
|
@@ -47,7 +47,7 @@ export interface TableHeadProps {
|
|
|
47
47
|
truncateOverflow?: boolean;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
export const TableHead
|
|
50
|
+
export const TableHead = <TRow extends object = Row,>({
|
|
51
51
|
columns,
|
|
52
52
|
align = 'left',
|
|
53
53
|
className = '',
|
|
@@ -57,7 +57,7 @@ export const TableHead: FC<TableHeadProps> = ({
|
|
|
57
57
|
onSort = undefined,
|
|
58
58
|
sortedColumn = undefined,
|
|
59
59
|
truncateOverflow = false,
|
|
60
|
-
}) => {
|
|
60
|
+
}: TableHeadProps<TRow>) => {
|
|
61
61
|
const tableHeadClasses = classNames(className);
|
|
62
62
|
|
|
63
63
|
return (
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { Key, KeyboardEvent, MouseEvent, ReactNode } from 'react';
|
|
2
2
|
import classNames from 'classnames';
|
|
3
3
|
import { Box } from '../../../Box/Box';
|
|
4
4
|
import { Icon } from '../../../Icon/Icon';
|
|
5
|
-
import { Column, EventWithColumnKey } from '../../../../types';
|
|
5
|
+
import { Column, EventWithColumnKey, Row } from '../../../../types';
|
|
6
6
|
import styles from './TableHeaderCell.module.scss';
|
|
7
7
|
|
|
8
|
-
export interface TableHeaderCellProps {
|
|
8
|
+
export interface TableHeaderCellProps<TRow extends object = Row> {
|
|
9
9
|
/**
|
|
10
10
|
* Title to display for the column.
|
|
11
11
|
*/
|
|
12
|
-
column: Column
|
|
12
|
+
column: Column<TRow>;
|
|
13
13
|
/**
|
|
14
14
|
* Text alignment for all table cells. Can be superseded by passing the same prop into the `Column` object
|
|
15
15
|
* for a specific column.
|
|
@@ -69,7 +69,7 @@ export interface TableHeaderCellProps {
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
// eslint-disable-line import/prefer-default-export
|
|
72
|
-
export const TableHeaderCell
|
|
72
|
+
export const TableHeaderCell = <TRow extends object = Row,>({
|
|
73
73
|
column,
|
|
74
74
|
align = 'left',
|
|
75
75
|
className = undefined,
|
|
@@ -83,7 +83,7 @@ export const TableHeaderCell: FC<TableHeaderCellProps> = ({
|
|
|
83
83
|
sticky = undefined,
|
|
84
84
|
truncateOverflow = false,
|
|
85
85
|
width = undefined,
|
|
86
|
-
}) => {
|
|
86
|
+
}: TableHeaderCellProps<TRow>) => {
|
|
87
87
|
const isColumnSorted = (columnDataKey: Key | undefined): boolean =>
|
|
88
88
|
!!sortedColumn && sortedColumn.dataKey === columnDataKey;
|
|
89
89
|
|
|
@@ -33,7 +33,7 @@ describe('TableRow', () => {
|
|
|
33
33
|
render(
|
|
34
34
|
<TableRow row={row} rowIndex={rowIndex} columns={customClassCell} />
|
|
35
35
|
);
|
|
36
|
-
expect(func).toHaveBeenCalledWith(
|
|
36
|
+
expect(func).toHaveBeenCalledWith(row.id, row, rowIndex);
|
|
37
37
|
const element = document.getElementsByClassName('my-custom-class')[0];
|
|
38
38
|
expect(element).toBeInTheDocument();
|
|
39
39
|
});
|
|
@@ -48,5 +48,21 @@ describe('TableRow', () => {
|
|
|
48
48
|
const element = document.getElementsByClassName('string-class')[0];
|
|
49
49
|
expect(element).toBeInTheDocument();
|
|
50
50
|
});
|
|
51
|
+
|
|
52
|
+
test('renders a placeholder instead of a non-renderable row value', () => {
|
|
53
|
+
render(
|
|
54
|
+
<TableRow
|
|
55
|
+
row={{ metadata: { state: 'ready' }, action: <button>Open</button> }}
|
|
56
|
+
columns={[
|
|
57
|
+
{ heading: 'Metadata', dataKey: 'metadata' },
|
|
58
|
+
{ heading: 'Action', dataKey: 'action' },
|
|
59
|
+
]}
|
|
60
|
+
emptyCellPlaceholder="--"
|
|
61
|
+
/>
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
expect(screen.getByText('--')).toBeInTheDocument();
|
|
65
|
+
expect(screen.getByRole('button', { name: 'Open' })).toBeInTheDocument();
|
|
66
|
+
});
|
|
51
67
|
});
|
|
52
68
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
2
2
|
import classNames from 'classnames';
|
|
3
3
|
import styles from './TableRow.module.scss';
|
|
4
4
|
import { Column, EventWithColumnKey, Row } from '../../../../types';
|
|
@@ -6,11 +6,11 @@ import { getColumnKeys } from '../../../../lib/getColumnKeys';
|
|
|
6
6
|
import TableBodyCell from '../../TableBody/TableBodyCell/TableBodyCell';
|
|
7
7
|
import { TableHeaderCell } from '../../TableHead/TableHeaderCell/TableHeaderCell';
|
|
8
8
|
|
|
9
|
-
export interface TableRowProps {
|
|
9
|
+
export interface TableRowProps<TRow extends object = Row> {
|
|
10
10
|
/**
|
|
11
11
|
* The table columns to be rendered
|
|
12
12
|
*/
|
|
13
|
-
columns: Column[];
|
|
13
|
+
columns: Column<TRow>[];
|
|
14
14
|
/**
|
|
15
15
|
* Text alignment for all table cells. Can be superseded by passing the same prop into the `Column` object
|
|
16
16
|
* for a specific column.
|
|
@@ -52,7 +52,7 @@ export interface TableRowProps {
|
|
|
52
52
|
/**
|
|
53
53
|
* The specific row to be rendered.
|
|
54
54
|
*/
|
|
55
|
-
row?:
|
|
55
|
+
row?: TRow;
|
|
56
56
|
/**
|
|
57
57
|
* The unique key to identify a React node for each row.
|
|
58
58
|
*/
|
|
@@ -71,7 +71,7 @@ export interface TableRowProps {
|
|
|
71
71
|
truncateOverflow?: boolean;
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
export const TableRow
|
|
74
|
+
export const TableRow = <TRow extends object = Row,>({
|
|
75
75
|
columns,
|
|
76
76
|
align = 'left',
|
|
77
77
|
className = '',
|
|
@@ -86,26 +86,46 @@ export const TableRow: FC<TableRowProps> = ({
|
|
|
86
86
|
row = undefined,
|
|
87
87
|
rowIndex = undefined,
|
|
88
88
|
truncateOverflow = false,
|
|
89
|
-
}) => {
|
|
89
|
+
}: TableRowProps<TRow>) => {
|
|
90
90
|
const tableRowClasses = classNames(
|
|
91
91
|
styles['table-row'],
|
|
92
92
|
{ [styles.hoverable]: isHoverable },
|
|
93
93
|
className
|
|
94
94
|
);
|
|
95
95
|
|
|
96
|
-
const
|
|
96
|
+
const isRenderableCell = (value: unknown): value is ReactNode => {
|
|
97
|
+
if (value === null || value === undefined) return true;
|
|
98
|
+
|
|
99
|
+
const valueType = typeof value;
|
|
100
|
+
if (
|
|
101
|
+
valueType === 'string' ||
|
|
102
|
+
valueType === 'number' ||
|
|
103
|
+
valueType === 'boolean'
|
|
104
|
+
) {
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (Array.isArray(value)) return value.every(isRenderableCell);
|
|
109
|
+
|
|
110
|
+
return React.isValidElement(value);
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
const renderCellContent = (column: Column<TRow>): ReactNode => {
|
|
97
114
|
if (column.render) {
|
|
98
115
|
const cellValue = column.dataKey && row ? row[column.dataKey] : undefined;
|
|
99
116
|
return column.render(cellValue, row, rowIndex);
|
|
100
117
|
}
|
|
101
118
|
|
|
102
|
-
|
|
119
|
+
const cellValue = column.dataKey && row ? row[column.dataKey] : null;
|
|
120
|
+
return isRenderableCell(cellValue) ? cellValue : null;
|
|
103
121
|
};
|
|
104
122
|
|
|
105
|
-
const getCellClassName = (column: Column): string | undefined => {
|
|
123
|
+
const getCellClassName = (column: Column<TRow>): string | undefined => {
|
|
106
124
|
if (column.cellClassName) {
|
|
107
125
|
if (typeof column.cellClassName === 'function') {
|
|
108
|
-
|
|
126
|
+
const cellValue =
|
|
127
|
+
column.dataKey && row ? row[column.dataKey] : undefined;
|
|
128
|
+
return column.cellClassName(cellValue, row, rowIndex);
|
|
109
129
|
}
|
|
110
130
|
return column.cellClassName;
|
|
111
131
|
}
|
|
@@ -3,7 +3,6 @@ import React, {
|
|
|
3
3
|
ChangeEvent,
|
|
4
4
|
FocusEvent,
|
|
5
5
|
ForwardRefExoticComponent,
|
|
6
|
-
HTMLProps,
|
|
7
6
|
InputHTMLAttributes,
|
|
8
7
|
KeyboardEvent,
|
|
9
8
|
MouseEvent,
|
|
@@ -11,7 +10,7 @@ import React, {
|
|
|
11
10
|
forwardRef,
|
|
12
11
|
} from 'react';
|
|
13
12
|
|
|
14
|
-
import { FormControl } from '../FormControl/FormControl';
|
|
13
|
+
import { FormControl, FormControlProps } from '../FormControl/FormControl';
|
|
15
14
|
import { Icon } from '../Icon/Icon';
|
|
16
15
|
import { ResponsiveProp } from '../../types';
|
|
17
16
|
import classNames from 'classnames';
|
|
@@ -21,7 +20,7 @@ import { getAutoCompleteValue } from '../../lib/getAutoCompleteValue';
|
|
|
21
20
|
import styles from './TextInput.module.scss';
|
|
22
21
|
|
|
23
22
|
export type TextInputSizeType = 'sm' | 'md' | 'lg';
|
|
24
|
-
|
|
23
|
+
interface TextInputOwnProps {
|
|
25
24
|
/**
|
|
26
25
|
* The input's id attribute. Used to programmatically tie the input with its label.
|
|
27
26
|
*/
|
|
@@ -38,6 +37,10 @@ export interface TextInputProps {
|
|
|
38
37
|
* The text value of the input. Required since our Input is a controlled component.
|
|
39
38
|
*/
|
|
40
39
|
value: InputHTMLAttributes<HTMLInputElement>['value'];
|
|
40
|
+
/**
|
|
41
|
+
* The input's autocomplete behavior.
|
|
42
|
+
*/
|
|
43
|
+
autoComplete?: boolean | string;
|
|
41
44
|
/**
|
|
42
45
|
* Automatically focus the input when the page is loaded.
|
|
43
46
|
*/
|
|
@@ -62,7 +65,7 @@ export interface TextInputProps {
|
|
|
62
65
|
/**
|
|
63
66
|
* Props passed directly to the input element of the component
|
|
64
67
|
*/
|
|
65
|
-
inputProps?: BoxProps
|
|
68
|
+
inputProps?: Omit<BoxProps<'input'>, 'as'>;
|
|
66
69
|
/**
|
|
67
70
|
* The input's disabled attribute
|
|
68
71
|
*/
|
|
@@ -119,12 +122,11 @@ export interface TextInputProps {
|
|
|
119
122
|
* The input 'type' value. Defaults to type 'text'.
|
|
120
123
|
*/
|
|
121
124
|
type?: InputHTMLAttributes<HTMLInputElement>['type'];
|
|
122
|
-
/**
|
|
123
|
-
* Additional props to be spread to rendered element
|
|
124
|
-
*/
|
|
125
|
-
[x: string]: any; // eslint-disable-line
|
|
126
125
|
}
|
|
127
126
|
|
|
127
|
+
export type TextInputProps = TextInputOwnProps &
|
|
128
|
+
Omit<FormControlProps, keyof TextInputOwnProps>;
|
|
129
|
+
|
|
128
130
|
export const TextInput: ForwardRefExoticComponent<TextInputProps> = forwardRef<
|
|
129
131
|
HTMLDivElement,
|
|
130
132
|
TextInputProps
|
|
@@ -6,7 +6,6 @@ import React, {
|
|
|
6
6
|
FocusEvent,
|
|
7
7
|
ForwardRefExoticComponent,
|
|
8
8
|
ReactNode,
|
|
9
|
-
HTMLProps,
|
|
10
9
|
InputHTMLAttributes,
|
|
11
10
|
} from 'react';
|
|
12
11
|
import classNames from 'classnames';
|
|
@@ -38,6 +37,10 @@ export interface TextInputInsetProps {
|
|
|
38
37
|
* The text value of the input. Required since our Input is a controlled component.
|
|
39
38
|
*/
|
|
40
39
|
value: InputHTMLAttributes<HTMLInputElement>['value'];
|
|
40
|
+
/**
|
|
41
|
+
* The input's autocomplete behavior.
|
|
42
|
+
*/
|
|
43
|
+
autoComplete?: boolean | string;
|
|
41
44
|
/**
|
|
42
45
|
* Automatically focus the input when the page is loaded.
|
|
43
46
|
*/
|
|
@@ -58,7 +61,7 @@ export interface TextInputInsetProps {
|
|
|
58
61
|
/**
|
|
59
62
|
* Props passed directly to the input element of the component
|
|
60
63
|
*/
|
|
61
|
-
inputProps?: BoxProps
|
|
64
|
+
inputProps?: Omit<BoxProps<'input'>, 'as'>;
|
|
62
65
|
/**
|
|
63
66
|
* The input's disabled attribute
|
|
64
67
|
*/
|
|
@@ -115,10 +118,6 @@ export interface TextInputInsetProps {
|
|
|
115
118
|
* The input 'type' value. Defaults to type 'text'.
|
|
116
119
|
*/
|
|
117
120
|
type?: InputHTMLAttributes<HTMLInputElement>['type'];
|
|
118
|
-
/**
|
|
119
|
-
* Additional props to be spread to rendered element
|
|
120
|
-
*/
|
|
121
|
-
[x: string]: any; // eslint-disable-line
|
|
122
121
|
}
|
|
123
122
|
|
|
124
123
|
export const TextInputInset: ForwardRefExoticComponent<TextInputInsetProps> =
|
|
@@ -9,7 +9,7 @@ import { generateResponsiveClasses } from '../../lib/generateResponsiveClasses';
|
|
|
9
9
|
import styles from './TextareaInput.module.scss';
|
|
10
10
|
|
|
11
11
|
export type TextareaInputSize = 'sm' | 'md' | 'lg';
|
|
12
|
-
|
|
12
|
+
interface TextareaInputOwnProps {
|
|
13
13
|
/**
|
|
14
14
|
* The input's id attribute. Used to programmatically tie the input with its label.
|
|
15
15
|
*/
|
|
@@ -96,12 +96,11 @@ export interface TextareaInputProps extends Omit<BoxProps, 'as' | 'width'> {
|
|
|
96
96
|
* The size of the text input.
|
|
97
97
|
*/
|
|
98
98
|
size?: TextareaInputSize | ResponsiveProp<TextareaInputSize>;
|
|
99
|
-
/**
|
|
100
|
-
* Additional props to be spread to rendered element
|
|
101
|
-
*/
|
|
102
|
-
[x: string]: any; // eslint-disable-line
|
|
103
99
|
}
|
|
104
100
|
|
|
101
|
+
export type TextareaInputProps = TextareaInputOwnProps &
|
|
102
|
+
Omit<BoxProps<'div'>, keyof TextareaInputOwnProps | 'as' | 'width'>;
|
|
103
|
+
|
|
105
104
|
export const TextareaInput: FC<TextareaInputProps> = ({
|
|
106
105
|
id,
|
|
107
106
|
label,
|
|
@@ -4,8 +4,7 @@ import React, {
|
|
|
4
4
|
FocusEvent,
|
|
5
5
|
ForwardRefExoticComponent,
|
|
6
6
|
ReactNode,
|
|
7
|
-
|
|
8
|
-
InputHTMLAttributes,
|
|
7
|
+
TextareaHTMLAttributes,
|
|
9
8
|
} from 'react';
|
|
10
9
|
import classNames from 'classnames';
|
|
11
10
|
import { ResponsiveProp } from '../../types';
|
|
@@ -30,11 +29,15 @@ export interface TextareaInputInsetProps {
|
|
|
30
29
|
/**
|
|
31
30
|
* Callback function to call on change event.
|
|
32
31
|
*/
|
|
33
|
-
onChange: (event: ChangeEvent<
|
|
32
|
+
onChange: (event: ChangeEvent<HTMLTextAreaElement>) => void;
|
|
34
33
|
/**
|
|
35
34
|
* The text value of the input. Required since our Input is a controlled component.
|
|
36
35
|
*/
|
|
37
|
-
value:
|
|
36
|
+
value: TextareaHTMLAttributes<HTMLTextAreaElement>['value'];
|
|
37
|
+
/**
|
|
38
|
+
* The textarea's autocomplete behavior.
|
|
39
|
+
*/
|
|
40
|
+
autoComplete?: boolean | string;
|
|
38
41
|
/**
|
|
39
42
|
* Automatically focus the input when the page is loaded.
|
|
40
43
|
*/
|
|
@@ -55,7 +58,7 @@ export interface TextareaInputInsetProps {
|
|
|
55
58
|
/**
|
|
56
59
|
* Props passed directly to the input element of the component
|
|
57
60
|
*/
|
|
58
|
-
inputProps?: BoxProps
|
|
61
|
+
inputProps?: Omit<BoxProps<'textarea'>, 'as'>;
|
|
59
62
|
/**
|
|
60
63
|
* The input's disabled attribute
|
|
61
64
|
*/
|
|
@@ -76,11 +79,11 @@ export interface TextareaInputInsetProps {
|
|
|
76
79
|
/**
|
|
77
80
|
* Callback function to call on blur event.
|
|
78
81
|
*/
|
|
79
|
-
onBlur?: (event: FocusEvent<
|
|
82
|
+
onBlur?: (event: FocusEvent<HTMLTextAreaElement>) => void;
|
|
80
83
|
/**
|
|
81
84
|
* Callback function to call on focus event.
|
|
82
85
|
*/
|
|
83
|
-
onFocus?: (event: FocusEvent<
|
|
86
|
+
onFocus?: (event: FocusEvent<HTMLTextAreaElement>) => void;
|
|
84
87
|
/**
|
|
85
88
|
* The input placeholder attribute.
|
|
86
89
|
*/
|
|
@@ -109,14 +112,6 @@ export interface TextareaInputInsetProps {
|
|
|
109
112
|
* An input helper rendered after the input field value
|
|
110
113
|
*/
|
|
111
114
|
suffix?: ReactNode;
|
|
112
|
-
/**
|
|
113
|
-
* The input 'type' value. Defaults to type 'text'.
|
|
114
|
-
*/
|
|
115
|
-
type?: InputHTMLAttributes<HTMLInputElement>['type'];
|
|
116
|
-
/**
|
|
117
|
-
* Additional props to be spread to rendered element
|
|
118
|
-
*/
|
|
119
|
-
[x: string]: any; // eslint-disable-line
|
|
120
115
|
}
|
|
121
116
|
|
|
122
117
|
export const TextareaInputInset: ForwardRefExoticComponent<TextareaInputInsetProps> =
|
|
@@ -144,7 +139,6 @@ export const TextareaInputInset: ForwardRefExoticComponent<TextareaInputInsetPro
|
|
|
144
139
|
resize = 'vertical',
|
|
145
140
|
rows = 5,
|
|
146
141
|
size = 'md',
|
|
147
|
-
type = 'text',
|
|
148
142
|
},
|
|
149
143
|
ref
|
|
150
144
|
) => {
|
|
@@ -180,7 +174,6 @@ export const TextareaInputInset: ForwardRefExoticComponent<TextareaInputInsetPro
|
|
|
180
174
|
placeholder,
|
|
181
175
|
required: isRequired,
|
|
182
176
|
rows,
|
|
183
|
-
type,
|
|
184
177
|
value,
|
|
185
178
|
};
|
|
186
179
|
|
|
@@ -90,7 +90,11 @@ export const Column = () =>
|
|
|
90
90
|
{
|
|
91
91
|
heading: 'Type',
|
|
92
92
|
dataKey: 'type',
|
|
93
|
-
render: (cell?: Cell) =>
|
|
93
|
+
render: (cell?: Cell) => (
|
|
94
|
+
<code style={codePreviewStyle}>
|
|
95
|
+
{typeof cell === 'string' || typeof cell === 'number' ? cell : null}
|
|
96
|
+
</code>
|
|
97
|
+
),
|
|
94
98
|
},
|
|
95
99
|
{ heading: 'Description', dataKey: 'description' },
|
|
96
100
|
];
|
package/src/lib/getColumnKeys.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { Key } from 'react';
|
|
2
|
-
import { Column } from '../types';
|
|
2
|
+
import { Column, Row } from '../types';
|
|
3
3
|
|
|
4
4
|
// eslint-disable-next-line import/prefer-default-export
|
|
5
|
-
export const getColumnKeys =
|
|
5
|
+
export const getColumnKeys = <TRow extends object = Row>(
|
|
6
|
+
columns: Column<TRow>[]
|
|
7
|
+
): Key[] => {
|
|
6
8
|
const INTERNAL_KEY_PREFIX = 'columnKeyPrefix';
|
|
7
|
-
const columnKeys:
|
|
9
|
+
const columnKeys: Key[] = [];
|
|
8
10
|
const keys: Record<string, boolean> = {};
|
|
9
11
|
|
|
10
12
|
columns.forEach((column) => {
|
package/src/types/index.ts
CHANGED
|
@@ -44,8 +44,7 @@ export type Breakpoint = {
|
|
|
44
44
|
|
|
45
45
|
export type DimensionSize = WidthSize | HeightSize;
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
export type UnknownPropertiesObjType = { [key: string]: any };
|
|
47
|
+
export type UnknownPropertiesObjType = Record<string, unknown>;
|
|
49
48
|
|
|
50
49
|
export interface FlexProperty {
|
|
51
50
|
flexGrow?: number | string;
|
|
@@ -148,9 +147,9 @@ export declare type ResponsiveProp<T> = {
|
|
|
148
147
|
|
|
149
148
|
export type Row = UnknownPropertiesObjType;
|
|
150
149
|
|
|
151
|
-
export type Cell =
|
|
150
|
+
export type Cell = Row[string];
|
|
152
151
|
|
|
153
|
-
export declare type Column = {
|
|
152
|
+
export declare type Column<TRow extends object = Row> = {
|
|
154
153
|
/**
|
|
155
154
|
* Text alignment for column cells (including header alignment). Cells will default to left if not defined.
|
|
156
155
|
*/
|
|
@@ -160,11 +159,11 @@ export declare type Column = {
|
|
|
160
159
|
*/
|
|
161
160
|
cellClassName?:
|
|
162
161
|
| string
|
|
163
|
-
| ((cell?: Cell, row?:
|
|
162
|
+
| ((cell?: Cell, row?: TRow, rowIndex?: number) => string);
|
|
164
163
|
/**
|
|
165
164
|
* The key value to be rendered based on the table `rows`.
|
|
166
165
|
*/
|
|
167
|
-
dataKey?: string
|
|
166
|
+
dataKey?: Extract<keyof TRow, string>;
|
|
168
167
|
/**
|
|
169
168
|
* Placeholder for empty cells Applies only to the cells of the particular column with this prop.
|
|
170
169
|
*/
|
|
@@ -190,7 +189,7 @@ export declare type Column = {
|
|
|
190
189
|
* Render method for column cell data. Provides ability to render any aspect of the cell/row with custom
|
|
191
190
|
* markup.
|
|
192
191
|
*/
|
|
193
|
-
render?: (cell?: Cell, row?:
|
|
192
|
+
render?: (cell?: Cell, row?: TRow, rowIndex?: number) => ReactNode;
|
|
194
193
|
/**
|
|
195
194
|
* Whether the column is stuck to the left or right.
|
|
196
195
|
*/
|