@indico-data/design-system 3.18.0 → 3.19.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/lib/components/forms/date/datePicker/types.d.ts +7 -0
- package/lib/components/forms/date/iconTriggerDatePicker/IconTriggerDatePicker.d.ts +3 -0
- package/lib/components/forms/date/iconTriggerDatePicker/types.d.ts +5 -0
- package/lib/components/forms/date/inputDatePicker/SingleInputDatePicker.d.ts +2 -1
- package/lib/components/forms/date/inputDateRangePicker/InputDateRangePicker.d.ts +3 -0
- package/lib/components/forms/date/inputDateRangePicker/types.d.ts +7 -0
- package/lib/components/forms/date/inputDateTimePicker/SingleInputDateTimePicker.d.ts +2 -1
- package/lib/components/forms/select/Select.d.ts +3 -1
- package/lib/components/forms/select/types.d.ts +10 -0
- package/lib/components/forms/subcomponents/Label.d.ts +4 -0
- package/lib/components/forms/subcomponents/types.d.ts +5 -0
- package/lib/components/forms/timePicker/TimePicker.d.ts +4 -1
- package/lib/components/forms/timePicker/types.d.ts +5 -0
- package/lib/components/modal/ConfirmationModal.d.ts +1 -1
- package/lib/components/modal/Modal.d.ts +1 -1
- package/lib/components/modal/Modal.stories.d.ts +4 -0
- package/lib/components/modal/types.d.ts +19 -5
- package/lib/components/pagination/Pagination.d.ts +1 -1
- package/lib/components/pagination/index.d.ts +1 -0
- package/lib/components/pagination/types.d.ts +13 -0
- package/lib/components/stepper/Stepper.d.ts +1 -1
- package/lib/components/stepper/components/BackNavigation.d.ts +2 -1
- package/lib/components/stepper/components/NextNavigation.d.ts +3 -1
- package/lib/components/stepper/types.d.ts +11 -0
- package/lib/components/table/LoadingComponent.d.ts +5 -1
- package/lib/components/table/components/HorizontalStickyHeader.d.ts +4 -1
- package/lib/components/table/hooks/usePinnedColumnsManager.d.ts +2 -2
- package/lib/components/table/types.d.ts +18 -0
- package/lib/components/table/utils/processColumns.d.ts +2 -2
- package/lib/components/tanstackTable/TankstackTable.types.d.ts +19 -2
- package/lib/components/tanstackTable/TanstackTable.d.ts +1 -1
- package/lib/components/tanstackTable/components/NoResults/NoResults.d.ts +2 -1
- package/lib/components/tanstackTable/components/TablePagination/TablePagination.d.ts +3 -1
- package/lib/index.d.ts +143 -23
- package/lib/index.esm.js +130 -60
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +130 -60
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/button/Button.tsx +4 -18
- package/src/components/button/__tests__/Button.test.tsx +30 -28
- package/src/components/forms/date/datePicker/DatePicker.stories.tsx +10 -0
- package/src/components/forms/date/datePicker/DatePicker.tsx +9 -2
- package/src/components/forms/date/datePicker/types.ts +8 -0
- package/src/components/forms/date/iconTriggerDatePicker/IconTriggerDatePicker.stories.tsx +10 -0
- package/src/components/forms/date/iconTriggerDatePicker/IconTriggerDatePicker.tsx +12 -1
- package/src/components/forms/date/iconTriggerDatePicker/types.ts +5 -0
- package/src/components/forms/date/inputDatePicker/SingleInputDatePicker.tsx +4 -3
- package/src/components/forms/date/inputDatePicker/__tests__/SingleInputDatePicker.test.tsx +2 -0
- package/src/components/forms/date/inputDateRangePicker/InputDateRangePicker.stories.tsx +10 -0
- package/src/components/forms/date/inputDateRangePicker/InputDateRangePicker.tsx +14 -2
- package/src/components/forms/date/inputDateRangePicker/types.ts +7 -0
- package/src/components/forms/date/inputDateTimePicker/SingleInputDateTimePicker.tsx +3 -2
- package/src/components/forms/input/Input.tsx +1 -0
- package/src/components/forms/numberInput/NumberInput.tsx +1 -0
- package/src/components/forms/passwordInput/PasswordInput.tsx +7 -1
- package/src/components/forms/select/Select.stories.tsx +6 -5
- package/src/components/forms/select/Select.tsx +15 -1
- package/src/components/forms/select/types.ts +11 -0
- package/src/components/forms/subcomponents/Label.tsx +20 -3
- package/src/components/forms/subcomponents/types.ts +5 -0
- package/src/components/forms/textarea/Textarea.tsx +1 -0
- package/src/components/forms/timePicker/TimePicker.stories.tsx +10 -0
- package/src/components/forms/timePicker/TimePicker.tsx +10 -1
- package/src/components/forms/timePicker/types.ts +5 -0
- package/src/components/modal/ConfirmationModal.tsx +19 -14
- package/src/components/modal/Modal.stories.tsx +53 -22
- package/src/components/modal/Modal.tsx +8 -2
- package/src/components/modal/types.ts +21 -5
- package/src/components/pagination/Pagination.stories.tsx +11 -0
- package/src/components/pagination/Pagination.tsx +14 -5
- package/src/components/pagination/index.ts +1 -0
- package/src/components/pagination/types.ts +14 -0
- package/src/components/stepper/Stepper.stories.tsx +11 -0
- package/src/components/stepper/Stepper.tsx +16 -2
- package/src/components/stepper/components/BackNavigation.tsx +5 -3
- package/src/components/stepper/components/NextNavigation.tsx +15 -5
- package/src/components/stepper/types.ts +12 -0
- package/src/components/table/LoadingComponent.tsx +6 -2
- package/src/components/table/Table.stories.tsx +10 -0
- package/src/components/table/Table.tsx +12 -2
- package/src/components/table/components/HorizontalStickyHeader.tsx +12 -1
- package/src/components/table/hooks/usePinnedColumnsManager.ts +3 -2
- package/src/components/table/types.ts +20 -0
- package/src/components/table/utils/processColumns.tsx +3 -1
- package/src/components/tanstackTable/TankstackTable.types.ts +20 -2
- package/src/components/tanstackTable/TanstackTable.stories.tsx +8 -6
- package/src/components/tanstackTable/TanstackTable.tsx +21 -11
- package/src/components/tanstackTable/components/NoResults/NoResults.tsx +9 -3
- package/src/components/tanstackTable/components/TablePagination/TablePagination.tsx +4 -1
- package/src/index.ts +1 -1
- package/src/storybook/formArgTypes.ts +10 -0
- package/src/storybookDocs/Permafrost.mdx +8 -0
package/package.json
CHANGED
|
@@ -79,35 +79,21 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>((props, ref) =>
|
|
|
79
79
|
>
|
|
80
80
|
{/* Loading Icon on the left (default) */}
|
|
81
81
|
{isLoading && !iconRight && (
|
|
82
|
-
<Icon
|
|
83
|
-
name="indico-o"
|
|
84
|
-
style={{ animation: 'spin 1s linear infinite' }}
|
|
85
|
-
ariaLabel="Loading..."
|
|
86
|
-
size={iconSize}
|
|
87
|
-
/>
|
|
82
|
+
<Icon name="indico-o" style={{ animation: 'spin 1s linear infinite' }} size={iconSize} />
|
|
88
83
|
)}
|
|
89
84
|
|
|
90
85
|
{/* Left Icon */}
|
|
91
|
-
{iconLeft && !isLoading &&
|
|
92
|
-
<Icon name={iconLeft} ariaLabel={`${iconLeft} Icon`} size={iconSize} />
|
|
93
|
-
)}
|
|
86
|
+
{iconLeft && !isLoading && <Icon name={iconLeft} ariaLabel={iconLeft} size={iconSize} />}
|
|
94
87
|
|
|
95
88
|
{/* Button children */}
|
|
96
89
|
{children}
|
|
97
90
|
|
|
98
91
|
{/* Right Icon */}
|
|
99
|
-
{iconRight && !isLoading &&
|
|
100
|
-
<Icon name={iconRight} ariaLabel={`${iconRight} Icon`} size={iconSize} />
|
|
101
|
-
)}
|
|
92
|
+
{iconRight && !isLoading && <Icon name={iconRight} ariaLabel={iconRight} size={iconSize} />}
|
|
102
93
|
|
|
103
94
|
{/* Loading Icon on the right */}
|
|
104
95
|
{isLoading && iconRight && (
|
|
105
|
-
<Icon
|
|
106
|
-
name="indico-o"
|
|
107
|
-
style={{ animation: 'spin 1s linear infinite' }}
|
|
108
|
-
ariaLabel="Loading..."
|
|
109
|
-
size={iconSize}
|
|
110
|
-
/>
|
|
96
|
+
<Icon name="indico-o" style={{ animation: 'spin 1s linear infinite' }} size={iconSize} />
|
|
111
97
|
)}
|
|
112
98
|
</button>
|
|
113
99
|
);
|
|
@@ -52,11 +52,10 @@ describe('Button', () => {
|
|
|
52
52
|
</Button>,
|
|
53
53
|
);
|
|
54
54
|
const button = screen.getByRole('button');
|
|
55
|
-
const loadingIcon = screen.getByLabelText('Loading...');
|
|
56
55
|
|
|
57
56
|
expect(button).toHaveClass('btn--loading');
|
|
58
57
|
expect(button).toBeDisabled();
|
|
59
|
-
expect(
|
|
58
|
+
expect(button).toHaveAttribute('aria-busy', 'true');
|
|
60
59
|
});
|
|
61
60
|
|
|
62
61
|
it('displays the loading icon on the left when isLoading and iconLeft exists and hides the iconLeft', () => {
|
|
@@ -65,9 +64,10 @@ describe('Button', () => {
|
|
|
65
64
|
Button
|
|
66
65
|
</Button>,
|
|
67
66
|
);
|
|
68
|
-
const
|
|
69
|
-
const iconLeft = screen.queryByLabelText('check
|
|
67
|
+
const button = screen.getByRole('button');
|
|
68
|
+
const iconLeft = screen.queryByLabelText('check');
|
|
70
69
|
|
|
70
|
+
expect(button).toHaveAttribute('aria-busy', 'true');
|
|
71
71
|
expect(iconLeft).not.toBeInTheDocument();
|
|
72
72
|
});
|
|
73
73
|
|
|
@@ -77,19 +77,22 @@ describe('Button', () => {
|
|
|
77
77
|
Button
|
|
78
78
|
</Button>,
|
|
79
79
|
);
|
|
80
|
-
const
|
|
81
|
-
const iconRight = screen.queryByLabelText('check
|
|
80
|
+
const button = screen.getByRole('button');
|
|
81
|
+
const iconRight = screen.queryByLabelText('check');
|
|
82
82
|
|
|
83
|
+
expect(button).toHaveAttribute('aria-busy', 'true');
|
|
83
84
|
expect(iconRight).not.toBeInTheDocument();
|
|
84
85
|
});
|
|
85
86
|
|
|
86
|
-
it('
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
87
|
+
it('sets aria-busy when loading with no children', () => {
|
|
88
|
+
const { rerender } = render(
|
|
89
|
+
<Button isLoading iconLeft="check" onClick={onClick} ariaLabel="btn" />,
|
|
90
|
+
);
|
|
91
|
+
const button = screen.getByRole('button');
|
|
92
|
+
expect(button).toHaveAttribute('aria-busy', 'true');
|
|
90
93
|
|
|
91
|
-
|
|
92
|
-
expect(
|
|
94
|
+
rerender(<Button isLoading iconRight="check" onClick={onClick} ariaLabel="btn" />);
|
|
95
|
+
expect(button).toHaveAttribute('aria-busy', 'true');
|
|
93
96
|
});
|
|
94
97
|
|
|
95
98
|
it('does not apply the loading class when not loading', () => {
|
|
@@ -99,11 +102,10 @@ describe('Button', () => {
|
|
|
99
102
|
</Button>,
|
|
100
103
|
);
|
|
101
104
|
const button = screen.getByRole('button');
|
|
102
|
-
const loadingIcon = screen.queryByLabelText('Loading...');
|
|
103
105
|
|
|
104
106
|
expect(button).not.toHaveClass('btn--loading');
|
|
105
107
|
expect(button).toBeEnabled();
|
|
106
|
-
expect(
|
|
108
|
+
expect(button).toHaveAttribute('aria-busy', 'false');
|
|
107
109
|
});
|
|
108
110
|
|
|
109
111
|
it('disables the button when disabled prop is true', () => {
|
|
@@ -123,7 +125,7 @@ describe('Button', () => {
|
|
|
123
125
|
describe('button with icons', () => {
|
|
124
126
|
it('renders an icon-only button when only iconLeft is provided', () => {
|
|
125
127
|
render(<Button iconLeft="check" ariaLabel="icon button" />);
|
|
126
|
-
const icon = screen.getByLabelText('check
|
|
128
|
+
const icon = screen.getByLabelText('check');
|
|
127
129
|
const button = screen.getByRole('button');
|
|
128
130
|
|
|
129
131
|
expect(icon).toBeInTheDocument();
|
|
@@ -133,7 +135,7 @@ describe('Button', () => {
|
|
|
133
135
|
|
|
134
136
|
it('renders an icon-only button when only iconRight is provided', () => {
|
|
135
137
|
render(<Button iconRight="check" ariaLabel="icon button" />);
|
|
136
|
-
const icon = screen.getByLabelText('check
|
|
138
|
+
const icon = screen.getByLabelText('check');
|
|
137
139
|
const button = screen.getByRole('button');
|
|
138
140
|
|
|
139
141
|
expect(icon).toBeInTheDocument();
|
|
@@ -147,7 +149,7 @@ describe('Button', () => {
|
|
|
147
149
|
Button
|
|
148
150
|
</Button>,
|
|
149
151
|
);
|
|
150
|
-
const icon = screen.getByLabelText('check
|
|
152
|
+
const icon = screen.getByLabelText('check');
|
|
151
153
|
const button = screen.getByRole('button');
|
|
152
154
|
|
|
153
155
|
expect(button).toContainElement(icon);
|
|
@@ -159,7 +161,7 @@ describe('Button', () => {
|
|
|
159
161
|
Button
|
|
160
162
|
</Button>,
|
|
161
163
|
);
|
|
162
|
-
const icon = screen.getByLabelText('check
|
|
164
|
+
const icon = screen.getByLabelText('check');
|
|
163
165
|
const button = screen.getByRole('button');
|
|
164
166
|
|
|
165
167
|
expect(button).toContainElement(icon);
|
|
@@ -171,8 +173,8 @@ describe('Button', () => {
|
|
|
171
173
|
Button
|
|
172
174
|
</Button>,
|
|
173
175
|
);
|
|
174
|
-
const leftIcon = screen.getByLabelText('check
|
|
175
|
-
const rightIcon = screen.getByLabelText('time
|
|
176
|
+
const leftIcon = screen.getByLabelText('check');
|
|
177
|
+
const rightIcon = screen.getByLabelText('time');
|
|
176
178
|
const button = screen.getByRole('button');
|
|
177
179
|
|
|
178
180
|
expect(button).toContainElement(leftIcon);
|
|
@@ -187,7 +189,7 @@ describe('Button', () => {
|
|
|
187
189
|
Button
|
|
188
190
|
</Button>,
|
|
189
191
|
);
|
|
190
|
-
const icon = screen.getByLabelText('check
|
|
192
|
+
const icon = screen.getByLabelText('check');
|
|
191
193
|
expect(icon).toHaveClass('icon--xs');
|
|
192
194
|
});
|
|
193
195
|
|
|
@@ -197,7 +199,7 @@ describe('Button', () => {
|
|
|
197
199
|
Button
|
|
198
200
|
</Button>,
|
|
199
201
|
);
|
|
200
|
-
const icon = screen.getByLabelText('check
|
|
202
|
+
const icon = screen.getByLabelText('check');
|
|
201
203
|
expect(icon).toHaveClass('icon--sm');
|
|
202
204
|
});
|
|
203
205
|
|
|
@@ -207,7 +209,7 @@ describe('Button', () => {
|
|
|
207
209
|
Button
|
|
208
210
|
</Button>,
|
|
209
211
|
);
|
|
210
|
-
const icon = screen.getByLabelText('check
|
|
212
|
+
const icon = screen.getByLabelText('check');
|
|
211
213
|
expect(icon).toHaveClass('icon--md');
|
|
212
214
|
});
|
|
213
215
|
|
|
@@ -217,7 +219,7 @@ describe('Button', () => {
|
|
|
217
219
|
Button
|
|
218
220
|
</Button>,
|
|
219
221
|
);
|
|
220
|
-
const icon = screen.getByLabelText('check
|
|
222
|
+
const icon = screen.getByLabelText('check');
|
|
221
223
|
expect(icon).toHaveClass('icon--md');
|
|
222
224
|
});
|
|
223
225
|
|
|
@@ -227,18 +229,18 @@ describe('Button', () => {
|
|
|
227
229
|
Button
|
|
228
230
|
</Button>,
|
|
229
231
|
);
|
|
230
|
-
const icon = screen.getByLabelText('check
|
|
232
|
+
const icon = screen.getByLabelText('check');
|
|
231
233
|
expect(icon).toHaveClass('icon--lg');
|
|
232
234
|
});
|
|
233
235
|
|
|
234
|
-
it('
|
|
236
|
+
it('sets aria-busy when loading regardless of button size', () => {
|
|
235
237
|
render(
|
|
236
238
|
<Button size="sm" isLoading ariaLabel="loading button">
|
|
237
239
|
Button
|
|
238
240
|
</Button>,
|
|
239
241
|
);
|
|
240
|
-
const
|
|
241
|
-
expect(
|
|
242
|
+
const button = screen.getByRole('button');
|
|
243
|
+
expect(button).toHaveAttribute('aria-busy', 'true');
|
|
242
244
|
});
|
|
243
245
|
});
|
|
244
246
|
});
|
|
@@ -240,6 +240,16 @@ const meta: Meta = {
|
|
|
240
240
|
},
|
|
241
241
|
},
|
|
242
242
|
},
|
|
243
|
+
text: {
|
|
244
|
+
control: 'object',
|
|
245
|
+
description: 'Customizable text.',
|
|
246
|
+
table: {
|
|
247
|
+
category: 'i18n Text',
|
|
248
|
+
type: {
|
|
249
|
+
summary: '{ selectTime?: string }',
|
|
250
|
+
},
|
|
251
|
+
},
|
|
252
|
+
},
|
|
243
253
|
},
|
|
244
254
|
};
|
|
245
255
|
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { DateRange, DayPicker, Mode, OnSelectHandler } from 'react-day-picker';
|
|
2
2
|
import 'react-day-picker/style.css';
|
|
3
|
-
import { DatePickerProps } from './types';
|
|
3
|
+
import { DatePickerProps, DatePickerText } from './types';
|
|
4
4
|
import { getCommonProps } from './contants';
|
|
5
5
|
import { TimePicker } from '../../timePicker/TimePicker';
|
|
6
6
|
import { Col, Row } from '../../../grid';
|
|
7
7
|
import { useEffect, useRef } from 'react';
|
|
8
8
|
|
|
9
|
+
const DEFAULT_TEXT: Required<DatePickerText> = {
|
|
10
|
+
selectTime: 'Select Time',
|
|
11
|
+
};
|
|
12
|
+
|
|
9
13
|
export const DatePicker = (props: DatePickerProps) => {
|
|
10
14
|
const {
|
|
11
15
|
mode = 'single',
|
|
@@ -39,9 +43,12 @@ export const DatePicker = (props: DatePickerProps) => {
|
|
|
39
43
|
ref,
|
|
40
44
|
timeTabIndex,
|
|
41
45
|
dateTabIndex,
|
|
46
|
+
text: textProp,
|
|
42
47
|
...rest
|
|
43
48
|
} = props;
|
|
44
49
|
|
|
50
|
+
const text = { ...DEFAULT_TEXT, ...textProp };
|
|
51
|
+
|
|
45
52
|
const futureDateByYear = (year: number) => new Date(new Date().getFullYear() + year, 11, 31);
|
|
46
53
|
const endMonthDefault = endMonth ?? futureDateByYear(5);
|
|
47
54
|
|
|
@@ -116,7 +123,7 @@ export const DatePicker = (props: DatePickerProps) => {
|
|
|
116
123
|
<div className="time-picker-wrapper">
|
|
117
124
|
<Row align="center">
|
|
118
125
|
<Col xs="content">
|
|
119
|
-
<p className="ma-0">
|
|
126
|
+
<p className="ma-0">{text.selectTime}</p>
|
|
120
127
|
</Col>
|
|
121
128
|
<Col>
|
|
122
129
|
<TimePicker
|
|
@@ -9,6 +9,12 @@ import {
|
|
|
9
9
|
OnSelectHandler,
|
|
10
10
|
} from 'react-day-picker';
|
|
11
11
|
|
|
12
|
+
/** Customizable text for DatePicker. */
|
|
13
|
+
export interface DatePickerText {
|
|
14
|
+
/** Label for "Select Time" text. Default: "Select Time" */
|
|
15
|
+
selectTime?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
12
18
|
export interface DatePickerProps {
|
|
13
19
|
ref?: React.LegacyRef<HTMLInputElement>;
|
|
14
20
|
/** The selected day(s). */
|
|
@@ -51,6 +57,8 @@ export interface DatePickerProps {
|
|
|
51
57
|
isReadOnly?: boolean;
|
|
52
58
|
timeTabIndex?: number;
|
|
53
59
|
dateTabIndex?: number;
|
|
60
|
+
/** Customizable display text. */
|
|
61
|
+
text?: DatePickerText;
|
|
54
62
|
}
|
|
55
63
|
|
|
56
64
|
export interface CommonProps {
|
|
@@ -175,6 +175,16 @@ const meta: Meta<typeof IconTriggerDatePicker> = {
|
|
|
175
175
|
},
|
|
176
176
|
action: 'onSelect',
|
|
177
177
|
},
|
|
178
|
+
text: {
|
|
179
|
+
control: 'object',
|
|
180
|
+
description: 'Customizable text.',
|
|
181
|
+
table: {
|
|
182
|
+
category: 'i18n Text',
|
|
183
|
+
type: {
|
|
184
|
+
summary: '{ triggerIcon?: string }',
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
},
|
|
178
188
|
},
|
|
179
189
|
};
|
|
180
190
|
|
|
@@ -6,6 +6,12 @@ import { DatePicker } from '../datePicker/DatePicker';
|
|
|
6
6
|
import { Icon } from '../../../icons/Icon';
|
|
7
7
|
import { UseFloatingOptions } from '@floating-ui/react-dom';
|
|
8
8
|
import { PortalOptions } from '../datePicker/types';
|
|
9
|
+
import { IconTriggerDatePickerText } from './types';
|
|
10
|
+
|
|
11
|
+
const DEFAULT_TEXT: Required<IconTriggerDatePickerText> = {
|
|
12
|
+
triggerIcon: 'Open date picker',
|
|
13
|
+
};
|
|
14
|
+
|
|
9
15
|
interface Props {
|
|
10
16
|
/** Allows you to select a single day, a range of days, or multiple days. */
|
|
11
17
|
mode?: Mode;
|
|
@@ -42,6 +48,8 @@ interface Props {
|
|
|
42
48
|
isPortal?: boolean;
|
|
43
49
|
/** The floating options for the date picker. Follows floating-ui options. */
|
|
44
50
|
floatingOptions?: UseFloatingOptions;
|
|
51
|
+
/** Customizable display text. */
|
|
52
|
+
text?: IconTriggerDatePickerText;
|
|
45
53
|
}
|
|
46
54
|
|
|
47
55
|
export const IconTriggerDatePicker = (props: Props) => {
|
|
@@ -64,9 +72,12 @@ export const IconTriggerDatePicker = (props: Props) => {
|
|
|
64
72
|
portalOptions,
|
|
65
73
|
floatingOptions,
|
|
66
74
|
isPortal,
|
|
75
|
+
text: textProp,
|
|
67
76
|
...rest
|
|
68
77
|
} = props;
|
|
69
78
|
|
|
79
|
+
const text = { ...DEFAULT_TEXT, ...textProp };
|
|
80
|
+
|
|
70
81
|
const [localMonth, setLocalMonth] = useState<Date>(initialMonth ?? new Date());
|
|
71
82
|
|
|
72
83
|
const handleSelect: OnSelectHandler<Date> = (date) => {
|
|
@@ -93,7 +104,7 @@ export const IconTriggerDatePicker = (props: Props) => {
|
|
|
93
104
|
floatingOptions={floatingOptions}
|
|
94
105
|
>
|
|
95
106
|
<Icon
|
|
96
|
-
aria-label=
|
|
107
|
+
aria-label={text.triggerIcon}
|
|
97
108
|
name={triggerIcon}
|
|
98
109
|
size={triggerIconSize}
|
|
99
110
|
className="date__picker__trigger"
|
|
@@ -16,7 +16,8 @@ export interface SingleInputDatePickerProps {
|
|
|
16
16
|
/** The layout of the caption. Enables you to add or remove the dropdown navigation for months/years */
|
|
17
17
|
captionLayout?: 'dropdown' | 'dropdown-months' | 'dropdown-years' | 'label';
|
|
18
18
|
id?: string;
|
|
19
|
-
label
|
|
19
|
+
/** The label for the input field. */
|
|
20
|
+
label: string;
|
|
20
21
|
onSelect: (selected: Date | undefined) => void;
|
|
21
22
|
initialMonth?: Date;
|
|
22
23
|
selected?: Date;
|
|
@@ -131,9 +132,9 @@ export function SingleInputDatePicker(props: SingleInputDatePickerProps) {
|
|
|
131
132
|
isClearable={isClearable}
|
|
132
133
|
onChange={handleInputChange}
|
|
133
134
|
errorMessage={errorMessage}
|
|
134
|
-
label={
|
|
135
|
+
label={label}
|
|
135
136
|
tabIndex={tabIndex}
|
|
136
|
-
name={
|
|
137
|
+
name={label}
|
|
137
138
|
ref={ref}
|
|
138
139
|
readonly={isReadOnly}
|
|
139
140
|
/>
|
|
@@ -30,6 +30,7 @@ describe('SingleInputDatePicker', () => {
|
|
|
30
30
|
render(
|
|
31
31
|
<SingleInputDatePicker
|
|
32
32
|
ariaLabel="Single Input Date Picker"
|
|
33
|
+
label="Date Picker"
|
|
33
34
|
data-testid="datepicker-testid"
|
|
34
35
|
captionLayout="label"
|
|
35
36
|
onSelect={mockOnSelect}
|
|
@@ -70,6 +71,7 @@ describe('SingleInputDatePicker', () => {
|
|
|
70
71
|
render(
|
|
71
72
|
<SingleInputDatePicker
|
|
72
73
|
ariaLabel="Single Input Date Picker"
|
|
74
|
+
label="Date Picker"
|
|
73
75
|
captionLayout="label"
|
|
74
76
|
data-testid="datepicker-testid"
|
|
75
77
|
onSelect={mockOnSelect}
|
|
@@ -261,6 +261,16 @@ const meta: Meta<typeof InputDateRangePicker> = {
|
|
|
261
261
|
disable: true,
|
|
262
262
|
},
|
|
263
263
|
},
|
|
264
|
+
text: {
|
|
265
|
+
control: 'object',
|
|
266
|
+
description: 'Customizable text.',
|
|
267
|
+
table: {
|
|
268
|
+
category: 'i18n Text',
|
|
269
|
+
type: {
|
|
270
|
+
summary: '{ fromDate?: string; toDate?: string }',
|
|
271
|
+
},
|
|
272
|
+
},
|
|
273
|
+
},
|
|
264
274
|
},
|
|
265
275
|
};
|
|
266
276
|
|
|
@@ -10,6 +10,13 @@ import { formatDateAsString } from '../inputDatePicker/helpers';
|
|
|
10
10
|
import { Button } from '../../../button';
|
|
11
11
|
import { UseFloatingOptions } from '@floating-ui/react-dom';
|
|
12
12
|
import { PortalOptions } from '../datePicker/types';
|
|
13
|
+
import { InputDateRangePickerText } from './types';
|
|
14
|
+
|
|
15
|
+
const DEFAULT_TEXT: Required<InputDateRangePickerText> = {
|
|
16
|
+
fromDate: 'From Date',
|
|
17
|
+
toDate: 'To Date',
|
|
18
|
+
};
|
|
19
|
+
|
|
13
20
|
interface InputDateRangePickerProps {
|
|
14
21
|
/** A label for assistive technologies. */
|
|
15
22
|
ariaLabel: string;
|
|
@@ -51,6 +58,8 @@ interface InputDateRangePickerProps {
|
|
|
51
58
|
floatingOptions?: UseFloatingOptions;
|
|
52
59
|
/** Whether the date picker is a portal. */
|
|
53
60
|
isPortal?: boolean;
|
|
61
|
+
/** Customizable display text. */
|
|
62
|
+
text?: InputDateRangePickerText;
|
|
54
63
|
}
|
|
55
64
|
|
|
56
65
|
export function InputDateRangePicker(props: InputDateRangePickerProps) {
|
|
@@ -85,9 +94,12 @@ export function InputDateRangePicker(props: InputDateRangePickerProps) {
|
|
|
85
94
|
portalOptions,
|
|
86
95
|
floatingOptions,
|
|
87
96
|
isPortal,
|
|
97
|
+
text: textProp,
|
|
88
98
|
...rest
|
|
89
99
|
} = props;
|
|
90
100
|
|
|
101
|
+
const text = { ...DEFAULT_TEXT, ...textProp };
|
|
102
|
+
|
|
91
103
|
const inputId = useId();
|
|
92
104
|
|
|
93
105
|
// Hold the input values in state
|
|
@@ -183,7 +195,7 @@ export function InputDateRangePicker(props: InputDateRangePickerProps) {
|
|
|
183
195
|
onChange={(e) => handleInputChange(e, 'from')}
|
|
184
196
|
errorMessage={fromErrorMessage}
|
|
185
197
|
label={fromLabel}
|
|
186
|
-
name={
|
|
198
|
+
name={text.fromDate}
|
|
187
199
|
data-testid="date-picker-from"
|
|
188
200
|
hasHiddenLabel={hasHiddenLabel}
|
|
189
201
|
ref={ref}
|
|
@@ -201,7 +213,7 @@ export function InputDateRangePicker(props: InputDateRangePickerProps) {
|
|
|
201
213
|
onChange={(e) => handleInputChange(e, 'to')}
|
|
202
214
|
errorMessage={toErrorMessage}
|
|
203
215
|
label={toLabel}
|
|
204
|
-
name={
|
|
216
|
+
name={text.toDate}
|
|
205
217
|
data-testid="date-picker-to"
|
|
206
218
|
hasHiddenLabel={hasHiddenLabel}
|
|
207
219
|
ref={ref}
|
|
@@ -18,7 +18,8 @@ export interface SingleInputDateTimePickerProps {
|
|
|
18
18
|
isDisabled?: boolean;
|
|
19
19
|
captionLayout?: 'dropdown' | 'dropdown-months' | 'dropdown-years' | 'label';
|
|
20
20
|
id?: string;
|
|
21
|
-
label
|
|
21
|
+
/** The label for the date input field. */
|
|
22
|
+
label: string;
|
|
22
23
|
onSelect: (selected: Date | undefined) => void;
|
|
23
24
|
initialMonth?: Date;
|
|
24
25
|
selected?: Date;
|
|
@@ -153,7 +154,7 @@ export function SingleInputDateTimePicker(props: SingleInputDateTimePickerProps)
|
|
|
153
154
|
onChange={handleInputChange}
|
|
154
155
|
errorMessage={errorMessage}
|
|
155
156
|
hasHiddenLabel={hasHiddenLabel}
|
|
156
|
-
label={
|
|
157
|
+
label={label}
|
|
157
158
|
name={`${id}-date-picker`}
|
|
158
159
|
tabIndex={dateTabIndex}
|
|
159
160
|
/>
|
|
@@ -32,6 +32,7 @@ const PasswordInput = React.forwardRef<HTMLInputElement, PasswordInputProps>(
|
|
|
32
32
|
errorMessage,
|
|
33
33
|
helpText,
|
|
34
34
|
hasShowPassword = true,
|
|
35
|
+
text: _text,
|
|
35
36
|
...rest
|
|
36
37
|
},
|
|
37
38
|
ref,
|
|
@@ -55,7 +56,12 @@ const PasswordInput = React.forwardRef<HTMLInputElement, PasswordInputProps>(
|
|
|
55
56
|
return (
|
|
56
57
|
<>
|
|
57
58
|
<div className="password-input-wrapper">
|
|
58
|
-
<Icon
|
|
59
|
+
<Icon
|
|
60
|
+
name="lock"
|
|
61
|
+
data-testid={`${name}-embedded-icon`}
|
|
62
|
+
className="embedded-icon"
|
|
63
|
+
size="sm"
|
|
64
|
+
/>
|
|
59
65
|
<input
|
|
60
66
|
ref={ref}
|
|
61
67
|
data-testid={`form-password-input-${name}`}
|
|
@@ -87,15 +87,16 @@ const meta: Meta<SelectProps<SelectOption> & LabelProps> = {
|
|
|
87
87
|
},
|
|
88
88
|
defaultValue: { summary: 'true' },
|
|
89
89
|
},
|
|
90
|
-
|
|
91
|
-
control: '
|
|
90
|
+
text: {
|
|
91
|
+
control: 'object',
|
|
92
|
+
description: 'Customizable text.',
|
|
92
93
|
table: {
|
|
93
|
-
category: '
|
|
94
|
+
category: 'i18n Text',
|
|
94
95
|
type: {
|
|
95
|
-
summary:
|
|
96
|
+
summary:
|
|
97
|
+
'{ placeholder?: string; noOptions?: string; loading?: string; required?: string }',
|
|
96
98
|
},
|
|
97
99
|
},
|
|
98
|
-
defaultValue: { summary: 'Select an option...' },
|
|
99
100
|
},
|
|
100
101
|
className: {
|
|
101
102
|
control: 'text',
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import classNames from 'classnames';
|
|
3
3
|
import ReactSelect, { Props as ReactSelectProps, components, OptionProps } from 'react-select';
|
|
4
|
-
import { SelectOption } from './types';
|
|
4
|
+
import { SelectOption, SelectText } from './types';
|
|
5
5
|
import { withLabel } from '../subcomponents/Label';
|
|
6
6
|
|
|
7
|
+
const DEFAULT_TEXT: Required<SelectText> = {
|
|
8
|
+
placeholder: 'Select...',
|
|
9
|
+
noOptions: 'No options',
|
|
10
|
+
loading: 'Loading...',
|
|
11
|
+
required: '(required)',
|
|
12
|
+
};
|
|
13
|
+
|
|
7
14
|
export interface SelectProps<OptionType extends SelectOption> extends ReactSelectProps<OptionType> {
|
|
8
15
|
/** Options for the select component */
|
|
9
16
|
options: OptionType[];
|
|
@@ -19,6 +26,8 @@ export interface SelectProps<OptionType extends SelectOption> extends ReactSelec
|
|
|
19
26
|
classNamePrefix?: string;
|
|
20
27
|
/** Event handler for when the selected value changes */
|
|
21
28
|
onChange?: (newValue: any, actionMeta: any) => void;
|
|
29
|
+
/** Customizable display text. */
|
|
30
|
+
text?: SelectText;
|
|
22
31
|
}
|
|
23
32
|
|
|
24
33
|
const OptionComponent = <OptionType extends SelectOption>({
|
|
@@ -43,10 +52,12 @@ const Select = React.forwardRef(
|
|
|
43
52
|
label,
|
|
44
53
|
hasHiddenLabel,
|
|
45
54
|
name,
|
|
55
|
+
text: textProp,
|
|
46
56
|
...props
|
|
47
57
|
}: SelectProps<OptionType>,
|
|
48
58
|
ref: React.Ref<any>,
|
|
49
59
|
) => {
|
|
60
|
+
const text = { ...DEFAULT_TEXT, ...textProp };
|
|
50
61
|
const defaultComponents = {
|
|
51
62
|
Option: OptionComponent as React.ComponentType<OptionProps<OptionType>>,
|
|
52
63
|
};
|
|
@@ -59,6 +70,9 @@ const Select = React.forwardRef(
|
|
|
59
70
|
classNamePrefix={classNamePrefix}
|
|
60
71
|
className={classNames('select-wrapper', className)}
|
|
61
72
|
components={mergedComponents}
|
|
73
|
+
placeholder={text.placeholder}
|
|
74
|
+
noOptionsMessage={() => text.noOptions}
|
|
75
|
+
loadingMessage={() => text.loading}
|
|
62
76
|
{...props}
|
|
63
77
|
/>
|
|
64
78
|
);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
+
import { FormLabelText } from '../subcomponents/Label';
|
|
2
3
|
|
|
3
4
|
export type SelectOption = {
|
|
4
5
|
label: string;
|
|
@@ -6,3 +7,13 @@ export type SelectOption = {
|
|
|
6
7
|
detail?: ReactNode;
|
|
7
8
|
[key: string]: any; // Allow for additional properties
|
|
8
9
|
};
|
|
10
|
+
|
|
11
|
+
/** Customizable text for Select. Extends FormLabelText for label-related text. */
|
|
12
|
+
export interface SelectText extends FormLabelText {
|
|
13
|
+
/** Placeholder text when no option is selected. Default: "Select..." */
|
|
14
|
+
placeholder?: string;
|
|
15
|
+
/** Text when there are no options. Default: "No options" */
|
|
16
|
+
noOptions?: string;
|
|
17
|
+
/** Text while loading options. Default: "Loading..." */
|
|
18
|
+
loading?: string;
|
|
19
|
+
}
|