@indico-data/design-system 2.36.4 → 2.38.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.
Files changed (70) hide show
  1. package/lib/index.css +40 -408
  2. package/lib/index.d.ts +122 -84
  3. package/lib/index.esm.css +40 -408
  4. package/lib/index.esm.js +15631 -16559
  5. package/lib/index.esm.js.map +1 -1
  6. package/lib/index.js +14165 -15092
  7. package/lib/index.js.map +1 -1
  8. package/lib/src/components/forms/date/datePicker/DatePicker.d.ts +3 -0
  9. package/lib/src/components/forms/date/datePicker/DatePicker.stories.d.ts +9 -0
  10. package/lib/src/components/forms/date/datePicker/contants.d.ts +21 -0
  11. package/lib/src/components/forms/date/datePicker/types.d.ts +48 -0
  12. package/lib/src/components/forms/date/iconTriggerDatePicker/IconTriggerDatePicker.d.ts +22 -0
  13. package/lib/src/components/forms/date/iconTriggerDatePicker/IconTriggerDatePicker.stories.d.ts +6 -0
  14. package/lib/src/components/forms/date/iconTriggerDatePicker/index.d.ts +1 -0
  15. package/lib/src/components/forms/date/inputDatePicker/SingleInputDatePicker.d.ts +23 -0
  16. package/lib/src/components/forms/date/inputDatePicker/SingleInputDatePicker.stories.d.ts +6 -0
  17. package/lib/src/components/forms/date/inputDatePicker/index.d.ts +1 -0
  18. package/lib/src/components/forms/date/inputDateRangePicker/InputDateRangePicker.d.ts +23 -0
  19. package/lib/src/components/forms/date/inputDateRangePicker/InputDateRangePicker.stories.d.ts +6 -0
  20. package/lib/src/components/forms/date/inputDateRangePicker/index.d.ts +1 -0
  21. package/lib/src/components/forms/input/Input.d.ts +1 -0
  22. package/lib/src/components/index.d.ts +3 -0
  23. package/lib/src/components/skeleton/Skeleton.d.ts +2 -2
  24. package/lib/src/components/skeleton/Skeleton.stories.d.ts +1 -0
  25. package/lib/src/index.d.ts +4 -1
  26. package/lib/src/legacy/components/index.d.ts +1 -1
  27. package/lib/src/legacy/components/inputs/index.d.ts +0 -2
  28. package/package.json +2 -2
  29. package/src/components/forms/date/datePicker/DatePicker.mdx +41 -0
  30. package/src/components/forms/date/datePicker/DatePicker.stories.tsx +307 -0
  31. package/src/components/forms/date/datePicker/DatePicker.tsx +68 -0
  32. package/src/components/forms/date/datePicker/contants.ts +22 -0
  33. package/src/components/forms/date/datePicker/styles/DatePicker.scss +85 -0
  34. package/src/components/forms/date/datePicker/types.ts +59 -0
  35. package/src/components/forms/date/iconTriggerDatePicker/IconTriggerDatePicker.mdx +17 -0
  36. package/src/components/forms/date/iconTriggerDatePicker/IconTriggerDatePicker.stories.tsx +201 -0
  37. package/src/components/forms/date/iconTriggerDatePicker/IconTriggerDatePicker.tsx +89 -0
  38. package/src/components/forms/date/iconTriggerDatePicker/index.ts +1 -0
  39. package/src/components/forms/date/inputDatePicker/SingleInputDatePicker.mdx +18 -0
  40. package/src/components/forms/date/inputDatePicker/SingleInputDatePicker.stories.tsx +208 -0
  41. package/src/components/forms/date/inputDatePicker/SingleInputDatePicker.tsx +117 -0
  42. package/src/components/forms/date/inputDatePicker/index.ts +1 -0
  43. package/src/components/forms/date/inputDateRangePicker/InputDateRangePicker.mdx +18 -0
  44. package/src/components/forms/date/inputDateRangePicker/InputDateRangePicker.stories.tsx +208 -0
  45. package/src/components/forms/date/inputDateRangePicker/InputDateRangePicker.tsx +117 -0
  46. package/src/components/forms/date/inputDateRangePicker/index.ts +1 -0
  47. package/src/components/forms/input/Input.tsx +3 -0
  48. package/src/components/index.ts +3 -0
  49. package/src/components/skeleton/Skeleton.stories.tsx +24 -4
  50. package/src/components/skeleton/Skeleton.tsx +4 -4
  51. package/src/index.ts +3 -2
  52. package/src/legacy/components/index.ts +0 -2
  53. package/src/legacy/components/inputs/index.ts +0 -2
  54. package/src/styles/index.scss +2 -1
  55. package/lib/src/legacy/components/inputs/DatePicker/DatePicker.d.ts +0 -15
  56. package/lib/src/legacy/components/inputs/DatePicker/DatePicker.stories.d.ts +0 -6
  57. package/lib/src/legacy/components/inputs/DatePicker/DatePicker.styles.d.ts +0 -1
  58. package/lib/src/legacy/components/inputs/DatePicker/index.d.ts +0 -1
  59. package/lib/src/legacy/components/inputs/NoInputDatePicker/NoInputDatePicker.d.ts +0 -21
  60. package/lib/src/legacy/components/inputs/NoInputDatePicker/NoInputDatePicker.stories.d.ts +0 -7
  61. package/lib/src/legacy/components/inputs/NoInputDatePicker/index.d.ts +0 -1
  62. package/src/legacy/components/inputs/DatePicker/DatePicker.stories.tsx +0 -30
  63. package/src/legacy/components/inputs/DatePicker/DatePicker.styles.ts +0 -437
  64. package/src/legacy/components/inputs/DatePicker/DatePicker.tsx +0 -165
  65. package/src/legacy/components/inputs/DatePicker/index.ts +0 -1
  66. package/src/legacy/components/inputs/NoInputDatePicker/NoInputDatePicker.scss +0 -441
  67. package/src/legacy/components/inputs/NoInputDatePicker/NoInputDatePicker.stories.tsx +0 -52
  68. package/src/legacy/components/inputs/NoInputDatePicker/NoInputDatePicker.tsx +0 -245
  69. package/src/legacy/components/inputs/NoInputDatePicker/index.ts +0 -1
  70. /package/src/{legacy/components/inputs/NoInputDatePicker/__tests__/NoInputDatePicker.test.tsx → components/forms/date/iconTriggerDatePicker/__tests__/IconTriggerDatePicker.test.tsx} +0 -0
@@ -0,0 +1,208 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { SingleInputDatePicker } from './SingleInputDatePicker';
3
+ import { useArgs } from '@storybook/preview-api';
4
+
5
+ const meta: Meta<typeof SingleInputDatePicker> = {
6
+ component: SingleInputDatePicker,
7
+ title: 'Forms/DatePicker/SingleInputDatePicker',
8
+ decorators: [
9
+ (Story) => (
10
+ <div style={{ height: '400px' }}>
11
+ <Story />
12
+ </div>
13
+ ),
14
+ ],
15
+ argTypes: {
16
+ ariaLabel: {
17
+ control: 'text',
18
+ description: 'A label for assistive technologies.',
19
+ table: {
20
+ category: 'Props',
21
+ type: {
22
+ summary: 'string',
23
+ },
24
+ },
25
+ },
26
+ className: {
27
+ control: false,
28
+ description: 'Accepts a CSS class name',
29
+ table: {
30
+ category: 'Props',
31
+ type: {
32
+ summary: 'string',
33
+ },
34
+ },
35
+ },
36
+ id: {
37
+ control: 'text',
38
+ description: 'The id of the input field.',
39
+ table: {
40
+ category: 'Props',
41
+ type: {
42
+ summary: 'string',
43
+ },
44
+ },
45
+ },
46
+ label: {
47
+ control: 'text',
48
+ description: 'The label for the input field.',
49
+ table: {
50
+ category: 'Props',
51
+ type: {
52
+ summary: 'string',
53
+ },
54
+ },
55
+ },
56
+ onSelect: {
57
+ action: 'selected',
58
+ description: 'Callback function that is called when a date is selected.',
59
+ table: {
60
+ category: 'Events',
61
+ type: {
62
+ summary: 'function',
63
+ },
64
+ },
65
+ },
66
+ selected: {
67
+ control: 'date',
68
+ description: 'The selected date.',
69
+ table: {
70
+ category: 'Props',
71
+ type: {
72
+ summary: 'Date',
73
+ },
74
+ },
75
+ },
76
+ inputPlaceholder: {
77
+ control: 'text',
78
+ description: 'The placeholder text for the input field.',
79
+ table: {
80
+ category: 'Props',
81
+ type: {
82
+ summary: 'string',
83
+ },
84
+ },
85
+ },
86
+ inputIconName: {
87
+ control: 'text',
88
+ description: 'The icon to display in the input field.',
89
+ table: {
90
+ category: 'Props',
91
+ type: {
92
+ summary: 'string',
93
+ },
94
+ },
95
+ },
96
+ isClearable: {
97
+ control: 'boolean',
98
+ description: 'Whether the input field should be clearable.',
99
+ table: {
100
+ category: 'Props',
101
+ type: {
102
+ summary: 'boolean',
103
+ },
104
+ },
105
+ },
106
+ isOpen: {
107
+ control: false,
108
+ description: 'Whether the date picker is open.',
109
+ table: {
110
+ category: 'Props',
111
+ type: {
112
+ summary: 'boolean',
113
+ },
114
+ },
115
+ },
116
+ clearOnClose: {
117
+ control: 'boolean',
118
+ description: 'Whether the input field should be cleared when the date picker is closed.',
119
+ table: {
120
+ category: 'Props',
121
+ type: {
122
+ summary: 'boolean',
123
+ },
124
+ },
125
+ },
126
+ errorMessage: {
127
+ control: 'text',
128
+ description: 'An error message to display.',
129
+ table: {
130
+ category: 'Props',
131
+ type: {
132
+ summary: 'string',
133
+ },
134
+ },
135
+ },
136
+ disableAfterDate: {
137
+ control: 'date',
138
+ description: 'Disable dates after this date.',
139
+ table: {
140
+ category: 'Props',
141
+ type: {
142
+ summary: 'Date',
143
+ },
144
+ },
145
+ },
146
+ disableBeforeDate: {
147
+ control: 'date',
148
+ description: 'Disable dates before this date.',
149
+ table: {
150
+ category: 'Props',
151
+ type: {
152
+ summary: 'Date',
153
+ },
154
+ },
155
+ },
156
+ isDisabled: {
157
+ control: 'boolean',
158
+ description: 'Disable the date picker.',
159
+ table: {
160
+ category: 'Props',
161
+ type: {
162
+ summary: 'boolean',
163
+ },
164
+ },
165
+ },
166
+ month: {
167
+ control: 'date',
168
+ description: 'The month to display.',
169
+ table: {
170
+ category: 'Props',
171
+ type: {
172
+ summary: 'Date',
173
+ },
174
+ },
175
+ },
176
+ 'data-testid': {
177
+ table: {
178
+ disable: true,
179
+ },
180
+ },
181
+ },
182
+ };
183
+
184
+ export default meta;
185
+
186
+ type Story = StoryObj<typeof SingleInputDatePicker>;
187
+
188
+ export const SingleInput: Story = {
189
+ args: {
190
+ id: 'date-picker',
191
+ label: 'Pick a date:',
192
+ inputPlaceholder: 'MM/DD/YYYY',
193
+ inputIconName: 'calendar',
194
+ isClearable: true,
195
+ isDisabled: false,
196
+ clearOnClose: false,
197
+ errorMessage: '',
198
+ ariaLabel: 'Date Picker',
199
+ },
200
+ render: (args) => {
201
+ const [{ selected }, updateArgs] = useArgs();
202
+ const handleSelect = (date: Date | undefined) => {
203
+ updateArgs({ selected: date });
204
+ };
205
+
206
+ return <SingleInputDatePicker {...args} selected={selected} onSelect={handleSelect} />;
207
+ },
208
+ };
@@ -0,0 +1,117 @@
1
+ import { useId, useState, useEffect } from 'react';
2
+ import { format, isValid, parse } from 'date-fns';
3
+ import { DatePicker } from '../datePicker/DatePicker';
4
+ import { Input } from '../../input';
5
+ import { IconName } from '@/types';
6
+ import { DateRange } from 'react-day-picker';
7
+ import { FloatUI } from '../../../floatUI';
8
+
9
+ interface SingleInputDatePickerProps {
10
+ ariaLabel: string;
11
+ disableBeforeDate?: Date;
12
+ disableAfterDate?: Date;
13
+ isDisabled?: boolean;
14
+ id?: string;
15
+ label?: string;
16
+ onSelect?: (selected: Date | undefined) => void;
17
+ month?: Date;
18
+ selected?: Date | DateRange | Date[] | undefined;
19
+ isOpen?: boolean;
20
+ clearOnClose?: boolean;
21
+ className?: string;
22
+ inputIconName?: IconName;
23
+ isClearable?: boolean;
24
+ inputPlaceholder?: string;
25
+ errorMessage?: string | undefined;
26
+ 'data-testid'?: string;
27
+ }
28
+
29
+ export function SingleInputDatePicker(props: SingleInputDatePickerProps) {
30
+ const {
31
+ ariaLabel,
32
+ className,
33
+ isDisabled,
34
+ disableBeforeDate,
35
+ disableAfterDate,
36
+ month,
37
+ id,
38
+ label,
39
+ onSelect,
40
+ selected,
41
+ isOpen,
42
+ inputPlaceholder,
43
+ clearOnClose,
44
+ inputIconName,
45
+ isClearable,
46
+ errorMessage,
47
+ ...rest
48
+ } = props;
49
+
50
+ const inputId = useId();
51
+
52
+ // Hold the month in state to control the calendar when the input changes
53
+ const [localMonth, setLocalMonth] = useState(new Date());
54
+
55
+ // Hold the selected date in state
56
+ const [selectedDate, setSelectedDate] = useState<Date | undefined>(undefined);
57
+
58
+ // Hold the input value in state
59
+ const [inputValue, setInputValue] = useState('');
60
+
61
+ const handleDayPickerSelect = (date: Date | undefined) => {
62
+ if (!date) {
63
+ setInputValue('');
64
+ setSelectedDate(undefined);
65
+ } else {
66
+ setSelectedDate(date);
67
+ setLocalMonth(date);
68
+ setInputValue(format(date, 'MM/dd/yyyy'));
69
+ }
70
+ };
71
+
72
+ const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
73
+ setInputValue(e.target.value); // keep the input value in sync
74
+
75
+ const parsedDate = parse(e.target.value, 'MM/dd/yyyy', new Date());
76
+
77
+ if (isValid(parsedDate)) {
78
+ setSelectedDate(parsedDate);
79
+ setLocalMonth(parsedDate);
80
+ } else {
81
+ setSelectedDate(undefined);
82
+ }
83
+ };
84
+
85
+ // clear selection if clear on close is true
86
+ useEffect(() => {
87
+ if (!isOpen && clearOnClose) {
88
+ setSelectedDate(undefined);
89
+ setInputValue('');
90
+ }
91
+ }, [isOpen, clearOnClose]);
92
+
93
+ return (
94
+ <FloatUI isOpen={isOpen} ariaLabel={ariaLabel}>
95
+ <Input
96
+ id={inputId}
97
+ value={inputValue}
98
+ placeholder={inputPlaceholder}
99
+ isDisabled={isDisabled}
100
+ iconName={inputIconName}
101
+ isClearable={isClearable}
102
+ onChange={handleInputChange}
103
+ errorMessage={errorMessage}
104
+ label={'Single Date Picker'}
105
+ name={'Date Picker'}
106
+ />
107
+ <DatePicker
108
+ month={localMonth}
109
+ onMonthChange={setLocalMonth}
110
+ mode="single"
111
+ selected={selectedDate}
112
+ onSelect={handleDayPickerSelect}
113
+ {...rest}
114
+ />
115
+ </FloatUI>
116
+ );
117
+ }
@@ -0,0 +1 @@
1
+ export { SingleInputDatePicker } from './SingleInputDatePicker';
@@ -0,0 +1,18 @@
1
+ import { Canvas, Meta, Controls } from '@storybook/blocks';
2
+ import * as InputDateRangePicker from './InputDateRangePicker.stories';
3
+ import { Row, Col } from '../../../grid/index';
4
+
5
+ <Meta title="Forms/DatePicker/InputDateRangePicker" name="InputDateRangePicker" />
6
+
7
+ # Input Date Range Picker
8
+ The Input Date Range Picker is a visual representation of an input field that allows you to enter a date value to the input or select a date from the date picker. It leverages our DatePicker component inside of a FloatingUI window.
9
+
10
+ <Canvas of={InputDateRangePicker.SingleInput} />
11
+
12
+ ## Props
13
+ In addition to the props listed below, it also accepts all props listed [here](story=?path=/docs/forms-datepicker--datepicker)
14
+ <Controls of={InputDateRangePicker.SingleInput} />
15
+
16
+
17
+ ## ToDo
18
+ - Create single component for all dropdown date pickers that accept an react element as the trigger, such as an icon, button, component, input, etc.
@@ -0,0 +1,208 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { InputDateRangePicker } from './InputDateRangePicker';
3
+ import { useArgs } from '@storybook/preview-api';
4
+
5
+ const meta: Meta<typeof InputDateRangePicker> = {
6
+ component: InputDateRangePicker,
7
+ title: 'Forms/DatePicker/InputDateRangePicker',
8
+ decorators: [
9
+ (Story) => (
10
+ <div style={{ height: '400px' }}>
11
+ <Story />
12
+ </div>
13
+ ),
14
+ ],
15
+ argTypes: {
16
+ ariaLabel: {
17
+ control: 'text',
18
+ description: 'A label for assistive technologies.',
19
+ table: {
20
+ category: 'Props',
21
+ type: {
22
+ summary: 'string',
23
+ },
24
+ },
25
+ },
26
+ className: {
27
+ control: false,
28
+ description: 'Accepts a CSS class name',
29
+ table: {
30
+ category: 'Props',
31
+ type: {
32
+ summary: 'string',
33
+ },
34
+ },
35
+ },
36
+ id: {
37
+ control: 'text',
38
+ description: 'The id of the input field.',
39
+ table: {
40
+ category: 'Props',
41
+ type: {
42
+ summary: 'string',
43
+ },
44
+ },
45
+ },
46
+ label: {
47
+ control: 'text',
48
+ description: 'The label for the input field.',
49
+ table: {
50
+ category: 'Props',
51
+ type: {
52
+ summary: 'string',
53
+ },
54
+ },
55
+ },
56
+ onSelect: {
57
+ action: 'selected',
58
+ description: 'Callback function that is called when a date is selected.',
59
+ table: {
60
+ category: 'Events',
61
+ type: {
62
+ summary: 'function',
63
+ },
64
+ },
65
+ },
66
+ selected: {
67
+ control: 'date',
68
+ description: 'The selected date.',
69
+ table: {
70
+ category: 'Props',
71
+ type: {
72
+ summary: 'Date',
73
+ },
74
+ },
75
+ },
76
+ inputPlaceholder: {
77
+ control: 'text',
78
+ description: 'The placeholder text for the input field.',
79
+ table: {
80
+ category: 'Props',
81
+ type: {
82
+ summary: 'string',
83
+ },
84
+ },
85
+ },
86
+ inputIconName: {
87
+ control: 'text',
88
+ description: 'The icon to display in the input field.',
89
+ table: {
90
+ category: 'Props',
91
+ type: {
92
+ summary: 'string',
93
+ },
94
+ },
95
+ },
96
+ isClearable: {
97
+ control: 'boolean',
98
+ description: 'Whether the input field should be clearable.',
99
+ table: {
100
+ category: 'Props',
101
+ type: {
102
+ summary: 'boolean',
103
+ },
104
+ },
105
+ },
106
+ isOpen: {
107
+ control: false,
108
+ description: 'Whether the date picker is open.',
109
+ table: {
110
+ category: 'Props',
111
+ type: {
112
+ summary: 'boolean',
113
+ },
114
+ },
115
+ },
116
+ clearOnClose: {
117
+ control: 'boolean',
118
+ description: 'Whether the input field should be cleared when the date picker is closed.',
119
+ table: {
120
+ category: 'Props',
121
+ type: {
122
+ summary: 'boolean',
123
+ },
124
+ },
125
+ },
126
+ errorMessage: {
127
+ control: 'text',
128
+ description: 'An error message to display.',
129
+ table: {
130
+ category: 'Props',
131
+ type: {
132
+ summary: 'string',
133
+ },
134
+ },
135
+ },
136
+ disableAfterDate: {
137
+ control: 'date',
138
+ description: 'Disable dates after this date.',
139
+ table: {
140
+ category: 'Props',
141
+ type: {
142
+ summary: 'Date',
143
+ },
144
+ },
145
+ },
146
+ disableBeforeDate: {
147
+ control: 'date',
148
+ description: 'Disable dates before this date.',
149
+ table: {
150
+ category: 'Props',
151
+ type: {
152
+ summary: 'Date',
153
+ },
154
+ },
155
+ },
156
+ isDisabled: {
157
+ control: 'boolean',
158
+ description: 'Disable the date picker.',
159
+ table: {
160
+ category: 'Props',
161
+ type: {
162
+ summary: 'boolean',
163
+ },
164
+ },
165
+ },
166
+ month: {
167
+ control: 'date',
168
+ description: 'The month to display.',
169
+ table: {
170
+ category: 'Props',
171
+ type: {
172
+ summary: 'Date',
173
+ },
174
+ },
175
+ },
176
+ 'data-testid': {
177
+ table: {
178
+ disable: true,
179
+ },
180
+ },
181
+ },
182
+ };
183
+
184
+ export default meta;
185
+
186
+ type Story = StoryObj<typeof InputDateRangePicker>;
187
+
188
+ export const SingleInput: Story = {
189
+ args: {
190
+ id: 'date-picker',
191
+ label: 'Pick a date:',
192
+ inputPlaceholder: 'MM/DD/YYYY',
193
+ inputIconName: 'calendar',
194
+ isClearable: true,
195
+ isDisabled: false,
196
+ clearOnClose: false,
197
+ errorMessage: '',
198
+ ariaLabel: 'Date Picker',
199
+ },
200
+ render: (args) => {
201
+ const [{ selected }, updateArgs] = useArgs();
202
+ const handleSelect = (date: Date | undefined) => {
203
+ updateArgs({ selected: date });
204
+ };
205
+
206
+ return <InputDateRangePicker {...args} selected={selected} onSelect={handleSelect} />;
207
+ },
208
+ };
@@ -0,0 +1,117 @@
1
+ import { useId, useState, useEffect } from 'react';
2
+ import { format, isValid, parse } from 'date-fns';
3
+ import { DatePicker } from '../datePicker/DatePicker';
4
+ import { Input } from '../../input';
5
+ import { IconName } from '@/types';
6
+ import { DateRange } from 'react-day-picker';
7
+ import { FloatUI } from '../../../floatUI';
8
+
9
+ interface InputDateRangePickerProps {
10
+ ariaLabel: string;
11
+ disableBeforeDate?: Date;
12
+ disableAfterDate?: Date;
13
+ isDisabled?: boolean;
14
+ id?: string;
15
+ label?: string;
16
+ onSelect?: (selected: Date | undefined) => void;
17
+ month?: Date;
18
+ selected?: Date | DateRange | Date[] | undefined;
19
+ isOpen?: boolean;
20
+ clearOnClose?: boolean;
21
+ className?: string;
22
+ inputIconName?: IconName;
23
+ isClearable?: boolean;
24
+ inputPlaceholder?: string;
25
+ errorMessage?: string | undefined;
26
+ 'data-testid'?: string;
27
+ }
28
+
29
+ export function InputDateRangePicker(props: InputDateRangePickerProps) {
30
+ const {
31
+ ariaLabel,
32
+ className,
33
+ isDisabled,
34
+ disableBeforeDate,
35
+ disableAfterDate,
36
+ month,
37
+ id,
38
+ label,
39
+ onSelect,
40
+ selected,
41
+ isOpen,
42
+ inputPlaceholder,
43
+ clearOnClose,
44
+ inputIconName,
45
+ isClearable,
46
+ errorMessage,
47
+ ...rest
48
+ } = props;
49
+
50
+ const inputId = useId();
51
+
52
+ // Hold the month in state to control the calendar when the input changes
53
+ const [localMonth, setLocalMonth] = useState(new Date());
54
+
55
+ // Hold the selected date in state
56
+ const [selectedDate, setSelectedDate] = useState<Date | undefined>(undefined);
57
+
58
+ // Hold the input value in state
59
+ const [inputValue, setInputValue] = useState('');
60
+
61
+ const handleDayPickerSelect = (date: Date | undefined) => {
62
+ if (!date) {
63
+ setInputValue('');
64
+ setSelectedDate(undefined);
65
+ } else {
66
+ setSelectedDate(date);
67
+ setLocalMonth(date);
68
+ setInputValue(format(date, 'MM/dd/yyyy'));
69
+ }
70
+ };
71
+
72
+ const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
73
+ setInputValue(e.target.value); // keep the input value in sync
74
+
75
+ const parsedDate = parse(e.target.value, 'MM/dd/yyyy', new Date());
76
+
77
+ if (isValid(parsedDate)) {
78
+ setSelectedDate(parsedDate);
79
+ setLocalMonth(parsedDate);
80
+ } else {
81
+ setSelectedDate(undefined);
82
+ }
83
+ };
84
+
85
+ // clear selection if clear on close is true
86
+ useEffect(() => {
87
+ if (!isOpen && clearOnClose) {
88
+ setSelectedDate(undefined);
89
+ setInputValue('');
90
+ }
91
+ }, [isOpen, clearOnClose]);
92
+
93
+ return (
94
+ <FloatUI isOpen={isOpen} ariaLabel={ariaLabel}>
95
+ <Input
96
+ id={inputId}
97
+ value={inputValue}
98
+ placeholder={inputPlaceholder}
99
+ isDisabled={isDisabled}
100
+ iconName={inputIconName}
101
+ isClearable={isClearable}
102
+ onChange={handleInputChange}
103
+ errorMessage={errorMessage}
104
+ label={'Single Date Picker'}
105
+ name={'Date Picker'}
106
+ />
107
+ <DatePicker
108
+ month={localMonth}
109
+ onMonthChange={setLocalMonth}
110
+ mode="single"
111
+ selected={selectedDate}
112
+ onSelect={handleDayPickerSelect}
113
+ {...rest}
114
+ />
115
+ </FloatUI>
116
+ );
117
+ }
@@ -0,0 +1 @@
1
+ export { InputDateRangePicker } from './InputDateRangePicker';
@@ -7,6 +7,7 @@ import { withLabel, LabelProps } from '../subcomponents/Label';
7
7
  import { DisplayFormError } from '../subcomponents/DisplayFormError';
8
8
 
9
9
  export interface BaseInputProps {
10
+ id?: string;
10
11
  value?: string | undefined;
11
12
  placeholder?: string;
12
13
  isDisabled?: boolean;
@@ -26,6 +27,7 @@ export interface InputProps extends BaseInputProps, LabelProps {}
26
27
  const Input = React.forwardRef<HTMLInputElement, InputProps>(
27
28
  (
28
29
  {
30
+ id,
29
31
  name,
30
32
  placeholder,
31
33
  isRequired,
@@ -64,6 +66,7 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
64
66
  )}
65
67
  <input
66
68
  ref={ref}
69
+ id={id}
67
70
  data-testid={`form-input-${name}`}
68
71
  name={name}
69
72
  type="text"
@@ -14,3 +14,6 @@ export { Skeleton } from './skeleton';
14
14
  export { Card } from './card';
15
15
  export { FloatUI } from './floatUI';
16
16
  export { Menu } from './menu';
17
+ export { DatePicker } from './forms/date/datePicker/DatePicker';
18
+ export { IconTriggerDatePicker } from './forms/date/iconTriggerDatePicker';
19
+ export { SingleInputDatePicker } from './forms/date/inputDatePicker';