uikit-react-public 0.11.16 → 0.11.20

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 (52) hide show
  1. package/dist/components/Datepicker/Datepicker.d.ts +5 -1
  2. package/dist/components/Datepicker/Datepicker.stories.d.ts +8 -1
  3. package/dist/components/Datepicker/Datepicker.types.d.ts +7 -0
  4. package/dist/components/Datepicker/index.d.ts +1 -0
  5. package/dist/components/Datepicker/subcomponents/AcademicWeek.d.ts +5 -0
  6. package/dist/components/Datepicker/subcomponents/AcademicWeeks.d.ts +7 -0
  7. package/dist/components/Datepicker/subcomponents/CalendarGrid/CalendarGrid.d.ts +3 -1
  8. package/dist/components/Datepicker/subcomponents/CalendarMenu/CalendarMenu.d.ts +5 -1
  9. package/dist/components/Datepicker/subcomponents/Day/Day.d.ts +4 -2
  10. package/dist/components/Datepicker/subcomponents/Day/Day.stories.d.ts +9 -1
  11. package/dist/components/Datepicker/subcomponents/EventDot.d.ts +6 -0
  12. package/dist/components/Datepicker/utils/getAcademicWeekNumbers/getAcademicWeekNumbers.d.ts +24 -0
  13. package/dist/components/Datepicker/utils/getAcademicWeekNumbers/getAcademicWeekNumbers.test.d.ts +1 -0
  14. package/dist/components/Datepicker/utils/index.d.ts +1 -0
  15. package/dist/components/Header/Header.d.ts +5 -4
  16. package/dist/components/Header/index.d.ts +1 -1
  17. package/dist/components/Select/Select.stories.d.ts +1 -1
  18. package/dist/components/Select/Select.types.d.ts +10 -50
  19. package/dist/components/Select/index.d.ts +1 -1
  20. package/dist/components/Select/subcomponents/CustomSelect.d.ts +2 -1
  21. package/dist/index.js +1865 -1748
  22. package/lib/components/Datepicker/Datepicker.stories.tsx +133 -0
  23. package/lib/components/Datepicker/Datepicker.tsx +23 -46
  24. package/lib/components/Datepicker/Datepicker.types.ts +9 -0
  25. package/lib/components/Datepicker/__tests__/__snapshots__/Datepicker.test.tsx.snap +487 -378
  26. package/lib/components/Datepicker/index.ts +1 -0
  27. package/lib/components/Datepicker/subcomponents/AcademicWeek.tsx +36 -0
  28. package/lib/components/Datepicker/subcomponents/AcademicWeeks.tsx +44 -0
  29. package/lib/components/Datepicker/subcomponents/CalendarGrid/CalendarGrid.tsx +9 -14
  30. package/lib/components/Datepicker/subcomponents/CalendarMenu/CalendarMenu.tsx +32 -6
  31. package/lib/components/Datepicker/subcomponents/Day/Day.stories.tsx +23 -0
  32. package/lib/components/Datepicker/subcomponents/Day/Day.tsx +31 -7
  33. package/lib/components/Datepicker/subcomponents/EventDot.tsx +40 -0
  34. package/lib/components/Datepicker/utils/getAcademicWeekNumbers/getAcademicWeekNumbers.test.ts +104 -0
  35. package/lib/components/Datepicker/utils/getAcademicWeekNumbers/getAcademicWeekNumbers.ts +85 -0
  36. package/lib/components/Datepicker/utils/index.ts +1 -0
  37. package/lib/components/Header/Header.tsx +32 -33
  38. package/lib/components/Header/HeaderMenu.tsx +9 -2
  39. package/lib/components/Header/__tests__/__snapshots__/Header.test.tsx.snap +40 -48
  40. package/lib/components/Header/index.ts +5 -1
  41. package/lib/components/Select/Select.stories.tsx +38 -39
  42. package/lib/components/Select/Select.tsx +4 -18
  43. package/lib/components/Select/Select.types.ts +30 -69
  44. package/lib/components/Select/__tests__/Select.test.tsx +6 -6
  45. package/lib/components/Select/__tests__/__snapshots__/Select.test.tsx.snap +1 -1
  46. package/lib/components/Select/index.ts +1 -1
  47. package/lib/components/Select/subcomponents/CustomSelect.tsx +22 -12
  48. package/lib/components/Select/subcomponents/NativeSelect.tsx +7 -3
  49. package/lib/components/Select/subcomponents/Panel.tsx +4 -4
  50. package/lib/components/Select/subcomponents/VisibleField.tsx +1 -1
  51. package/package.json +3 -3
  52. package/LICENSE +0 -9
@@ -1,6 +1,7 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react';
2
2
  import { useArgs } from '@storybook/preview-api';
3
3
  import Datepicker from './Datepicker';
4
+ import type { AcademicWeek } from './Datepicker.types';
4
5
 
5
6
  const meta = {
6
7
  title: 'Components/Work in progress/Datepicker/Datepicker',
@@ -11,6 +12,7 @@ const meta = {
11
12
  minDate: { control: { type: 'date' } },
12
13
  maxDate: { control: { type: 'date' } },
13
14
  native: { control: { type: 'boolean' } },
15
+ showAcademicWeeks: { control: { type: 'boolean' } },
14
16
  },
15
17
  tags: ['autodocs'],
16
18
  } satisfies Meta<typeof Datepicker>;
@@ -68,3 +70,134 @@ export const AsNative: Story = {
68
70
  );
69
71
  },
70
72
  };
73
+
74
+ const dateToISOString = (date: Date) => {
75
+ return date.toISOString().split('T')[0];
76
+ };
77
+
78
+ export const WithEvents: Story = {
79
+ name: 'With events',
80
+ args: {
81
+ date: null,
82
+ onDateChange: () => {},
83
+ // IIFE gives us event dots for the current month
84
+ events: (() => {
85
+ const currentDate = new Date();
86
+ const currentYear = currentDate.getFullYear();
87
+ const currentMonth = currentDate.getMonth();
88
+ return [
89
+ // Grey event dots
90
+ { date: dateToISOString(new Date(currentYear, currentMonth, -2)) },
91
+ { date: dateToISOString(new Date(currentYear, currentMonth, -1)) },
92
+ { date: dateToISOString(new Date(currentYear, currentMonth, -1)) },
93
+ { date: dateToISOString(new Date(currentYear, currentMonth, 0)) },
94
+ { date: dateToISOString(new Date(currentYear, currentMonth, 0)) },
95
+ { date: dateToISOString(new Date(currentYear, currentMonth, 0)) },
96
+ // Blue event dots
97
+ { date: dateToISOString(new Date(currentYear, currentMonth, 1)) },
98
+ { date: dateToISOString(new Date(currentYear, currentMonth, 2)) },
99
+ { date: dateToISOString(new Date(currentYear, currentMonth, 2)) },
100
+ { date: dateToISOString(new Date(currentYear, currentMonth, 3)) },
101
+ { date: dateToISOString(new Date(currentYear, currentMonth, 3)) },
102
+ { date: dateToISOString(new Date(currentYear, currentMonth, 3)) },
103
+ ];
104
+ })(),
105
+ },
106
+ render: () => {
107
+ const [args, updateArgs] = useArgs();
108
+ args.date = args.date ? new Date(args.date) : null;
109
+ args.minDate = args.minDate ? new Date(args.minDate) : null;
110
+ args.maxDate = args.maxDate ? new Date(args.maxDate) : null;
111
+ const onDateChange = (date: Date | null | undefined) =>
112
+ updateArgs({ date: date });
113
+ return (
114
+ <Datepicker
115
+ {...args}
116
+ date={args.date}
117
+ onDateChange={onDateChange}
118
+ events={args.events}
119
+ />
120
+ );
121
+ },
122
+ };
123
+
124
+ const academicWeeks: AcademicWeek[] = [
125
+ { start: '2025-08-25', number: 1 },
126
+ { start: '2025-09-01', number: 2 },
127
+ { start: '2025-09-08', number: 3 },
128
+ { start: '2025-09-15', number: 4 },
129
+ { start: '2025-09-22', number: 5 },
130
+ { start: '2025-09-29', number: 6 },
131
+ { start: '2025-10-06', number: 7 },
132
+ { start: '2025-10-13', number: 8 },
133
+ { start: '2025-10-20', number: 9 },
134
+ { start: '2025-10-27', number: 10 },
135
+ { start: '2025-11-03', number: 11 },
136
+ { start: '2025-11-10', number: 12 },
137
+ { start: '2025-11-17', number: 13 },
138
+ { start: '2025-11-24', number: 14 },
139
+ { start: '2025-12-01', number: 15 },
140
+ { start: '2025-12-08', number: 16 },
141
+ { start: '2025-12-15', number: 17 },
142
+ { start: '2025-12-22', number: 18 },
143
+ { start: '2025-12-29', number: 19 },
144
+ { start: '2026-01-05', number: 20 },
145
+ { start: '2026-01-12', number: 21 },
146
+ { start: '2026-01-19', number: 22 },
147
+ { start: '2026-01-26', number: 23 },
148
+ { start: '2026-02-02', number: 24 },
149
+ { start: '2026-02-09', number: 25 },
150
+ { start: '2026-02-16', number: 26 },
151
+ { start: '2026-02-23', number: 27 },
152
+ { start: '2026-03-02', number: 28 },
153
+ { start: '2026-03-09', number: 29 },
154
+ { start: '2026-03-16', number: 30 },
155
+ { start: '2026-03-23', number: 31 },
156
+ { start: '2026-03-30', number: 32 },
157
+ { start: '2026-04-06', number: 33 },
158
+ { start: '2026-04-13', number: 34 },
159
+ { start: '2026-04-20', number: 35 },
160
+ { start: '2026-04-27', number: 36 },
161
+ { start: '2026-05-04', number: 37 },
162
+ { start: '2026-05-11', number: 38 },
163
+ { start: '2026-05-18', number: 39 },
164
+ { start: '2026-05-25', number: 40 },
165
+ { start: '2026-06-01', number: 41 },
166
+ { start: '2026-06-08', number: 42 },
167
+ { start: '2026-06-15', number: 43 },
168
+ { start: '2026-06-22', number: 44 },
169
+ { start: '2026-06-29', number: 45 },
170
+ { start: '2026-07-06', number: 46 },
171
+ { start: '2026-07-13', number: 47 },
172
+ { start: '2026-07-20', number: 48 },
173
+ { start: '2026-07-27', number: 49 },
174
+ { start: '2026-08-03', number: 50 },
175
+ { start: '2026-08-10', number: 51 },
176
+ { start: '2026-08-17', number: 52 },
177
+ { start: '2026-08-24', number: 53 },
178
+ ];
179
+
180
+ export const WithAcademicWeeks: Story = {
181
+ name: 'With academic weeks',
182
+ args: {
183
+ date: null,
184
+ onDateChange: () => {},
185
+ showAcademicWeeks: true,
186
+ academicWeeks: academicWeeks,
187
+ },
188
+ render: () => {
189
+ const [args, updateArgs] = useArgs();
190
+ args.date = args.date ? new Date(args.date) : null;
191
+ args.minDate = args.minDate ? new Date(args.minDate) : null;
192
+ args.maxDate = args.maxDate ? new Date(args.maxDate) : null;
193
+ const onDateChange = (date: Date | null | undefined) =>
194
+ updateArgs({ date: date });
195
+ return (
196
+ <Datepicker
197
+ {...args}
198
+ date={args.date}
199
+ onDateChange={onDateChange}
200
+ />
201
+ );
202
+ },
203
+ };
@@ -1,26 +1,21 @@
1
- import {
2
- useState,
3
- useRef,
4
- memo,
5
- InputHTMLAttributes,
6
- } from 'react';
1
+ import { useState, useRef, memo, InputHTMLAttributes } from 'react';
7
2
  import { css, cx } from '@emotion/css';
8
- import {
9
- Native,
10
- DateField,
11
- CalendarMenu,
12
- } from './subcomponents';
3
+ import { Native, DateField, CalendarMenu } from './subcomponents';
13
4
  import { useTheme } from '../../theme';
5
+ import { CalendarEvent } from './Datepicker.types';
6
+ import type { AcademicWeek } from './Datepicker.types';
14
7
 
15
8
  export const NAME = 'ucl-datepicker';
16
9
 
17
- export interface DatepickerProps
18
- extends InputHTMLAttributes<HTMLInputElement> {
10
+ export interface DatepickerProps extends InputHTMLAttributes<HTMLInputElement> {
19
11
  date: Date | null | undefined;
20
12
  minDate?: Date | null | undefined;
21
13
  maxDate?: Date | null | undefined;
22
14
  onDateChange: (date: Date | null | undefined) => void;
23
15
  native?: boolean;
16
+ events?: CalendarEvent[];
17
+ showAcademicWeeks?: boolean;
18
+ academicWeeks?: AcademicWeek[]; // Array of academic week strings in YYYY-MM-DD format
24
19
  testId?: string;
25
20
  }
26
21
 
@@ -29,7 +24,10 @@ const Datepicker = ({
29
24
  minDate,
30
25
  maxDate,
31
26
  onDateChange,
32
- native,
27
+ native = false,
28
+ events = [],
29
+ showAcademicWeeks = false,
30
+ academicWeeks = [],
33
31
  testId = NAME,
34
32
  className,
35
33
  ...props
@@ -50,48 +48,28 @@ const Datepicker = ({
50
48
  />
51
49
  );
52
50
 
53
- const blur = () =>
54
- (document.activeElement as HTMLElement)?.blur();
51
+ const blur = () => (document.activeElement as HTMLElement)?.blur();
55
52
 
56
- const handleKeyDown = (
57
- event: React.KeyboardEvent<HTMLDivElement>
58
- ) => {
53
+ const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {
59
54
  // Keyboard mappings for interacting with the date `<CalendarMenu>`
60
55
  // Escape & Enter both close the `<CalendarMenu>`
61
- if (event.key === 'Escape' || event.key === 'Enter')
62
- blur();
56
+ if (event.key === 'Escape' || event.key === 'Enter') blur();
63
57
  // Move the currently selected date in the `<CalendarGrid />`
64
58
  else if (event.key === 'ArrowLeft' && date)
65
59
  onDateChange(
66
- new Date(
67
- date.getFullYear(),
68
- date.getMonth(),
69
- date.getDate() - 1
70
- )
60
+ new Date(date.getFullYear(), date.getMonth(), date.getDate() - 1)
71
61
  );
72
62
  else if (event.key === 'ArrowRight' && date)
73
63
  onDateChange(
74
- new Date(
75
- date.getFullYear(),
76
- date.getMonth(),
77
- date.getDate() + 1
78
- )
64
+ new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1)
79
65
  );
80
66
  else if (event.key === 'ArrowUp' && date)
81
67
  onDateChange(
82
- new Date(
83
- date.getFullYear(),
84
- date.getMonth(),
85
- date.getDate() - 7
86
- )
68
+ new Date(date.getFullYear(), date.getMonth(), date.getDate() - 7)
87
69
  );
88
70
  else if (event.key === 'ArrowDown' && date)
89
71
  onDateChange(
90
- new Date(
91
- date.getFullYear(),
92
- date.getMonth(),
93
- date.getDate() + 7
94
- )
72
+ new Date(date.getFullYear(), date.getMonth(), date.getDate() + 7)
95
73
  );
96
74
  };
97
75
 
@@ -101,11 +79,7 @@ const Datepicker = ({
101
79
 
102
80
  const handleBlurCapture = (event: React.FocusEvent) => {
103
81
  // Only close if focus moves outside `<Datepicker>` and its subcomponents
104
- if (
105
- !datepickerRef.current?.contains(
106
- event.relatedTarget as Node
107
- )
108
- )
82
+ if (!datepickerRef.current?.contains(event.relatedTarget as Node))
109
83
  setIsOpen(false);
110
84
  };
111
85
 
@@ -143,6 +117,9 @@ const Datepicker = ({
143
117
  date={date}
144
118
  setDate={onDateChange}
145
119
  onDatePick={handleDatePick}
120
+ events={events}
121
+ showAcademicWeeks={showAcademicWeeks}
122
+ academicWeeks={academicWeeks}
146
123
  testId={testId}
147
124
  />
148
125
  )}
@@ -0,0 +1,9 @@
1
+ // Used to display EventDots inside `<Day>` component
2
+ export type CalendarEvent = {
3
+ date: string; // Date string in YYYY-MM-DD format
4
+ };
5
+
6
+ export type AcademicWeek = {
7
+ start: string; // Date string in YYYY-MM-DD format
8
+ number: number;
9
+ };