@navikt/ds-react 1.2.2 → 1.3.0-alpha.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 (134) hide show
  1. package/_docs.json +1119 -319
  2. package/cjs/datepicker/DatePicker.js +122 -0
  3. package/cjs/datepicker/DatePickerInput.js +68 -0
  4. package/cjs/datepicker/DatePickerStandalone.js +80 -0
  5. package/cjs/datepicker/caption/Caption.js +23 -0
  6. package/cjs/datepicker/caption/DropdownCaption.js +36 -0
  7. package/cjs/datepicker/caption/index.js +10 -0
  8. package/cjs/datepicker/caption/package.json +6 -0
  9. package/cjs/datepicker/hooks/index.js +7 -0
  10. package/cjs/datepicker/hooks/package.json +6 -0
  11. package/cjs/datepicker/hooks/useDatepicker.js +101 -0
  12. package/cjs/datepicker/hooks/useRangeDatepicker.js +174 -0
  13. package/cjs/datepicker/index.js +11 -0
  14. package/cjs/datepicker/package.json +6 -0
  15. package/cjs/datepicker/utils/dates-disabled.js +29 -0
  16. package/cjs/datepicker/utils/format-date.js +7 -0
  17. package/cjs/datepicker/utils/get-dates.js +43 -0
  18. package/cjs/datepicker/utils/index.js +19 -0
  19. package/cjs/datepicker/utils/labels.js +59 -0
  20. package/cjs/datepicker/utils/locale.js +21 -0
  21. package/cjs/datepicker/utils/package.json +6 -0
  22. package/cjs/datepicker/utils/parse-date.js +29 -0
  23. package/cjs/datepicker/utils/valid-date.js +8 -0
  24. package/cjs/index.js +1 -0
  25. package/cjs/monthpicker/MonthPicker.js +112 -0
  26. package/cjs/monthpicker/index.js +8 -0
  27. package/cjs/monthpicker/package.json +6 -0
  28. package/cjs/monthpicker/utils/check-dates.js +12 -0
  29. package/cjs/monthpicker/utils/handle-selected.js +17 -0
  30. package/esm/chat/Chat.d.ts +1 -1
  31. package/esm/datepicker/DatePicker.d.ts +107 -0
  32. package/esm/datepicker/DatePicker.js +94 -0
  33. package/esm/datepicker/DatePicker.js.map +1 -0
  34. package/esm/datepicker/DatePickerInput.d.ts +25 -0
  35. package/esm/datepicker/DatePickerInput.js +40 -0
  36. package/esm/datepicker/DatePickerInput.js.map +1 -0
  37. package/esm/datepicker/DatePickerStandalone.d.ts +12 -0
  38. package/esm/datepicker/DatePickerStandalone.js +52 -0
  39. package/esm/datepicker/DatePickerStandalone.js.map +1 -0
  40. package/esm/datepicker/caption/Caption.d.ts +4 -0
  41. package/esm/datepicker/caption/Caption.js +17 -0
  42. package/esm/datepicker/caption/Caption.js.map +1 -0
  43. package/esm/datepicker/caption/DropdownCaption.d.ts +4 -0
  44. package/esm/datepicker/caption/DropdownCaption.js +30 -0
  45. package/esm/datepicker/caption/DropdownCaption.js.map +1 -0
  46. package/esm/datepicker/caption/index.d.ts +2 -0
  47. package/esm/datepicker/caption/index.js +3 -0
  48. package/esm/datepicker/caption/index.js.map +1 -0
  49. package/esm/datepicker/hooks/index.d.ts +2 -0
  50. package/esm/datepicker/hooks/index.js +3 -0
  51. package/esm/datepicker/hooks/index.js.map +1 -0
  52. package/esm/datepicker/hooks/useDatepicker.d.ts +37 -0
  53. package/esm/datepicker/hooks/useDatepicker.js +98 -0
  54. package/esm/datepicker/hooks/useDatepicker.js.map +1 -0
  55. package/esm/datepicker/hooks/useRangeDatepicker.d.ts +36 -0
  56. package/esm/datepicker/hooks/useRangeDatepicker.js +171 -0
  57. package/esm/datepicker/hooks/useRangeDatepicker.js.map +1 -0
  58. package/esm/datepicker/index.d.ts +5 -0
  59. package/esm/datepicker/index.js +3 -0
  60. package/esm/datepicker/index.js.map +1 -0
  61. package/esm/datepicker/utils/dates-disabled.d.ts +1 -0
  62. package/esm/datepicker/utils/dates-disabled.js +26 -0
  63. package/esm/datepicker/utils/dates-disabled.js.map +1 -0
  64. package/esm/datepicker/utils/format-date.d.ts +1 -0
  65. package/esm/datepicker/utils/format-date.js +4 -0
  66. package/esm/datepicker/utils/format-date.js.map +1 -0
  67. package/esm/datepicker/utils/get-dates.d.ts +2 -0
  68. package/esm/datepicker/utils/get-dates.js +39 -0
  69. package/esm/datepicker/utils/get-dates.js.map +1 -0
  70. package/esm/datepicker/utils/index.d.ts +6 -0
  71. package/esm/datepicker/utils/index.js +7 -0
  72. package/esm/datepicker/utils/index.js.map +1 -0
  73. package/esm/datepicker/utils/labels.d.ts +4 -0
  74. package/esm/datepicker/utils/labels.js +55 -0
  75. package/esm/datepicker/utils/labels.js.map +1 -0
  76. package/esm/datepicker/utils/locale.d.ts +2 -0
  77. package/esm/datepicker/utils/locale.js +15 -0
  78. package/esm/datepicker/utils/locale.js.map +1 -0
  79. package/esm/datepicker/utils/parse-date.d.ts +2 -0
  80. package/esm/datepicker/utils/parse-date.js +26 -0
  81. package/esm/datepicker/utils/parse-date.js.map +1 -0
  82. package/esm/datepicker/utils/valid-date.d.ts +2 -0
  83. package/esm/datepicker/utils/valid-date.js +5 -0
  84. package/esm/datepicker/utils/valid-date.js.map +1 -0
  85. package/esm/index.d.ts +1 -0
  86. package/esm/index.js +1 -0
  87. package/esm/index.js.map +1 -1
  88. package/esm/monthpicker/MonthPicker.d.ts +27 -0
  89. package/esm/monthpicker/MonthPicker.js +84 -0
  90. package/esm/monthpicker/MonthPicker.js.map +1 -0
  91. package/esm/monthpicker/index.d.ts +2 -0
  92. package/esm/monthpicker/index.js +2 -0
  93. package/esm/monthpicker/index.js.map +1 -0
  94. package/esm/monthpicker/utils/check-dates.d.ts +2 -0
  95. package/esm/monthpicker/utils/check-dates.js +8 -0
  96. package/esm/monthpicker/utils/check-dates.js.map +1 -0
  97. package/esm/monthpicker/utils/handle-selected.d.ts +3 -0
  98. package/esm/monthpicker/utils/handle-selected.js +12 -0
  99. package/esm/monthpicker/utils/handle-selected.js.map +1 -0
  100. package/package.json +7 -3
  101. package/src/chat/Chat.tsx +1 -1
  102. package/src/chat/chat.stories.tsx +1 -5
  103. package/src/datepicker/DatePicker.tsx +281 -0
  104. package/src/datepicker/DatePickerInput.tsx +131 -0
  105. package/src/datepicker/DatePickerStandalone.tsx +121 -0
  106. package/src/datepicker/caption/Caption.tsx +51 -0
  107. package/src/datepicker/caption/DropdownCaption.tsx +94 -0
  108. package/src/datepicker/caption/index.ts +2 -0
  109. package/src/datepicker/datepicker.stories.mdx +467 -0
  110. package/src/datepicker/datepicker.stories.tsx +257 -0
  111. package/src/datepicker/hooks/index.ts +2 -0
  112. package/src/datepicker/hooks/useDatepicker.tsx +181 -0
  113. package/src/datepicker/hooks/useRangeDatepicker.tsx +285 -0
  114. package/src/datepicker/index.ts +5 -0
  115. package/src/datepicker/utils/__tests__/dates-disabled.test.ts +48 -0
  116. package/src/datepicker/utils/__tests__/format-dates.test.ts +14 -0
  117. package/src/datepicker/utils/__tests__/get-dates.test.ts +79 -0
  118. package/src/datepicker/utils/__tests__/parse-dates.test.ts +81 -0
  119. package/src/datepicker/utils/dates-disabled.ts +26 -0
  120. package/src/datepicker/utils/format-date.ts +5 -0
  121. package/src/datepicker/utils/get-dates.ts +44 -0
  122. package/src/datepicker/utils/index.ts +6 -0
  123. package/src/datepicker/utils/labels.ts +58 -0
  124. package/src/datepicker/utils/locale.ts +15 -0
  125. package/src/datepicker/utils/parse-date.ts +28 -0
  126. package/src/datepicker/utils/valid-date.ts +4 -0
  127. package/src/index.ts +1 -0
  128. package/src/monthpicker/MonthPicker.tsx +238 -0
  129. package/src/monthpicker/index.ts +2 -0
  130. package/src/monthpicker/monthpicker.stories.tsx +35 -0
  131. package/src/monthpicker/utils/__tests__/check-dates.test.ts +34 -0
  132. package/src/monthpicker/utils/__tests__/handle-selected.test.ts +87 -0
  133. package/src/monthpicker/utils/check-dates.ts +15 -0
  134. package/src/monthpicker/utils/handle-selected.ts +26 -0
@@ -0,0 +1,467 @@
1
+ import { Canvas, Meta, Story } from "@storybook/addon-docs";
2
+
3
+ <Meta title="ds-react/Datepicker" />
4
+
5
+ # DatePicker
6
+
7
+ Datepicker er nå klar for testing (Men fortsatt veldig WIP)! Komponenten har ikke blitt ordentlig testet enda, da både kode og UU så bør ikke brukes i prod.
8
+
9
+ ## Single
10
+
11
+ Default-løsning er `mode="single"`. Bare en dag kan velges om gangen da. Bruk `required`-prop hvis bruker MÅ velge en dato
12
+
13
+ ```jsx
14
+ <DatePicker onSelect={(date?: Date) => handleDates(date)}>
15
+ <DatePicker.Input label="Velg dato" />
16
+ </DatePicker>
17
+
18
+ <DatePicker mode="single" onSelect={(date?: Date) => handleDates(date)}>
19
+ <DatePicker.Input label="Velg dato" />
20
+ </DatePicker>
21
+ ```
22
+
23
+ ## Multiple
24
+
25
+ `mode="multiple"` gir muligheten til å velge flere dager. Siden man ikke kan vise flere dager i samme input-felt,
26
+ bør lukke/åpne interaksjonen ikke være `<DatePicker.Input />`
27
+
28
+ ```jsx
29
+ <DatePicker
30
+ mode="multiple"
31
+ open={toggleOpen}
32
+ onClose={() => setToggleOpen(false)}
33
+ onSelect={(dates?: Date[]) => handleDates(dates)}
34
+ min={2}
35
+ max={5}
36
+ >
37
+ <Button onClick={() => setToggleOpen((x) => !x)}>Velg dager</Button>
38
+ </DatePicker>
39
+ ```
40
+
41
+ ## Range
42
+
43
+ `mode="range"` gir muligheten til å velge en periode `{from:Date, to?:Date}`. Bruk da to inputfelt for å vise from/to
44
+
45
+ ```jsx
46
+ <DatePicker mode="range" onSelect={(dates?: DateRange) => handleDates(dates)}>
47
+ <DatePicker.Input label="Fra" />
48
+ <DatePicker.Input label="Til" />
49
+ </DatePicker>
50
+ ```
51
+
52
+ ## useDatepicker
53
+
54
+ For at du ikke skal måtte styre all logikken med date-formatering, fokus, onChange etc har vi egne hooks for dette.
55
+
56
+ `useDatepicker` håndterer alt av Dato-formatering, onChange i input-felter og alle nødvendige datepicker og input-props
57
+
58
+ obs! Du må selv validere valget, evt legge til feilmeldinger i input.
59
+
60
+ ```jsx
61
+ export const demo = () => {
62
+ const { dayPickerProps, selectedDay, inputProps } = useDatepicker({
63
+ fromDate: new Date("Aug 23 2019"),
64
+ });
65
+
66
+ useEffect(() => {
67
+ selectedDay && isValidDate(selectedDay) && console.log(selectedDay);
68
+ }, [selectedDay]);
69
+
70
+ return (
71
+ <DatePicker {...dayPickerProps}>
72
+ <DatePicker.Input {...inputProps} label="Velg dato" />
73
+ </DatePicker>
74
+ );
75
+ };
76
+ ```
77
+
78
+ ## useRangeDatepicker
79
+
80
+ `useRangeDatepicker` har sammen funksjonen som `useDatepicker`, men med muligheten for to inputfelt
81
+
82
+ ```jsx
83
+ export const demo = () => {
84
+ const { dayPickerProps, fromInputProps, toInputProps, selectedRange } =
85
+ useRangeDatepicker({
86
+ fromDate: new Date("Aug 23 2019"),
87
+ });
88
+
89
+ useEffect(() => {
90
+ selectedRange && console.log(selectedRange);
91
+ }, [selectedRange]);
92
+
93
+ return (
94
+ <DatePicker
95
+ {...dayPickerProps}
96
+ classNames={{ wrapper: "input-wrapper-styling" }}
97
+ >
98
+ <DatePicker.Input {...fromInputProps} label="Fra" />
99
+ <DatePicker.Input {...toInputProps} label="Til" />
100
+ </DatePicker>
101
+ );
102
+ };
103
+ ```
104
+
105
+ ## Standalone
106
+
107
+ I noen tilfeller ønsker man å alltid vise DatePicker uten popover, og kan da bruke `Standalone`-versjonen
108
+
109
+ ```jsx
110
+ <DatePicker.Standalone />
111
+ ```
112
+
113
+ ## showWeekNumber
114
+
115
+ Viser ukenummer i venstre-spalte. Obs! DatePicker tar allerede mye plass på mobil, så bør brukes forsiktig
116
+
117
+ ```jsx
118
+ <DatePicker showWeekNumber>
119
+ <DatePicker.Input label="Velg dato" />
120
+ </DatePicker>
121
+ ```
122
+
123
+ ## yearSelector
124
+
125
+ Gir muligheten til å velge år + månede i en `<Select/>`. Vises bare hvis `fromDate` og `toDate` er satt, da man ikke bør vise uendelig med valg.
126
+
127
+ ```jsx
128
+ <DatePicker
129
+ yearSelector
130
+ fromDate={new Date("Aug 23 2018")}
131
+ toDate={new Date("Aug 23 2022")}
132
+ >
133
+ <DatePicker.Input label="Velg dato" />
134
+ </DatePicker>
135
+ ```
136
+
137
+ ## disable-dager
138
+
139
+ Disabled-prop bruker en [Matcher](https://react-day-picker.js.org/api/types/Matcher), som gir mye fleksibilitet når man skal disable dager
140
+
141
+ Kan også sette `disableWeekends`-prop for å sette lørdag + søndag som disabled
142
+
143
+ ```jsx
144
+ const disabledDays = [
145
+ new Date("Aug 10 2022"),
146
+ { from: new Date("Aug 31 2022"), to: new Date("Sep 8 2022") },
147
+ (day: Date) => isDisabled(date),
148
+ ];
149
+
150
+ <DatePicker disabled={disabledDays}>
151
+ <DatePicker.Input label="Velg dato" />
152
+ </DatePicker>;
153
+ ```
154
+
155
+ ## locale
156
+
157
+ DatePicker har innebygd støtte for nb, nn og en(gb)
158
+
159
+ ```jsx
160
+ <DatePicker locale="en">
161
+ <DatePicker.Input label="Pick a date" />
162
+ </DatePicker>
163
+ ```
164
+
165
+ ## Validering
166
+
167
+ ```jsx
168
+ export const Validering = () => {
169
+ const { dayPickerProps, selectedDay, inputProps } = useDatepicker({
170
+ fromDate: new Date("Aug 23 2019"),
171
+ });
172
+
173
+ const [errorState, setErrorState] = useState<string | null>(null);
174
+
175
+ useEffect(() => {
176
+ if (!selectedDay || !isValidDate(selectedDay)) return;
177
+ isSaturday(selectedDay) <- Utility-funksjon i date-fns
178
+ ? setErrorState(
179
+ "NAV-kontoret er ikke åpent på lørdager. Velg en annen dag."
180
+ )
181
+ : setErrorState(null);
182
+ }, [selectedDay]);
183
+
184
+ return (
185
+ <div style={{ display: "flex", gap: "1rem" }}>
186
+ <DatePicker {...dayPickerProps}>
187
+ <DatePicker.Input
188
+ error={errorState}
189
+ {...inputProps}
190
+ label="Velg dato"
191
+ />
192
+ </DatePicker>
193
+ </div>
194
+ );
195
+ };
196
+ ```
197
+
198
+ ## Typer
199
+
200
+ ### Datepicker
201
+
202
+ ```ts
203
+ /**
204
+ * Element datepicker anchors to. Use <DatePicker.Input /> for built-in toggle,
205
+ * or make your own with the open/onClose props
206
+ */
207
+ children?: React.ReactNode;
208
+ /**
209
+ * Changes datepicker locale
210
+ * @default "nb" (norsk bokmål)
211
+ */
212
+ locale?: "nb" | "nn" | "en";
213
+ /**
214
+ * The earliest Date available for the user to pick from
215
+ */
216
+ fromDate?: Date;
217
+ /**
218
+ * The latest Date available for the user to pick from
219
+ */
220
+ toDate?: Date;
221
+ /**
222
+ * Adds a `Select` for picking Year and Month
223
+ * Needs `fromDate` + `toDate` to be set!
224
+ * @default false
225
+ */
226
+ yearSelector?: boolean;
227
+ /**
228
+ * Apply the disabled modifier to the matching days.
229
+ * {@link https://react-day-picker.js.org/api/types/Matcher | Matcher type-definition}
230
+ */
231
+ disabled?: Matcher[];
232
+ /**
233
+ * Disable saturday and sunday.
234
+ * @default false
235
+ */
236
+ disableWeekends?: boolean;
237
+ /**
238
+ * Shows week numbers in left-column
239
+ * Use with caution, takes up valuable screenspace in small screens!
240
+ * @default false
241
+ */
242
+ showWeekNumber?: boolean;
243
+ /**
244
+ * Open state for user-controlled state
245
+ * @remark Controlled by component by default
246
+ */
247
+ open?: boolean;
248
+ /**
249
+ * onClose callback for user-controlled state
250
+ */
251
+ onClose?: () => void;
252
+ /**
253
+ * onOpenToggle callback for user-controlled-state
254
+ * @remark only called if `<DatePicker.Input />` is used
255
+ */
256
+ onOpenToggle?: () => void;
257
+ /**
258
+ * Classnames for adding classes
259
+ */
260
+ classNames?: {
261
+ /**
262
+ * Children wrapper
263
+ */
264
+ wrapper?: string;
265
+ /**
266
+ * DatePicker-wrapper
267
+ */
268
+ datepicker?: string;
269
+ };
270
+
271
+ /**
272
+ * For avansert bruk
273
+ * @private
274
+ */
275
+ month?: Date;
276
+ onMonthChange?: MonthChangeEventHandler;
277
+ today?: Date;
278
+ onDayClick?: DayClickEventHandler;
279
+ ```
280
+
281
+ ### Datepicker.Standalone
282
+
283
+ ```ts
284
+ /**
285
+ * Element datepicker anchors to. Use <DatePicker.Input /> for built-in toggle,
286
+ * or make your own with the open/onClose props
287
+ */
288
+ children?: React.ReactNode;
289
+ /**
290
+ * Changes datepicker locale
291
+ * @default "nb" (norsk bokmål)
292
+ */
293
+ locale?: "nb" | "nn" | "en";
294
+ /**
295
+ * The earliest Date available for the user to pick from
296
+ */
297
+ fromDate?: Date;
298
+ /**
299
+ * The latest Date available for the user to pick from
300
+ */
301
+ toDate?: Date;
302
+ /**
303
+ * Adds a `Select` for picking Year and Month
304
+ * Needs `fromDate` + `toDate` to be set!
305
+ * @default false
306
+ */
307
+ yearSelector?: boolean;
308
+ /**
309
+ * Apply the disabled modifier to the matching days.
310
+ * {@link https://react-day-picker.js.org/api/types/Matcher | Matcher type-definition}
311
+ */
312
+ disabled?: Matcher[];
313
+ /**
314
+ * Disable saturday and sunday.
315
+ * @default false
316
+ */
317
+ disableWeekends?: boolean;
318
+ /**
319
+ * Shows week numbers in left-column
320
+ * Use with caution, takes up valuable screenspace in small screens!
321
+ * @default false
322
+ */
323
+ showWeekNumber?: boolean;
324
+ className?: string;
325
+
326
+ /**
327
+ * For avansert bruk
328
+ * @private
329
+ */
330
+ month?: Date;
331
+ onMonthChange?: MonthChangeEventHandler;
332
+ today?: Date;
333
+ onDayClick?: DayClickEventHandler;
334
+ ```
335
+
336
+ ### DatePicker.Input
337
+
338
+ ```ts
339
+ /**
340
+ * Input label
341
+ */
342
+ label: React.ReactNode;
343
+ /**
344
+ * Shows label and description for screenreaders-only
345
+ * @default false
346
+ */
347
+ hideLabel?: boolean;
348
+ /**
349
+ * Changes padding and font-sizes
350
+ * @default medium
351
+ */
352
+ size?: "medium" | "small";
353
+ /**
354
+ * @private
355
+ */
356
+ wrapperRef: React.RefObject<HTMLDivElement>
357
+ ```
358
+
359
+ ### useDatepicker
360
+
361
+ ```ts
362
+ export interface UseDatepickerOptions
363
+ extends Pick<
364
+ DatePickerProps,
365
+ | "locale"
366
+ | "fromDate"
367
+ | "toDate"
368
+ | "today"
369
+ | "toDate"
370
+ | "fromDate"
371
+ | "toDate"
372
+ > {
373
+ /** The initially selected date */
374
+ defaultSelected?: Date;
375
+ /** Make the selection required. */
376
+ required?: boolean;
377
+ /**
378
+ * Opens datepicker on input-focus
379
+ * @default true
380
+ */
381
+ openOnFocus?: boolean;
382
+ }
383
+ interface UseDatepickerValue {
384
+ /**
385
+ * Use: <DatePicker {...dayPickerProps}/>
386
+ */
387
+ dayPickerProps: DatePickerProps;
388
+ /**
389
+ * Use: <DatePicker.Input {...inputProps}/>
390
+ */
391
+ inputProps: Pick<
392
+ DatePickerInputProps,
393
+ "onChange" | "onFocus" | "onBlur" | "value"
394
+ >;
395
+ /**
396
+ * Resets all states
397
+ */
398
+ reset: () => void;
399
+ /**
400
+ * Selected Date callback
401
+ */
402
+ selectedDay?: Date;
403
+ /**
404
+ * Manually set selected day if needed
405
+ */
406
+ setSelected: (date?: Date) => void;
407
+ }
408
+ ```
409
+
410
+ ### useRangeDatepicker
411
+
412
+ ```ts
413
+ export interface UseRangeDatepickerOptions
414
+ extends Pick<
415
+ DatePickerProps,
416
+ | "locale"
417
+ | "fromDate"
418
+ | "toDate"
419
+ | "today"
420
+ | "toDate"
421
+ | "fromDate"
422
+ | "toDate"
423
+ > {
424
+ /** The initially selected date */
425
+ defaultSelected?: DateRange;
426
+ /** Make the selection required. */
427
+ required?: boolean;
428
+ /**
429
+ * Opens datepicker on input-focus
430
+ * @default true
431
+ */
432
+ openOnFocus?: boolean;
433
+ }
434
+
435
+ interface UseRangeDatepickerValue {
436
+ /**
437
+ * Use: <DatePicker {...dayPickerProps}/>
438
+ */
439
+ dayPickerProps: DatePickerProps;
440
+ /**
441
+ * Use: <DatePicker.Input label="from" {...fromInputProps}/>
442
+ */
443
+ fromInputProps: Pick<
444
+ DatePickerInputProps,
445
+ "onChange" | "onFocus" | "onBlur" | "value"
446
+ >;
447
+ /**
448
+ * Use: <DatePicker.Input label="to" {...toInputProps}/>
449
+ */
450
+ toInputProps: Pick<
451
+ DatePickerInputProps,
452
+ "onChange" | "onFocus" | "onBlur" | "value"
453
+ >;
454
+ /**
455
+ * Resets all states
456
+ */
457
+ reset: () => void;
458
+ /**
459
+ * Selected range-callback
460
+ */
461
+ selectedRange?: DateRange;
462
+ /**
463
+ * Manually set selected range if needed
464
+ */
465
+ setSelected: (date?: DateRange) => void;
466
+ }
467
+ ```
@@ -0,0 +1,257 @@
1
+ import { isSaturday } from "date-fns";
2
+ import React, { useEffect, useId, useState } from "react";
3
+ import { DatePicker, useDatepicker, useRangeDatepicker } from "..";
4
+ import { Button } from "../..";
5
+ import { isValidDate } from "./utils";
6
+
7
+ const disabledDays = [
8
+ new Date("Aug 10 2022"),
9
+ { from: new Date("Aug 31 2022"), to: new Date("Sep 8 2022") },
10
+ ];
11
+
12
+ export default {
13
+ title: "ds-react/Datepicker",
14
+ component: DatePicker,
15
+ argTypes: {
16
+ size: {
17
+ control: {
18
+ type: "radio",
19
+ options: ["medium", "small"],
20
+ },
21
+ },
22
+ locale: {
23
+ control: {
24
+ type: "radio",
25
+ options: ["nb", "nn", "en"],
26
+ },
27
+ },
28
+ mode: {
29
+ defaultValue: "single",
30
+ control: {
31
+ type: "radio",
32
+ options: ["single", "multiple", "range"],
33
+ },
34
+ },
35
+ },
36
+ };
37
+
38
+ export const Default = (props) => {
39
+ const [open, setOpen] = useState(false);
40
+
41
+ const rangeCtx = useRangeDatepicker({
42
+ fromDate: new Date("Aug 23 2020"),
43
+ toDate: new Date("Aug 23 2023"),
44
+ openOnFocus: props.openOnFocus,
45
+ });
46
+
47
+ const singleCtx = useDatepicker({
48
+ fromDate: new Date("Aug 23 2020"),
49
+ toDate: new Date("Aug 23 2023"),
50
+ openOnFocus: props.openOnFocus,
51
+ });
52
+
53
+ const newProps = {
54
+ ...(!props.inputfield || props.mode === "multiple"
55
+ ? {
56
+ open,
57
+ onClose: () => setOpen(false),
58
+ fromDate: new Date("Aug 23 2020"),
59
+ toDate: new Date("Aug 23 2023"),
60
+ }
61
+ : {}),
62
+ };
63
+
64
+ const Comp = !props.standalone ? DatePicker : DatePicker.Standalone;
65
+
66
+ return (
67
+ <div>
68
+ <Comp
69
+ locale={props?.locale}
70
+ yearSelector={props?.yearSelector}
71
+ disableWeekends={props?.disableWeekends}
72
+ showWeekNumber={props.showWeekNumber}
73
+ mode={props.mode}
74
+ {...(props.mode === "single"
75
+ ? singleCtx.dayPickerProps
76
+ : props.mode === "range"
77
+ ? rangeCtx.dayPickerProps
78
+ : {})}
79
+ {...newProps}
80
+ >
81
+ {!props.standalone && (
82
+ <>
83
+ {props.inputfield && props.mode !== "multiple" ? (
84
+ <>
85
+ {props.mode === "range" ? (
86
+ <div style={{ display: "flex", gap: "1rem" }}>
87
+ <DatePicker.Input
88
+ label="Fra"
89
+ size={props?.size}
90
+ {...rangeCtx.fromInputProps}
91
+ />
92
+ <DatePicker.Input
93
+ label="Til"
94
+ size={props?.size}
95
+ {...rangeCtx.toInputProps}
96
+ />
97
+ </div>
98
+ ) : (
99
+ <>
100
+ <DatePicker.Input
101
+ label="Velg dato"
102
+ size={props?.size}
103
+ {...singleCtx.inputProps}
104
+ />
105
+ </>
106
+ )}
107
+ </>
108
+ ) : (
109
+ <Button onClick={() => setOpen((x) => !x)}>
110
+ Åpne datovelger
111
+ </Button>
112
+ )}
113
+ </>
114
+ )}
115
+ </Comp>
116
+ </div>
117
+ );
118
+ };
119
+
120
+ Default.args = {
121
+ yearSelector: false,
122
+ disableWeekends: false,
123
+ showWeekNumber: false,
124
+ inputfield: true,
125
+ standalone: false,
126
+ openOnFocus: true,
127
+ };
128
+
129
+ export const YearSelector = (props) => (
130
+ <div>
131
+ <DatePicker
132
+ yearSelector
133
+ fromDate={new Date("Aug 23 2018")}
134
+ toDate={new Date("Aug 23 2022")}
135
+ >
136
+ <DatePicker.Input label="Velg dato" size={props.size}></DatePicker.Input>
137
+ </DatePicker>
138
+ </div>
139
+ );
140
+
141
+ export const DisabledDays = (props) => (
142
+ <div>
143
+ <DatePicker disabled={disabledDays} disableWeekends locale="en">
144
+ <DatePicker.Input label="Velg dato" size={props.size}></DatePicker.Input>
145
+ </DatePicker>
146
+ </div>
147
+ );
148
+
149
+ export const ShowWeekNumber = (props) => (
150
+ <div>
151
+ <DatePicker showWeekNumber>
152
+ <DatePicker.Input label="Velg dato" size={props.size}></DatePicker.Input>
153
+ </DatePicker>
154
+ </div>
155
+ );
156
+
157
+ export const UseDatepicker = () => {
158
+ const { dayPickerProps, selectedDay, inputProps } = useDatepicker({
159
+ fromDate: new Date("Aug 23 2019"),
160
+ locale: "en",
161
+ openOnFocus: true,
162
+ });
163
+
164
+ useEffect(() => {
165
+ selectedDay && isValidDate(selectedDay) && console.log(selectedDay);
166
+ }, [selectedDay]);
167
+
168
+ return (
169
+ <div style={{ display: "flex", gap: "1rem" }}>
170
+ <DatePicker {...dayPickerProps}>
171
+ <DatePicker.Input {...inputProps} label="Velg dato" />
172
+ </DatePicker>
173
+ </div>
174
+ );
175
+ };
176
+
177
+ export const UseRangedDatepicker = () => {
178
+ const { dayPickerProps, fromInputProps, toInputProps, selectedRange } =
179
+ useRangeDatepicker({
180
+ fromDate: new Date("Aug 23 2019"),
181
+ openOnFocus: true,
182
+ });
183
+
184
+ useEffect(() => {
185
+ selectedRange && console.log(selectedRange);
186
+ }, [selectedRange]);
187
+
188
+ return (
189
+ <div style={{ display: "flex", gap: "1rem" }}>
190
+ <DatePicker {...dayPickerProps}>
191
+ <div style={{ display: "flex", gap: "1rem" }}>
192
+ <DatePicker.Input {...fromInputProps} label="Fra" />
193
+ <DatePicker.Input {...toInputProps} label="Til" />
194
+ </div>
195
+ </DatePicker>
196
+ </div>
197
+ );
198
+ };
199
+
200
+ export const NoPopover = () => (
201
+ <div>
202
+ <DatePicker.Standalone />
203
+ </div>
204
+ );
205
+
206
+ export const UserControlled = () => {
207
+ const [open, setOpen] = useState(false);
208
+ const id = useId();
209
+
210
+ return (
211
+ <div>
212
+ <DatePicker
213
+ mode="multiple"
214
+ open={open}
215
+ onClose={() => setOpen(false)}
216
+ id={id}
217
+ >
218
+ <Button
219
+ aria-controls={id}
220
+ aria-haspopup="grid"
221
+ onClick={() => setOpen((x) => !x)}
222
+ >
223
+ Legg til dager
224
+ </Button>
225
+ </DatePicker>
226
+ </div>
227
+ );
228
+ };
229
+
230
+ export const Validering = () => {
231
+ const { dayPickerProps, selectedDay, inputProps } = useDatepicker({
232
+ fromDate: new Date("Aug 23 2019"),
233
+ });
234
+
235
+ const [errorState, setErrorState] = useState<string | null>(null);
236
+
237
+ useEffect(() => {
238
+ if (!selectedDay || !isValidDate(selectedDay)) return;
239
+ isSaturday(selectedDay)
240
+ ? setErrorState(
241
+ "NAV-kontoret er ikke åpent på lørdager. Velg en annen dag."
242
+ )
243
+ : setErrorState(null);
244
+ }, [selectedDay]);
245
+
246
+ return (
247
+ <div style={{ display: "flex", gap: "1rem" }}>
248
+ <DatePicker {...dayPickerProps}>
249
+ <DatePicker.Input
250
+ error={errorState}
251
+ {...inputProps}
252
+ label="Velg dato"
253
+ />
254
+ </DatePicker>
255
+ </div>
256
+ );
257
+ };
@@ -0,0 +1,2 @@
1
+ export { useDatepicker } from "./useDatepicker";
2
+ export { useRangeDatepicker } from "./useRangeDatepicker";