@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.
- package/_docs.json +1119 -319
- package/cjs/datepicker/DatePicker.js +122 -0
- package/cjs/datepicker/DatePickerInput.js +68 -0
- package/cjs/datepicker/DatePickerStandalone.js +80 -0
- package/cjs/datepicker/caption/Caption.js +23 -0
- package/cjs/datepicker/caption/DropdownCaption.js +36 -0
- package/cjs/datepicker/caption/index.js +10 -0
- package/cjs/datepicker/caption/package.json +6 -0
- package/cjs/datepicker/hooks/index.js +7 -0
- package/cjs/datepicker/hooks/package.json +6 -0
- package/cjs/datepicker/hooks/useDatepicker.js +101 -0
- package/cjs/datepicker/hooks/useRangeDatepicker.js +174 -0
- package/cjs/datepicker/index.js +11 -0
- package/cjs/datepicker/package.json +6 -0
- package/cjs/datepicker/utils/dates-disabled.js +29 -0
- package/cjs/datepicker/utils/format-date.js +7 -0
- package/cjs/datepicker/utils/get-dates.js +43 -0
- package/cjs/datepicker/utils/index.js +19 -0
- package/cjs/datepicker/utils/labels.js +59 -0
- package/cjs/datepicker/utils/locale.js +21 -0
- package/cjs/datepicker/utils/package.json +6 -0
- package/cjs/datepicker/utils/parse-date.js +29 -0
- package/cjs/datepicker/utils/valid-date.js +8 -0
- package/cjs/index.js +1 -0
- package/cjs/monthpicker/MonthPicker.js +112 -0
- package/cjs/monthpicker/index.js +8 -0
- package/cjs/monthpicker/package.json +6 -0
- package/cjs/monthpicker/utils/check-dates.js +12 -0
- package/cjs/monthpicker/utils/handle-selected.js +17 -0
- package/esm/chat/Chat.d.ts +1 -1
- package/esm/datepicker/DatePicker.d.ts +107 -0
- package/esm/datepicker/DatePicker.js +94 -0
- package/esm/datepicker/DatePicker.js.map +1 -0
- package/esm/datepicker/DatePickerInput.d.ts +25 -0
- package/esm/datepicker/DatePickerInput.js +40 -0
- package/esm/datepicker/DatePickerInput.js.map +1 -0
- package/esm/datepicker/DatePickerStandalone.d.ts +12 -0
- package/esm/datepicker/DatePickerStandalone.js +52 -0
- package/esm/datepicker/DatePickerStandalone.js.map +1 -0
- package/esm/datepicker/caption/Caption.d.ts +4 -0
- package/esm/datepicker/caption/Caption.js +17 -0
- package/esm/datepicker/caption/Caption.js.map +1 -0
- package/esm/datepicker/caption/DropdownCaption.d.ts +4 -0
- package/esm/datepicker/caption/DropdownCaption.js +30 -0
- package/esm/datepicker/caption/DropdownCaption.js.map +1 -0
- package/esm/datepicker/caption/index.d.ts +2 -0
- package/esm/datepicker/caption/index.js +3 -0
- package/esm/datepicker/caption/index.js.map +1 -0
- package/esm/datepicker/hooks/index.d.ts +2 -0
- package/esm/datepicker/hooks/index.js +3 -0
- package/esm/datepicker/hooks/index.js.map +1 -0
- package/esm/datepicker/hooks/useDatepicker.d.ts +37 -0
- package/esm/datepicker/hooks/useDatepicker.js +98 -0
- package/esm/datepicker/hooks/useDatepicker.js.map +1 -0
- package/esm/datepicker/hooks/useRangeDatepicker.d.ts +36 -0
- package/esm/datepicker/hooks/useRangeDatepicker.js +171 -0
- package/esm/datepicker/hooks/useRangeDatepicker.js.map +1 -0
- package/esm/datepicker/index.d.ts +5 -0
- package/esm/datepicker/index.js +3 -0
- package/esm/datepicker/index.js.map +1 -0
- package/esm/datepicker/utils/dates-disabled.d.ts +1 -0
- package/esm/datepicker/utils/dates-disabled.js +26 -0
- package/esm/datepicker/utils/dates-disabled.js.map +1 -0
- package/esm/datepicker/utils/format-date.d.ts +1 -0
- package/esm/datepicker/utils/format-date.js +4 -0
- package/esm/datepicker/utils/format-date.js.map +1 -0
- package/esm/datepicker/utils/get-dates.d.ts +2 -0
- package/esm/datepicker/utils/get-dates.js +39 -0
- package/esm/datepicker/utils/get-dates.js.map +1 -0
- package/esm/datepicker/utils/index.d.ts +6 -0
- package/esm/datepicker/utils/index.js +7 -0
- package/esm/datepicker/utils/index.js.map +1 -0
- package/esm/datepicker/utils/labels.d.ts +4 -0
- package/esm/datepicker/utils/labels.js +55 -0
- package/esm/datepicker/utils/labels.js.map +1 -0
- package/esm/datepicker/utils/locale.d.ts +2 -0
- package/esm/datepicker/utils/locale.js +15 -0
- package/esm/datepicker/utils/locale.js.map +1 -0
- package/esm/datepicker/utils/parse-date.d.ts +2 -0
- package/esm/datepicker/utils/parse-date.js +26 -0
- package/esm/datepicker/utils/parse-date.js.map +1 -0
- package/esm/datepicker/utils/valid-date.d.ts +2 -0
- package/esm/datepicker/utils/valid-date.js +5 -0
- package/esm/datepicker/utils/valid-date.js.map +1 -0
- package/esm/index.d.ts +1 -0
- package/esm/index.js +1 -0
- package/esm/index.js.map +1 -1
- package/esm/monthpicker/MonthPicker.d.ts +27 -0
- package/esm/monthpicker/MonthPicker.js +84 -0
- package/esm/monthpicker/MonthPicker.js.map +1 -0
- package/esm/monthpicker/index.d.ts +2 -0
- package/esm/monthpicker/index.js +2 -0
- package/esm/monthpicker/index.js.map +1 -0
- package/esm/monthpicker/utils/check-dates.d.ts +2 -0
- package/esm/monthpicker/utils/check-dates.js +8 -0
- package/esm/monthpicker/utils/check-dates.js.map +1 -0
- package/esm/monthpicker/utils/handle-selected.d.ts +3 -0
- package/esm/monthpicker/utils/handle-selected.js +12 -0
- package/esm/monthpicker/utils/handle-selected.js.map +1 -0
- package/package.json +7 -3
- package/src/chat/Chat.tsx +1 -1
- package/src/chat/chat.stories.tsx +1 -5
- package/src/datepicker/DatePicker.tsx +281 -0
- package/src/datepicker/DatePickerInput.tsx +131 -0
- package/src/datepicker/DatePickerStandalone.tsx +121 -0
- package/src/datepicker/caption/Caption.tsx +51 -0
- package/src/datepicker/caption/DropdownCaption.tsx +94 -0
- package/src/datepicker/caption/index.ts +2 -0
- package/src/datepicker/datepicker.stories.mdx +467 -0
- package/src/datepicker/datepicker.stories.tsx +257 -0
- package/src/datepicker/hooks/index.ts +2 -0
- package/src/datepicker/hooks/useDatepicker.tsx +181 -0
- package/src/datepicker/hooks/useRangeDatepicker.tsx +285 -0
- package/src/datepicker/index.ts +5 -0
- package/src/datepicker/utils/__tests__/dates-disabled.test.ts +48 -0
- package/src/datepicker/utils/__tests__/format-dates.test.ts +14 -0
- package/src/datepicker/utils/__tests__/get-dates.test.ts +79 -0
- package/src/datepicker/utils/__tests__/parse-dates.test.ts +81 -0
- package/src/datepicker/utils/dates-disabled.ts +26 -0
- package/src/datepicker/utils/format-date.ts +5 -0
- package/src/datepicker/utils/get-dates.ts +44 -0
- package/src/datepicker/utils/index.ts +6 -0
- package/src/datepicker/utils/labels.ts +58 -0
- package/src/datepicker/utils/locale.ts +15 -0
- package/src/datepicker/utils/parse-date.ts +28 -0
- package/src/datepicker/utils/valid-date.ts +4 -0
- package/src/index.ts +1 -0
- package/src/monthpicker/MonthPicker.tsx +238 -0
- package/src/monthpicker/index.ts +2 -0
- package/src/monthpicker/monthpicker.stories.tsx +35 -0
- package/src/monthpicker/utils/__tests__/check-dates.test.ts +34 -0
- package/src/monthpicker/utils/__tests__/handle-selected.test.ts +87 -0
- package/src/monthpicker/utils/check-dates.ts +15 -0
- 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
|
+
};
|