@design-system-rte/core 1.6.5 → 1.7.0-rc1

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 (27) hide show
  1. package/components/datepicker/datepicker-menu-focus-order.d.ts +4 -0
  2. package/components/datepicker/datepicker-menu-focus-order.d.ts.map +1 -0
  3. package/components/datepicker/datepicker-menu-focus-order.js +34 -0
  4. package/components/datepicker/datepicker.constants.d.ts +23 -0
  5. package/components/datepicker/datepicker.constants.d.ts.map +1 -0
  6. package/components/datepicker/datepicker.constants.js +36 -0
  7. package/components/datepicker/datepicker.interface.d.ts +59 -0
  8. package/components/datepicker/datepicker.utils.d.ts +132 -0
  9. package/components/datepicker/datepicker.utils.d.ts.map +1 -0
  10. package/components/datepicker/datepicker.utils.js +539 -0
  11. package/components/datepicker/index.d.ts +6 -0
  12. package/components/datepicker/index.d.ts.map +1 -0
  13. package/components/datepicker/index.js +4 -0
  14. package/components/datepicker/segmented-date-field.d.ts +27 -0
  15. package/components/datepicker/segmented-date-field.d.ts.map +1 -0
  16. package/components/datepicker/segmented-date-field.js +318 -0
  17. package/components/file-upload/file-upload.interface.d.ts +26 -0
  18. package/components/file-upload/file-upload.util.d.ts +7 -0
  19. package/components/file-upload/file-upload.util.d.ts.map +1 -0
  20. package/components/file-upload/file-upload.util.js +16 -0
  21. package/components/file-upload/index.d.ts +2 -0
  22. package/components/file-upload/index.d.ts.map +1 -0
  23. package/components/file-upload/index.js +1 -0
  24. package/components/toast/toast.utils.d.ts +1 -1
  25. package/index.d.ts +2 -0
  26. package/index.js +2 -0
  27. package/package.json +9 -1
@@ -0,0 +1,318 @@
1
+ import { ARROW_DOWN_KEY, ARROW_LEFT_KEY, ARROW_RIGHT_KEY, ARROW_UP_KEY, BACKSPACE_KEY, DELETE_KEY, } from "../../constants/keyboard/keyboard.constants";
2
+ import { buildMaskedDdMmYyyyFromDigitParts, parseDate, parseDdMmYyyyMaskedString, getLastDayOfMonth, } from "./datepicker.utils";
3
+ export const SEGMENT_ORDER = ["day", "month", "year"];
4
+ const SEGMENT_LENGTH = {
5
+ day: 2,
6
+ month: 2,
7
+ year: 4,
8
+ };
9
+ const SEGMENT_DIGITS_KEY = {
10
+ day: "dayDigits",
11
+ month: "monthDigits",
12
+ year: "yearDigits",
13
+ };
14
+ function readSegmentDigits(state, segment) {
15
+ return state[SEGMENT_DIGITS_KEY[segment]];
16
+ }
17
+ function withSegmentDigits(state, segment, digits) {
18
+ const key = SEGMENT_DIGITS_KEY[segment];
19
+ return { ...state, [key]: digits };
20
+ }
21
+ export function getSegmentDisplayText(digits, segment, emptyPlaceholder) {
22
+ if (!digits?.length) {
23
+ return emptyPlaceholder;
24
+ }
25
+ const maxLength = SEGMENT_LENGTH[segment];
26
+ if (digits.length < maxLength) {
27
+ return digits.padStart(maxLength, "0");
28
+ }
29
+ return digits;
30
+ }
31
+ export function createEmptySegmentedDateFieldState() {
32
+ return {
33
+ dayDigits: "",
34
+ monthDigits: "",
35
+ yearDigits: "",
36
+ activeSegment: "day",
37
+ };
38
+ }
39
+ export function segmentedStateFromDdMmYyyyString(value) {
40
+ const parts = parseDdMmYyyyMaskedString(value);
41
+ return {
42
+ dayDigits: parts.dayDigits,
43
+ monthDigits: parts.monthDigits,
44
+ yearDigits: parts.yearDigits,
45
+ activeSegment: "day",
46
+ };
47
+ }
48
+ export function segmentedStateFromIsoDate(date) {
49
+ return {
50
+ dayDigits: `${date.getDate()}`.padStart(2, "0"),
51
+ monthDigits: `${date.getMonth() + 1}`.padStart(2, "0"),
52
+ yearDigits: `${date.getFullYear()}`.padStart(4, "0"),
53
+ activeSegment: "day",
54
+ };
55
+ }
56
+ export function buildDigitsOnlyFromState(state) {
57
+ return `${state.dayDigits}${state.monthDigits}${state.yearDigits}`;
58
+ }
59
+ export function buildMaskedDdMmYyyyFromState(state) {
60
+ return buildMaskedDdMmYyyyFromDigitParts({
61
+ dayDigits: state.dayDigits,
62
+ monthDigits: state.monthDigits,
63
+ yearDigits: state.yearDigits,
64
+ });
65
+ }
66
+ export function getParsedDateFromState(state) {
67
+ return parseDate(buildMaskedDdMmYyyyFromState(state));
68
+ }
69
+ function segmentToIndex(segment) {
70
+ return SEGMENT_ORDER.indexOf(segment);
71
+ }
72
+ function nextSegment(segment) {
73
+ const index = segmentToIndex(segment);
74
+ if (index < 0 || index >= SEGMENT_ORDER.length - 1) {
75
+ return null;
76
+ }
77
+ return SEGMENT_ORDER[index + 1] ?? null;
78
+ }
79
+ function clampDigits(raw, maxLength) {
80
+ return raw.replace(/\D/g, "").slice(0, maxLength);
81
+ }
82
+ function getMaxDayForDaySegment(state) {
83
+ const { monthDigits, yearDigits } = state;
84
+ if (monthDigits.length === 2 && yearDigits.length === 4) {
85
+ const monthNum = Number.parseInt(monthDigits, 10);
86
+ const yearNum = Number.parseInt(yearDigits, 10);
87
+ if (!Number.isNaN(monthNum) && monthNum >= 1 && monthNum <= 12 && !Number.isNaN(yearNum)) {
88
+ return getLastDayOfMonth(yearNum, monthNum - 1);
89
+ }
90
+ }
91
+ return 31;
92
+ }
93
+ function isMonthDigitsCompleteValid(monthDigits) {
94
+ if (monthDigits.length !== 2) {
95
+ return false;
96
+ }
97
+ const monthNum = Number.parseInt(monthDigits, 10);
98
+ return !Number.isNaN(monthNum) && monthNum >= 1 && monthNum <= 12;
99
+ }
100
+ function isYearDigitsCompleteValid(yearDigits) {
101
+ if (yearDigits.length !== 4) {
102
+ return false;
103
+ }
104
+ const yearNum = Number.parseInt(yearDigits, 10);
105
+ return !Number.isNaN(yearNum) && yearNum >= 1 && yearNum <= 9999;
106
+ }
107
+ function isDayDigitsCompleteValid(dayDigits, monthDigits, yearDigits) {
108
+ if (dayDigits.length !== 2) {
109
+ return false;
110
+ }
111
+ const dayNum = Number.parseInt(dayDigits, 10);
112
+ if (Number.isNaN(dayNum) || dayNum < 1 || dayNum > 31) {
113
+ return false;
114
+ }
115
+ if (monthDigits.length === 2 && yearDigits.length === 4) {
116
+ const monthNum = Number.parseInt(monthDigits, 10);
117
+ const yearNum = Number.parseInt(yearDigits, 10);
118
+ if (Number.isNaN(monthNum) || monthNum < 1 || monthNum > 12 || Number.isNaN(yearNum)) {
119
+ return true;
120
+ }
121
+ const maxDay = getLastDayOfMonth(yearNum, monthNum - 1);
122
+ return dayNum >= 1 && dayNum <= maxDay;
123
+ }
124
+ return true;
125
+ }
126
+ export function isSegmentCompleteValid(segment, state) {
127
+ if (segment === "day") {
128
+ return isDayDigitsCompleteValid(state.dayDigits, state.monthDigits, state.yearDigits);
129
+ }
130
+ if (segment === "month") {
131
+ return isMonthDigitsCompleteValid(state.monthDigits);
132
+ }
133
+ return isYearDigitsCompleteValid(state.yearDigits);
134
+ }
135
+ function clearSegmentDigits(state, segment) {
136
+ return withSegmentDigits(state, segment, "");
137
+ }
138
+ function padSegmentDigitsToWidth(digits, segment) {
139
+ const maxLength = SEGMENT_LENGTH[segment];
140
+ if (digits.length && digits.length < maxLength) {
141
+ return digits.padStart(maxLength, "0");
142
+ }
143
+ return digits;
144
+ }
145
+ export function applySegmentLeaveWhenChangingActiveSegment(state, nextActiveSegment) {
146
+ if (state.activeSegment === nextActiveSegment) {
147
+ return state;
148
+ }
149
+ const segmentLeaving = state.activeSegment;
150
+ let nextState = { ...state };
151
+ const rawDigits = readSegmentDigits(state, segmentLeaving);
152
+ const paddedDigits = padSegmentDigitsToWidth(rawDigits, segmentLeaving);
153
+ if (paddedDigits !== rawDigits) {
154
+ nextState = withSegmentDigits(nextState, segmentLeaving, paddedDigits);
155
+ }
156
+ if (!isSegmentCompleteValid(segmentLeaving, nextState)) {
157
+ nextState = clearSegmentDigits(nextState, segmentLeaving);
158
+ }
159
+ return { ...nextState, activeSegment: nextActiveSegment };
160
+ }
161
+ export function resetIncompleteSegmentsOnBlur(state) {
162
+ let next = {
163
+ ...state,
164
+ dayDigits: padSegmentDigitsToWidth(state.dayDigits, "day"),
165
+ monthDigits: padSegmentDigitsToWidth(state.monthDigits, "month"),
166
+ yearDigits: padSegmentDigitsToWidth(state.yearDigits, "year"),
167
+ };
168
+ if (!isSegmentCompleteValid("day", next)) {
169
+ next = { ...next, dayDigits: "" };
170
+ }
171
+ if (!isSegmentCompleteValid("month", next)) {
172
+ next = { ...next, monthDigits: "" };
173
+ }
174
+ if (!isSegmentCompleteValid("year", next)) {
175
+ next = { ...next, yearDigits: "" };
176
+ }
177
+ return next;
178
+ }
179
+ export function firstIncompleteSegmentForState(state) {
180
+ if (state.dayDigits.length < SEGMENT_LENGTH.day) {
181
+ return "day";
182
+ }
183
+ if (state.monthDigits.length < SEGMENT_LENGTH.month) {
184
+ return "month";
185
+ }
186
+ if (state.yearDigits.length < SEGMENT_LENGTH.year) {
187
+ return "year";
188
+ }
189
+ return "year";
190
+ }
191
+ function appendDigitToSegment(state, digit) {
192
+ const segment = state.activeSegment;
193
+ const maxLength = SEGMENT_LENGTH[segment];
194
+ const current = readSegmentDigits(state, segment);
195
+ if (current.length >= maxLength) {
196
+ return { ...withSegmentDigits(state, segment, digit), activeSegment: segment };
197
+ }
198
+ const nextValue = `${current}${digit}`;
199
+ if (segment === "day" && nextValue.length === 2) {
200
+ const dayNum = Number.parseInt(nextValue, 10);
201
+ if (dayNum < 1 || dayNum > 31) {
202
+ return state;
203
+ }
204
+ }
205
+ if (segment === "month" && nextValue.length === 2) {
206
+ const monthNum = Number.parseInt(nextValue, 10);
207
+ if (monthNum < 1 || monthNum > 12) {
208
+ return state;
209
+ }
210
+ }
211
+ let activeSegment = segment;
212
+ if (nextValue.length >= maxLength && segment !== "year") {
213
+ const advanced = nextSegment(segment);
214
+ if (advanced !== null) {
215
+ activeSegment = advanced;
216
+ }
217
+ }
218
+ return { ...withSegmentDigits(state, segment, nextValue), activeSegment };
219
+ }
220
+ function moveActiveSegmentClamped(state, delta) {
221
+ const currentIndex = segmentToIndex(state.activeSegment);
222
+ const nextIndex = currentIndex + delta;
223
+ if (nextIndex < 0 || nextIndex > SEGMENT_ORDER.length - 1) {
224
+ return state;
225
+ }
226
+ const nextActive = SEGMENT_ORDER[nextIndex];
227
+ if (nextActive === undefined) {
228
+ return state;
229
+ }
230
+ return applySegmentLeaveWhenChangingActiveSegment(state, nextActive);
231
+ }
232
+ function stepMonthDigits(monthDigits, delta) {
233
+ let value = monthDigits.length ? Number.parseInt(monthDigits, 10) : 0;
234
+ if (value === 0 && monthDigits.length === 0) {
235
+ value = delta > 0 ? 0 : 13;
236
+ }
237
+ let nextNum = value + delta;
238
+ nextNum = Math.max(1, Math.min(12, nextNum));
239
+ return String(nextNum).padStart(2, "0");
240
+ }
241
+ function stepYearDigits(yearDigits, delta) {
242
+ const currentYear = new Date().getFullYear();
243
+ if (yearDigits.length === 0) {
244
+ return clampDigits(String(currentYear + delta), 4);
245
+ }
246
+ const padded = yearDigits.padEnd(4, "0");
247
+ let next = Number.parseInt(padded, 10) + delta;
248
+ if (Number.isNaN(next)) {
249
+ next = currentYear + delta;
250
+ }
251
+ next = Math.max(1000, Math.min(9999, next));
252
+ return clampDigits(String(next), 4);
253
+ }
254
+ function withDayDigitsClampedToMonth(state, dayNumber) {
255
+ const maxDay = getMaxDayForDaySegment(state);
256
+ const clamped = Math.max(1, Math.min(maxDay, dayNumber));
257
+ return { ...state, dayDigits: String(clamped).padStart(2, "0") };
258
+ }
259
+ function applyArrowUp(state) {
260
+ if (state.activeSegment === "day") {
261
+ const value = state.dayDigits.length ? Number.parseInt(state.dayDigits, 10) : 0;
262
+ return withDayDigitsClampedToMonth(state, value + 1);
263
+ }
264
+ if (state.activeSegment === "month") {
265
+ return { ...state, monthDigits: stepMonthDigits(state.monthDigits, 1) };
266
+ }
267
+ return { ...state, yearDigits: stepYearDigits(state.yearDigits, 1) };
268
+ }
269
+ function applyArrowDown(state) {
270
+ if (state.activeSegment === "day") {
271
+ let value = state.dayDigits.length ? Number.parseInt(state.dayDigits, 10) : 0;
272
+ if (value === 0 && state.dayDigits.length === 0) {
273
+ value = getMaxDayForDaySegment(state) + 1;
274
+ }
275
+ return withDayDigitsClampedToMonth(state, value - 1);
276
+ }
277
+ if (state.activeSegment === "month") {
278
+ return { ...state, monthDigits: stepMonthDigits(state.monthDigits, -1) };
279
+ }
280
+ return { ...state, yearDigits: stepYearDigits(state.yearDigits, -1) };
281
+ }
282
+ function emptyActiveSegment(state) {
283
+ return withSegmentDigits(state, state.activeSegment, "");
284
+ }
285
+ export function reduceSegmentedDateFieldKey(params) {
286
+ const { state, key, isComposing } = params;
287
+ if (isComposing) {
288
+ return null;
289
+ }
290
+ if (key === ARROW_LEFT_KEY) {
291
+ return moveActiveSegmentClamped(state, -1);
292
+ }
293
+ if (key === ARROW_RIGHT_KEY) {
294
+ return moveActiveSegmentClamped(state, 1);
295
+ }
296
+ if (key === ARROW_UP_KEY) {
297
+ return applyArrowUp(state);
298
+ }
299
+ if (key === ARROW_DOWN_KEY) {
300
+ return applyArrowDown(state);
301
+ }
302
+ if (key === BACKSPACE_KEY || key === DELETE_KEY) {
303
+ return emptyActiveSegment(state);
304
+ }
305
+ if (key.length === 1 && /\d/.test(key)) {
306
+ return appendDigitToSegment(state, key);
307
+ }
308
+ return null;
309
+ }
310
+ export function shouldPreventDefaultSegmentedKey(key) {
311
+ if ([ARROW_LEFT_KEY, ARROW_RIGHT_KEY, ARROW_UP_KEY, ARROW_DOWN_KEY, BACKSPACE_KEY, DELETE_KEY].includes(key)) {
312
+ return true;
313
+ }
314
+ if (key.length === 1 && /\d/.test(key)) {
315
+ return true;
316
+ }
317
+ return false;
318
+ }
@@ -0,0 +1,26 @@
1
+ import { InputProps } from "../common/input-props";
2
+
3
+ export interface FileUploadProps extends Omit<InputProps, "value" | "onChange"> {
4
+ id: string;
5
+ label: string;
6
+ showLabel?: boolean;
7
+ compactSpacing?: boolean;
8
+ multiple?: boolean;
9
+ buttonLabel: string;
10
+ accept?: string;
11
+ onChange?: (files: File[]) => void;
12
+ onUpload?: (file: File) => Promise<void>;
13
+ errorFilesMap?: string[];
14
+ onRemovingFile?: (file: File) => void;
15
+ onUploadingFile?: (file: File) => void;
16
+ showAssistiveText?: boolean;
17
+ }
18
+
19
+ export interface FileItemProps {
20
+ file: File;
21
+ removeFile: () => void;
22
+ isError?: boolean;
23
+ errorMessage?: string;
24
+ compact?: boolean;
25
+ isLoading?: boolean;
26
+ }
@@ -0,0 +1,7 @@
1
+ export declare const getStringWidthFromContext: (ctx: CanvasRenderingContext2D) => (t: string) => number;
2
+ export declare const formatFileSize: (bytes: number) => string;
3
+ export declare const extractFileNameParts: (name: string) => {
4
+ baseName: string;
5
+ fileType: string;
6
+ };
7
+ //# sourceMappingURL=file-upload.util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-upload.util.d.ts","sourceRoot":"","sources":["../../../components/file-upload/file-upload.util.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,yBAAyB,GAAI,KAAK,wBAAwB,MAAM,GAAG,MAAM,WAA6B,CAAC;AAEpH,eAAO,MAAM,cAAc,GAAI,OAAO,MAAM,WAK3C,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,MAAM,MAAM;;;CAKhD,CAAC"}
@@ -0,0 +1,16 @@
1
+ export const getStringWidthFromContext = (ctx) => (t) => ctx.measureText(t).width;
2
+ export const formatFileSize = (bytes) => {
3
+ if (bytes < 1024)
4
+ return `${bytes} o`;
5
+ if (bytes < 1024 ** 2)
6
+ return `${(bytes / 1024).toFixed(2)} Ko`;
7
+ if (bytes < 1024 ** 3)
8
+ return `${(bytes / 1024 ** 2).toFixed(2)} Mo`;
9
+ return `${(bytes / 1024 ** 3).toFixed(2)} Go`;
10
+ };
11
+ export const extractFileNameParts = (name) => {
12
+ const fileTypeIndex = name.lastIndexOf(".");
13
+ const fileType = fileTypeIndex !== -1 ? name.substring(fileTypeIndex) : "";
14
+ const baseName = fileTypeIndex !== -1 ? name.substring(0, fileTypeIndex) : name;
15
+ return { baseName, fileType };
16
+ };
@@ -0,0 +1,2 @@
1
+ export type * from "./file-upload.interface";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../components/file-upload/index.ts"],"names":[],"mappings":"AAAA,mBAAmB,yBAAyB,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -1,5 +1,5 @@
1
1
  export declare const getToastPriority: (toast: {
2
2
  hasActionButton: boolean;
3
3
  type: "info" | "success" | "warning" | "error" | "neutral";
4
- }) => 3 | 2 | 1 | 4 | 9 | 5 | 6 | 7 | 8 | 10;
4
+ }) => 3 | 2 | 1 | 4 | 10 | 8 | 6 | 7 | 9 | 5;
5
5
  //# sourceMappingURL=toast.utils.d.ts.map
package/index.d.ts CHANGED
@@ -16,6 +16,7 @@ export * from "./components/checkbox";
16
16
  export * from "./components/checkbox-group";
17
17
  export * from "./components/chip";
18
18
  export * from "./components/divider";
19
+ export * from "./components/datepicker";
19
20
  export * from "./components/drawer";
20
21
  export * from "./components/dropdown";
21
22
  export * from "./components/grid";
@@ -45,4 +46,5 @@ export * from "./components/stepper";
45
46
  export * from "./components/accordion";
46
47
  export * from "./components/avatar";
47
48
  export * from "./utils";
49
+ export * from "./components/file-upload";
48
50
  //# sourceMappingURL=index.d.ts.map
package/index.js CHANGED
@@ -16,6 +16,7 @@ export * from "./components/checkbox";
16
16
  export * from "./components/checkbox-group";
17
17
  export * from "./components/chip";
18
18
  export * from "./components/divider";
19
+ export * from "./components/datepicker";
19
20
  export * from "./components/drawer";
20
21
  export * from "./components/dropdown";
21
22
  export * from "./components/grid";
@@ -45,3 +46,4 @@ export * from "./components/stepper";
45
46
  export * from "./components/accordion";
46
47
  export * from "./components/avatar";
47
48
  export * from "./utils";
49
+ export * from "./components/file-upload";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@design-system-rte/core",
3
- "version": "1.6.5",
3
+ "version": "1.7.0-rc1",
4
4
  "main": "index.js",
5
5
  "types": "index.d.ts",
6
6
  "files": [
@@ -74,6 +74,10 @@
74
74
  "types": "./components/chip/index.d.ts",
75
75
  "default": "./components/chip/index.js"
76
76
  },
77
+ "./components/datepicker": {
78
+ "types": "./components/datepicker/index.d.ts",
79
+ "default": "./components/datepicker/index.js"
80
+ },
77
81
  "./components/divider": {
78
82
  "types": "./components/divider/index.d.ts",
79
83
  "default": "./components/divider/index.js"
@@ -86,6 +90,10 @@
86
90
  "types": "./components/dropdown/index.d.ts",
87
91
  "default": "./components/dropdown/index.js"
88
92
  },
93
+ "./components/file-upload": {
94
+ "types": "./components/file-upload/index.d.ts",
95
+ "default": "./components/file-upload/index.js"
96
+ },
89
97
  "./components/grid": {
90
98
  "types": "./components/grid/index.d.ts",
91
99
  "default": "./components/grid/index.js"