uikit-react-public 0.11.16 → 0.11.24
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/components/Calendar/Calendar.d.ts +3 -0
- package/dist/components/Calendar/Calendar.stories.d.ts +42 -0
- package/dist/components/Calendar/Calendar.types.d.ts +18 -0
- package/dist/components/Calendar/index.d.ts +2 -0
- package/dist/components/Calendar/subcomponents/AcademicWeek.d.ts +5 -0
- package/dist/components/Calendar/subcomponents/AcademicWeeks.d.ts +7 -0
- package/dist/components/Calendar/subcomponents/ColumnHeading.d.ts +7 -0
- package/dist/components/Calendar/subcomponents/Controls.d.ts +6 -0
- package/dist/components/Calendar/subcomponents/Day.d.ts +12 -0
- package/dist/components/{Datepicker/subcomponents/Day → Calendar/subcomponents}/Day.stories.d.ts +9 -1
- package/dist/components/Calendar/subcomponents/EventDot.d.ts +6 -0
- package/dist/components/Calendar/subcomponents/Grid.d.ts +11 -0
- package/dist/components/Calendar/subcomponents/index.d.ts +7 -0
- package/dist/components/Calendar/utils/getAcademicWeekNumbers/getAcademicWeekNumbers.d.ts +24 -0
- package/dist/components/Calendar/utils/index.d.ts +4 -0
- package/dist/components/Calendar/utils/normaliseMonth/normaliseMonth.d.ts +9 -0
- package/dist/components/Calendar/utils/normaliseMonth/normaliseMonth.test.d.ts +1 -0
- package/dist/components/Calendar/utils/parseDateFromString/parseDateFromString.d.ts +9 -0
- package/dist/components/Calendar/utils/parseDateFromString/parseDateFromString.test.d.ts +1 -0
- package/dist/components/Datepicker/Datepicker.d.ts +3 -12
- package/dist/components/Datepicker/Datepicker.stories.d.ts +16 -3
- package/dist/components/Datepicker/Datepicker.types.d.ts +23 -0
- package/dist/components/Datepicker/index.d.ts +1 -1
- package/dist/components/Datepicker/subcomponents/CustomDatepicker.d.ts +17 -0
- package/dist/components/Datepicker/subcomponents/DatepickerInput.d.ts +10 -0
- package/dist/components/Datepicker/subcomponents/NativeDatepicker.d.ts +6 -0
- package/dist/components/Datepicker/subcomponents/Panel.d.ts +6 -0
- package/dist/components/Datepicker/subcomponents/VisibleField.d.ts +12 -0
- package/dist/components/Datepicker/subcomponents/index.d.ts +5 -7
- package/dist/components/Datepicker/utils/dateToLocaleISOString/dateToLocaleISOString.d.ts +17 -0
- package/dist/components/Datepicker/utils/dateToLocaleISOString/dateToLocaleISOString.test.d.ts +1 -0
- package/dist/components/Datepicker/utils/index.d.ts +2 -2
- package/dist/components/Datepicker/utils/parseInputValue/parseInputValue.d.ts +11 -0
- package/dist/components/Datepicker/utils/parseInputValue/parseInputValue.test.d.ts +1 -0
- package/dist/components/Footer/Footer.d.ts +1 -1
- package/dist/components/Header/Header.d.ts +5 -4
- package/dist/components/Header/index.d.ts +1 -1
- package/dist/components/Menu/Menu.d.ts +2 -1
- package/dist/components/Menu/MenuContent.d.ts +1 -0
- package/dist/components/Select/Select.stories.d.ts +1 -1
- package/dist/components/Select/Select.types.d.ts +10 -50
- package/dist/components/Select/index.d.ts +1 -1
- package/dist/components/Select/subcomponents/CustomSelect.d.ts +2 -1
- package/dist/components/index.d.ts +2 -0
- package/dist/index.js +3332 -3063
- package/lib/components/Calendar/Calendar.stories.tsx +209 -0
- package/lib/components/Calendar/Calendar.tsx +121 -0
- package/lib/components/Calendar/Calendar.types.ts +21 -0
- package/lib/components/Calendar/__tests__/Calendar.test.tsx +71 -0
- package/lib/components/Calendar/__tests__/__snapshots__/Calendar.test.tsx.snap +1218 -0
- package/lib/components/Calendar/index.ts +6 -0
- package/lib/components/Calendar/subcomponents/AcademicWeek.tsx +36 -0
- package/lib/components/Calendar/subcomponents/AcademicWeeks.tsx +46 -0
- package/lib/components/Calendar/subcomponents/ColumnHeading.tsx +40 -0
- package/lib/components/{Datepicker/subcomponents/MonthSelector/MonthSelector.tsx → Calendar/subcomponents/Controls.tsx} +17 -17
- package/lib/components/{Datepicker/subcomponents/Day → Calendar/subcomponents}/Day.stories.tsx +30 -7
- package/lib/components/Calendar/subcomponents/Day.tsx +130 -0
- package/lib/components/Calendar/subcomponents/EventDot.tsx +40 -0
- package/lib/components/Calendar/subcomponents/Grid.tsx +117 -0
- package/lib/components/Calendar/subcomponents/index.ts +7 -0
- package/lib/components/Calendar/utils/getAcademicWeekNumbers/getAcademicWeekNumbers.test.ts +104 -0
- package/lib/components/Calendar/utils/getAcademicWeekNumbers/getAcademicWeekNumbers.ts +85 -0
- package/lib/components/{Datepicker → Calendar}/utils/getDatesForCalendarGrid/getDatesForCalendarGrid.test.ts +29 -65
- package/lib/components/{Datepicker → Calendar}/utils/getDatesForCalendarGrid/getDatesForCalendarGrid.ts +11 -43
- package/lib/components/Calendar/utils/index.ts +4 -0
- package/lib/components/Calendar/utils/normaliseMonth/normaliseMonth.test.ts +40 -0
- package/lib/components/Calendar/utils/normaliseMonth/normaliseMonth.ts +16 -0
- package/lib/components/Calendar/utils/parseDateFromString/parseDateFromString.test.ts +15 -0
- package/lib/components/Calendar/utils/parseDateFromString/parseDateFromString.ts +19 -0
- package/lib/components/Datepicker/Datepicker.stories.tsx +220 -23
- package/lib/components/Datepicker/Datepicker.tsx +34 -137
- package/lib/components/Datepicker/Datepicker.types.ts +38 -0
- package/lib/components/Datepicker/__tests__/Datepicker.test.tsx +53 -112
- package/lib/components/Datepicker/__tests__/__snapshots__/Datepicker.test.tsx.snap +92 -638
- package/lib/components/Datepicker/index.ts +1 -1
- package/lib/components/Datepicker/subcomponents/CustomDatepicker.tsx +209 -0
- package/lib/components/Datepicker/subcomponents/DatepickerInput.tsx +74 -0
- package/lib/components/Datepicker/subcomponents/NativeDatepicker.tsx +70 -0
- package/lib/components/Datepicker/subcomponents/Panel.tsx +32 -0
- package/lib/components/Datepicker/subcomponents/VisibleField.tsx +104 -0
- package/lib/components/Datepicker/subcomponents/index.ts +5 -7
- package/lib/components/Datepicker/utils/dateToLocaleISOString/dateToLocaleISOString.test.ts +32 -0
- package/lib/components/Datepicker/utils/dateToLocaleISOString/dateToLocaleISOString.ts +23 -0
- package/lib/components/Datepicker/utils/index.ts +2 -2
- package/lib/components/Datepicker/utils/parseInputValue/parseInputValue.test.ts +110 -0
- package/lib/components/Datepicker/utils/parseInputValue/parseInputValue.ts +57 -0
- package/lib/components/Footer/Footer.tsx +3 -3
- package/lib/components/Footer/__tests__/__snapshots__/Footer.test.tsx.snap +6 -6
- package/lib/components/Header/Header.tsx +32 -33
- package/lib/components/Header/HeaderMenu.tsx +9 -2
- package/lib/components/Header/__tests__/__snapshots__/Header.test.tsx.snap +40 -48
- package/lib/components/Header/index.ts +5 -1
- package/lib/components/Menu/Menu.tsx +3 -0
- package/lib/components/Menu/MenuContent.tsx +4 -1
- package/lib/components/Select/Select.stories.tsx +38 -39
- package/lib/components/Select/Select.tsx +4 -18
- package/lib/components/Select/Select.types.ts +30 -69
- package/lib/components/Select/__tests__/Select.test.tsx +6 -6
- package/lib/components/Select/__tests__/__snapshots__/Select.test.tsx.snap +1 -1
- package/lib/components/Select/index.ts +1 -1
- package/lib/components/Select/subcomponents/CustomSelect.tsx +22 -12
- package/lib/components/Select/subcomponents/NativeSelect.tsx +7 -3
- package/lib/components/Select/subcomponents/Panel.tsx +4 -4
- package/lib/components/Select/subcomponents/VisibleField.tsx +1 -1
- package/lib/components/index.ts +3 -0
- package/package.json +4 -4
- package/LICENSE +0 -9
- package/dist/components/Datepicker/subcomponents/CalendarGrid/CalendarGrid.d.ts +0 -6
- package/dist/components/Datepicker/subcomponents/CalendarGrid/index.d.ts +0 -1
- package/dist/components/Datepicker/subcomponents/CalendarMenu/CalendarMenu.d.ts +0 -8
- package/dist/components/Datepicker/subcomponents/CalendarMenu/index.d.ts +0 -1
- package/dist/components/Datepicker/subcomponents/ColumnHeadings/ColumnHeadings.d.ts +0 -2
- package/dist/components/Datepicker/subcomponents/ColumnHeadings/index.d.ts +0 -1
- package/dist/components/Datepicker/subcomponents/DateField/DateField.d.ts +0 -7
- package/dist/components/Datepicker/subcomponents/DateField/index.d.ts +0 -1
- package/dist/components/Datepicker/subcomponents/Day/Day.d.ts +0 -10
- package/dist/components/Datepicker/subcomponents/Day/index.d.ts +0 -1
- package/dist/components/Datepicker/subcomponents/MonthSelector/MonthSelector.d.ts +0 -6
- package/dist/components/Datepicker/subcomponents/MonthSelector/index.d.ts +0 -1
- package/dist/components/Datepicker/subcomponents/Native/Native.d.ts +0 -9
- package/dist/components/Datepicker/subcomponents/Native/index.d.ts +0 -1
- package/dist/components/Datepicker/utils/parseDateForDateField/parseDateForDateField.d.ts +0 -20
- package/lib/components/Datepicker/subcomponents/CalendarGrid/CalendarGrid.tsx +0 -59
- package/lib/components/Datepicker/subcomponents/CalendarGrid/index.ts +0 -1
- package/lib/components/Datepicker/subcomponents/CalendarMenu/CalendarMenu.tsx +0 -64
- package/lib/components/Datepicker/subcomponents/CalendarMenu/index.ts +0 -1
- package/lib/components/Datepicker/subcomponents/ColumnHeadings/ColumnHeadings.tsx +0 -35
- package/lib/components/Datepicker/subcomponents/ColumnHeadings/index.ts +0 -1
- package/lib/components/Datepicker/subcomponents/DateField/DateField.tsx +0 -155
- package/lib/components/Datepicker/subcomponents/DateField/__tests__/DateField.test.tsx +0 -191
- package/lib/components/Datepicker/subcomponents/DateField/index.ts +0 -1
- package/lib/components/Datepicker/subcomponents/Day/Day.tsx +0 -94
- package/lib/components/Datepicker/subcomponents/Day/index.ts +0 -1
- package/lib/components/Datepicker/subcomponents/MonthSelector/index.ts +0 -1
- package/lib/components/Datepicker/subcomponents/Native/Native.tsx +0 -59
- package/lib/components/Datepicker/subcomponents/Native/index.ts +0 -1
- package/lib/components/Datepicker/utils/parseDateForDateField/parseDateForDateField.test.ts +0 -41
- package/lib/components/Datepicker/utils/parseDateForDateField/parseDateForDateField.ts +0 -48
- /package/dist/components/{Datepicker/subcomponents/DateField/__tests__/DateField.test.d.ts → Calendar/__tests__/Calendar.test.d.ts} +0 -0
- /package/dist/components/{Datepicker/utils/getDatesForCalendarGrid/getDatesForCalendarGrid.test.d.ts → Calendar/utils/getAcademicWeekNumbers/getAcademicWeekNumbers.test.d.ts} +0 -0
- /package/dist/components/{Datepicker → Calendar}/utils/getDatesForCalendarGrid/getDatesForCalendarGrid.d.ts +0 -0
- /package/dist/components/{Datepicker/utils/parseDateForDateField/parseDateForDateField.test.d.ts → Calendar/utils/getDatesForCalendarGrid/getDatesForCalendarGrid.test.d.ts} +0 -0
|
@@ -2,7 +2,6 @@ import type { Meta, StoryObj } from '@storybook/react';
|
|
|
2
2
|
import { useArgs } from '@storybook/preview-api';
|
|
3
3
|
import Select from './Select';
|
|
4
4
|
import { Icon } from '../';
|
|
5
|
-
import { SelectEvent } from './Select.types';
|
|
6
5
|
|
|
7
6
|
const meta = {
|
|
8
7
|
title: 'Components/Ready to use/Select',
|
|
@@ -29,9 +28,9 @@ const meta = {
|
|
|
29
28
|
value: undefined,
|
|
30
29
|
onChange: () => {},
|
|
31
30
|
options: [
|
|
32
|
-
{
|
|
33
|
-
{
|
|
34
|
-
{
|
|
31
|
+
{ label: 'Option one', value: '1' },
|
|
32
|
+
{ label: 'Option two', value: '2' },
|
|
33
|
+
{ label: 'Option three', value: '3' },
|
|
35
34
|
],
|
|
36
35
|
},
|
|
37
36
|
} satisfies Meta<typeof Select>;
|
|
@@ -42,7 +41,7 @@ type Story = StoryObj<typeof meta>;
|
|
|
42
41
|
export const Default: Story = {
|
|
43
42
|
render: () => {
|
|
44
43
|
const [args, updateArgs] = useArgs();
|
|
45
|
-
const
|
|
44
|
+
const onValueChange = (value: string) => {
|
|
46
45
|
updateArgs({ value });
|
|
47
46
|
};
|
|
48
47
|
return (
|
|
@@ -50,7 +49,7 @@ export const Default: Story = {
|
|
|
50
49
|
{...args}
|
|
51
50
|
options={args.options}
|
|
52
51
|
value={args.value}
|
|
53
|
-
|
|
52
|
+
onValueChange={onValueChange}
|
|
54
53
|
/>
|
|
55
54
|
);
|
|
56
55
|
},
|
|
@@ -62,7 +61,7 @@ export const Native: Story = {
|
|
|
62
61
|
},
|
|
63
62
|
render: () => {
|
|
64
63
|
const [args, updateArgs] = useArgs();
|
|
65
|
-
const
|
|
64
|
+
const onValueChange = (value: string) => {
|
|
66
65
|
updateArgs({ value });
|
|
67
66
|
};
|
|
68
67
|
return (
|
|
@@ -70,7 +69,7 @@ export const Native: Story = {
|
|
|
70
69
|
{...args}
|
|
71
70
|
options={args.options}
|
|
72
71
|
value={args.value}
|
|
73
|
-
|
|
72
|
+
onValueChange={onValueChange}
|
|
74
73
|
/>
|
|
75
74
|
);
|
|
76
75
|
},
|
|
@@ -80,14 +79,14 @@ export const OptionsWithIcons: Story = {
|
|
|
80
79
|
name: 'Options with icons',
|
|
81
80
|
args: {
|
|
82
81
|
options: [
|
|
83
|
-
{
|
|
84
|
-
{
|
|
85
|
-
{
|
|
82
|
+
{ label: 'Option 1', value: '1', icon: <Icon.Printer /> },
|
|
83
|
+
{ label: 'Option 2', value: '2', icon: <Icon.User /> },
|
|
84
|
+
{ label: 'Option 3', value: '3', icon: <Icon.Info /> },
|
|
86
85
|
],
|
|
87
86
|
},
|
|
88
87
|
render: () => {
|
|
89
88
|
const [args, updateArgs] = useArgs();
|
|
90
|
-
const
|
|
89
|
+
const onValueChange = (value: string) => {
|
|
91
90
|
updateArgs({ value });
|
|
92
91
|
};
|
|
93
92
|
|
|
@@ -96,7 +95,7 @@ export const OptionsWithIcons: Story = {
|
|
|
96
95
|
{...args}
|
|
97
96
|
options={args.options}
|
|
98
97
|
value={args.value}
|
|
99
|
-
|
|
98
|
+
onValueChange={onValueChange}
|
|
100
99
|
/>
|
|
101
100
|
);
|
|
102
101
|
},
|
|
@@ -108,7 +107,7 @@ export const Disabled: Story = {
|
|
|
108
107
|
},
|
|
109
108
|
render: () => {
|
|
110
109
|
const [args, updateArgs] = useArgs();
|
|
111
|
-
const
|
|
110
|
+
const onValueChange = (value: string) => {
|
|
112
111
|
updateArgs({ value });
|
|
113
112
|
};
|
|
114
113
|
|
|
@@ -117,7 +116,7 @@ export const Disabled: Story = {
|
|
|
117
116
|
{...args}
|
|
118
117
|
options={args.options}
|
|
119
118
|
value={args.value}
|
|
120
|
-
|
|
119
|
+
onValueChange={onValueChange}
|
|
121
120
|
/>
|
|
122
121
|
);
|
|
123
122
|
},
|
|
@@ -127,7 +126,7 @@ export const WithPlaceholder: Story = {
|
|
|
127
126
|
args: { placeholder: 'Please select an option' },
|
|
128
127
|
render: () => {
|
|
129
128
|
const [args, updateArgs] = useArgs();
|
|
130
|
-
const
|
|
129
|
+
const onValueChange = (value: string) => {
|
|
131
130
|
updateArgs({ value });
|
|
132
131
|
};
|
|
133
132
|
|
|
@@ -136,7 +135,7 @@ export const WithPlaceholder: Story = {
|
|
|
136
135
|
{...args}
|
|
137
136
|
options={args.options}
|
|
138
137
|
value={args.value}
|
|
139
|
-
|
|
138
|
+
onValueChange={onValueChange}
|
|
140
139
|
/>
|
|
141
140
|
);
|
|
142
141
|
},
|
|
@@ -146,14 +145,14 @@ export const SingleLongOption: Story = {
|
|
|
146
145
|
name: 'Long option',
|
|
147
146
|
args: {
|
|
148
147
|
options: [
|
|
149
|
-
{
|
|
150
|
-
{
|
|
151
|
-
{
|
|
148
|
+
{ label: 'Option 1', value: '1' },
|
|
149
|
+
{ label: 'Option 2', value: '2' },
|
|
150
|
+
{ label: 'Option 3 long long long long ', value: '3' },
|
|
152
151
|
],
|
|
153
152
|
},
|
|
154
153
|
render: () => {
|
|
155
154
|
const [args, updateArgs] = useArgs();
|
|
156
|
-
const
|
|
155
|
+
const onValueChange = (value: string) => {
|
|
157
156
|
updateArgs({ value });
|
|
158
157
|
};
|
|
159
158
|
|
|
@@ -162,7 +161,7 @@ export const SingleLongOption: Story = {
|
|
|
162
161
|
{...args}
|
|
163
162
|
options={args.options}
|
|
164
163
|
value={args.value}
|
|
165
|
-
|
|
164
|
+
onValueChange={onValueChange}
|
|
166
165
|
/>
|
|
167
166
|
);
|
|
168
167
|
},
|
|
@@ -172,26 +171,26 @@ export const ManyOptions: Story = {
|
|
|
172
171
|
name: 'Many options',
|
|
173
172
|
args: {
|
|
174
173
|
options: [
|
|
175
|
-
{
|
|
176
|
-
{
|
|
177
|
-
{
|
|
178
|
-
{
|
|
179
|
-
{
|
|
180
|
-
{
|
|
181
|
-
{
|
|
182
|
-
{
|
|
183
|
-
{
|
|
184
|
-
{
|
|
185
|
-
{
|
|
186
|
-
{
|
|
187
|
-
{
|
|
188
|
-
{
|
|
189
|
-
{
|
|
174
|
+
{ label: 'Option one', value: '1' },
|
|
175
|
+
{ label: 'Option two', value: '2' },
|
|
176
|
+
{ label: 'Option three', value: '3' },
|
|
177
|
+
{ label: 'Option four', value: '4' },
|
|
178
|
+
{ label: 'Option five', value: '5' },
|
|
179
|
+
{ label: 'Option six', value: '6' },
|
|
180
|
+
{ label: 'Option seven', value: '7' },
|
|
181
|
+
{ label: 'Option eight', value: '8' },
|
|
182
|
+
{ label: 'Option nine', value: '9' },
|
|
183
|
+
{ label: 'Option ten', value: '10' },
|
|
184
|
+
{ label: 'Option eleven', value: '11' },
|
|
185
|
+
{ label: 'Option twelve', value: '12' },
|
|
186
|
+
{ label: 'Option thirteen', value: '13' },
|
|
187
|
+
{ label: 'Option fourteen', value: '14' },
|
|
188
|
+
{ label: 'Option fifteen', value: '15' },
|
|
190
189
|
],
|
|
191
190
|
},
|
|
192
191
|
render: () => {
|
|
193
192
|
const [args, updateArgs] = useArgs();
|
|
194
|
-
const
|
|
193
|
+
const onValueChange = (value: string) => {
|
|
195
194
|
updateArgs({ value });
|
|
196
195
|
};
|
|
197
196
|
return (
|
|
@@ -199,7 +198,7 @@ export const ManyOptions: Story = {
|
|
|
199
198
|
{...args}
|
|
200
199
|
options={args.options}
|
|
201
200
|
value={args.value}
|
|
202
|
-
|
|
201
|
+
onValueChange={onValueChange}
|
|
203
202
|
/>
|
|
204
203
|
);
|
|
205
204
|
},
|
|
@@ -3,33 +3,19 @@ import { SelectProps } from './Select.types';
|
|
|
3
3
|
|
|
4
4
|
const Select = (props: SelectProps) => {
|
|
5
5
|
if (props.native) {
|
|
6
|
-
|
|
7
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
8
|
-
const { onChange, value, native, ...rest } = props;
|
|
9
|
-
const handleNativeChange = (
|
|
10
|
-
event: React.ChangeEvent<HTMLSelectElement>
|
|
11
|
-
) => {
|
|
12
|
-
if (onChange) onChange(event, event.target.value);
|
|
13
|
-
};
|
|
6
|
+
const { onChange, value, ...rest } = props;
|
|
14
7
|
return (
|
|
15
8
|
<NativeSelect
|
|
16
|
-
onChange={
|
|
9
|
+
onChange={onChange}
|
|
17
10
|
value={value || ''}
|
|
18
11
|
{...rest}
|
|
19
12
|
/>
|
|
20
13
|
);
|
|
21
14
|
} else {
|
|
22
|
-
|
|
23
|
-
const { onChange, native, ...rest } = props;
|
|
24
|
-
const handleCustomChange = (
|
|
25
|
-
event: React.MouseEvent | React.KeyboardEvent,
|
|
26
|
-
value: string
|
|
27
|
-
) => {
|
|
28
|
-
if (onChange) onChange(event, value);
|
|
29
|
-
};
|
|
15
|
+
const { onValueChange, ...rest } = props;
|
|
30
16
|
return (
|
|
31
17
|
<CustomSelect
|
|
32
|
-
|
|
18
|
+
onValueChange={onValueChange}
|
|
33
19
|
{...rest}
|
|
34
20
|
/>
|
|
35
21
|
);
|
|
@@ -7,7 +7,7 @@ export type OptionData = {
|
|
|
7
7
|
/**
|
|
8
8
|
* Display text shown to the user
|
|
9
9
|
*/
|
|
10
|
-
|
|
10
|
+
label: string;
|
|
11
11
|
/**
|
|
12
12
|
* Data-friendly value that is returned when the option is selected
|
|
13
13
|
* We assume this will be submitted to a server or used in some other way
|
|
@@ -21,16 +21,6 @@ export type OptionData = {
|
|
|
21
21
|
icon?: React.ReactNode;
|
|
22
22
|
};
|
|
23
23
|
|
|
24
|
-
/**
|
|
25
|
-
* Utility type we expose to developers
|
|
26
|
-
* We expect this to be used in typing event handlers
|
|
27
|
-
* This only applies to the top-level <Select> component
|
|
28
|
-
*/
|
|
29
|
-
export type SelectEvent =
|
|
30
|
-
| React.ChangeEvent<HTMLSelectElement>
|
|
31
|
-
| React.MouseEvent
|
|
32
|
-
| React.KeyboardEvent;
|
|
33
|
-
|
|
34
24
|
/**
|
|
35
25
|
* Top level props that <Select> accepts when implemented
|
|
36
26
|
*/
|
|
@@ -39,20 +29,6 @@ interface BaseSelectProps {
|
|
|
39
29
|
* An array of option data, to be rendered either natively or custom
|
|
40
30
|
*/
|
|
41
31
|
options: OptionData[];
|
|
42
|
-
/**
|
|
43
|
-
* The currently selected value
|
|
44
|
-
* This determines which option is shown when the select is closed
|
|
45
|
-
*/
|
|
46
|
-
value: string | undefined | null;
|
|
47
|
-
/**
|
|
48
|
-
* Generic onChange that splits into native and custom versions
|
|
49
|
-
* The original event is exposed, and the value always returns the value of the selected option
|
|
50
|
-
*/
|
|
51
|
-
onChange: (event: SelectEvent, value: string) => void;
|
|
52
|
-
/**
|
|
53
|
-
* Prevents use, including focus events
|
|
54
|
-
*/
|
|
55
|
-
disabled?: boolean | undefined;
|
|
56
32
|
/**
|
|
57
33
|
* Placeholder text shown when no option is selected
|
|
58
34
|
* Displayed in visible field of custom implementation
|
|
@@ -69,30 +45,23 @@ interface BaseSelectProps {
|
|
|
69
45
|
* as `data-testid`
|
|
70
46
|
*/
|
|
71
47
|
testId?: string;
|
|
72
|
-
/**
|
|
73
|
-
* Optional className for styling
|
|
74
|
-
* This is passed to the root element of the component
|
|
75
|
-
* for additional CSS styling via Emotion.
|
|
76
|
-
*/
|
|
77
|
-
className?: string;
|
|
78
48
|
/**
|
|
79
49
|
* Native flag determines which implementation to use
|
|
80
50
|
*/
|
|
81
51
|
native?: boolean;
|
|
82
|
-
// `ref` prop added in the discriminated union below
|
|
83
52
|
}
|
|
84
53
|
|
|
85
|
-
export type SelectProps = BaseSelectProps &
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
54
|
+
// export type SelectProps = BaseSelectProps &
|
|
55
|
+
// // Discriminated union to determine which implementation to use
|
|
56
|
+
// (| ({ native: true; ref?: React.RefObject<HTMLSelectElement | null> } & Omit<
|
|
57
|
+
// React.SelectHTMLAttributes<HTMLSelectElement>,
|
|
58
|
+
// keyof BaseSelectProps
|
|
59
|
+
// >)
|
|
60
|
+
// | ({ native?: false; ref?: React.RefObject<HTMLDivElement | null> } & Omit<
|
|
61
|
+
// React.HTMLAttributes<HTMLDivElement>,
|
|
62
|
+
// keyof BaseSelectProps
|
|
63
|
+
// >)
|
|
64
|
+
// );
|
|
96
65
|
|
|
97
66
|
// Props interface for the two variants are separated.
|
|
98
67
|
// We expose SelectProps for developers to use, and handle discrepancies internally.
|
|
@@ -101,37 +70,29 @@ export type SelectProps = BaseSelectProps &
|
|
|
101
70
|
* Internal props for the custom implementation, with <div> as root element
|
|
102
71
|
* onChange already exists on <div>. We override it.
|
|
103
72
|
*/
|
|
104
|
-
export
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
value: string
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
placeholder?: string;
|
|
116
|
-
width?: number;
|
|
117
|
-
testId?: string;
|
|
118
|
-
className?: string;
|
|
119
|
-
ref?: React.RefObject<HTMLDivElement | null>;
|
|
120
|
-
}
|
|
73
|
+
export type CustomSelectProps = Omit<
|
|
74
|
+
React.HTMLAttributes<HTMLDivElement>,
|
|
75
|
+
'onChange'
|
|
76
|
+
> &
|
|
77
|
+
BaseSelectProps & {
|
|
78
|
+
native?: false;
|
|
79
|
+
value?: string | number;
|
|
80
|
+
disabled?: boolean;
|
|
81
|
+
onValueChange?: (value: string, ev: React.UIEvent) => void;
|
|
82
|
+
ref?: React.RefObject<HTMLDivElement | null>;
|
|
83
|
+
};
|
|
121
84
|
|
|
122
85
|
/**
|
|
123
86
|
* Internal props for native implementation, with <select> as root element
|
|
124
87
|
* Default props like value and onChange are passed to the <select> element automatically
|
|
125
88
|
*/
|
|
126
|
-
export
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
ref?: React.RefObject<HTMLSelectElement | null>;
|
|
134
|
-
}
|
|
89
|
+
export type NativeSelectProps = React.SelectHTMLAttributes<HTMLSelectElement> &
|
|
90
|
+
BaseSelectProps & {
|
|
91
|
+
native: true;
|
|
92
|
+
ref?: React.RefObject<HTMLSelectElement | null>;
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export type SelectProps = NativeSelectProps | CustomSelectProps;
|
|
135
96
|
|
|
136
97
|
/**
|
|
137
98
|
* Each option as displayed in the Panel of <CustomSelect>
|
|
@@ -5,9 +5,9 @@ import Select from '../Select';
|
|
|
5
5
|
import { ThemeContextProvider } from '../../../theme/useTheme';
|
|
6
6
|
|
|
7
7
|
const defaultOptions = [
|
|
8
|
-
{
|
|
9
|
-
{
|
|
10
|
-
{
|
|
8
|
+
{ label: 'Option 1', value: '1' },
|
|
9
|
+
{ label: 'Option 2', value: '2' },
|
|
10
|
+
{ label: 'Option 3', value: '3' },
|
|
11
11
|
];
|
|
12
12
|
|
|
13
13
|
describe('Select', () => {
|
|
@@ -78,9 +78,9 @@ describe('Select', () => {
|
|
|
78
78
|
// Options should be present
|
|
79
79
|
const options = renderResult.getAllByTestId('ucl-uikit-select__option');
|
|
80
80
|
expect(options.length).toBe(defaultOptions.length);
|
|
81
|
-
expect(options[0].textContent).toBe(defaultOptions[0].
|
|
82
|
-
expect(options[1].textContent).toBe(defaultOptions[1].
|
|
83
|
-
expect(options[2].textContent).toBe(defaultOptions[2].
|
|
81
|
+
expect(options[0].textContent).toBe(defaultOptions[0].label);
|
|
82
|
+
expect(options[1].textContent).toBe(defaultOptions[1].label);
|
|
83
|
+
expect(options[2].textContent).toBe(defaultOptions[2].label);
|
|
84
84
|
});
|
|
85
85
|
|
|
86
86
|
test('Cannot be used when disabled', async () => {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { default } from './Select';
|
|
2
|
-
export type { SelectProps, OptionData
|
|
2
|
+
export type { SelectProps, OptionData } from './Select.types';
|
|
@@ -5,14 +5,15 @@ import { useTheme } from '../../../theme';
|
|
|
5
5
|
import type { CustomSelectProps } from '../Select.types';
|
|
6
6
|
|
|
7
7
|
const NAME = 'ucl-uikit-select';
|
|
8
|
+
export const DEFAULT_WIDTH_PX = 200;
|
|
8
9
|
|
|
9
10
|
const CustomSelect = ({
|
|
10
11
|
value,
|
|
11
12
|
options = [],
|
|
12
|
-
|
|
13
|
+
onValueChange,
|
|
13
14
|
disabled,
|
|
14
15
|
placeholder,
|
|
15
|
-
width =
|
|
16
|
+
width = DEFAULT_WIDTH_PX,
|
|
16
17
|
testId = NAME,
|
|
17
18
|
className,
|
|
18
19
|
ref,
|
|
@@ -58,7 +59,7 @@ const CustomSelect = ({
|
|
|
58
59
|
|
|
59
60
|
// Used by <CustomOption> and passed as prop
|
|
60
61
|
const handleSelect = (event: React.MouseEvent, optionValue: string) => {
|
|
61
|
-
if (
|
|
62
|
+
if (onValueChange) onValueChange(optionValue, event);
|
|
62
63
|
closePanel();
|
|
63
64
|
};
|
|
64
65
|
|
|
@@ -96,7 +97,7 @@ const CustomSelect = ({
|
|
|
96
97
|
}
|
|
97
98
|
if (!value) {
|
|
98
99
|
// Initialise at the last option if no value provided
|
|
99
|
-
|
|
100
|
+
onValueChange?.(options[options.length - 1].value, event);
|
|
100
101
|
return;
|
|
101
102
|
}
|
|
102
103
|
const currentOptionIndex = options.findIndex(
|
|
@@ -104,7 +105,7 @@ const CustomSelect = ({
|
|
|
104
105
|
);
|
|
105
106
|
const previousOptionIndex =
|
|
106
107
|
(currentOptionIndex - 1 + options.length) % options.length;
|
|
107
|
-
|
|
108
|
+
onValueChange?.(options[previousOptionIndex].value, event);
|
|
108
109
|
return;
|
|
109
110
|
}
|
|
110
111
|
// Select the next option
|
|
@@ -115,26 +116,25 @@ const CustomSelect = ({
|
|
|
115
116
|
}
|
|
116
117
|
if (!value) {
|
|
117
118
|
// Initialise at the first option if no value provided
|
|
118
|
-
|
|
119
|
+
onValueChange?.(options[0].value, event);
|
|
119
120
|
return;
|
|
120
121
|
}
|
|
121
122
|
const currentOptionIndex = options.findIndex(
|
|
122
123
|
(option) => option.value === value
|
|
123
124
|
);
|
|
124
125
|
const nextOptionIndex = (currentOptionIndex + 1) % options.length;
|
|
125
|
-
|
|
126
|
+
onValueChange?.(options[nextOptionIndex].value, event);
|
|
126
127
|
return;
|
|
127
128
|
}
|
|
128
129
|
};
|
|
129
130
|
|
|
130
131
|
const baseStyle = css`
|
|
131
|
-
display: flex;
|
|
132
|
+
display: inline-flex;
|
|
132
133
|
align-items: center;
|
|
133
134
|
justify-content: space-between;
|
|
134
135
|
position: relative;
|
|
135
|
-
width: ${width}px;
|
|
136
136
|
min-width: 80px;
|
|
137
|
-
|
|
137
|
+
width: fit-content;
|
|
138
138
|
height: 48px;
|
|
139
139
|
box-sizing: border-box;
|
|
140
140
|
padding: 0 16px;
|
|
@@ -156,6 +156,10 @@ const CustomSelect = ({
|
|
|
156
156
|
}
|
|
157
157
|
`;
|
|
158
158
|
|
|
159
|
+
const widthStyle = css`
|
|
160
|
+
width: ${width}px;
|
|
161
|
+
`;
|
|
162
|
+
|
|
159
163
|
const disabledStyle = css`
|
|
160
164
|
color: ${theme.color.text.disabled};
|
|
161
165
|
border: ${theme.border.b1} solid ${theme.color.neutral.grey20};
|
|
@@ -166,7 +170,13 @@ const CustomSelect = ({
|
|
|
166
170
|
}
|
|
167
171
|
`;
|
|
168
172
|
|
|
169
|
-
const style = cx(
|
|
173
|
+
const style = cx(
|
|
174
|
+
NAME,
|
|
175
|
+
baseStyle,
|
|
176
|
+
!!width && widthStyle,
|
|
177
|
+
disabled && disabledStyle,
|
|
178
|
+
className
|
|
179
|
+
);
|
|
170
180
|
|
|
171
181
|
return (
|
|
172
182
|
<div
|
|
@@ -199,7 +209,7 @@ const CustomSelect = ({
|
|
|
199
209
|
aria-selected={value === option.value}
|
|
200
210
|
>
|
|
201
211
|
{option.icon}
|
|
202
|
-
{option.
|
|
212
|
+
{option.label}
|
|
203
213
|
</CustomOption>
|
|
204
214
|
))}
|
|
205
215
|
</Panel>
|
|
@@ -7,7 +7,7 @@ const NAME = 'ucl-uikit-select--native';
|
|
|
7
7
|
|
|
8
8
|
const NativeSelect = ({
|
|
9
9
|
options,
|
|
10
|
-
width
|
|
10
|
+
width,
|
|
11
11
|
disabled,
|
|
12
12
|
placeholder,
|
|
13
13
|
testId = NAME,
|
|
@@ -22,7 +22,6 @@ const NativeSelect = ({
|
|
|
22
22
|
const chevronDownSvg = chevronDownSvgDataUri(chevronColour);
|
|
23
23
|
|
|
24
24
|
const baseStyle = css`
|
|
25
|
-
width: ${width}px;
|
|
26
25
|
padding: 0 ${theme.padding.p40} 0 ${theme.padding.p16};
|
|
27
26
|
height: ${theme.padding.p48};
|
|
28
27
|
line-height: ${theme.font.lineHeight.h150};
|
|
@@ -43,6 +42,10 @@ const NativeSelect = ({
|
|
|
43
42
|
background-repeat: no-repeat;
|
|
44
43
|
`;
|
|
45
44
|
|
|
45
|
+
const widthStyle = css`
|
|
46
|
+
width: ${width}px;
|
|
47
|
+
`;
|
|
48
|
+
|
|
46
49
|
const hoverStyle = css`
|
|
47
50
|
&:hover {
|
|
48
51
|
border-color: ${theme.color.neutral.grey60};
|
|
@@ -70,6 +73,7 @@ const NativeSelect = ({
|
|
|
70
73
|
const style = cx(
|
|
71
74
|
NAME,
|
|
72
75
|
baseStyle,
|
|
76
|
+
!!width && widthStyle,
|
|
73
77
|
!disabled && hoverStyle,
|
|
74
78
|
!disabled && focusStyle,
|
|
75
79
|
disabled && disabledStyle,
|
|
@@ -98,7 +102,7 @@ const NativeSelect = ({
|
|
|
98
102
|
key={option.value}
|
|
99
103
|
value={option.value}
|
|
100
104
|
>
|
|
101
|
-
{option.
|
|
105
|
+
{option.label}
|
|
102
106
|
</option>
|
|
103
107
|
))
|
|
104
108
|
: null}
|
|
@@ -19,14 +19,14 @@ const Panel = (props: PanelProps) => {
|
|
|
19
19
|
position: absolute;
|
|
20
20
|
top: 46px;
|
|
21
21
|
left: -1px; // -1px to align with the border of the field
|
|
22
|
-
|
|
23
22
|
z-index: 10; // Required: panel must be 'above' subsquent DOM elements
|
|
24
|
-
width: 100%;
|
|
25
|
-
|
|
23
|
+
min-width: 100%;
|
|
24
|
+
width: fit-content;
|
|
25
|
+
max-height: 300px;
|
|
26
26
|
overflow-y: auto;
|
|
27
27
|
overflow-x: hidden;
|
|
28
28
|
box-sizing: content-box;
|
|
29
|
-
padding:
|
|
29
|
+
padding: ${theme.padding.p8} 0;
|
|
30
30
|
border: ${theme.border.b1} solid ${theme.color.neutral.grey20};
|
|
31
31
|
background-color: ${theme.color.neutral.white};
|
|
32
32
|
`;
|
package/lib/components/index.ts
CHANGED
|
@@ -130,3 +130,6 @@ export type { RadioProps, LabelledRadioProps } from './Radio';
|
|
|
130
130
|
|
|
131
131
|
export { default as Datepicker } from './Datepicker';
|
|
132
132
|
export type { DatepickerProps } from './Datepicker';
|
|
133
|
+
|
|
134
|
+
export { default as Calendar } from './Calendar';
|
|
135
|
+
export type { CalendarProps } from './Calendar';
|
package/package.json
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "uikit-react-public",
|
|
3
3
|
"private": false,
|
|
4
|
-
"license": "
|
|
5
|
-
"version": "0.11.
|
|
4
|
+
"license": "UNLICENSED",
|
|
5
|
+
"version": "0.11.24",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "dist/index.js",
|
|
8
8
|
"types": "dist/index.d.ts",
|
|
9
9
|
"files": [
|
|
10
10
|
"dist",
|
|
11
|
-
"lib"
|
|
12
|
-
"README.md"
|
|
11
|
+
"lib"
|
|
13
12
|
],
|
|
14
13
|
"publishConfig": {
|
|
15
14
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -25,6 +24,7 @@
|
|
|
25
24
|
"typecheck": "tsc --noemit",
|
|
26
25
|
"test": "vitest",
|
|
27
26
|
"test:nowatch": "vitest run",
|
|
27
|
+
"check": "npm run lint && npm run typecheck && npm run test",
|
|
28
28
|
"coverage": "vitest run --coverage",
|
|
29
29
|
"report": "vite ./coverage",
|
|
30
30
|
"preview": "vite preview",
|
package/LICENSE
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright 2025 UCL
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
-
|
|
7
|
-
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
-
|
|
9
|
-
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './CalendarGrid';
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
interface CalendarMenuProps {
|
|
2
|
-
date: Date | null | undefined;
|
|
3
|
-
setDate: (date: Date) => void;
|
|
4
|
-
onDatePick: () => void;
|
|
5
|
-
testId?: string;
|
|
6
|
-
}
|
|
7
|
-
declare const CalendarMenu: ({ date, setDate, onDatePick, testId, }: CalendarMenuProps) => import("react/jsx-runtime").JSX.Element;
|
|
8
|
-
export default CalendarMenu;
|