@fremtind/jokul 0.11.0 → 0.12.1
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/README.md +76 -0
- package/build/NativeSelect-CNcZmpDZ.cjs +2 -0
- package/build/{NativeSelect-BxgwmRDc.cjs.map → NativeSelect-CNcZmpDZ.cjs.map} +1 -1
- package/build/NativeSelect-CfNZEQF0.js +2 -0
- package/build/{NativeSelect-DwtOOfyt.js.map → NativeSelect-CfNZEQF0.js.map} +1 -1
- package/build/build-stats.html +1 -1
- package/build/cjs/components/datepicker/DatePicker.js +1 -1
- package/build/cjs/components/datepicker/DatePicker.js.map +1 -1
- package/build/cjs/components/datepicker/internal/Calendar.js +1 -1
- package/build/cjs/components/datepicker/internal/Calendar.js.map +1 -1
- package/build/cjs/components/feedback/Feedback.js +2 -0
- package/build/cjs/components/feedback/Feedback.js.map +1 -0
- package/build/cjs/components/feedback/FeedbackSuccess.js +2 -0
- package/build/cjs/components/feedback/FeedbackSuccess.js.map +1 -0
- package/build/cjs/components/feedback/FeedbackValues.js +2 -0
- package/build/cjs/components/feedback/FeedbackValues.js.map +1 -0
- package/build/cjs/components/feedback/feedbackContext.js +2 -0
- package/build/cjs/components/feedback/feedbackContext.js.map +1 -0
- package/build/cjs/components/feedback/followup/Followup.js +2 -0
- package/build/cjs/components/feedback/followup/Followup.js.map +1 -0
- package/build/cjs/components/feedback/followup/followupContext.js +2 -0
- package/build/cjs/components/feedback/followup/followupContext.js.map +1 -0
- package/build/cjs/components/feedback/followup/useFollowup.js +2 -0
- package/build/cjs/components/feedback/followup/useFollowup.js.map +1 -0
- package/build/cjs/components/feedback/index.js +2 -0
- package/build/cjs/components/feedback/index.js.map +1 -0
- package/build/cjs/components/feedback/main-question/MainQuestion.js +2 -0
- package/build/cjs/components/feedback/main-question/MainQuestion.js.map +1 -0
- package/build/cjs/components/feedback/main-question/mainQuestionContext.js +2 -0
- package/build/cjs/components/feedback/main-question/mainQuestionContext.js.map +1 -0
- package/build/cjs/components/feedback/main-question/useMainQuestion.js +2 -0
- package/build/cjs/components/feedback/main-question/useMainQuestion.js.map +1 -0
- package/build/cjs/components/feedback/presets.js +2 -0
- package/build/cjs/components/feedback/presets.js.map +1 -0
- package/build/cjs/components/feedback/questions/AddonQuestion.js +2 -0
- package/build/cjs/components/feedback/questions/AddonQuestion.js.map +1 -0
- package/build/cjs/components/feedback/questions/CheckboxQuestion.js +2 -0
- package/build/cjs/components/feedback/questions/CheckboxQuestion.js.map +1 -0
- package/build/cjs/components/feedback/questions/ContactQuestion.js +2 -0
- package/build/cjs/components/feedback/questions/ContactQuestion.js.map +1 -0
- package/build/cjs/components/feedback/questions/RadioQuestion.js +2 -0
- package/build/cjs/components/feedback/questions/RadioQuestion.js.map +1 -0
- package/build/cjs/components/feedback/questions/SmileyQuestion.js +2 -0
- package/build/cjs/components/feedback/questions/SmileyQuestion.js.map +1 -0
- package/build/cjs/components/feedback/questions/TextQuestion.js +2 -0
- package/build/cjs/components/feedback/questions/TextQuestion.js.map +1 -0
- package/build/cjs/components/feedback/questions/index.js +2 -0
- package/build/cjs/components/feedback/questions/index.js.map +1 -0
- package/build/cjs/components/feedback/questions/smileyUtils.js +2 -0
- package/build/cjs/components/feedback/questions/smileyUtils.js.map +1 -0
- package/build/cjs/components/feedback/types.js +2 -0
- package/build/cjs/components/feedback/types.js.map +1 -0
- package/build/cjs/components/feedback/utils.js +2 -0
- package/build/cjs/components/feedback/utils.js.map +1 -0
- package/build/cjs/components/index.js +1 -1
- package/build/cjs/components/message/DismissButton.js +2 -0
- package/build/cjs/components/message/DismissButton.js.map +1 -0
- package/build/cjs/components/message/FormErrorMessage.js +2 -0
- package/build/cjs/components/message/FormErrorMessage.js.map +1 -0
- package/build/cjs/components/message/Message.js +2 -0
- package/build/cjs/components/message/Message.js.map +1 -0
- package/build/cjs/components/message/index.js +2 -0
- package/build/cjs/components/message/index.js.map +1 -0
- package/build/cjs/components/select/NativeSelect.js +1 -1
- package/build/cjs/components/select/Select.js +1 -1
- package/build/cjs/components/select/index.js +1 -1
- package/build/cjs/components/text-input/BaseTextInput.js +1 -1
- package/build/cjs/components/text-input/BaseTextInput.js.map +1 -1
- package/build/cjs/components/text-input/TextArea.js +1 -1
- package/build/cjs/components/text-input/TextArea.js.map +1 -1
- package/build/cjs/components/text-input/TextInput.js +1 -1
- package/build/cjs/components/text-input/TextInput.js.map +1 -1
- package/build/cjs/index.js +1 -1
- package/build/cjs/utilities/index.js +1 -1
- package/build/cjs/utilities/validators/hasMinimumWords/hasMinimumWords.js +2 -0
- package/build/cjs/utilities/validators/hasMinimumWords/hasMinimumWords.js.map +1 -0
- package/build/cjs/utilities/validators/hasNoIllegalCharacters/hasNoIllegalCharacters.js +2 -0
- package/build/cjs/utilities/validators/hasNoIllegalCharacters/hasNoIllegalCharacters.js.map +1 -0
- package/build/cjs/utilities/validators/index.js +2 -0
- package/build/cjs/utilities/validators/index.js.map +1 -0
- package/build/cjs/utilities/validators/isExactLength/isExactLength.js +2 -0
- package/build/cjs/utilities/validators/isExactLength/isExactLength.js.map +1 -0
- package/build/cjs/utilities/validators/isInteger/isInteger.js +2 -0
- package/build/cjs/utilities/validators/isInteger/isInteger.js.map +1 -0
- package/build/cjs/utilities/validators/isValidChassisnummer/isValidChassisnummer.js +2 -0
- package/build/cjs/utilities/validators/isValidChassisnummer/isValidChassisnummer.js.map +1 -0
- package/build/cjs/utilities/validators/isValidDogId/isValidDogId.js +2 -0
- package/build/cjs/utilities/validators/isValidDogId/isValidDogId.js.map +1 -0
- package/build/cjs/utilities/validators/isValidEpost/isValidEpost.js +2 -0
- package/build/cjs/utilities/validators/isValidEpost/isValidEpost.js.map +1 -0
- package/build/cjs/utilities/validators/isValidFodselsnummer/isValidFodselsnummer.js +2 -0
- package/build/cjs/utilities/validators/isValidFodselsnummer/isValidFodselsnummer.js.map +1 -0
- package/build/cjs/utilities/validators/isValidKortnummer/isValidKortnummer.js +2 -0
- package/build/cjs/utilities/validators/isValidKortnummer/isValidKortnummer.js.map +1 -0
- package/build/cjs/utilities/validators/isValidName/isValidName.js +2 -0
- package/build/cjs/utilities/validators/isValidName/isValidName.js.map +1 -0
- package/build/cjs/utilities/validators/isValidOrganisasjonsnummer/isValidOrganisasjonsnummer.js +2 -0
- package/build/cjs/utilities/validators/isValidOrganisasjonsnummer/isValidOrganisasjonsnummer.js.map +1 -0
- package/build/cjs/utilities/validators/isValidRegistreringsnummer/isValidRegistreringsnummer.js +2 -0
- package/build/cjs/utilities/validators/isValidRegistreringsnummer/isValidRegistreringsnummer.js.map +1 -0
- package/build/cjs/utilities/validators/isValidTelefonnummer/isValidTelefonnummer.js +2 -0
- package/build/cjs/utilities/validators/isValidTelefonnummer/isValidTelefonnummer.js.map +1 -0
- package/build/components/feedback/Feedback.d.ts +42 -0
- package/build/components/feedback/FeedbackSuccess.d.ts +3 -0
- package/build/components/feedback/FeedbackValues.d.ts +6 -0
- package/build/components/feedback/feedbackContext.d.ts +19 -0
- package/build/components/feedback/followup/Followup.d.ts +14 -0
- package/build/components/feedback/followup/followupContext.d.ts +9 -0
- package/build/components/feedback/followup/useFollowup.d.ts +19 -0
- package/build/components/feedback/index.d.ts +3 -0
- package/build/components/feedback/main-question/MainQuestion.d.ts +16 -0
- package/build/components/feedback/main-question/mainQuestionContext.d.ts +9 -0
- package/build/components/feedback/main-question/useMainQuestion.d.ts +13 -0
- package/build/components/feedback/presets.d.ts +6 -0
- package/build/components/feedback/questions/AddonQuestion.d.ts +7 -0
- package/build/components/feedback/questions/CheckboxQuestion.d.ts +3 -0
- package/build/components/feedback/questions/ContactQuestion.d.ts +28 -0
- package/build/components/feedback/questions/RadioQuestion.d.ts +3 -0
- package/build/components/feedback/questions/SmileyQuestion.d.ts +3 -0
- package/build/components/feedback/questions/TextQuestion.d.ts +3 -0
- package/build/components/feedback/questions/index.d.ts +6 -0
- package/build/components/feedback/questions/smileyUtils.d.ts +4 -0
- package/build/components/feedback/types.d.ts +86 -0
- package/build/components/feedback/utils.d.ts +4 -0
- package/build/components/index.d.ts +2 -0
- package/build/components/message/DismissButton.d.ts +5 -0
- package/build/components/message/FormErrorMessage.d.ts +14 -0
- package/build/components/message/Message.d.ts +19 -0
- package/build/components/message/index.d.ts +2 -0
- package/build/es/components/datepicker/DatePicker.js +1 -1
- package/build/es/components/datepicker/DatePicker.js.map +1 -1
- package/build/es/components/datepicker/internal/Calendar.js +1 -1
- package/build/es/components/datepicker/internal/Calendar.js.map +1 -1
- package/build/es/components/feedback/Feedback.js +2 -0
- package/build/es/components/feedback/Feedback.js.map +1 -0
- package/build/es/components/feedback/FeedbackSuccess.js +2 -0
- package/build/es/components/feedback/FeedbackSuccess.js.map +1 -0
- package/build/es/components/feedback/FeedbackValues.js +2 -0
- package/build/es/components/feedback/FeedbackValues.js.map +1 -0
- package/build/es/components/feedback/feedbackContext.js +2 -0
- package/build/es/components/feedback/feedbackContext.js.map +1 -0
- package/build/es/components/feedback/followup/Followup.js +2 -0
- package/build/es/components/feedback/followup/Followup.js.map +1 -0
- package/build/es/components/feedback/followup/followupContext.js +2 -0
- package/build/es/components/feedback/followup/followupContext.js.map +1 -0
- package/build/es/components/feedback/followup/useFollowup.js +2 -0
- package/build/es/components/feedback/followup/useFollowup.js.map +1 -0
- package/build/es/components/feedback/index.js +2 -0
- package/build/es/components/feedback/index.js.map +1 -0
- package/build/es/components/feedback/main-question/MainQuestion.js +2 -0
- package/build/es/components/feedback/main-question/MainQuestion.js.map +1 -0
- package/build/es/components/feedback/main-question/mainQuestionContext.js +2 -0
- package/build/es/components/feedback/main-question/mainQuestionContext.js.map +1 -0
- package/build/es/components/feedback/main-question/useMainQuestion.js +2 -0
- package/build/es/components/feedback/main-question/useMainQuestion.js.map +1 -0
- package/build/es/components/feedback/presets.js +2 -0
- package/build/es/components/feedback/presets.js.map +1 -0
- package/build/es/components/feedback/questions/AddonQuestion.js +2 -0
- package/build/es/components/feedback/questions/AddonQuestion.js.map +1 -0
- package/build/es/components/feedback/questions/CheckboxQuestion.js +2 -0
- package/build/es/components/feedback/questions/CheckboxQuestion.js.map +1 -0
- package/build/es/components/feedback/questions/ContactQuestion.js +2 -0
- package/build/es/components/feedback/questions/ContactQuestion.js.map +1 -0
- package/build/es/components/feedback/questions/RadioQuestion.js +2 -0
- package/build/es/components/feedback/questions/RadioQuestion.js.map +1 -0
- package/build/es/components/feedback/questions/SmileyQuestion.js +2 -0
- package/build/es/components/feedback/questions/SmileyQuestion.js.map +1 -0
- package/build/es/components/feedback/questions/TextQuestion.js +2 -0
- package/build/es/components/feedback/questions/TextQuestion.js.map +1 -0
- package/build/es/components/feedback/questions/index.js +2 -0
- package/build/es/components/feedback/questions/index.js.map +1 -0
- package/build/es/components/feedback/questions/smileyUtils.js +2 -0
- package/build/es/components/feedback/questions/smileyUtils.js.map +1 -0
- package/build/es/components/feedback/types.js +2 -0
- package/build/es/components/feedback/types.js.map +1 -0
- package/build/es/components/feedback/utils.js +2 -0
- package/build/es/components/feedback/utils.js.map +1 -0
- package/build/es/components/index.js +1 -1
- package/build/es/components/message/DismissButton.js +2 -0
- package/build/es/components/message/DismissButton.js.map +1 -0
- package/build/es/components/message/FormErrorMessage.js +2 -0
- package/build/es/components/message/FormErrorMessage.js.map +1 -0
- package/build/es/components/message/Message.js +2 -0
- package/build/es/components/message/Message.js.map +1 -0
- package/build/es/components/message/index.js +2 -0
- package/build/es/components/message/index.js.map +1 -0
- package/build/es/components/select/NativeSelect.js +1 -1
- package/build/es/components/select/Select.js +1 -1
- package/build/es/components/select/index.js +1 -1
- package/build/es/components/text-input/BaseTextInput.js +1 -1
- package/build/es/components/text-input/BaseTextInput.js.map +1 -1
- package/build/es/components/text-input/TextArea.js +1 -1
- package/build/es/components/text-input/TextArea.js.map +1 -1
- package/build/es/components/text-input/TextInput.js +1 -1
- package/build/es/components/text-input/TextInput.js.map +1 -1
- package/build/es/index.js +1 -1
- package/build/es/utilities/index.js +1 -1
- package/build/es/utilities/validators/hasMinimumWords/hasMinimumWords.js +2 -0
- package/build/es/utilities/validators/hasMinimumWords/hasMinimumWords.js.map +1 -0
- package/build/es/utilities/validators/hasNoIllegalCharacters/hasNoIllegalCharacters.js +2 -0
- package/build/es/utilities/validators/hasNoIllegalCharacters/hasNoIllegalCharacters.js.map +1 -0
- package/build/es/utilities/validators/index.js +2 -0
- package/build/es/utilities/validators/index.js.map +1 -0
- package/build/es/utilities/validators/isExactLength/isExactLength.js +2 -0
- package/build/es/utilities/validators/isExactLength/isExactLength.js.map +1 -0
- package/build/es/utilities/validators/isInteger/isInteger.js +2 -0
- package/build/es/utilities/validators/isInteger/isInteger.js.map +1 -0
- package/build/es/utilities/validators/isValidChassisnummer/isValidChassisnummer.js +2 -0
- package/build/es/utilities/validators/isValidChassisnummer/isValidChassisnummer.js.map +1 -0
- package/build/es/utilities/validators/isValidDogId/isValidDogId.js +2 -0
- package/build/es/utilities/validators/isValidDogId/isValidDogId.js.map +1 -0
- package/build/es/utilities/validators/isValidEpost/isValidEpost.js +2 -0
- package/build/es/utilities/validators/isValidEpost/isValidEpost.js.map +1 -0
- package/build/es/utilities/validators/isValidFodselsnummer/isValidFodselsnummer.js +2 -0
- package/build/es/utilities/validators/isValidFodselsnummer/isValidFodselsnummer.js.map +1 -0
- package/build/es/utilities/validators/isValidKortnummer/isValidKortnummer.js +2 -0
- package/build/es/utilities/validators/isValidKortnummer/isValidKortnummer.js.map +1 -0
- package/build/es/utilities/validators/isValidName/isValidName.js +2 -0
- package/build/es/utilities/validators/isValidName/isValidName.js.map +1 -0
- package/build/es/utilities/validators/isValidOrganisasjonsnummer/isValidOrganisasjonsnummer.js +2 -0
- package/build/es/utilities/validators/isValidOrganisasjonsnummer/isValidOrganisasjonsnummer.js.map +1 -0
- package/build/es/utilities/validators/isValidRegistreringsnummer/isValidRegistreringsnummer.js +2 -0
- package/build/es/utilities/validators/isValidRegistreringsnummer/isValidRegistreringsnummer.js.map +1 -0
- package/build/es/utilities/validators/isValidTelefonnummer/isValidTelefonnummer.js +2 -0
- package/build/es/utilities/validators/isValidTelefonnummer/isValidTelefonnummer.js.map +1 -0
- package/build/utilities/index.d.ts +1 -0
- package/build/utilities/validators/hasMinimumWords/hasMinimumWords.d.ts +10 -0
- package/build/utilities/validators/hasNoIllegalCharacters/hasNoIllegalCharacters.d.ts +7 -0
- package/build/utilities/validators/index.d.ts +12 -0
- package/build/utilities/validators/isExactLength/isExactLength.d.ts +7 -0
- package/build/utilities/validators/isInteger/isInteger.d.ts +7 -0
- package/build/utilities/validators/isValidChassisnummer/isValidChassisnummer.d.ts +7 -0
- package/build/utilities/validators/isValidDogId/isValidDogId.d.ts +7 -0
- package/build/utilities/validators/isValidEpost/isValidEpost.d.ts +7 -0
- package/build/utilities/validators/isValidFodselsnummer/isValidFodselsnummer.d.ts +30 -0
- package/build/utilities/validators/isValidKortnummer/isValidKortnummer.d.ts +6 -0
- package/build/utilities/validators/isValidName/isValidName.d.ts +7 -0
- package/build/utilities/validators/isValidOrganisasjonsnummer/isValidOrganisasjonsnummer.d.ts +6 -0
- package/build/utilities/validators/isValidRegistreringsnummer/isValidRegistreringsnummer.d.ts +12 -0
- package/build/utilities/validators/isValidTelefonnummer/isValidTelefonnummer.d.ts +7 -0
- package/package.json +6 -2
- package/src/components/button/styles/button.css +4 -4
- package/src/components/button/styles/button.min.css +1 -1
- package/src/components/checkbox/styles/checkbox.css +4 -4
- package/src/components/checkbox/styles/checkbox.min.css +1 -1
- package/src/components/feedback/styles/_index.scss +1 -0
- package/src/components/feedback/styles/feedback.css +104 -0
- package/src/components/feedback/styles/feedback.min.css +1 -0
- package/src/components/feedback/styles/feedback.scss +103 -0
- package/src/components/loader/styles/loader.css +6 -6
- package/src/components/loader/styles/loader.min.css +1 -1
- package/src/components/loader/styles/skeleton-loader.css +5 -5
- package/src/components/loader/styles/skeleton-loader.min.css +1 -1
- package/src/components/message/styles/_index.scss +1 -0
- package/src/components/message/styles/message.css +203 -0
- package/src/components/message/styles/message.min.css +1 -0
- package/src/components/message/styles/message.scss +180 -0
- package/src/components/radio-button/styles/radio-button.css +2 -2
- package/src/components/radio-button/styles/radio-button.min.css +1 -1
- package/src/components/tooltip/styles/tooltip.css +15 -0
- package/src/components/tooltip/styles/tooltip.min.css +1 -1
- package/src/components/tooltip/styles/tooltip.scss +16 -0
- package/build/NativeSelect-BxgwmRDc.cjs +0 -2
- package/build/NativeSelect-DwtOOfyt.js +0 -2
|
@@ -6,6 +6,7 @@ export * from './checkbox';
|
|
|
6
6
|
export * from './combobox';
|
|
7
7
|
export * from './cookie-consent';
|
|
8
8
|
export * from './datepicker';
|
|
9
|
+
export * from './feedback';
|
|
9
10
|
export * from './icon';
|
|
10
11
|
export * from './icon-button';
|
|
11
12
|
export * from './image';
|
|
@@ -14,6 +15,7 @@ export * from './link';
|
|
|
14
15
|
export * from './link-list';
|
|
15
16
|
export * from './list';
|
|
16
17
|
export * from './loader';
|
|
18
|
+
export * from './message';
|
|
17
19
|
export * from './modal';
|
|
18
20
|
export * from './popover';
|
|
19
21
|
export * from './radio-button';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { default as React, ButtonHTMLAttributes } from 'react';
|
|
2
|
+
export interface DismissButtonProps extends Exclude<ButtonHTMLAttributes<HTMLButtonElement>, "disabled"> {
|
|
3
|
+
label?: string;
|
|
4
|
+
}
|
|
5
|
+
export declare const DismissButton: React.ForwardRefExoticComponent<DismissButtonProps & React.RefAttributes<HTMLButtonElement>>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { MessageProps } from './Message';
|
|
3
|
+
export interface FormErrorMessageProps {
|
|
4
|
+
className?: string;
|
|
5
|
+
id?: string;
|
|
6
|
+
/**
|
|
7
|
+
* @default { title: "Feil og mangler i skjemaet" }
|
|
8
|
+
*/
|
|
9
|
+
messageProps?: Partial<MessageProps>;
|
|
10
|
+
errors: (string | undefined)[];
|
|
11
|
+
isSubmitted: boolean;
|
|
12
|
+
isValid: boolean;
|
|
13
|
+
}
|
|
14
|
+
export declare const FormErrorMessage: React.ForwardRefExoticComponent<FormErrorMessageProps & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { default as React, AriaRole } from 'react';
|
|
2
|
+
import { Density, WithChildren } from '../..';
|
|
3
|
+
export interface MessageProps extends WithChildren {
|
|
4
|
+
id?: string;
|
|
5
|
+
title?: string;
|
|
6
|
+
fullWidth?: boolean;
|
|
7
|
+
density?: Density;
|
|
8
|
+
className?: string;
|
|
9
|
+
dismissed?: boolean;
|
|
10
|
+
dismissAction?: {
|
|
11
|
+
handleDismiss: () => void;
|
|
12
|
+
buttonTitle?: string;
|
|
13
|
+
};
|
|
14
|
+
role?: AriaRole;
|
|
15
|
+
}
|
|
16
|
+
export declare const InfoMessage: React.ForwardRefExoticComponent<MessageProps & React.RefAttributes<HTMLDivElement>>;
|
|
17
|
+
export declare const ErrorMessage: React.ForwardRefExoticComponent<MessageProps & React.RefAttributes<HTMLDivElement>>;
|
|
18
|
+
export declare const WarningMessage: React.ForwardRefExoticComponent<MessageProps & React.RefAttributes<HTMLDivElement>>;
|
|
19
|
+
export declare const SuccessMessage: React.ForwardRefExoticComponent<MessageProps & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{jsx as o,jsxs as e}from"react/jsx-runtime";import t
|
|
1
|
+
import{jsx as o,jsxs as e}from"react/jsx-runtime";import{c as t}from"../../../clsx-BeLtu-UY.js";import n from"date-fns/startOfDay";import{forwardRef as r,useState as i,useRef as s,useCallback as a}from"react";import{flushSync as c}from"react-dom";import{useAnimatedHeight as l}from"../../hooks/useAnimatedHeight/useAnimatedHeight.js";import"../../hooks/useScreen/useScreen.js";import{useClickOutside as p}from"../../hooks/useClickOutside/useClickOutside.js";import{useFocusOutside as u}from"../../hooks/useFocusOutside/useFocusOutside.js";import"../../hooks/useId/useId.js";import{useKeyListener as m}from"../../hooks/useKeyListener/useKeyListener.js";import"../icon/Icon.js";import"../icon/icons/animated/ArrowVerticalAnimated.js";import"../icon/icons/animated/ArrowHorizontalAnimated.js";import"../icon/icons/animated/PlusRemoveAnimated.js";import"../icon/icons/ArrowDownIcon.js";import"../icon/icons/ArrowLeftIcon.js";import"../icon/icons/ArrowNorthEastIcon.js";import"../icon/icons/ArrowRightIcon.js";import"../icon/icons/ArrowUpIcon.js";import{CalendarIcon as d}from"../icon/icons/CalendarIcon.js";import"../icon/icons/CheckIcon.js";import"../icon/icons/ChevronDownIcon.js";import"../icon/icons/ChevronLeftIcon.js";import"../icon/icons/ChevronRightIcon.js";import"../icon/icons/ChevronUpIcon.js";import"../icon/icons/CloseIcon.js";import"../icon/icons/CopyIcon.js";import"../icon/icons/DotsIcon.js";import"../icon/icons/DragIcon.js";import"../icon/icons/ErrorIcon.js";import"../icon/icons/GreenCheckIcon.js";import"../icon/icons/HamburgerIcon.js";import"../icon/icons/InfoIcon.js";import"../icon/icons/LinkIcon.js";import"../icon/icons/PlusIcon.js";import"../icon/icons/QuestionIcon.js";import"../icon/icons/RedCrossIcon.js";import"../icon/icons/SearchIcon.js";import"../icon/icons/SuccessIcon.js";import"../icon/icons/WarningIcon.js";import"../icon/icons/MinusIcon.js";import"../icon/icons/ThumbDownIcon.js";import"../icon/icons/ThumbUpIcon.js";import"../icon/icons/TrashCanIcon.js";import"../icon/icons/PenIcon.js";import"../tooltip/Tooltip.js";import"../tooltip/TooltipContent.js";import"../tooltip/TooltipTrigger.js";import{InputGroup as j}from"../input-group/InputGroup.js";import"../text-input/BaseTextArea.js";import{BaseTextInput as f}from"../text-input/BaseTextInput.js";import"../text-input/TextArea.js";import"../text-input/TextInput.js";import{Calendar as h}from"./internal/Calendar.js";import{getInitialDate as I}from"./internal/utils.js";import{parseDateString as k,formatInput as v}from"./utils.js";import{isWithinLowerBound as y,isWithinUpperBound as D}from"./validation.js";const b=r(((r,b)=>{const{"data-testautoid":g,id:w,className:C="",label:L="Velg dato",labelProps:T,defaultValue:x,defaultShow:A=!1,value:O,disableBeforeDate:P,disableAfterDate:_,yearsToShow:E,name:S,helpLabel:N,errorLabel:R,invalid:B,density:U,days:K,months:H,monthLabel:V,yearLabel:F,placeholder:W="dd.mm.åååå",width:G="11.25rem",onChange:M,onBlur:q,onFocus:z,onKeyDown:Q,action:J,showCalendarLabel:X="Åpne kalender",hideCalendarLabel:Y="Lukk kalender",supportLabelProps:Z,tooltipProps:$,...oo}=r;"production"!==process.env.NODE_ENV&&O&&x&&console.warn("DatePicker må enten være controlled eller uncontrolled. Hvis du bruker defaultValue og value sammen vil defaultValue bli ignorert.");const eo=k(P),to=eo?n(eo):void 0,no=k(_),ro=no?n(no):void 0,[io,so]=i(I(O,x,to,ro)),[ao,co]=i(null),[lo,po]=i(A),[uo]=l(lo),mo=s(null),jo=s(null),fo=a((o=>{jo.current=o,b&&("function"==typeof b?b(o):b.current=o)}),[jo,b]),ho=s(null),Io=a((o=>{z&&ho.current&&(ho.current.contains(o.relatedTarget)||z(o,io,{error:ao,value:o.target.value}))}),[z,io,ao]),ko=a((o=>{q&&q(o,io,{error:ao,value:o.target.value})}),[q,io,ao]),vo=a((o=>{"Escape"===o.key&&(po(!1),o.preventDefault(),o.stopPropagation()),null!=J&&J.onKeyDown&&J.onKeyDown(o)}),[po,J]),yo=a((o=>{if("Escape"===o.key&&(po(!1),o.preventDefault(),o.stopPropagation()),Q){let e=o.currentTarget.value;/[\d.]/.test(o.key)&&(e+=o.key),Q(o,io,{error:ao,value:e})}}),[Q,po,io,ao]),Do=a((o=>{let e=null,t=null;if(o.target.value){const n=k(o.target.value);n?to&&!y(n,to)?t="OUTSIDE_LOWER_BOUND":ro&&!D(n,ro)?t="OUTSIDE_UPPER_BOUND":po(!1):t="WRONG_FORMAT",e=n||null}co(t),so(e),M&&M(o,e,{error:t,value:o.target.value})}),[M,co,so,po,to,ro]),bo=a((o=>{c((()=>{po(!lo)}));const e=uo.current,t=e&&e.querySelector('[aria-pressed="true"]');t&&t.focus(),null!=J&&J.onClick&&J.onClick(o)}),[po,lo,J,uo]),go=a((()=>{po(!lo)}),[po,lo]),wo=a((()=>{po(!1)}),[po]),Co=a((({date:o})=>{if(po(!1),so(o),jo.current){const e=jo.current;e.value=v(o);const t=document.createEvent("HTMLEvents");t.initEvent("input",!0,!1),e.dispatchEvent(t),e.focus(),M&&M(t,o,{error:null,value:e.value})}}),[po,so,M]),Lo=a((o=>{o.preventDefault(),po(!1),mo.current&&mo.current.focus()}),[po]);return p(ho,wo),u(ho,wo),m(uo,["Escape"],(()=>{po(!1),jo.current&&jo.current.focus()})),o(j,{id:w,className:t("jkl-datepicker",C,{"jkl-datepicker--open":lo}),...oo,ref:ho,label:L,labelProps:T,density:U,helpLabel:N,errorLabel:R,supportLabelProps:Z,tooltipProps:$,render:t=>e("div",{"data-testid":"jkl-datepicker__input-wrapper",className:"jkl-datepicker__input-wrapper","data-density":U,tabIndex:-1,onKeyDown:yo,children:[o(f,{ref:fo,"data-testid":"jkl-datepicker__input","data-testautoid":g,className:"jkl-datepicker__input",name:S,defaultValue:x,density:U,value:O,type:"text",placeholder:W,width:G,onFocus:Io,onBlur:ko,onClick:go,onChange:Do,...t,action:{buttonRef:mo,icon:o(d,{}),label:lo?Y:X,...J,onClick:bo,onKeyDown:vo}}),o("div",{className:"jkl-datepicker__calendar-wrapper",children:o(h,{ref:uo,density:U,date:io,minDate:to,maxDate:ro,days:K,months:H,monthLabel:V,yearLabel:F,yearsToShow:E,hidden:!lo,onDateSelected:Co,onTabOutside:Lo})})]})})}));b.displayName="DatePicker";export{b as DatePicker};
|
|
2
2
|
//# sourceMappingURL=DatePicker.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatePicker.js","sources":["../../../../src/components/datepicker/DatePicker.tsx"],"sourcesContent":["import cn from \"classnames\";\nimport startOfDay from \"date-fns/startOfDay\";\nimport React, {\n ChangeEvent,\n FocusEvent,\n KeyboardEvent,\n MouseEvent,\n forwardRef,\n useCallback,\n useRef,\n useState,\n} from \"react\";\nimport { flushSync } from \"react-dom\";\nimport { useAnimatedHeight, useClickOutside, useFocusOutside, useKeyListener } from \"../../hooks\";\nimport { CalendarIcon } from \"../icon\";\nimport { InputGroup } from \"../input-group\";\nimport { BaseTextInput } from \"../text-input\";\nimport { Calendar } from \"./internal/Calendar\";\nimport { getInitialDate, DateInfo } from \"./internal/utils\";\nimport { DatePickerProps, DateValidationError } from \"./types\";\nimport { formatInput, parseDateString } from \"./utils\";\nimport { isWithinLowerBound, isWithinUpperBound } from \"./validation\";\n\nexport const DatePicker = forwardRef<HTMLInputElement, DatePickerProps>((props, forwardedInputRef) => {\n const {\n \"data-testautoid\": testAutoId,\n id,\n className = \"\",\n label = \"Velg dato\",\n labelProps,\n defaultValue,\n defaultShow = false,\n value,\n disableBeforeDate: disableBefore,\n disableAfterDate: disableAfter,\n yearsToShow,\n name,\n helpLabel,\n errorLabel,\n invalid,\n density,\n days,\n months,\n monthLabel,\n yearLabel,\n placeholder = \"dd.mm.åååå\",\n width = \"11.25rem\",\n onChange,\n onBlur,\n onFocus,\n onKeyDown,\n action,\n showCalendarLabel = \"Åpne kalender\",\n hideCalendarLabel = \"Lukk kalender\",\n supportLabelProps,\n tooltipProps,\n ...rest\n } = props;\n\n if (process.env.NODE_ENV !== \"production\" && value && defaultValue) {\n console.warn(\n \"DatePicker må enten være controlled eller uncontrolled. Hvis du bruker defaultValue og value sammen vil defaultValue bli ignorert.\",\n );\n }\n /// Input state\n\n const disableBeforeDate = parseDateString(disableBefore);\n const minDate = disableBeforeDate ? startOfDay(disableBeforeDate) : undefined;\n const disableAfterDate = parseDateString(disableAfter);\n const maxDate = disableAfterDate ? startOfDay(disableAfterDate) : undefined;\n\n const [date, setDate] = useState(getInitialDate(value, defaultValue, minDate, maxDate));\n const [error, setError] = useState<DateValidationError | null>(null);\n\n /// Calendar state\n\n const [showCalendar, setShowCalendar] = useState(defaultShow);\n const [calendarRef] = useAnimatedHeight<HTMLDivElement>(showCalendar);\n\n /// Input events\n\n const iconButtonRef = useRef<HTMLButtonElement | null>(null);\n const inputRef = useRef<HTMLInputElement | null>(null);\n\n // Hjelper for å gjøre det enklere å både forwarde refen men også bruke den selv internt\n const unifiedInputRef = useCallback(\n (instance: HTMLInputElement | null) => {\n inputRef.current = instance;\n if (forwardedInputRef) {\n if (typeof forwardedInputRef === \"function\") {\n forwardedInputRef(instance);\n } else {\n forwardedInputRef.current = instance;\n }\n }\n },\n [inputRef, forwardedInputRef],\n );\n\n const datepickerRef = useRef<HTMLDivElement>(null);\n const handleFocus = useCallback(\n (e: FocusEvent<HTMLInputElement>) => {\n if (!onFocus || !datepickerRef.current) {\n return;\n }\n\n const nextFocusIsInside = datepickerRef.current.contains(e.relatedTarget as Node);\n if (!nextFocusIsInside) {\n onFocus(e, date, { error, value: e.target.value });\n }\n },\n [onFocus, date, error],\n );\n\n const handleBlur = useCallback(\n (e: FocusEvent<HTMLInputElement>) => {\n if (onBlur) {\n onBlur(e, date, { error, value: e.target.value });\n }\n },\n [onBlur, date, error],\n );\n\n const handleKeyDownAction = useCallback(\n (e: React.KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === \"Escape\") {\n setShowCalendar(false);\n e.preventDefault();\n e.stopPropagation();\n }\n\n if (action?.onKeyDown) {\n action.onKeyDown(e);\n }\n },\n [setShowCalendar, action],\n );\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Escape\") {\n setShowCalendar(false);\n e.preventDefault();\n e.stopPropagation();\n }\n\n if (onKeyDown) {\n let nextValue = e.currentTarget.value;\n if (/[\\d.]/.test(e.key)) {\n nextValue += e.key;\n }\n onKeyDown(e, date, { error, value: nextValue });\n }\n },\n [onKeyDown, setShowCalendar, date, error],\n );\n\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n let nextDate: Date | null = null;\n let nextError: DateValidationError | null = null;\n\n if (e.target.value) {\n const val = parseDateString(e.target.value);\n if (!val) {\n nextError = \"WRONG_FORMAT\";\n } else if (minDate && !isWithinLowerBound(val, minDate)) {\n nextError = \"OUTSIDE_LOWER_BOUND\";\n } else if (maxDate && !isWithinUpperBound(val, maxDate)) {\n nextError = \"OUTSIDE_UPPER_BOUND\";\n } else {\n setShowCalendar(false);\n }\n nextDate = val || null;\n }\n\n setError(nextError);\n setDate(nextDate);\n\n if (onChange) {\n onChange(e, nextDate, { error: nextError, value: e.target.value });\n }\n },\n [onChange, setError, setDate, setShowCalendar, minDate, maxDate],\n );\n\n /// Calendar events\n\n const clickCalendar = useCallback(\n (e: MouseEvent<HTMLButtonElement>) => {\n flushSync(() => {\n setShowCalendar(!showCalendar);\n });\n\n const calendarEl = calendarRef.current;\n const button = calendarEl && (calendarEl.querySelector('[aria-pressed=\"true\"]') as HTMLButtonElement);\n button && button.focus();\n\n if (action?.onClick) {\n action.onClick(e);\n }\n },\n [setShowCalendar, showCalendar, action, calendarRef],\n );\n\n const clickInput = useCallback(() => {\n setShowCalendar(!showCalendar);\n }, [setShowCalendar, showCalendar]);\n\n const hideCalendar = useCallback(() => {\n setShowCalendar(false);\n }, [setShowCalendar]);\n\n const handleClickCalendarDay = useCallback(\n ({ date }: DateInfo) => {\n setShowCalendar(false);\n setDate(date);\n\n if (inputRef.current) {\n const node = inputRef.current;\n\n node.value = formatInput(date);\n\n // Simulér et change-event så APIet blir så likt som mulig en endring av inputfeltet\n const event = document.createEvent(\"HTMLEvents\");\n event.initEvent(\"input\", true, false);\n node.dispatchEvent(event);\n\n node.focus();\n\n if (onChange) {\n // Det er ikke helt sant at dette er et React.SyntheticEvent, men it's fine – probably?\n // Den har tingene man kan forvente, men hvis du gjør serdeles fancy ting med events\n // så kan det hende du må utvide denne for å dekke behovet ditt.\n onChange(event as unknown as ChangeEvent<HTMLInputElement>, date, {\n error: null,\n value: node.value,\n });\n }\n }\n },\n [setShowCalendar, setDate, onChange],\n );\n\n const handleTabOutsideCalendar = useCallback(\n (e: KeyboardEvent) => {\n e.preventDefault();\n setShowCalendar(false);\n iconButtonRef.current && iconButtonRef.current.focus();\n },\n [setShowCalendar],\n );\n\n useClickOutside(datepickerRef, hideCalendar);\n useFocusOutside(datepickerRef, hideCalendar);\n useKeyListener(calendarRef, [\"Escape\"], () => {\n setShowCalendar(false);\n inputRef.current && inputRef.current.focus();\n });\n\n return (\n <InputGroup\n id={id}\n className={cn(\"jkl-datepicker\", className, {\n \"jkl-datepicker--open\": showCalendar,\n })}\n {...rest}\n ref={datepickerRef}\n label={label}\n labelProps={labelProps}\n density={density}\n helpLabel={helpLabel}\n errorLabel={errorLabel}\n supportLabelProps={supportLabelProps}\n tooltipProps={tooltipProps}\n render={(inputProps) => (\n // The <div> element handles keyboard events that bubble up from <button> elements inside\n // eslint-disable-next-line jsx-a11y/no-static-element-interactions\n <div\n data-testid=\"jkl-datepicker__input-wrapper\"\n className=\"jkl-datepicker__input-wrapper\"\n data-density={density}\n tabIndex={-1} // Må være her for Safari onBlur quirk! https://bugs.webkit.org/show_bug.cgi?id=22261\n onKeyDown={handleKeyDown}\n >\n <BaseTextInput\n ref={unifiedInputRef}\n data-testid=\"jkl-datepicker__input\"\n data-testautoid={testAutoId}\n className=\"jkl-datepicker__input\"\n name={name}\n defaultValue={defaultValue}\n density={density}\n value={value}\n type=\"text\"\n placeholder={placeholder}\n width={width}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onClick={clickInput}\n onChange={handleChange}\n {...inputProps}\n action={{\n buttonRef: iconButtonRef,\n icon: <CalendarIcon />,\n label: showCalendar ? hideCalendarLabel : showCalendarLabel,\n ...action,\n onClick: clickCalendar,\n onKeyDown: handleKeyDownAction,\n }}\n />\n <div className=\"jkl-datepicker__calendar-wrapper\">\n <Calendar\n ref={calendarRef}\n density={density}\n date={date}\n minDate={minDate}\n maxDate={maxDate}\n days={days}\n months={months}\n monthLabel={monthLabel}\n yearLabel={yearLabel}\n yearsToShow={yearsToShow}\n hidden={!showCalendar}\n onDateSelected={handleClickCalendarDay}\n onTabOutside={handleTabOutsideCalendar}\n />\n </div>\n </div>\n )}\n />\n );\n});\n\nDatePicker.displayName = \"DatePicker\";\n"],"names":["DatePicker","forwardRef","props","forwardedInputRef","testAutoId","id","className","label","labelProps","defaultValue","defaultShow","value","disableBeforeDate","disableBefore","disableAfterDate","disableAfter","yearsToShow","name","helpLabel","errorLabel","invalid","density","days","months","monthLabel","yearLabel","placeholder","width","onChange","onBlur","onFocus","onKeyDown","action","showCalendarLabel","hideCalendarLabel","supportLabelProps","tooltipProps","rest","process","env","NODE_ENV","console","warn","parseDateString","minDate","startOfDay","maxDate","date","setDate","useState","getInitialDate","error","setError","showCalendar","setShowCalendar","calendarRef","useAnimatedHeight","iconButtonRef","useRef","inputRef","unifiedInputRef","useCallback","instance","current","datepickerRef","handleFocus","e","contains","relatedTarget","target","handleBlur","handleKeyDownAction","key","preventDefault","stopPropagation","handleKeyDown","nextValue","currentTarget","test","handleChange","nextDate","nextError","val","isWithinLowerBound","isWithinUpperBound","clickCalendar","flushSync","calendarEl","button","querySelector","focus","onClick","clickInput","hideCalendar","handleClickCalendarDay","node","formatInput","event","document","createEvent","initEvent","dispatchEvent","handleTabOutsideCalendar","useClickOutside","useFocusOutside","useKeyListener","jsx","InputGroup","cn","ref","render","inputProps","jsxs","tabIndex","children","BaseTextInput","type","buttonRef","icon","CalendarIcon","Calendar","hidden","onDateSelected","onTabOutside","displayName"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DatePicker.js","sources":["../../../../src/components/datepicker/DatePicker.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport startOfDay from \"date-fns/startOfDay\";\nimport React, {\n ChangeEvent,\n FocusEvent,\n KeyboardEvent,\n MouseEvent,\n forwardRef,\n useCallback,\n useRef,\n useState,\n} from \"react\";\nimport { flushSync } from \"react-dom\";\nimport { useAnimatedHeight, useClickOutside, useFocusOutside, useKeyListener } from \"../../hooks\";\nimport { CalendarIcon } from \"../icon\";\nimport { InputGroup } from \"../input-group\";\nimport { BaseTextInput } from \"../text-input\";\nimport { Calendar } from \"./internal/Calendar\";\nimport { getInitialDate, DateInfo } from \"./internal/utils\";\nimport { DatePickerProps, DateValidationError } from \"./types\";\nimport { formatInput, parseDateString } from \"./utils\";\nimport { isWithinLowerBound, isWithinUpperBound } from \"./validation\";\n\nexport const DatePicker = forwardRef<HTMLInputElement, DatePickerProps>((props, forwardedInputRef) => {\n const {\n \"data-testautoid\": testAutoId,\n id,\n className = \"\",\n label = \"Velg dato\",\n labelProps,\n defaultValue,\n defaultShow = false,\n value,\n disableBeforeDate: disableBefore,\n disableAfterDate: disableAfter,\n yearsToShow,\n name,\n helpLabel,\n errorLabel,\n invalid,\n density,\n days,\n months,\n monthLabel,\n yearLabel,\n placeholder = \"dd.mm.åååå\",\n width = \"11.25rem\",\n onChange,\n onBlur,\n onFocus,\n onKeyDown,\n action,\n showCalendarLabel = \"Åpne kalender\",\n hideCalendarLabel = \"Lukk kalender\",\n supportLabelProps,\n tooltipProps,\n ...rest\n } = props;\n\n if (process.env.NODE_ENV !== \"production\" && value && defaultValue) {\n console.warn(\n \"DatePicker må enten være controlled eller uncontrolled. Hvis du bruker defaultValue og value sammen vil defaultValue bli ignorert.\",\n );\n }\n /// Input state\n\n const disableBeforeDate = parseDateString(disableBefore);\n const minDate = disableBeforeDate ? startOfDay(disableBeforeDate) : undefined;\n const disableAfterDate = parseDateString(disableAfter);\n const maxDate = disableAfterDate ? startOfDay(disableAfterDate) : undefined;\n\n const [date, setDate] = useState(getInitialDate(value, defaultValue, minDate, maxDate));\n const [error, setError] = useState<DateValidationError | null>(null);\n\n /// Calendar state\n\n const [showCalendar, setShowCalendar] = useState(defaultShow);\n const [calendarRef] = useAnimatedHeight<HTMLDivElement>(showCalendar);\n\n /// Input events\n\n const iconButtonRef = useRef<HTMLButtonElement | null>(null);\n const inputRef = useRef<HTMLInputElement | null>(null);\n\n // Hjelper for å gjøre det enklere å både forwarde refen men også bruke den selv internt\n const unifiedInputRef = useCallback(\n (instance: HTMLInputElement | null) => {\n inputRef.current = instance;\n if (forwardedInputRef) {\n if (typeof forwardedInputRef === \"function\") {\n forwardedInputRef(instance);\n } else {\n forwardedInputRef.current = instance;\n }\n }\n },\n [inputRef, forwardedInputRef],\n );\n\n const datepickerRef = useRef<HTMLDivElement>(null);\n const handleFocus = useCallback(\n (e: FocusEvent<HTMLInputElement>) => {\n if (!onFocus || !datepickerRef.current) {\n return;\n }\n\n const nextFocusIsInside = datepickerRef.current.contains(e.relatedTarget as Node);\n if (!nextFocusIsInside) {\n onFocus(e, date, { error, value: e.target.value });\n }\n },\n [onFocus, date, error],\n );\n\n const handleBlur = useCallback(\n (e: FocusEvent<HTMLInputElement>) => {\n if (onBlur) {\n onBlur(e, date, { error, value: e.target.value });\n }\n },\n [onBlur, date, error],\n );\n\n const handleKeyDownAction = useCallback(\n (e: React.KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === \"Escape\") {\n setShowCalendar(false);\n e.preventDefault();\n e.stopPropagation();\n }\n\n if (action?.onKeyDown) {\n action.onKeyDown(e);\n }\n },\n [setShowCalendar, action],\n );\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Escape\") {\n setShowCalendar(false);\n e.preventDefault();\n e.stopPropagation();\n }\n\n if (onKeyDown) {\n let nextValue = e.currentTarget.value;\n if (/[\\d.]/.test(e.key)) {\n nextValue += e.key;\n }\n onKeyDown(e, date, { error, value: nextValue });\n }\n },\n [onKeyDown, setShowCalendar, date, error],\n );\n\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n let nextDate: Date | null = null;\n let nextError: DateValidationError | null = null;\n\n if (e.target.value) {\n const val = parseDateString(e.target.value);\n if (!val) {\n nextError = \"WRONG_FORMAT\";\n } else if (minDate && !isWithinLowerBound(val, minDate)) {\n nextError = \"OUTSIDE_LOWER_BOUND\";\n } else if (maxDate && !isWithinUpperBound(val, maxDate)) {\n nextError = \"OUTSIDE_UPPER_BOUND\";\n } else {\n setShowCalendar(false);\n }\n nextDate = val || null;\n }\n\n setError(nextError);\n setDate(nextDate);\n\n if (onChange) {\n onChange(e, nextDate, { error: nextError, value: e.target.value });\n }\n },\n [onChange, setError, setDate, setShowCalendar, minDate, maxDate],\n );\n\n /// Calendar events\n\n const clickCalendar = useCallback(\n (e: MouseEvent<HTMLButtonElement>) => {\n flushSync(() => {\n setShowCalendar(!showCalendar);\n });\n\n const calendarEl = calendarRef.current;\n const button = calendarEl && (calendarEl.querySelector('[aria-pressed=\"true\"]') as HTMLButtonElement);\n button && button.focus();\n\n if (action?.onClick) {\n action.onClick(e);\n }\n },\n [setShowCalendar, showCalendar, action, calendarRef],\n );\n\n const clickInput = useCallback(() => {\n setShowCalendar(!showCalendar);\n }, [setShowCalendar, showCalendar]);\n\n const hideCalendar = useCallback(() => {\n setShowCalendar(false);\n }, [setShowCalendar]);\n\n const handleClickCalendarDay = useCallback(\n ({ date }: DateInfo) => {\n setShowCalendar(false);\n setDate(date);\n\n if (inputRef.current) {\n const node = inputRef.current;\n\n node.value = formatInput(date);\n\n // Simulér et change-event så APIet blir så likt som mulig en endring av inputfeltet\n const event = document.createEvent(\"HTMLEvents\");\n event.initEvent(\"input\", true, false);\n node.dispatchEvent(event);\n\n node.focus();\n\n if (onChange) {\n // Det er ikke helt sant at dette er et React.SyntheticEvent, men it's fine – probably?\n // Den har tingene man kan forvente, men hvis du gjør serdeles fancy ting med events\n // så kan det hende du må utvide denne for å dekke behovet ditt.\n onChange(event as unknown as ChangeEvent<HTMLInputElement>, date, {\n error: null,\n value: node.value,\n });\n }\n }\n },\n [setShowCalendar, setDate, onChange],\n );\n\n const handleTabOutsideCalendar = useCallback(\n (e: KeyboardEvent) => {\n e.preventDefault();\n setShowCalendar(false);\n iconButtonRef.current && iconButtonRef.current.focus();\n },\n [setShowCalendar],\n );\n\n useClickOutside(datepickerRef, hideCalendar);\n useFocusOutside(datepickerRef, hideCalendar);\n useKeyListener(calendarRef, [\"Escape\"], () => {\n setShowCalendar(false);\n inputRef.current && inputRef.current.focus();\n });\n\n return (\n <InputGroup\n id={id}\n className={clsx(\"jkl-datepicker\", className, {\n \"jkl-datepicker--open\": showCalendar,\n })}\n {...rest}\n ref={datepickerRef}\n label={label}\n labelProps={labelProps}\n density={density}\n helpLabel={helpLabel}\n errorLabel={errorLabel}\n supportLabelProps={supportLabelProps}\n tooltipProps={tooltipProps}\n render={(inputProps) => (\n // The <div> element handles keyboard events that bubble up from <button> elements inside\n // eslint-disable-next-line jsx-a11y/no-static-element-interactions\n <div\n data-testid=\"jkl-datepicker__input-wrapper\"\n className=\"jkl-datepicker__input-wrapper\"\n data-density={density}\n tabIndex={-1} // Må være her for Safari onBlur quirk! https://bugs.webkit.org/show_bug.cgi?id=22261\n onKeyDown={handleKeyDown}\n >\n <BaseTextInput\n ref={unifiedInputRef}\n data-testid=\"jkl-datepicker__input\"\n data-testautoid={testAutoId}\n className=\"jkl-datepicker__input\"\n name={name}\n defaultValue={defaultValue}\n density={density}\n value={value}\n type=\"text\"\n placeholder={placeholder}\n width={width}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onClick={clickInput}\n onChange={handleChange}\n {...inputProps}\n action={{\n buttonRef: iconButtonRef,\n icon: <CalendarIcon />,\n label: showCalendar ? hideCalendarLabel : showCalendarLabel,\n ...action,\n onClick: clickCalendar,\n onKeyDown: handleKeyDownAction,\n }}\n />\n <div className=\"jkl-datepicker__calendar-wrapper\">\n <Calendar\n ref={calendarRef}\n density={density}\n date={date}\n minDate={minDate}\n maxDate={maxDate}\n days={days}\n months={months}\n monthLabel={monthLabel}\n yearLabel={yearLabel}\n yearsToShow={yearsToShow}\n hidden={!showCalendar}\n onDateSelected={handleClickCalendarDay}\n onTabOutside={handleTabOutsideCalendar}\n />\n </div>\n </div>\n )}\n />\n );\n});\n\nDatePicker.displayName = \"DatePicker\";\n"],"names":["DatePicker","forwardRef","props","forwardedInputRef","testAutoId","id","className","label","labelProps","defaultValue","defaultShow","value","disableBeforeDate","disableBefore","disableAfterDate","disableAfter","yearsToShow","name","helpLabel","errorLabel","invalid","density","days","months","monthLabel","yearLabel","placeholder","width","onChange","onBlur","onFocus","onKeyDown","action","showCalendarLabel","hideCalendarLabel","supportLabelProps","tooltipProps","rest","process","env","NODE_ENV","console","warn","parseDateString","minDate","startOfDay","maxDate","date","setDate","useState","getInitialDate","error","setError","showCalendar","setShowCalendar","calendarRef","useAnimatedHeight","iconButtonRef","useRef","inputRef","unifiedInputRef","useCallback","instance","current","datepickerRef","handleFocus","e","contains","relatedTarget","target","handleBlur","handleKeyDownAction","key","preventDefault","stopPropagation","handleKeyDown","nextValue","currentTarget","test","handleChange","nextDate","nextError","val","isWithinLowerBound","isWithinUpperBound","clickCalendar","flushSync","calendarEl","button","querySelector","focus","onClick","clickInput","hideCalendar","handleClickCalendarDay","node","formatInput","event","document","createEvent","initEvent","dispatchEvent","handleTabOutsideCalendar","useClickOutside","useFocusOutside","useKeyListener","jsx","InputGroup","clsx","ref","render","inputProps","jsxs","tabIndex","children","BaseTextInput","type","buttonRef","icon","CalendarIcon","Calendar","hidden","onDateSelected","onTabOutside","displayName"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{jsx as e,jsxs as t}from"react/jsx-runtime";import n
|
|
1
|
+
import{jsx as e,jsxs as t}from"react/jsx-runtime";import{c as n}from"../../../../clsx-BeLtu-UY.js";import{forwardRef as a,useReducer as o,useEffect as r,useCallback as c,useRef as i}from"react";import{flushSync as s}from"react-dom";import"../../../hooks/useScreen/useScreen.js";import{useId as l}from"../../../hooks/useId/useId.js";import"../../icon/Icon.js";import"../../icon/icons/animated/ArrowVerticalAnimated.js";import"../../icon/icons/animated/ArrowHorizontalAnimated.js";import"../../icon/icons/animated/PlusRemoveAnimated.js";import"../../icon/icons/ArrowDownIcon.js";import{ArrowLeftIcon as d}from"../../icon/icons/ArrowLeftIcon.js";import"../../icon/icons/ArrowNorthEastIcon.js";import{ArrowRightIcon as u}from"../../icon/icons/ArrowRightIcon.js";import"../../icon/icons/ArrowUpIcon.js";import"../../icon/icons/CalendarIcon.js";import"../../icon/icons/CheckIcon.js";import{ChevronDownIcon as m}from"../../icon/icons/ChevronDownIcon.js";import"../../icon/icons/ChevronLeftIcon.js";import"../../icon/icons/ChevronRightIcon.js";import"../../icon/icons/ChevronUpIcon.js";import"../../icon/icons/CloseIcon.js";import"../../icon/icons/CopyIcon.js";import"../../icon/icons/DotsIcon.js";import"../../icon/icons/DragIcon.js";import"../../icon/icons/ErrorIcon.js";import"../../icon/icons/GreenCheckIcon.js";import"../../icon/icons/HamburgerIcon.js";import"../../icon/icons/InfoIcon.js";import"../../icon/icons/LinkIcon.js";import"../../icon/icons/PlusIcon.js";import"../../icon/icons/QuestionIcon.js";import"../../icon/icons/RedCrossIcon.js";import"../../icon/icons/SearchIcon.js";import"../../icon/icons/SuccessIcon.js";import"../../icon/icons/WarningIcon.js";import"../../icon/icons/MinusIcon.js";import"../../icon/icons/ThumbDownIcon.js";import"../../icon/icons/ThumbUpIcon.js";import"../../icon/icons/TrashCanIcon.js";import"../../icon/icons/PenIcon.js";import{calendarReducer as h,calendarInitializer as p}from"./calendarReducer.js";import{useCalendar as g}from"./useCalendar.js";import{getInitialDateShown as j,isBackDisabled as f,subtractMonth as b,isForwardDisabled as v,addMonth as k,getYearSelectOptions as w,getMonthSelectOptions as D,DEFAULT_YEARS_TO_SHOW as I}from"./utils.js";const y=["Januar","Februar","Mars","April","Mai","Juni","Juli","August","September","Oktober","November","Desember"],A=["man","tir","ons","tor","fre","lør","søn"],S=a(((a,S)=>{const{hidden:_,date:M,defaultSelected:C,density:F,minDate:N,maxDate:E,days:x=A,months:Y=y,monthLabel:O="Velg måned",yearLabel:T="Velg år",yearsToShow:$=I,onTabOutside:R,...L}=a,q=l("jkl-calendar"),[{offset:P,selectedDate:U,shownDate:K},H]=o(h,j(M,C,N,E),p),J=K.getMonth(),V=K.getFullYear();r((()=>{H({type:"SET_SELECTED_DATE",newDate:j(M,C,N,E)})}),[M,C,N,E]);const W=c((e=>{H({type:"SET_OFFSET",newOffset:e})}),[]),{calendars:z,getBackProps:B,getDateProps:G,getForwardProps:Q,handleOffsetChanged:X}=g({date:U,selected:U,minDate:N,maxDate:E,offset:P,onOffsetChanged:W,firstDayOfWeek:1,...L}),Z=i(null),ee=c((e=>{if(!Z.current)return;const t=document.activeElement,n=Z.current.querySelectorAll('button.jkl-calendar-date-button:not([data-adjacent="true"]'),a=async e=>{null==t||t.setAttribute("tabindex","-1"),e.setAttribute("tabindex","0"),e.focus()};n.forEach(((o,r)=>{const c=r+e;if(o==t)if(c<=n.length-1&&c>=0)a(n[c]);else if(e<0){if(f({calendars:z,minDate:N})||(s((()=>{X(P-b({calendars:z,offset:1,minDate:N}))})),!Z.current))return;const e=Z.current.querySelectorAll('button.jkl-calendar-date-button:not([data-adjacent="true"]');e[e.length+c]&&(e[0].setAttribute("tabindex","-1"),a(e[e.length+c]))}else{if(v({calendars:z,maxDate:E})||(s((()=>{X(P+k({calendars:z,offset:1,maxDate:E}))})),!Z.current))return;const e=Z.current.querySelectorAll('button.jkl-calendar-date-button:not([data-adjacent="true"]');e[c-n.length]&&(e[0].setAttribute("tabindex","-1"),a(e[c-n.length]))}}))}),[X,Z,P,z,E,N]),te=c((e=>{switch(e.key){case"ArrowUp":ee(-7),e.preventDefault();break;case"ArrowRight":ee(1),e.preventDefault();break;case"ArrowDown":ee(7),e.preventDefault();break;case"ArrowLeft":ee(-1),e.preventDefault()}}),[ee]),ne=c((e=>{var t;if("Tab"!==e.key)return;const n=null==(t=Z.current)?void 0:t.querySelectorAll('button:not([disabled]):not([tabindex="-1"]), select');if(!n)return;const a=n[0],o=n[n.length-1];e.shiftKey||document.activeElement!==o?e.shiftKey&&document.activeElement===a&&(o.focus(),e.preventDefault()):(a.focus(),e.preventDefault())}),[]),ae=c((e=>{const{date:t,selected:n,selectable:a,prevMonth:o,nextMonth:r}=e;return!!a&&!(!n&&t.toString()!==(null==N?void 0:N.toString())&&(o||r||K.getFullYear()!==t.getFullYear()||U.getMonth()===t.getMonth()||1!==t.getDate()))}),[K,N,U]),oe=c((()=>{N&&K.getFullYear()-N.getFullYear()==0&&K.getMonth()-N.getMonth()==1?document.querySelectorAll(".jkl-calendar-navigation__arrow")[1].focus():E&&E.getFullYear()-K.getFullYear()==0&&E.getMonth()-K.getMonth()==1&&document.querySelectorAll(".jkl-calendar-navigation__arrow")[0].focus()}),[N,E,K]),re=c((e=>{if(4!==e.target.value.length)return;const t=Number.parseInt(e.target.value);if(Number.isNaN(t))return;let n=12*(t-K.getFullYear());const a=new Date(K.getFullYear(),K.getMonth()+n,K.getDate());E&&E.getFullYear()===a.getFullYear()&&E.getMonth()<a.getMonth()?n-=a.getMonth()-E.getMonth():N&&N.getFullYear()===a.getFullYear()&&N.getMonth()>a.getMonth()&&(n+=N.getMonth()-a.getMonth()),H({type:"ADD_OFFSET",addedOffset:n})}),[K,N,E]),ce=c((e=>{if(!U&&!M)return;const t=K.getFullYear()-(U||new Date).getFullYear(),n=Number.parseInt(e.target.value)-(U||new Date).getMonth();H({type:"SET_OFFSET",newOffset:12*t+n})}),[U,M,K]),ie=w(V,N,E,$),se=D(V,Y,N,E);return e("div",{ref:S,id:q,className:n("jkl-calendar",{"jkl-calendar--hidden":_}),"data-testid":"jkl-calendar",children:t("div",{className:"jkl-calendar__padding",ref:Z,onKeyDown:ne,children:[t("fieldset",{className:"jkl-calendar-navigation",children:[t("div",{children:[e("button",{...B({calendars:z,onClick:oe}),className:"jkl-calendar-navigation__arrow",type:"button",children:e(d,{variant:"medium",bold:!0})}),e("button",{...Q({calendars:z,onClick:oe}),className:"jkl-calendar-navigation__arrow",type:"button",children:e(u,{variant:"medium",bold:!0})})]}),t("div",{children:[t("div",{className:"jkl-calendar-navigation-dropdown",children:[e("select",{onChange:ce,className:"jkl-calendar-navigation-dropdown__select","aria-label":O,value:J.toString(),children:se.map((({label:t,value:n})=>e("option",{value:n,children:t},n)))}),e(m,{bold:!0,className:"jkl-calendar-navigation-dropdown__chevron"})]}),t("div",{className:"jkl-calendar-navigation-dropdown",children:[e("select",{onChange:re,className:"jkl-calendar-navigation-dropdown__select","aria-label":T,value:V.toString(),children:ie.map((t=>e("option",{value:t,children:t},t)))}),e(m,{bold:!0,className:"jkl-calendar-navigation-dropdown__chevron"})]})]})]}),z.map((n=>t("table",{className:"jkl-calendar-table","data-testid":"jkl-datepicker-calendar",children:[t("caption",{className:"jkl-sr-only",children:[Y[n.month],", ",n.year]}),e("thead",{children:e("tr",{children:x.map((t=>e("th",{children:t},`${n.month}${n.year}${t}`)))})}),e("tbody",{"data-testid":"jkl-datepicker-dates",children:n.weeks.map(((t,a)=>e("tr",{children:t.map(((t,o)=>{const r=`${n.month}${n.year}${a}${o}`;if("string"==typeof t)return e("td",{className:"jkl-calendar__date jkl-calendar__date--empty",children:t},r);const{date:c,selectable:i,today:s,prevMonth:l,nextMonth:d}=t;return e("td",{children:e("button",{...G({dateObj:t}),type:"button",className:"jkl-calendar-date-button",tabIndex:ae(t)?0:-1,"aria-label":`${c.getDate()}. ${Y[c.getMonth()].toLowerCase()}`,"aria-current":s?"date":void 0,"data-adjacent":l||d?"true":void 0,disabled:!i,onKeyDown:te,children:e("span",{"aria-hidden":"true",children:c.getDate()})})},r)}))},`${n.month}${n.year}${a}`)))})]},`${n.month}${n.year}`)))]})})}));S.displayName="Calendar";export{S as Calendar};
|
|
2
2
|
//# sourceMappingURL=Calendar.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Calendar.js","sources":["../../../../../src/components/datepicker/internal/Calendar.tsx"],"sourcesContent":["import cn from \"classnames\";\nimport React, { forwardRef, useCallback, useEffect, useReducer, useRef } from \"react\";\nimport { flushSync } from \"react-dom\";\nimport { Density } from \"../../../core\";\nimport { useId } from \"../../../hooks\";\nimport { ArrowLeftIcon, ArrowRightIcon, ChevronDownIcon } from \"../../icon\";\nimport type { YearsToShow } from \"../types\";\nimport { calendarInitializer, calendarReducer } from \"./calendarReducer\";\nimport { useCalendar, UseCalendarProps } from \"./useCalendar\";\nimport {\n addMonth,\n subtractMonth,\n isBackDisabled,\n isForwardDisabled,\n getYearSelectOptions,\n getMonthSelectOptions,\n DateInfo,\n getInitialDateShown,\n DEFAULT_YEARS_TO_SHOW,\n} from \"./utils\";\n\ninterface CalendarProps\n extends Omit<UseCalendarProps, \"date\" | \"onOffsetChanged\" | \"offset\" | \"firstDayOfWeek\" | \"selected\"> {\n date: Date | null;\n density?: Density;\n defaultSelected?: Date;\n hidden?: boolean;\n days?: string[];\n months?: string[];\n monthLabel?: string;\n yearLabel?: string;\n yearsToShow?: YearsToShow;\n onTabOutside: React.KeyboardEventHandler;\n}\n\nconst defaultMonths = [\n \"Januar\",\n \"Februar\",\n \"Mars\",\n \"April\",\n \"Mai\",\n \"Juni\",\n \"Juli\",\n \"August\",\n \"September\",\n \"Oktober\",\n \"November\",\n \"Desember\",\n];\n\nconst defaultDays = [\"man\", \"tir\", \"ons\", \"tor\", \"fre\", \"lør\", \"søn\"];\n\nexport const Calendar = forwardRef<HTMLDivElement, CalendarProps>((props, ref) => {\n const {\n hidden,\n date,\n defaultSelected,\n density,\n minDate,\n maxDate,\n days = defaultDays,\n months = defaultMonths,\n monthLabel = \"Velg måned\",\n yearLabel = \"Velg år\",\n yearsToShow = DEFAULT_YEARS_TO_SHOW,\n onTabOutside,\n ...rest\n } = props;\n\n const id = useId(\"jkl-calendar\");\n\n const [{ offset, selectedDate, shownDate }, dispatch] = useReducer(\n calendarReducer,\n getInitialDateShown(date, defaultSelected, minDate, maxDate),\n calendarInitializer,\n );\n\n const shownMonth = shownDate.getMonth();\n const shownYear = shownDate.getFullYear();\n\n useEffect(() => {\n dispatch({\n type: \"SET_SELECTED_DATE\",\n newDate: getInitialDateShown(date, defaultSelected, minDate, maxDate),\n });\n }, [date, defaultSelected, minDate, maxDate]);\n\n const onOffsetChanged = useCallback((newOffset: number) => {\n dispatch({\n type: \"SET_OFFSET\",\n newOffset,\n });\n }, []);\n\n const { calendars, getBackProps, getDateProps, getForwardProps, handleOffsetChanged } = useCalendar({\n date: selectedDate,\n selected: selectedDate,\n minDate,\n maxDate,\n offset,\n onOffsetChanged,\n firstDayOfWeek: 1,\n ...rest,\n });\n\n /// Calendar keyboard navigation\n\n const calendarPaddingRef = useRef<HTMLDivElement>(null);\n const doFocusChange = useCallback(\n (offsetDiff: number) => {\n if (!calendarPaddingRef.current) {\n return;\n }\n\n const e = document.activeElement;\n const buttons = calendarPaddingRef.current.querySelectorAll<HTMLButtonElement>(\n 'button.jkl-calendar-date-button:not([data-adjacent=\"true\"]',\n );\n\n const changeFocusTo = async (nextButton: HTMLButtonElement) => {\n e?.setAttribute(\"tabindex\", \"-1\");\n nextButton.setAttribute(\"tabindex\", \"0\");\n nextButton.focus();\n };\n\n buttons.forEach((el, i) => {\n const newNodeKey = i + offsetDiff;\n\n if (el == e) {\n if (newNodeKey <= buttons.length - 1 && newNodeKey >= 0) {\n changeFocusTo(buttons[newNodeKey]);\n } else if (offsetDiff < 0) {\n if (isBackDisabled({ calendars, minDate })) {\n return;\n }\n\n // Hvis newNodeKey er utenfor samlingen med knapper så har vi prøvd å gå til\n // en dag utenfor måneden. Er offsetDiff negativ så har vi gått tilbake en\n // måned.\n flushSync(() => {\n handleOffsetChanged(offset - subtractMonth({ calendars, offset: 1, minDate }));\n });\n if (!calendarPaddingRef.current) {\n return;\n }\n const newButtons = calendarPaddingRef.current.querySelectorAll<HTMLButtonElement>(\n 'button.jkl-calendar-date-button:not([data-adjacent=\"true\"]',\n );\n // + - = -\n if (newButtons[newButtons.length + newNodeKey]) {\n // Sørg for at ikke både 1. i måneden og valgt dag er fokuserbare\n newButtons[0].setAttribute(\"tabindex\", \"-1\");\n changeFocusTo(newButtons[newButtons.length + newNodeKey]);\n }\n } else {\n if (isForwardDisabled({ calendars, maxDate })) {\n return;\n }\n\n // Hvis newNodeKey er utenfor samlingen med knapper så har vi prøvd å gå til\n // en dag utenfor måneden. Er offsetDiff positiv så har vi gått frem en\n // måned.\n flushSync(() => {\n handleOffsetChanged(offset + addMonth({ calendars, offset: 1, maxDate }));\n });\n if (!calendarPaddingRef.current) {\n return;\n }\n const newButtons = calendarPaddingRef.current.querySelectorAll<HTMLButtonElement>(\n 'button.jkl-calendar-date-button:not([data-adjacent=\"true\"]',\n );\n // NewNodeKey er basert på forrige måneds liste med knapper. For at verdien skal bli\n // riktig i vår nye måned må vi trekke fra anntal dager fra forrige måned.\n if (newButtons[newNodeKey - buttons.length]) {\n // Sørg for at ikke både 1. i måneden og valgt dag er fokuserbare\n newButtons[0].setAttribute(\"tabindex\", \"-1\");\n changeFocusTo(newButtons[newNodeKey - buttons.length]);\n }\n }\n }\n });\n },\n [handleOffsetChanged, calendarPaddingRef, offset, calendars, maxDate, minDate],\n );\n\n const handleArrowNavigation = useCallback(\n (event: React.KeyboardEvent) => {\n switch (event.key) {\n case \"ArrowUp\":\n doFocusChange(-7);\n event.preventDefault();\n break;\n case \"ArrowRight\":\n doFocusChange(1);\n event.preventDefault();\n break;\n case \"ArrowDown\":\n doFocusChange(7);\n event.preventDefault();\n break;\n case \"ArrowLeft\":\n doFocusChange(-1);\n event.preventDefault();\n break;\n default:\n break;\n }\n },\n [doFocusChange],\n );\n\n const handleTabInside: React.KeyboardEventHandler = useCallback((event) => {\n if (event.key !== \"Tab\") return;\n\n const focusableElements = calendarPaddingRef.current?.querySelectorAll<HTMLElement>(\n 'button:not([disabled]):not([tabindex=\"-1\"]), select',\n );\n\n if (!focusableElements) return;\n\n const firstElement = focusableElements[0];\n const lastElement = focusableElements[focusableElements.length - 1];\n\n if (!event.shiftKey && document.activeElement === lastElement) {\n firstElement.focus();\n event.preventDefault();\n } else if (event.shiftKey && document.activeElement === firstElement) {\n lastElement.focus();\n event.preventDefault();\n }\n }, []);\n\n const isFocusableDate = useCallback(\n (dateInfo: DateInfo) => {\n const { date, selected, selectable, prevMonth, nextMonth } = dateInfo;\n\n // Datoen kan ikke velges\n if (!selectable) {\n return false;\n }\n // Datoen er valgt dato\n if (selected) {\n return true;\n }\n // Datoen er første valgbare dato\n if (date.toString() === minDate?.toString()) {\n return true;\n }\n\n // Datoen er første i måneden som vises\n if (\n !prevMonth &&\n !nextMonth &&\n shownDate.getFullYear() === date.getFullYear() &&\n selectedDate.getMonth() !== date.getMonth() &&\n date.getDate() === 1\n ) {\n return true;\n }\n\n return false;\n },\n [shownDate, minDate, selectedDate],\n );\n\n const handleGotoEdgeMonth = useCallback(() => {\n if (\n // Vi er i ferd med å gå til første måned\n minDate &&\n shownDate.getFullYear() - minDate.getFullYear() === 0 &&\n shownDate.getMonth() - minDate.getMonth() === 1\n ) {\n // Fokuser på \"neste månded\"-knappen\n document.querySelectorAll<HTMLButtonElement>(\".jkl-calendar-navigation__arrow\")[1].focus();\n } else if (\n // Vi er i ferd med å gå til siste måned\n maxDate &&\n maxDate.getFullYear() - shownDate.getFullYear() === 0 &&\n maxDate.getMonth() - shownDate.getMonth() === 1\n ) {\n // Fokuser på \"forrige månded\"-knappen\n document.querySelectorAll<HTMLButtonElement>(\".jkl-calendar-navigation__arrow\")[0].focus();\n }\n }, [minDate, maxDate, shownDate]);\n\n /// Extended variant events\n\n const handleYearChange = useCallback<React.ChangeEventHandler<HTMLSelectElement>>(\n (event) => {\n if (event.target.value.length !== 4) {\n return;\n }\n\n const year: number = Number.parseInt(event.target.value);\n if (Number.isNaN(year)) {\n return;\n }\n\n let offset = (year - shownDate.getFullYear()) * 12;\n const expectedDate = new Date(shownDate.getFullYear(), shownDate.getMonth() + offset, shownDate.getDate());\n\n // Pass på at vi ikke hopper forbi maks. eller min. dato\n if (\n maxDate &&\n maxDate.getFullYear() === expectedDate.getFullYear() &&\n maxDate.getMonth() < expectedDate.getMonth()\n ) {\n offset -= expectedDate.getMonth() - maxDate.getMonth();\n } else if (\n minDate &&\n minDate.getFullYear() === expectedDate.getFullYear() &&\n minDate.getMonth() > expectedDate.getMonth()\n ) {\n offset += minDate.getMonth() - expectedDate.getMonth();\n }\n\n dispatch({\n type: \"ADD_OFFSET\",\n addedOffset: offset,\n });\n\n return;\n },\n [shownDate, minDate, maxDate],\n );\n\n const handleMonthChange = useCallback<React.ChangeEventHandler<HTMLSelectElement>>(\n (event) => {\n if (!selectedDate && !date) {\n return;\n }\n\n const yearDiff = shownDate.getFullYear() - (selectedDate || new Date()).getFullYear();\n const monthDiff = Number.parseInt(event.target.value) - (selectedDate || new Date()).getMonth();\n\n dispatch({\n type: \"SET_OFFSET\",\n newOffset: yearDiff * 12 + monthDiff,\n });\n\n return;\n },\n [selectedDate, date, shownDate],\n );\n\n const yearSelectOptions = getYearSelectOptions(shownYear, minDate, maxDate, yearsToShow);\n const monthSelectOptions = getMonthSelectOptions(shownYear, months, minDate, maxDate);\n\n return (\n <div\n ref={ref}\n id={id}\n className={cn(\"jkl-calendar\", {\n \"jkl-calendar--hidden\": hidden,\n })}\n data-testid=\"jkl-calendar\"\n >\n {/* Vi lytter på på trykk på Tab inne i kalenderen for å håndtere fokus */}\n {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */}\n <div className=\"jkl-calendar__padding\" ref={calendarPaddingRef} onKeyDown={handleTabInside}>\n <fieldset className=\"jkl-calendar-navigation\">\n <div>\n <button\n {...getBackProps({ calendars, onClick: handleGotoEdgeMonth })}\n className=\"jkl-calendar-navigation__arrow\"\n type=\"button\"\n >\n <ArrowLeftIcon variant=\"medium\" bold />\n </button>\n <button\n {...getForwardProps({ calendars, onClick: handleGotoEdgeMonth })}\n className=\"jkl-calendar-navigation__arrow\"\n type=\"button\"\n >\n <ArrowRightIcon variant=\"medium\" bold />\n </button>\n </div>\n <div>\n <div className=\"jkl-calendar-navigation-dropdown\">\n <select\n onChange={handleMonthChange}\n className=\"jkl-calendar-navigation-dropdown__select\"\n aria-label={monthLabel}\n value={shownMonth.toString()}\n >\n {monthSelectOptions.map(({ label, value }) => (\n <option key={value} value={value}>\n {label}\n </option>\n ))}\n </select>\n <ChevronDownIcon bold className=\"jkl-calendar-navigation-dropdown__chevron\" />\n </div>\n <div className=\"jkl-calendar-navigation-dropdown\">\n <select\n onChange={handleYearChange}\n className=\"jkl-calendar-navigation-dropdown__select\"\n aria-label={yearLabel}\n value={shownYear.toString()}\n >\n {yearSelectOptions.map((year) => (\n <option key={year} value={year}>\n {year}\n </option>\n ))}\n </select>\n <ChevronDownIcon bold className=\"jkl-calendar-navigation-dropdown__chevron\" />\n </div>\n </div>\n </fieldset>\n {calendars.map((calendar) => (\n <table\n className=\"jkl-calendar-table\"\n key={`${calendar.month}${calendar.year}`}\n data-testid=\"jkl-datepicker-calendar\"\n >\n <caption className=\"jkl-sr-only\">\n {months[calendar.month]}, {calendar.year}\n </caption>\n <thead>\n <tr>\n {days.map((weekday) => (\n <th key={`${calendar.month}${calendar.year}${weekday}`}>{weekday}</th>\n ))}\n </tr>\n </thead>\n <tbody data-testid=\"jkl-datepicker-dates\">\n {calendar.weeks.map((week, weekIndex) => (\n <tr key={`${calendar.month}${calendar.year}${weekIndex}`}>\n {week.map((dateInfo, index) => {\n const key = `${calendar.month}${calendar.year}${weekIndex}${index}`;\n if (typeof dateInfo === \"string\") {\n return (\n <td className=\"jkl-calendar__date jkl-calendar__date--empty\" key={key}>\n {dateInfo}\n </td>\n );\n }\n const { date, selectable, today, prevMonth, nextMonth } = dateInfo;\n\n return (\n <td key={key}>\n <button\n {...getDateProps({\n dateObj: dateInfo,\n })}\n type=\"button\"\n className=\"jkl-calendar-date-button\"\n tabIndex={isFocusableDate(dateInfo) ? 0 : -1}\n aria-label={`${date.getDate()}. ${months[\n date.getMonth()\n ].toLowerCase()}`}\n aria-current={today ? \"date\" : undefined}\n data-adjacent={prevMonth || nextMonth ? \"true\" : undefined}\n disabled={!selectable}\n onKeyDown={handleArrowNavigation}\n >\n <span aria-hidden=\"true\">{date.getDate()}</span>\n </button>\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n ))}\n </div>\n </div>\n );\n});\n\nCalendar.displayName = \"Calendar\";\n"],"names":["defaultMonths","defaultDays","Calendar","forwardRef","props","ref","hidden","date","defaultSelected","density","minDate","maxDate","days","months","monthLabel","yearLabel","yearsToShow","DEFAULT_YEARS_TO_SHOW","onTabOutside","rest","id","useId","offset","selectedDate","shownDate","dispatch","useReducer","calendarReducer","getInitialDateShown","calendarInitializer","shownMonth","getMonth","shownYear","getFullYear","useEffect","type","newDate","onOffsetChanged","useCallback","newOffset","calendars","getBackProps","getDateProps","getForwardProps","handleOffsetChanged","useCalendar","selected","firstDayOfWeek","calendarPaddingRef","useRef","doFocusChange","offsetDiff","current","e","document","activeElement","buttons","querySelectorAll","changeFocusTo","async","nextButton","setAttribute","focus","forEach","el","i","newNodeKey","length","isBackDisabled","flushSync","subtractMonth","newButtons","isForwardDisabled","addMonth","handleArrowNavigation","event","key","preventDefault","handleTabInside","focusableElements","_a","firstElement","lastElement","shiftKey","isFocusableDate","dateInfo","selectable","prevMonth","nextMonth","toString","getDate","handleGotoEdgeMonth","handleYearChange","target","value","year","Number","parseInt","isNaN","expectedDate","Date","addedOffset","handleMonthChange","yearDiff","monthDiff","yearSelectOptions","getYearSelectOptions","monthSelectOptions","getMonthSelectOptions","jsx","className","cn","children","onKeyDown","jsxs","onClick","ArrowLeftIcon","variant","bold","ArrowRightIcon","onChange","map","label","ChevronDownIcon","calendar","month","weekday","weeks","week","weekIndex","index","today","dateObj","tabIndex","toLowerCase","disabled","displayName"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Calendar.js","sources":["../../../../../src/components/datepicker/internal/Calendar.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport React, { forwardRef, useCallback, useEffect, useReducer, useRef } from \"react\";\nimport { flushSync } from \"react-dom\";\nimport { Density } from \"../../../core\";\nimport { useId } from \"../../../hooks\";\nimport { ArrowLeftIcon, ArrowRightIcon, ChevronDownIcon } from \"../../icon\";\nimport type { YearsToShow } from \"../types\";\nimport { calendarInitializer, calendarReducer } from \"./calendarReducer\";\nimport { useCalendar, UseCalendarProps } from \"./useCalendar\";\nimport {\n addMonth,\n subtractMonth,\n isBackDisabled,\n isForwardDisabled,\n getYearSelectOptions,\n getMonthSelectOptions,\n DateInfo,\n getInitialDateShown,\n DEFAULT_YEARS_TO_SHOW,\n} from \"./utils\";\n\ninterface CalendarProps\n extends Omit<UseCalendarProps, \"date\" | \"onOffsetChanged\" | \"offset\" | \"firstDayOfWeek\" | \"selected\"> {\n date: Date | null;\n density?: Density;\n defaultSelected?: Date;\n hidden?: boolean;\n days?: string[];\n months?: string[];\n monthLabel?: string;\n yearLabel?: string;\n yearsToShow?: YearsToShow;\n onTabOutside: React.KeyboardEventHandler;\n}\n\nconst defaultMonths = [\n \"Januar\",\n \"Februar\",\n \"Mars\",\n \"April\",\n \"Mai\",\n \"Juni\",\n \"Juli\",\n \"August\",\n \"September\",\n \"Oktober\",\n \"November\",\n \"Desember\",\n];\n\nconst defaultDays = [\"man\", \"tir\", \"ons\", \"tor\", \"fre\", \"lør\", \"søn\"];\n\nexport const Calendar = forwardRef<HTMLDivElement, CalendarProps>((props, ref) => {\n const {\n hidden,\n date,\n defaultSelected,\n density,\n minDate,\n maxDate,\n days = defaultDays,\n months = defaultMonths,\n monthLabel = \"Velg måned\",\n yearLabel = \"Velg år\",\n yearsToShow = DEFAULT_YEARS_TO_SHOW,\n onTabOutside,\n ...rest\n } = props;\n\n const id = useId(\"jkl-calendar\");\n\n const [{ offset, selectedDate, shownDate }, dispatch] = useReducer(\n calendarReducer,\n getInitialDateShown(date, defaultSelected, minDate, maxDate),\n calendarInitializer,\n );\n\n const shownMonth = shownDate.getMonth();\n const shownYear = shownDate.getFullYear();\n\n useEffect(() => {\n dispatch({\n type: \"SET_SELECTED_DATE\",\n newDate: getInitialDateShown(date, defaultSelected, minDate, maxDate),\n });\n }, [date, defaultSelected, minDate, maxDate]);\n\n const onOffsetChanged = useCallback((newOffset: number) => {\n dispatch({\n type: \"SET_OFFSET\",\n newOffset,\n });\n }, []);\n\n const { calendars, getBackProps, getDateProps, getForwardProps, handleOffsetChanged } = useCalendar({\n date: selectedDate,\n selected: selectedDate,\n minDate,\n maxDate,\n offset,\n onOffsetChanged,\n firstDayOfWeek: 1,\n ...rest,\n });\n\n /// Calendar keyboard navigation\n\n const calendarPaddingRef = useRef<HTMLDivElement>(null);\n const doFocusChange = useCallback(\n (offsetDiff: number) => {\n if (!calendarPaddingRef.current) {\n return;\n }\n\n const e = document.activeElement;\n const buttons = calendarPaddingRef.current.querySelectorAll<HTMLButtonElement>(\n 'button.jkl-calendar-date-button:not([data-adjacent=\"true\"]',\n );\n\n const changeFocusTo = async (nextButton: HTMLButtonElement) => {\n e?.setAttribute(\"tabindex\", \"-1\");\n nextButton.setAttribute(\"tabindex\", \"0\");\n nextButton.focus();\n };\n\n buttons.forEach((el, i) => {\n const newNodeKey = i + offsetDiff;\n\n if (el == e) {\n if (newNodeKey <= buttons.length - 1 && newNodeKey >= 0) {\n changeFocusTo(buttons[newNodeKey]);\n } else if (offsetDiff < 0) {\n if (isBackDisabled({ calendars, minDate })) {\n return;\n }\n\n // Hvis newNodeKey er utenfor samlingen med knapper så har vi prøvd å gå til\n // en dag utenfor måneden. Er offsetDiff negativ så har vi gått tilbake en\n // måned.\n flushSync(() => {\n handleOffsetChanged(offset - subtractMonth({ calendars, offset: 1, minDate }));\n });\n if (!calendarPaddingRef.current) {\n return;\n }\n const newButtons = calendarPaddingRef.current.querySelectorAll<HTMLButtonElement>(\n 'button.jkl-calendar-date-button:not([data-adjacent=\"true\"]',\n );\n // + - = -\n if (newButtons[newButtons.length + newNodeKey]) {\n // Sørg for at ikke både 1. i måneden og valgt dag er fokuserbare\n newButtons[0].setAttribute(\"tabindex\", \"-1\");\n changeFocusTo(newButtons[newButtons.length + newNodeKey]);\n }\n } else {\n if (isForwardDisabled({ calendars, maxDate })) {\n return;\n }\n\n // Hvis newNodeKey er utenfor samlingen med knapper så har vi prøvd å gå til\n // en dag utenfor måneden. Er offsetDiff positiv så har vi gått frem en\n // måned.\n flushSync(() => {\n handleOffsetChanged(offset + addMonth({ calendars, offset: 1, maxDate }));\n });\n if (!calendarPaddingRef.current) {\n return;\n }\n const newButtons = calendarPaddingRef.current.querySelectorAll<HTMLButtonElement>(\n 'button.jkl-calendar-date-button:not([data-adjacent=\"true\"]',\n );\n // NewNodeKey er basert på forrige måneds liste med knapper. For at verdien skal bli\n // riktig i vår nye måned må vi trekke fra anntal dager fra forrige måned.\n if (newButtons[newNodeKey - buttons.length]) {\n // Sørg for at ikke både 1. i måneden og valgt dag er fokuserbare\n newButtons[0].setAttribute(\"tabindex\", \"-1\");\n changeFocusTo(newButtons[newNodeKey - buttons.length]);\n }\n }\n }\n });\n },\n [handleOffsetChanged, calendarPaddingRef, offset, calendars, maxDate, minDate],\n );\n\n const handleArrowNavigation = useCallback(\n (event: React.KeyboardEvent) => {\n switch (event.key) {\n case \"ArrowUp\":\n doFocusChange(-7);\n event.preventDefault();\n break;\n case \"ArrowRight\":\n doFocusChange(1);\n event.preventDefault();\n break;\n case \"ArrowDown\":\n doFocusChange(7);\n event.preventDefault();\n break;\n case \"ArrowLeft\":\n doFocusChange(-1);\n event.preventDefault();\n break;\n default:\n break;\n }\n },\n [doFocusChange],\n );\n\n const handleTabInside: React.KeyboardEventHandler = useCallback((event) => {\n if (event.key !== \"Tab\") return;\n\n const focusableElements = calendarPaddingRef.current?.querySelectorAll<HTMLElement>(\n 'button:not([disabled]):not([tabindex=\"-1\"]), select',\n );\n\n if (!focusableElements) return;\n\n const firstElement = focusableElements[0];\n const lastElement = focusableElements[focusableElements.length - 1];\n\n if (!event.shiftKey && document.activeElement === lastElement) {\n firstElement.focus();\n event.preventDefault();\n } else if (event.shiftKey && document.activeElement === firstElement) {\n lastElement.focus();\n event.preventDefault();\n }\n }, []);\n\n const isFocusableDate = useCallback(\n (dateInfo: DateInfo) => {\n const { date, selected, selectable, prevMonth, nextMonth } = dateInfo;\n\n // Datoen kan ikke velges\n if (!selectable) {\n return false;\n }\n // Datoen er valgt dato\n if (selected) {\n return true;\n }\n // Datoen er første valgbare dato\n if (date.toString() === minDate?.toString()) {\n return true;\n }\n\n // Datoen er første i måneden som vises\n if (\n !prevMonth &&\n !nextMonth &&\n shownDate.getFullYear() === date.getFullYear() &&\n selectedDate.getMonth() !== date.getMonth() &&\n date.getDate() === 1\n ) {\n return true;\n }\n\n return false;\n },\n [shownDate, minDate, selectedDate],\n );\n\n const handleGotoEdgeMonth = useCallback(() => {\n if (\n // Vi er i ferd med å gå til første måned\n minDate &&\n shownDate.getFullYear() - minDate.getFullYear() === 0 &&\n shownDate.getMonth() - minDate.getMonth() === 1\n ) {\n // Fokuser på \"neste månded\"-knappen\n document.querySelectorAll<HTMLButtonElement>(\".jkl-calendar-navigation__arrow\")[1].focus();\n } else if (\n // Vi er i ferd med å gå til siste måned\n maxDate &&\n maxDate.getFullYear() - shownDate.getFullYear() === 0 &&\n maxDate.getMonth() - shownDate.getMonth() === 1\n ) {\n // Fokuser på \"forrige månded\"-knappen\n document.querySelectorAll<HTMLButtonElement>(\".jkl-calendar-navigation__arrow\")[0].focus();\n }\n }, [minDate, maxDate, shownDate]);\n\n /// Extended variant events\n\n const handleYearChange = useCallback<React.ChangeEventHandler<HTMLSelectElement>>(\n (event) => {\n if (event.target.value.length !== 4) {\n return;\n }\n\n const year: number = Number.parseInt(event.target.value);\n if (Number.isNaN(year)) {\n return;\n }\n\n let offset = (year - shownDate.getFullYear()) * 12;\n const expectedDate = new Date(shownDate.getFullYear(), shownDate.getMonth() + offset, shownDate.getDate());\n\n // Pass på at vi ikke hopper forbi maks. eller min. dato\n if (\n maxDate &&\n maxDate.getFullYear() === expectedDate.getFullYear() &&\n maxDate.getMonth() < expectedDate.getMonth()\n ) {\n offset -= expectedDate.getMonth() - maxDate.getMonth();\n } else if (\n minDate &&\n minDate.getFullYear() === expectedDate.getFullYear() &&\n minDate.getMonth() > expectedDate.getMonth()\n ) {\n offset += minDate.getMonth() - expectedDate.getMonth();\n }\n\n dispatch({\n type: \"ADD_OFFSET\",\n addedOffset: offset,\n });\n\n return;\n },\n [shownDate, minDate, maxDate],\n );\n\n const handleMonthChange = useCallback<React.ChangeEventHandler<HTMLSelectElement>>(\n (event) => {\n if (!selectedDate && !date) {\n return;\n }\n\n const yearDiff = shownDate.getFullYear() - (selectedDate || new Date()).getFullYear();\n const monthDiff = Number.parseInt(event.target.value) - (selectedDate || new Date()).getMonth();\n\n dispatch({\n type: \"SET_OFFSET\",\n newOffset: yearDiff * 12 + monthDiff,\n });\n\n return;\n },\n [selectedDate, date, shownDate],\n );\n\n const yearSelectOptions = getYearSelectOptions(shownYear, minDate, maxDate, yearsToShow);\n const monthSelectOptions = getMonthSelectOptions(shownYear, months, minDate, maxDate);\n\n return (\n <div\n ref={ref}\n id={id}\n className={clsx(\"jkl-calendar\", {\n \"jkl-calendar--hidden\": hidden,\n })}\n data-testid=\"jkl-calendar\"\n >\n {/* Vi lytter på på trykk på Tab inne i kalenderen for å håndtere fokus */}\n {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */}\n <div className=\"jkl-calendar__padding\" ref={calendarPaddingRef} onKeyDown={handleTabInside}>\n <fieldset className=\"jkl-calendar-navigation\">\n <div>\n <button\n {...getBackProps({ calendars, onClick: handleGotoEdgeMonth })}\n className=\"jkl-calendar-navigation__arrow\"\n type=\"button\"\n >\n <ArrowLeftIcon variant=\"medium\" bold />\n </button>\n <button\n {...getForwardProps({ calendars, onClick: handleGotoEdgeMonth })}\n className=\"jkl-calendar-navigation__arrow\"\n type=\"button\"\n >\n <ArrowRightIcon variant=\"medium\" bold />\n </button>\n </div>\n <div>\n <div className=\"jkl-calendar-navigation-dropdown\">\n <select\n onChange={handleMonthChange}\n className=\"jkl-calendar-navigation-dropdown__select\"\n aria-label={monthLabel}\n value={shownMonth.toString()}\n >\n {monthSelectOptions.map(({ label, value }) => (\n <option key={value} value={value}>\n {label}\n </option>\n ))}\n </select>\n <ChevronDownIcon bold className=\"jkl-calendar-navigation-dropdown__chevron\" />\n </div>\n <div className=\"jkl-calendar-navigation-dropdown\">\n <select\n onChange={handleYearChange}\n className=\"jkl-calendar-navigation-dropdown__select\"\n aria-label={yearLabel}\n value={shownYear.toString()}\n >\n {yearSelectOptions.map((year) => (\n <option key={year} value={year}>\n {year}\n </option>\n ))}\n </select>\n <ChevronDownIcon bold className=\"jkl-calendar-navigation-dropdown__chevron\" />\n </div>\n </div>\n </fieldset>\n {calendars.map((calendar) => (\n <table\n className=\"jkl-calendar-table\"\n key={`${calendar.month}${calendar.year}`}\n data-testid=\"jkl-datepicker-calendar\"\n >\n <caption className=\"jkl-sr-only\">\n {months[calendar.month]}, {calendar.year}\n </caption>\n <thead>\n <tr>\n {days.map((weekday) => (\n <th key={`${calendar.month}${calendar.year}${weekday}`}>{weekday}</th>\n ))}\n </tr>\n </thead>\n <tbody data-testid=\"jkl-datepicker-dates\">\n {calendar.weeks.map((week, weekIndex) => (\n <tr key={`${calendar.month}${calendar.year}${weekIndex}`}>\n {week.map((dateInfo, index) => {\n const key = `${calendar.month}${calendar.year}${weekIndex}${index}`;\n if (typeof dateInfo === \"string\") {\n return (\n <td className=\"jkl-calendar__date jkl-calendar__date--empty\" key={key}>\n {dateInfo}\n </td>\n );\n }\n const { date, selectable, today, prevMonth, nextMonth } = dateInfo;\n\n return (\n <td key={key}>\n <button\n {...getDateProps({\n dateObj: dateInfo,\n })}\n type=\"button\"\n className=\"jkl-calendar-date-button\"\n tabIndex={isFocusableDate(dateInfo) ? 0 : -1}\n aria-label={`${date.getDate()}. ${months[\n date.getMonth()\n ].toLowerCase()}`}\n aria-current={today ? \"date\" : undefined}\n data-adjacent={prevMonth || nextMonth ? \"true\" : undefined}\n disabled={!selectable}\n onKeyDown={handleArrowNavigation}\n >\n <span aria-hidden=\"true\">{date.getDate()}</span>\n </button>\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n ))}\n </div>\n </div>\n );\n});\n\nCalendar.displayName = \"Calendar\";\n"],"names":["defaultMonths","defaultDays","Calendar","forwardRef","props","ref","hidden","date","defaultSelected","density","minDate","maxDate","days","months","monthLabel","yearLabel","yearsToShow","DEFAULT_YEARS_TO_SHOW","onTabOutside","rest","id","useId","offset","selectedDate","shownDate","dispatch","useReducer","calendarReducer","getInitialDateShown","calendarInitializer","shownMonth","getMonth","shownYear","getFullYear","useEffect","type","newDate","onOffsetChanged","useCallback","newOffset","calendars","getBackProps","getDateProps","getForwardProps","handleOffsetChanged","useCalendar","selected","firstDayOfWeek","calendarPaddingRef","useRef","doFocusChange","offsetDiff","current","e","document","activeElement","buttons","querySelectorAll","changeFocusTo","async","nextButton","setAttribute","focus","forEach","el","i","newNodeKey","length","isBackDisabled","flushSync","subtractMonth","newButtons","isForwardDisabled","addMonth","handleArrowNavigation","event","key","preventDefault","handleTabInside","focusableElements","_a","firstElement","lastElement","shiftKey","isFocusableDate","dateInfo","selectable","prevMonth","nextMonth","toString","getDate","handleGotoEdgeMonth","handleYearChange","target","value","year","Number","parseInt","isNaN","expectedDate","Date","addedOffset","handleMonthChange","yearDiff","monthDiff","yearSelectOptions","getYearSelectOptions","monthSelectOptions","getMonthSelectOptions","jsx","className","clsx","children","onKeyDown","jsxs","onClick","ArrowLeftIcon","variant","bold","ArrowRightIcon","onChange","map","label","ChevronDownIcon","calendar","month","weekday","weeks","week","weekIndex","index","today","dateObj","tabIndex","toLowerCase","disabled","displayName"],"mappings":"+oEAmCA,MAAMA,EAAgB,CAClB,SACA,UACA,OACA,QACA,MACA,OACA,OACA,SACA,YACA,UACA,WACA,YAGEC,EAAc,CAAC,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,OAElDC,EAAWC,GAA0C,CAACC,EAAOC,KAChE,MACFC,OAAAA,EACAC,KAAAA,EACAC,gBAAAA,EACAC,QAAAA,EACAC,QAAAA,EACAC,QAAAA,EACAC,KAAAA,EAAOX,EACPY,OAAAA,EAASb,EACTc,WAAAA,EAAa,aACbC,UAAAA,EAAY,UACZC,YAAAA,EAAcC,EACdC,aAAAA,KACGC,GACHf,EAEEgB,EAAKC,EAAM,kBAERC,OAAAA,EAAQC,aAAAA,EAAcC,UAAAA,GAAaC,GAAYC,EACpDC,EACAC,EAAoBrB,EAAMC,EAAiBE,EAASC,GACpDkB,GAGEC,EAAaN,EAAUO,WACvBC,EAAYR,EAAUS,cAE5BC,GAAU,KACGT,EAAA,CACLU,KAAM,oBACNC,QAASR,EAAoBrB,EAAMC,EAAiBE,EAASC,IAChE,GACF,CAACJ,EAAMC,EAAiBE,EAASC,IAE9B0B,MAAAA,EAAkBC,GAAaC,IACxBd,EAAA,CACLU,KAAM,aACNI,UAAAA,GACH,GACF,KAEKC,UAAAA,EAAWC,aAAAA,EAAcC,aAAAA,EAAcC,gBAAAA,EAAiBC,oBAAAA,GAAwBC,EAAY,CAChGtC,KAAMgB,EACNuB,SAAUvB,EACVb,QAAAA,EACAC,QAAAA,EACAW,OAAAA,EACAe,gBAAAA,EACAU,eAAgB,KACb5B,IAKD6B,EAAqBC,EAAuB,MAC5CC,GAAgBZ,GACjBa,IACO,IAACH,EAAmBI,QACpB,OAGJ,MAAMC,EAAIC,SAASC,cACbC,EAAUR,EAAmBI,QAAQK,iBACvC,8DAGEC,EAAgBC,MAAOC,IACtB,MAAAP,GAAAA,EAAAQ,aAAa,WAAY,MACjBD,EAAAC,aAAa,WAAY,KACpCD,EAAWE,OAAM,EAGbN,EAAAO,SAAQ,CAACC,EAAIC,KACjB,MAAMC,EAAaD,EAAId,EAEvB,GAAIa,GAAMX,EACN,GAAIa,GAAcV,EAAQW,OAAS,GAAKD,GAAc,EACpCR,EAAAF,EAAQU,SAAW,GAC1Bf,EAAa,EAAG,CACnBiB,GAAAA,EAAe,CAAE5B,UAAAA,EAAW9B,QAAAA,MAOhC2D,GAAU,KACczB,EAAAtB,EAASgD,EAAc,CAAE9B,UAAAA,EAAWlB,OAAQ,EAAGZ,QAAAA,IAAU,KAE5EsC,EAAmBI,SACpB,OAEEmB,MAAAA,EAAavB,EAAmBI,QAAQK,iBAC1C,8DAGAc,EAAWA,EAAWJ,OAASD,KAE/BK,EAAW,GAAGV,aAAa,WAAY,MACvCH,EAAca,EAAWA,EAAWJ,OAASD,IACjD,KACG,CACCM,GAAAA,EAAkB,CAAEhC,UAAAA,EAAW7B,QAAAA,MAOnC0D,GAAU,KACczB,EAAAtB,EAASmD,EAAS,CAAEjC,UAAAA,EAAWlB,OAAQ,EAAGX,QAAAA,IAAU,KAEvEqC,EAAmBI,SACpB,OAEEmB,MAAAA,EAAavB,EAAmBI,QAAQK,iBAC1C,8DAIAc,EAAWL,EAAaV,EAAQW,UAEhCI,EAAW,GAAGV,aAAa,WAAY,MACvCH,EAAca,EAAWL,EAAaV,EAAQW,SAEtD,IAEP,GAEL,CAACvB,EAAqBI,EAAoB1B,EAAQkB,EAAW7B,EAASD,IAGpEgE,GAAwBpC,GACzBqC,IACG,OAAQA,EAAMC,KACV,IAAK,UACD1B,IAAc,GACdyB,EAAME,iBACN,MACJ,IAAK,aACD3B,GAAc,GACdyB,EAAME,iBACN,MACJ,IAAK,YACD3B,GAAc,GACdyB,EAAME,iBACN,MACJ,IAAK,YACD3B,IAAc,GACdyB,EAAME,iBAId,GAEJ,CAAC3B,KAGC4B,GAA8CxC,GAAaqC,UACzDA,GAAc,QAAdA,EAAMC,IAAe,OAEnB,MAAAG,EAAoB,OAAAC,EAAAhC,EAAmBI,gBAAnB4B,EAA4BvB,iBAClD,uDAGJ,IAAKsB,EAAmB,OAElBE,MAAAA,EAAeF,EAAkB,GACjCG,EAAcH,EAAkBA,EAAkBZ,OAAS,GAE5DQ,EAAMQ,UAAY7B,SAASC,gBAAkB2B,EAGvCP,EAAMQ,UAAY7B,SAASC,gBAAkB0B,IACpDC,EAAYpB,QACZa,EAAME,mBAJNI,EAAanB,QACba,EAAME,iBAGe,GAE1B,IAEGO,GAAkB9C,GACnB+C,IACS,MAAE9E,KAAAA,EAAMuC,SAAAA,EAAUwC,WAAAA,EAAYC,UAAAA,EAAWC,UAAAA,GAAcH,EAG7D,QAAKC,MAIDxC,GAIAvC,EAAKkF,cAAe,MAAA/E,OAAA,EAAAA,EAAS+E,cAM5BF,GACAC,GACDhE,EAAUS,gBAAkB1B,EAAK0B,eACjCV,EAAaQ,aAAexB,EAAKwB,YACd,IAAnBxB,EAAKmF,WAjBE,GAwBf,CAAClE,EAAWd,EAASa,IAGnBoE,GAAsBrD,GAAY,KAGhC5B,GACAc,EAAUS,cAAgBvB,EAAQuB,eAAkB,GACpDT,EAAUO,WAAarB,EAAQqB,YAAe,EAG9CuB,SAASG,iBAAoC,mCAAmC,GAAGK,QAGnFnD,GACAA,EAAQsB,cAAgBT,EAAUS,eAAkB,GACpDtB,EAAQoB,WAAaP,EAAUO,YAAe,GAG9CuB,SAASG,iBAAoC,mCAAmC,GAAGK,OAAM,GAE9F,CAACpD,EAASC,EAASa,IAIhBoE,GAAmBtD,GACpBqC,IACOA,GAA8B,IAA9BA,EAAMkB,OAAOC,MAAM3B,OACnB,OAGJ,MAAM4B,EAAeC,OAAOC,SAAStB,EAAMkB,OAAOC,OAC9C,GAAAE,OAAOE,MAAMH,GACb,OAGJ,IAAIzE,EAA4C,IAAlCyE,EAAOvE,EAAUS,eAC/B,MAAMkE,EAAe,IAAIC,KAAK5E,EAAUS,cAAeT,EAAUO,WAAaT,EAAQE,EAAUkE,WAI5F/E,GACAA,EAAQsB,gBAAkBkE,EAAalE,eACvCtB,EAAQoB,WAAaoE,EAAapE,WAElCT,GAAU6E,EAAapE,WAAapB,EAAQoB,WAE5CrB,GACAA,EAAQuB,gBAAkBkE,EAAalE,eACvCvB,EAAQqB,WAAaoE,EAAapE,aAElCT,GAAUZ,EAAQqB,WAAaoE,EAAapE,YAGvCN,EAAA,CACLU,KAAM,aACNkE,YAAa/E,GAChB,GAIL,CAACE,EAAWd,EAASC,IAGnB2F,GAAoBhE,GACrBqC,IACO,IAACpD,IAAiBhB,EAClB,OAGEgG,MAAAA,EAAW/E,EAAUS,eAAiBV,GAAoB,IAAA6E,MAAQnE,cAClEuE,EAAYR,OAAOC,SAAStB,EAAMkB,OAAOC,QAAUvE,GAAgB,IAAI6E,MAAQrE,WAE5EN,EAAA,CACLU,KAAM,aACNI,UAAsB,GAAXgE,EAAgBC,GAC9B,GAIL,CAACjF,EAAchB,EAAMiB,IAGnBiF,GAAoBC,EAAqB1E,EAAWtB,EAASC,EAASK,GACtE2F,GAAqBC,EAAsB5E,EAAWnB,EAAQH,EAASC,GAGzE,OAAAkG,EAAC,MAAA,CACGxG,IAAAA,EACAe,GAAAA,EACA0F,UAAWC,EAAK,eAAgB,CAC5B,uBAAwBzG,IAE5B,cAAY,eAIZ0G,WAAC,MAAI,CAAAF,UAAU,wBAAwBzG,IAAK2C,EAAoBiE,UAAWnC,GACvEkC,SAAA,CAACE,EAAA,WAAA,CAASJ,UAAU,0BAChBE,SAAA,CAAAE,EAAC,MACG,CAAAF,SAAA,CAAAH,EAAC,SAAA,IACOpE,EAAa,CAAED,UAAAA,EAAW2E,QAASxB,KACvCmB,UAAU,iCACV3E,KAAK,SAEL6E,SAACH,EAAAO,EAAA,CAAcC,QAAQ,SAASC,MAAI,MAExCT,EAAC,SAAA,IACOlE,EAAgB,CAAEH,UAAAA,EAAW2E,QAASxB,KAC1CmB,UAAU,iCACV3E,KAAK,SAEL6E,SAACH,EAAAU,EAAA,CAAeF,QAAQ,SAASC,MAAI,WAG5C,MACG,CAAAN,SAAA,CAACE,EAAA,MAAA,CAAIJ,UAAU,mCACXE,SAAA,CAAAH,EAAC,SAAA,CACGW,SAAUlB,GACVQ,UAAU,2CACV,aAAYhG,EACZgF,MAAOhE,EAAW2D,WAEjBuB,SAAmBL,GAAAc,KAAI,EAAGC,MAAAA,EAAO5B,MAAAA,KAC9Be,EAAC,SAAmB,CAAAf,MAAAA,EACfkB,SADQU,GAAA5B,OAKpBe,EAAAc,EAAA,CAAgBL,MAAI,EAACR,UAAU,iDAEpCI,EAAC,MAAI,CAAAJ,UAAU,mCACXE,SAAA,CAAAH,EAAC,SAAA,CACGW,SAAU5B,GACVkB,UAAU,2CACV,aAAY/F,EACZ+E,MAAO9D,EAAUyD,WAEhBuB,SAAAP,GAAkBgB,KAAK1B,GACpBc,EAAC,UAAkBf,MAAOC,EACrBiB,SADQjB,GAAAA,OAKpBc,EAAAc,EAAA,CAAgBL,MAAI,EAACR,UAAU,uDAI3CtE,EAAUiF,KAAKG,GACZV,EAAC,QAAA,CACGJ,UAAU,qBAEV,cAAY,0BAEZE,SAAA,CAACE,EAAA,UAAA,CAAQJ,UAAU,cACdE,SAAA,CAAAnG,EAAO+G,EAASC,OAAO,KAAGD,EAAS7B,QAExCc,EAAC,SACGG,SAACH,EAAA,KAAA,CACIG,WAAKS,KAAKK,GACPjB,EAAC,KAAwD,CAAAG,SAAAc,GAAhD,GAAGF,EAASC,QAAQD,EAAS7B,OAAO+B,aAIxD,QAAM,CAAA,cAAY,uBACdd,SAAAY,EAASG,MAAMN,KAAI,CAACO,EAAMC,MACtB,KACI,CAAAjB,SAAAgB,EAAKP,KAAI,CAACpC,EAAU6C,KACXtD,MAAAA,EAAM,GAAGgD,EAASC,QAAQD,EAAS7B,OAAOkC,IAAYC,IACxD,GAAoB,iBAAb7C,EAEF,OAAAwB,EAAA,KAAA,CAAGC,UAAU,+CACTE,YAD6DpC,GAKpE,MAAErE,KAAAA,EAAM+E,WAAAA,EAAY6C,MAAAA,EAAO5C,UAAAA,EAAWC,UAAAA,GAAcH,EAE1D,SACK,KACG,CAAA2B,SAAAH,EAAC,SAAA,IACOnE,EAAa,CACb0F,QAAS/C,IAEblD,KAAK,SACL2E,UAAU,2BACVuB,SAAUjD,GAAgBC,GAAY,GAAI,EAC1C,aAAY,GAAG9E,EAAKmF,cAAc7E,EAC9BN,EAAKwB,YACPuG,gBACF,eAAcH,EAAQ,YAAS,EAC/B,gBAAe5C,GAAaC,EAAY,YAAS,EACjD+C,UAAWjD,EACX2B,UAAWvC,GAEXsC,WAAC,OAAK,CAAA,cAAY,OAAQA,SAAAzG,EAAKmF,eAhB9Bd,EAkBT,KA/BH,GAAGgD,EAASC,QAAQD,EAAS7B,OAAOkC,WAfhD,GAAGL,EAASC,QAAQD,EAAS7B,cAsD9C,IAKZ7F,EAASsI,YAAc"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{jsx as o,jsxs as i}from"react/jsx-runtime";import{useState as t}from"react";import{FeedbackContextProvider as n}from"./feedbackContext.js";import{Followup as s}from"./followup/Followup.js";import{MainQuestion as c}from"./main-question/MainQuestion.js";import"../checkbox/Checkbox.js";import"../../hooks/useScreen/useScreen.js";import"../../hooks/useId/useId.js";import"../tooltip/Tooltip.js";import"../tooltip/TooltipContent.js";import"../tooltip/TooltipTrigger.js";import"../icon/Icon.js";import"../icon/icons/animated/ArrowVerticalAnimated.js";import"../icon/icons/animated/ArrowHorizontalAnimated.js";import"../icon/icons/animated/PlusRemoveAnimated.js";import"../icon/icons/ArrowDownIcon.js";import"../icon/icons/ArrowLeftIcon.js";import"../icon/icons/ArrowNorthEastIcon.js";import"../icon/icons/ArrowRightIcon.js";import"../icon/icons/ArrowUpIcon.js";import"../icon/icons/CalendarIcon.js";import"../icon/icons/CheckIcon.js";import"../icon/icons/ChevronDownIcon.js";import"../icon/icons/ChevronLeftIcon.js";import"../icon/icons/ChevronRightIcon.js";import"../icon/icons/ChevronUpIcon.js";import"../icon/icons/CloseIcon.js";import"../icon/icons/CopyIcon.js";import"../icon/icons/DotsIcon.js";import"../icon/icons/DragIcon.js";import"../icon/icons/ErrorIcon.js";import"../icon/icons/GreenCheckIcon.js";import"../icon/icons/HamburgerIcon.js";import"../icon/icons/InfoIcon.js";import"../icon/icons/LinkIcon.js";import"../icon/icons/PlusIcon.js";import"../icon/icons/QuestionIcon.js";import"../icon/icons/RedCrossIcon.js";import"../icon/icons/SearchIcon.js";import"../icon/icons/SuccessIcon.js";import"../icon/icons/WarningIcon.js";import"../icon/icons/MinusIcon.js";import"../icon/icons/ThumbDownIcon.js";import"../icon/icons/ThumbUpIcon.js";import"../icon/icons/TrashCanIcon.js";import"../icon/icons/PenIcon.js";import"../input-group/InputGroup.js";import"./followup/followupContext.js";import"./main-question/mainQuestionContext.js";import"../radio-button/RadioButton.js";import"../radio-button/radioGroupContext.js";import"../radio-button/BaseRadioButton.js";import"../text-input/BaseTextArea.js";import"../text-input/BaseTextInput.js";import"../text-input/TextArea.js";import"../text-input/TextInput.js";import{ContactQuestion as r}from"./questions/ContactQuestion.js";const e=({className:e,followup:p,contactQuestion:m,counter:a,...j})=>{const[u,l]=t(!1),[d,I]=t(!1),[b,C]=t(!1),[h,w]=t(!1);return o("div",{className:`jkl-feedback ${e||""}`,"data-testid":"feedback",children:i(n,{value:{feedbackSubmitted:u,followupStarted:d,followupSubmitted:b,contactSubmitted:h,counter:a,setFeedbackSubmitted:l,setFollowupStarted:I,setFollowupSubmitted:C,setContactSubmitted:w},children:[!d&&o(c,{...j}),u&&!h&&p&&o(s,{...p}),m&&o("div",{"aria-live":"polite",children:(!p&&u||b)&&o(r,{...m})})]})})};export{e as Feedback};
|
|
2
|
+
//# sourceMappingURL=Feedback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Feedback.js","sources":["../../../../src/components/feedback/Feedback.tsx"],"sourcesContent":["import React, { ReactElement, ReactNode, useState, ComponentProps } from \"react\";\nimport { BaseTextAreaProps } from \"../text-input\";\nimport { FeedbackContextProvider } from \"./feedbackContext\";\nimport { Followup } from \"./followup/Followup\";\nimport { MainQuestion } from \"./main-question/MainQuestion\";\nimport { ContactQuestion } from \"./questions\";\nimport { FeedbackOption, FeedbackType } from \"./types\";\n\ntype FollowupProps = ComponentProps<typeof Followup>;\ntype ContactQuestionProps = ComponentProps<typeof ContactQuestion>;\n\ntype Props = {\n className?: string;\n /** Velg typen alternativer, Smiley eller RadioButtons. */\n type: \"radio\" | \"smiley\";\n /** Spørsmålet som stilles til brukeren */\n label: string;\n /** Hjelpetekst til hovedspørsmålet */\n helpLabel?: string;\n /** Svaralternativer til spørsmålet */\n options: FeedbackOption[];\n /** Dersom du vil stille et åpent spørsmål i tillegg kan du sette denne til en truthy verdi */\n addOnQuestion?:\n | {\n /** Spørsmålet du vil stille */\n label?: string;\n /** Eventuell hjelpetekst. Om du ikke spesifiserer en vil det vises en påminnelse om å ikke skrive inn personling informasjon. */\n helpLabel?: string;\n }\n | boolean;\n /** Lar deg tilpasse meldingen som kommer når brukeren sender inn tilbakemeldingen. */\n successMessage?: {\n title: string;\n children: ReactNode;\n };\n /**\n * Funksjon for å håndtere innsending av tilbakemelding\n * @param value Verdien av tilbakemeldingen. Dette er et objekt med følgende egenskaper:\n * - `feedbackValue`: Selve verdien av tilbakemeldingen (format varierer etter spørsmålstype)\n * - `intentionalSubmit`: Er `true` hvis brukeren aktivt sendte inn skjemaet, `false` hvis skjemaet ble sendt inn automatisk\n * - `message`: Eventuell utfyllende melding fra bruker. Blir kun sendt inn ved aktiv innsending\n */\n onSubmit: (value: FeedbackType) => void;\n\n followup?: FollowupProps;\n contactQuestion?: ContactQuestionProps;\n} & Pick<BaseTextAreaProps, \"counter\">;\n\nexport const Feedback = ({\n className,\n followup,\n contactQuestion,\n counter,\n ...mainQuestionProps\n}: Props): ReactElement => {\n const [feedbackSubmitted, setFeedbackSubmitted] = useState(false);\n const [followupStarted, setFollowupStarted] = useState(false);\n const [followupSubmitted, setFollowupSubmitted] = useState(false);\n const [contactSubmitted, setContactSubmitted] = useState(false);\n\n return (\n <div className={`jkl-feedback ${className || \"\"}`} data-testid=\"feedback\">\n <FeedbackContextProvider\n value={{\n feedbackSubmitted,\n followupStarted,\n followupSubmitted,\n contactSubmitted,\n counter,\n setFeedbackSubmitted,\n setFollowupStarted,\n setFollowupSubmitted,\n setContactSubmitted,\n }}\n >\n {!followupStarted && <MainQuestion {...mainQuestionProps} />}\n {feedbackSubmitted && !contactSubmitted && followup && <Followup {...followup} />}\n {contactQuestion && (\n <div aria-live=\"polite\">\n {/* Show contact question after followup, or after feedback if no followup */}\n {((!followup && feedbackSubmitted) || followupSubmitted) && (\n <ContactQuestion {...contactQuestion} />\n )}\n </div>\n )}\n </FeedbackContextProvider>\n </div>\n );\n};\n"],"names":["Feedback","className","followup","contactQuestion","counter","mainQuestionProps","feedbackSubmitted","setFeedbackSubmitted","useState","followupStarted","setFollowupStarted","followupSubmitted","setFollowupSubmitted","contactSubmitted","setContactSubmitted","jsx","children","jsxs","FeedbackContextProvider","value","MainQuestion","Followup","ContactQuestion"],"mappings":"wuEAgDO,MAAMA,EAAW,EACpBC,UAAAA,EACAC,SAAAA,EACAC,gBAAAA,EACAC,QAAAA,KACGC,MAEG,MAACC,EAAmBC,GAAwBC,GAAS,IACpDC,EAAiBC,GAAsBF,GAAS,IAChDG,EAAmBC,GAAwBJ,GAAS,IACpDK,EAAkBC,GAAuBN,GAAS,GAGrD,OAAAO,EAAC,OAAId,UAAW,gBAAgBA,GAAa,KAAM,cAAY,WAC3De,SAAAC,EAACC,EAAA,CACGC,MAAO,CACHb,kBAAAA,EACAG,gBAAAA,EACAE,kBAAAA,EACAE,iBAAAA,EACAT,QAAAA,EACAG,qBAAAA,EACAG,mBAAAA,EACAE,qBAAAA,EACAE,oBAAAA,GAGHE,SAAA,EAACP,GAAmBM,EAACK,EAAc,IAAGf,IACtCC,IAAsBO,GAAoBX,GAAaa,EAAAM,EAAA,IAAanB,IACpEC,GACGY,EAAC,MAAI,CAAA,YAAU,SAERC,WAACd,GAAYI,GAAsBK,IAClCI,EAACO,EAAiB,IAAGnB,UAKzC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{jsx as s}from"react/jsx-runtime";import{c as e}from"../../../clsx-BeLtu-UY.js";import{SuccessMessage as a}from"../message/Message.js";import"../message/FormErrorMessage.js";const r=({children:r,className:c,...m})=>s(a,{className:e("jkl-feedback__fade-in",c),...m,"aria-live":"polite",children:r});export{r as FeedbackSuccess};
|
|
2
|
+
//# sourceMappingURL=FeedbackSuccess.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FeedbackSuccess.js","sources":["../../../../src/components/feedback/FeedbackSuccess.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport React, { FC } from \"react\";\nimport { SuccessMessage, MessageProps } from \"../message\";\n\nexport const FeedbackSuccess: FC<MessageProps> = ({ children, className, ...rest }) => (\n <SuccessMessage className={clsx(\"jkl-feedback__fade-in\", className)} {...rest} aria-live=\"polite\">\n {children}\n </SuccessMessage>\n);\n"],"names":["FeedbackSuccess","children","className","rest","jsx","SuccessMessage","clsx"],"mappings":"oLAIO,MAAMA,EAAoC,EAAGC,SAAAA,EAAUC,UAAAA,KAAcC,KACxEC,EAACC,GAAeH,UAAWI,EAAK,wBAAyBJ,MAAgBC,EAAM,YAAU,SACpFF,SAAAA"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e={label:"Ikke fornøyd i det hele tatt",value:1},l={label:"Ikke fornøyd",value:2},a={label:"Verken fornøyd eller misfornøyd",value:3},r={label:"Fornøyd",value:4},d={label:"Veldig fornøyd",value:5};export{r as HAPPY,a as NEUTRAL,l as UNHAPPY,d as VERY_HAPPY,e as VERY_UNHAPPY};
|
|
2
|
+
//# sourceMappingURL=FeedbackValues.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FeedbackValues.js","sources":["../../../../src/components/feedback/FeedbackValues.tsx"],"sourcesContent":["import { FeedbackOption } from \"./types\";\n\nexport const VERY_UNHAPPY: FeedbackOption = { label: \"Ikke fornøyd i det hele tatt\", value: 1 };\nexport const UNHAPPY: FeedbackOption = { label: \"Ikke fornøyd\", value: 2 };\nexport const NEUTRAL: FeedbackOption = { label: \"Verken fornøyd eller misfornøyd\", value: 3 };\nexport const HAPPY: FeedbackOption = { label: \"Fornøyd\", value: 4 };\nexport const VERY_HAPPY: FeedbackOption = { label: \"Veldig fornøyd\", value: 5 };\n"],"names":["VERY_UNHAPPY","label","value","UNHAPPY","NEUTRAL","HAPPY","VERY_HAPPY"],"mappings":"AAEO,MAAMA,EAA+B,CAAEC,MAAO,+BAAgCC,MAAO,GAC/EC,EAA0B,CAAEF,MAAO,eAAgBC,MAAO,GAC1DE,EAA0B,CAAEH,MAAO,kCAAmCC,MAAO,GAC7EG,EAAwB,CAAEJ,MAAO,UAAWC,MAAO,GACnDI,EAA6B,CAAEL,MAAO,iBAAkBC,MAAO"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{jsx as t}from"react/jsx-runtime";import{createContext as e,useContext as o}from"react";const l=e({feedbackSubmitted:!1,followupStarted:!1,followupSubmitted:!1,contactSubmitted:!1,setFeedbackSubmitted:()=>null,setFollowupStarted:()=>null,setFollowupSubmitted:()=>null,setContactSubmitted:()=>null}),u=()=>o(l),a=({value:e,children:o})=>t(l.Provider,{value:e,children:o});export{a as FeedbackContextProvider,u as useFeedbackContext};
|
|
2
|
+
//# sourceMappingURL=feedbackContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feedbackContext.js","sources":["../../../../src/components/feedback/feedbackContext.tsx"],"sourcesContent":["import React, { createContext, FC, useContext } from \"react\";\nimport { WithChildren } from \"../..\";\nimport { BaseTextAreaProps } from \"../text-input\";\n\ntype FeedbackContext = {\n feedbackSubmitted: boolean;\n followupStarted: boolean;\n followupSubmitted: boolean;\n contactSubmitted: boolean;\n setFeedbackSubmitted: (state: boolean) => void;\n setFollowupStarted: (state: boolean) => void;\n setFollowupSubmitted: (state: boolean) => void;\n setContactSubmitted: (state: boolean) => void;\n} & Pick<BaseTextAreaProps, \"counter\">;\n\nconst initialState: FeedbackContext = {\n feedbackSubmitted: false,\n followupStarted: false,\n followupSubmitted: false,\n contactSubmitted: false,\n setFeedbackSubmitted: () => null,\n setFollowupStarted: () => null,\n setFollowupSubmitted: () => null,\n setContactSubmitted: () => null,\n};\n\nconst feedbackContext = createContext(initialState);\n\nexport const useFeedbackContext = (): FeedbackContext => useContext(feedbackContext);\n\ninterface FeedbackContextProviderProps extends WithChildren {\n value: FeedbackContext;\n}\n\nexport const FeedbackContextProvider: FC<FeedbackContextProviderProps> = ({ value, children }) => (\n <feedbackContext.Provider value={value}>{children}</feedbackContext.Provider>\n);\n"],"names":["feedbackContext","createContext","feedbackSubmitted","followupStarted","followupSubmitted","contactSubmitted","setFeedbackSubmitted","setFollowupStarted","setFollowupSubmitted","setContactSubmitted","useFeedbackContext","useContext","FeedbackContextProvider","value","children","jsx","Provider"],"mappings":"8FAeA,MAWMA,EAAkBC,EAXc,CAClCC,mBAAmB,EACnBC,iBAAiB,EACjBC,mBAAmB,EACnBC,kBAAkB,EAClBC,qBAAsB,IAAM,KAC5BC,mBAAoB,IAAM,KAC1BC,qBAAsB,IAAM,KAC5BC,oBAAqB,IAAM,OAKlBC,EAAqB,IAAuBC,EAAWX,GAMvDY,EAA4D,EAAGC,MAAAA,EAAOC,SAAAA,KAC/EC,EAACf,EAAgBgB,SAAhB,CAAyBH,MAAAA,EAAeC,SAAAA"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{jsx as o,jsxs as i}from"react/jsx-runtime";import{useState as t,useRef as s,useEffect as n,createElement as e}from"react";import"../../../hooks/useScreen/useScreen.js";import"../../../hooks/useId/useId.js";import"../../icon/Icon.js";import"../../icon/icons/animated/ArrowVerticalAnimated.js";import"../../icon/icons/animated/ArrowHorizontalAnimated.js";import"../../icon/icons/animated/PlusRemoveAnimated.js";import"../../icon/icons/ArrowDownIcon.js";import"../../icon/icons/ArrowLeftIcon.js";import"../../icon/icons/ArrowNorthEastIcon.js";import"../../icon/icons/ArrowRightIcon.js";import"../../icon/icons/ArrowUpIcon.js";import"../../icon/icons/CalendarIcon.js";import"../../icon/icons/CheckIcon.js";import"../../icon/icons/ChevronDownIcon.js";import"../../icon/icons/ChevronLeftIcon.js";import"../../icon/icons/ChevronRightIcon.js";import"../../icon/icons/ChevronUpIcon.js";import"../../icon/icons/CloseIcon.js";import"../../icon/icons/CopyIcon.js";import"../../icon/icons/DotsIcon.js";import"../../icon/icons/DragIcon.js";import"../../icon/icons/ErrorIcon.js";import"../../icon/icons/GreenCheckIcon.js";import"../../icon/icons/HamburgerIcon.js";import"../../icon/icons/InfoIcon.js";import"../../icon/icons/LinkIcon.js";import"../../icon/icons/PlusIcon.js";import"../../icon/icons/QuestionIcon.js";import"../../icon/icons/RedCrossIcon.js";import"../../icon/icons/SearchIcon.js";import"../../icon/icons/SuccessIcon.js";import"../../icon/icons/WarningIcon.js";import"../../icon/icons/MinusIcon.js";import"../../icon/icons/ThumbDownIcon.js";import"../../icon/icons/ThumbUpIcon.js";import"../../icon/icons/TrashCanIcon.js";import"../../icon/icons/PenIcon.js";import{PrimaryButton as r,SecondaryButton as c,TertiaryButton as m}from"../../button/Button.js";import"../../card/Card.js";import"../../card/CardImage.js";import"../../card/NavCard.js";import"../../checkbox/Checkbox.js";import"../../combobox/Combobox.js";import"../../cookie-consent/CookieConsentContext.js";import"react-dom";import"../../modal/Modal.js";import"react-a11y-dialog";import"../../list/List.js";import"../../list/ListItem.js";import"../../datepicker/DatePicker.js";import{useFeedbackContext as p}from"../feedbackContext.js";import{FeedbackSuccess as a}from"../FeedbackSuccess.js";import"../../tooltip/Tooltip.js";import"../../tooltip/TooltipContent.js";import"../../tooltip/TooltipTrigger.js";import"../../input-group/InputGroup.js";import{FollowUpProvider as l}from"./followupContext.js";import"../main-question/mainQuestionContext.js";import"../../radio-button/RadioButton.js";import"../../radio-button/radioGroupContext.js";import"../../radio-button/BaseRadioButton.js";import"../../text-input/BaseTextArea.js";import"../../text-input/BaseTextInput.js";import"../../text-input/TextArea.js";import"../../text-input/TextInput.js";import"../../../utilities/polymorphism/SlotComponent.js";import{getQuestionFromType as j}from"../utils.js";import"../../icon-button/IconButton.js";import"../../link/Link.js";import"../../link/NavLink.js";import"../../link-list/LinkList.js";import"../../message/Message.js";import"../../message/FormErrorMessage.js";import"../../popover/Popover.js";import"../../../../NativeSelect-CfNZEQF0.js";import"../../tag/Tag.js";import{useFollowup as u}from"./useFollowup.js";const d={title:"Takk, igjen!",children:"Vi setter pris på at du tok deg tid til å svare på flere spørsmål. Det hjelper oss med å gjøre nettsidene bedre for deg og alle andre som bruker dem."},k=({questions:k,successMessage:I=d,onSubmit:b})=>{const[h,g]=t(!1),f=s(null),x=u(k,b),{handleAbort:C,handleNext:v,step:w,submitted:S}=x,{followupStarted:N,setFollowupStarted:T,setFollowupSubmitted:A,contactSubmitted:y}=p();n((()=>{0!==w.number&&f.current&&f.current.focus()}),[w]),n((()=>{A(S)}),[S,A]);const F=j(k[w.number].type),L=w.isLast?r:c;return h?null:o("div",{"aria-live":"polite",children:i(l,{state:x,children:[!N&&i("div",{className:"jkl-feedback__fade-in",children:[o("p",{className:"jkl-heading-4 jkl-spacing-xl--top jkl-spacing-xs--bottom",children:"Har du tid til å svare på noen flere spørsmål?"}),o("p",{className:"jkl-body jkl-spacing-xl--bottom",children:"Det tar kun et minutt, og hjelper oss å lage bedre løsninger for deg."}),o(r,{onClick:()=>T(!0),className:"jkl-spacing-xl--right",children:"Jeg har tid!"}),o(m,{onClick:()=>g(!0),children:"Nei takk"})]}),!S&&N&&i("form",{onSubmit:v,className:"jkl-feedback__fade-in",children:[i("p",{className:"jkl-feedback__step-counter",ref:f,children:["Steg ",w.number+1," av ",k.length]}),e(F,{...k[w.number],autoFocus:!0,key:w.number}),i("div",{className:"jkl-spacing-xl--top","aria-live":"off",children:[o(L,{type:"submit",children:w.isLast?"Send inn":"Neste"}),o(m,{onClick:C,className:"jkl-spacing-xl--left",children:"Avbryt"})]})]}),S&&!y&&o(a,{...I})]})})};export{k as Followup};
|
|
2
|
+
//# sourceMappingURL=Followup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Followup.js","sources":["../../../../../src/components/feedback/followup/Followup.tsx"],"sourcesContent":["import React, { ReactNode, useEffect, useRef, useState, FC } from \"react\";\nimport { PrimaryButton, SecondaryButton, TertiaryButton } from \"../..\";\nimport { useFeedbackContext } from \"../feedbackContext\";\nimport { FeedbackSuccess } from \"../FeedbackSuccess\";\nimport { FeedbackAnswer, FollowupQuestion } from \"../types\";\nimport { getQuestionFromType } from \"../utils\";\nimport { FollowUpProvider } from \"./followupContext\";\nimport { useFollowup } from \"./useFollowup\";\n\nconst defaultSuccessMessage = {\n title: \"Takk, igjen!\",\n children:\n \"Vi setter pris på at du tok deg tid til å svare på flere spørsmål. Det hjelper oss med å gjøre nettsidene bedre for deg og alle andre som bruker dem.\",\n};\n\ninterface Props {\n /** Spørsmålet/ene som skal stilles. Kan være av typen radio, checkbox eller text */\n questions: FollowupQuestion[];\n /** Lar deg tilpasse meldingen som kommer når brukeren har svart på spørsmålene. */\n successMessage?: {\n title: string;\n children: ReactNode;\n };\n onSubmit: (values: FeedbackAnswer[]) => void;\n}\n\nexport const Followup: FC<Props> = ({ questions, successMessage = defaultSuccessMessage, onSubmit }) => {\n const [noThanks, setNoThanks] = useState(false);\n const focusRef = useRef<HTMLParagraphElement>(null);\n const followupState = useFollowup(questions, onSubmit);\n const { handleAbort, handleNext, step, submitted } = followupState;\n const { followupStarted, setFollowupStarted, setFollowupSubmitted, contactSubmitted } = useFeedbackContext();\n\n useEffect(() => {\n if (step.number === 0) {\n return;\n }\n focusRef.current && focusRef.current.focus();\n }, [step]);\n\n useEffect(() => {\n setFollowupSubmitted(submitted);\n }, [submitted, setFollowupSubmitted]);\n\n const QuestionComponent = getQuestionFromType(questions[step.number].type);\n const Button = step.isLast ? PrimaryButton : SecondaryButton;\n\n if (noThanks) {\n return null;\n }\n\n return (\n <div aria-live=\"polite\">\n <FollowUpProvider state={followupState}>\n {!followupStarted && (\n <div className=\"jkl-feedback__fade-in\">\n <p className=\"jkl-heading-4 jkl-spacing-xl--top jkl-spacing-xs--bottom\">\n Har du tid til å svare på noen flere spørsmål?\n </p>\n <p className=\"jkl-body jkl-spacing-xl--bottom\">\n Det tar kun et minutt, og hjelper oss å lage bedre løsninger for deg.\n </p>\n <PrimaryButton onClick={() => setFollowupStarted(true)} className=\"jkl-spacing-xl--right\">\n Jeg har tid!\n </PrimaryButton>\n <TertiaryButton onClick={() => setNoThanks(true)}>Nei takk</TertiaryButton>\n </div>\n )}\n {!submitted && followupStarted && (\n <form onSubmit={handleNext} className=\"jkl-feedback__fade-in\">\n <p className=\"jkl-feedback__step-counter\" ref={focusRef}>\n Steg {step.number + 1} av {questions.length}\n </p>\n {/* eslint-disable-next-line jsx-a11y/no-autofocus */}\n <QuestionComponent {...questions[step.number]} autoFocus key={step.number} />\n <div className=\"jkl-spacing-xl--top\" aria-live=\"off\">\n <Button type=\"submit\">{step.isLast ? \"Send inn\" : \"Neste\"}</Button>\n <TertiaryButton onClick={handleAbort} className=\"jkl-spacing-xl--left\">\n Avbryt\n </TertiaryButton>\n </div>\n </form>\n )}\n {submitted && !contactSubmitted && <FeedbackSuccess {...successMessage} />}\n </FollowUpProvider>\n </div>\n );\n};\n"],"names":["defaultSuccessMessage","title","children","Followup","questions","successMessage","onSubmit","noThanks","setNoThanks","useState","focusRef","useRef","followupState","useFollowup","handleAbort","handleNext","step","submitted","followupStarted","setFollowupStarted","setFollowupSubmitted","contactSubmitted","useFeedbackContext","useEffect","number","current","focus","QuestionComponent","getQuestionFromType","type","Button","isLast","PrimaryButton","SecondaryButton","jsxs","FollowUpProvider","state","className","jsx","onClick","TertiaryButton","ref","length","createElement","autoFocus","key","FeedbackSuccess"],"mappings":"0sGASA,MAAMA,EAAwB,CAC1BC,MAAO,eACPC,SACI,yJAcKC,EAAsB,EAAGC,UAAAA,EAAWC,eAAAA,EAAiBL,EAAuBM,SAAAA,MACrF,MAAOC,EAAUC,GAAeC,GAAS,GACnCC,EAAWC,EAA6B,MACxCC,EAAgBC,EAAYT,EAAWE,IACrCQ,YAAAA,EAAaC,WAAAA,EAAYC,KAAAA,EAAMC,UAAAA,GAAcL,GAC7CM,gBAAAA,EAAiBC,mBAAAA,EAAoBC,qBAAAA,EAAsBC,iBAAAA,GAAqBC,IAExFC,GAAU,KACc,IAAhBP,EAAKQ,QAGAd,EAAAe,SAAWf,EAASe,QAAQC,OAAM,GAC5C,CAACV,IAEJO,GAAU,KACNH,EAAqBH,EAAS,GAC/B,CAACA,EAAWG,IAETO,MAAAA,EAAoBC,EAAoBxB,EAAUY,EAAKQ,QAAQK,MAC/DC,EAASd,EAAKe,OAASC,EAAgBC,EAE7C,OAAI1B,EACO,OAIN,MAAI,CAAA,YAAU,SACXL,SAACgC,EAAAC,EAAA,CAAiBC,MAAOxB,EACpBV,SAAA,EAACgB,GACEgB,EAAC,MAAI,CAAAG,UAAU,wBACXnC,SAAA,CAACoC,EAAA,IAAA,CAAED,UAAU,2DAA2DnC,SAExE,mDACCoC,EAAA,IAAA,CAAED,UAAU,kCAAkCnC,SAE/C,0EACAoC,EAACN,GAAcO,QAAS,IAAMpB,GAAmB,GAAOkB,UAAU,wBAAwBnC,SAE1F,mBACCsC,EAAe,CAAAD,QAAS,IAAM/B,GAAY,GAAON,SAAQ,iBAGhEe,GAAaC,GACXgB,EAAC,QAAK5B,SAAUS,EAAYsB,UAAU,wBAClCnC,SAAA,CAAAgC,EAAC,IAAE,CAAAG,UAAU,6BAA6BI,IAAK/B,EAAUR,SAAA,CAAA,QAC/Cc,EAAKQ,OAAS,EAAE,OAAKpB,EAAUsC,UAGzCC,EAAChB,EAAmB,IAAGvB,EAAUY,EAAKQ,QAASoB,WAAS,EAACC,IAAK7B,EAAKQ,SAClEU,EAAA,MAAA,CAAIG,UAAU,sBAAsB,YAAU,MAC3CnC,SAAA,CAAAoC,EAACR,GAAOD,KAAK,SAAU3B,SAAKc,EAAAe,OAAS,WAAa,YACjDS,EAAe,CAAAD,QAASzB,EAAauB,UAAU,uBAAuBnC,SAEvE,iBAIXe,IAAcI,GAAqBiB,EAAAQ,EAAA,IAAoBzC,QAEhE"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{jsx as e}from"react/jsx-runtime";import{createContext as o,useContext as t}from"react";const r=o(void 0),s=()=>t(r),a=({state:o,children:t})=>e(r.Provider,{value:o,children:t});export{a as FollowUpProvider,s as useFollowUpContext};
|
|
2
|
+
//# sourceMappingURL=followupContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"followupContext.js","sources":["../../../../../src/components/feedback/followup/followupContext.tsx"],"sourcesContent":["import React, { createContext, useContext } from \"react\";\nimport { WithChildren } from \"../../..\";\nimport { FollowupState } from \"../types\";\n\nconst followUpContext = createContext<FollowupState | undefined>(undefined);\n\nexport const useFollowUpContext = (): FollowupState | undefined => useContext(followUpContext);\n\ninterface FollowupContextProviderProps extends WithChildren {\n state: FollowupState;\n}\n\nexport const FollowUpProvider: React.FC<FollowupContextProviderProps> = ({ state, children }) => (\n <followUpContext.Provider value={state}>{children}</followUpContext.Provider>\n);\n"],"names":["followUpContext","createContext","useFollowUpContext","useContext","FollowUpProvider","state","children","jsx","Provider","value"],"mappings":"8FAIA,MAAMA,EAAkBC,OAAyC,GAEpDC,EAAqB,IAAiCC,EAAWH,GAMjEI,EAA2D,EAAGC,MAAAA,EAAOC,SAAAA,KAC7EC,EAAAP,EAAgBQ,SAAhB,CAAyBC,MAAOJ,EAAQC,SAAAA"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{useState as e,useRef as t,useEffect as n,useCallback as u}from"react";const s=(s,r)=>{const[o,a]=e(),[i,l]=e({number:0,question:s[0],isLast:1===s.length}),[d,m]=e(!1),[v,c]=e(!1),[b,f]=e(),p=t({values:o,submitted:v,onSubmit:r});n((()=>{p.current={...p.current,values:o,submitted:v}}),[o,v]);const q=u((()=>{!p.current.submitted&&void 0!==p.current.values&&p.current.onSubmit(p.current.values)}),[]);return n((()=>{d&&(q(),c(!0))}),[d,q]),n((()=>(typeof window<"u"&&window.addEventListener("beforeunload",q),()=>{q(),window.removeEventListener("beforeunload",q)})),[q]),{questions:s,values:o,step:i,currentValue:b,setCurrentValue:f,submitted:v,handleNext:function(e){null==e||e.preventDefault();const t=Array.isArray(b)?b.map((e=>e.value.toString())):null==b?void 0:b.value,n={...i.question,name:i.question.name||i.question.label,value:t};a((e=>[...(null==e?void 0:e.filter((e=>e.name!==n.name)))||[],n])),f(void 0),i.isLast?m(!0):l((e=>{const t=e.number+1;return{number:t,question:s[t],isLast:t+1>=s.length}}))},handleAbort:function(){a(void 0),f(void 0),l({number:0,question:s[0],isLast:1===s.length}),c(!0)}}};export{s as useFollowup};
|
|
2
|
+
//# sourceMappingURL=useFollowup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFollowup.js","sources":["../../../../../src/components/feedback/followup/useFollowup.ts"],"sourcesContent":["import { Dispatch, FormEvent, SetStateAction, useCallback, useEffect, useRef, useState } from \"react\";\nimport { FeedbackAnswer, FeedbackOption, FollowupQuestion } from \"../types\";\n\ntype CurrentValue = FeedbackOption<string | number> | FeedbackOption<string | number>[] | undefined;\n\ntype Followup = {\n questions: FollowupQuestion[];\n values: FeedbackAnswer[] | undefined;\n step: {\n number: number;\n question: FollowupQuestion;\n isLast: boolean;\n };\n currentValue: CurrentValue;\n setCurrentValue: Dispatch<SetStateAction<CurrentValue>>;\n submitted: boolean;\n handleNext: () => void;\n handleAbort: () => void;\n};\n\nexport const useFollowup = (questions: FollowupQuestion[], onSubmit: (a: FeedbackAnswer[]) => void): Followup => {\n const [values, setValues] = useState<FeedbackAnswer[]>();\n const [step, setStep] = useState({\n number: 0,\n question: questions[0],\n isLast: questions.length === 1,\n });\n const [shouldSubmit, setShouldSubmit] = useState(false);\n const [submitted, setSubmitted] = useState(false);\n const [currentValue, setCurrentValue] = useState<FeedbackOption | FeedbackOption[]>();\n\n // Store info in a ref to facilitate autosubmit on component unmount,\n // or when leaving page\n const followupRef = useRef({\n values,\n submitted,\n onSubmit,\n });\n\n // Keep values in ref updated\n useEffect(() => {\n followupRef.current = {\n ...followupRef.current,\n values,\n submitted,\n };\n }, [values, submitted]);\n\n // General method for submitting info\n const _handleSubmit = useCallback(() => {\n if (!followupRef.current.submitted && followupRef.current.values !== undefined) {\n followupRef.current.onSubmit(followupRef.current.values);\n }\n }, []);\n\n // Function for handling going to the next step in the form wizard\n function handleNext(e?: FormEvent<HTMLFormElement>) {\n e?.preventDefault();\n\n const value = Array.isArray(currentValue)\n ? currentValue.map((option) => option.value.toString())\n : currentValue?.value;\n\n const newValue = {\n ...step.question,\n name: step.question.name || step.question.label,\n value,\n };\n\n setValues((oldValues) => {\n const filteredValues = oldValues?.filter((oldValue) => oldValue.name !== newValue.name) || [];\n return [...filteredValues, newValue as FeedbackAnswer];\n });\n setCurrentValue(undefined);\n\n if (step.isLast) {\n setShouldSubmit(true);\n } else {\n setStep((currentStep) => {\n const newStepNum = currentStep.number + 1;\n return {\n number: newStepNum,\n question: questions[newStepNum],\n isLast: newStepNum + 1 >= questions.length,\n };\n });\n }\n }\n\n // Let the user abort without submitting answers\n function handleAbort() {\n setValues(undefined);\n setCurrentValue(undefined);\n setStep({\n number: 0,\n question: questions[0],\n isLast: questions.length === 1,\n });\n setSubmitted(true);\n }\n\n // Submit info after user submits last question\n useEffect(() => {\n if (shouldSubmit) {\n _handleSubmit();\n setSubmitted(true);\n }\n }, [shouldSubmit, _handleSubmit]);\n\n // Submit info if component unmounts or page unloads\n useEffect(() => {\n if (typeof window !== \"undefined\") {\n window.addEventListener(\"beforeunload\", _handleSubmit);\n }\n return () => {\n _handleSubmit();\n window.removeEventListener(\"beforeunload\", _handleSubmit);\n };\n }, [_handleSubmit]);\n\n return { questions, values, step, currentValue, setCurrentValue, submitted, handleNext, handleAbort };\n};\n"],"names":["useFollowup","questions","onSubmit","values","setValues","useState","step","setStep","number","question","isLast","length","shouldSubmit","setShouldSubmit","submitted","setSubmitted","currentValue","setCurrentValue","followupRef","useRef","useEffect","current","_handleSubmit","useCallback","window","addEventListener","removeEventListener","handleNext","e","preventDefault","value","Array","isArray","map","option","toString","newValue","name","label","oldValues","filter","oldValue","currentStep","newStepNum","handleAbort"],"mappings":"6EAoBa,MAAAA,EAAc,CAACC,EAA+BC,KACjD,MAACC,EAAQC,GAAaC,KACrBC,EAAMC,GAAWF,EAAS,CAC7BG,OAAQ,EACRC,SAAUR,EAAU,GACpBS,OAA6B,IAArBT,EAAUU,UAEfC,EAAcC,GAAmBR,GAAS,IAC1CS,EAAWC,GAAgBV,GAAS,IACpCW,EAAcC,GAAmBZ,IAIlCa,EAAcC,EAAO,CACvBhB,OAAAA,EACAW,UAAAA,EACAZ,SAAAA,IAIJkB,GAAU,KACNF,EAAYG,QAAU,IACfH,EAAYG,QACflB,OAAAA,EACAW,UAAAA,EAAA,GAEL,CAACX,EAAQW,IAGNQ,MAAAA,EAAgBC,GAAY,MACzBL,EAAYG,QAAQP,gBAA4C,IAA/BI,EAAYG,QAAQlB,QACtDe,EAAYG,QAAQnB,SAASgB,EAAYG,QAAQlB,OAAM,GAE5D,IAiDH,OAAAiB,GAAU,KACFR,IACcU,IACdP,GAAa,GAAI,GAEtB,CAACH,EAAcU,IAGlBF,GAAU,YACKI,OAAW,KACXA,OAAAC,iBAAiB,eAAgBH,GAErC,KACWA,IACPE,OAAAE,oBAAoB,eAAgBJ,EAAa,IAE7D,CAACA,IAEG,CAAErB,UAAAA,EAAWE,OAAAA,EAAQG,KAAAA,EAAMU,aAAAA,EAAcC,gBAAAA,EAAiBH,UAAAA,EAAWa,WAhE5E,SAAoBC,GAChB,MAAAA,GAAAA,EAAGC,iBAEH,MAAMC,EAAQC,MAAMC,QAAQhB,GACtBA,EAAaiB,KAAKC,GAAWA,EAAOJ,MAAMK,aAC1C,MAAAnB,OAAAA,EAAAA,EAAcc,MAEdM,EAAW,IACV9B,EAAKG,SACR4B,KAAM/B,EAAKG,SAAS4B,MAAQ/B,EAAKG,SAAS6B,MAC1CR,MAAAA,GAGJ1B,GAAWmC,GAEA,KADgB,MAAAA,OAAAA,EAAAA,EAAWC,QAAQC,GAAaA,EAASJ,OAASD,EAASC,SAAS,GAChED,KAE/BnB,OAAgB,GAEZX,EAAKI,OACLG,GAAgB,GAEhBN,GAASmC,IACCC,MAAAA,EAAaD,EAAYlC,OAAS,EACjC,MAAA,CACHA,OAAQmC,EACRlC,SAAUR,EAAU0C,GACpBjC,OAAQiC,EAAa,GAAK1C,EAAUU,OAAA,GAIpD,EAiCwFiC,YA9BxF,WACIxC,OAAU,GACVa,OAAgB,GACRV,EAAA,CACJC,OAAQ,EACRC,SAAUR,EAAU,GACpBS,OAA6B,IAArBT,EAAUU,SAEtBI,GAAa,EACjB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{jsxs as o,Fragment as i,jsx as n}from"react/jsx-runtime";import{c as t}from"../../../../clsx-BeLtu-UY.js";import{useEffect as s}from"react";import{useAnimatedHeight as e}from"../../../hooks/useAnimatedHeight/useAnimatedHeight.js";import"../../../hooks/useScreen/useScreen.js";import"../../../hooks/useId/useId.js";import{PrimaryButton as r,TertiaryButton as c}from"../../button/Button.js";import{useFeedbackContext as m}from"../feedbackContext.js";import{FeedbackSuccess as p}from"../FeedbackSuccess.js";import"../../checkbox/Checkbox.js";import"../../tooltip/Tooltip.js";import"../../tooltip/TooltipContent.js";import"../../tooltip/TooltipTrigger.js";import"../../icon/Icon.js";import"../../icon/icons/animated/ArrowVerticalAnimated.js";import"../../icon/icons/animated/ArrowHorizontalAnimated.js";import"../../icon/icons/animated/PlusRemoveAnimated.js";import"../../icon/icons/ArrowDownIcon.js";import"../../icon/icons/ArrowLeftIcon.js";import"../../icon/icons/ArrowNorthEastIcon.js";import"../../icon/icons/ArrowRightIcon.js";import"../../icon/icons/ArrowUpIcon.js";import"../../icon/icons/CalendarIcon.js";import"../../icon/icons/CheckIcon.js";import"../../icon/icons/ChevronDownIcon.js";import"../../icon/icons/ChevronLeftIcon.js";import"../../icon/icons/ChevronRightIcon.js";import"../../icon/icons/ChevronUpIcon.js";import"../../icon/icons/CloseIcon.js";import"../../icon/icons/CopyIcon.js";import"../../icon/icons/DotsIcon.js";import"../../icon/icons/DragIcon.js";import"../../icon/icons/ErrorIcon.js";import"../../icon/icons/GreenCheckIcon.js";import"../../icon/icons/HamburgerIcon.js";import"../../icon/icons/InfoIcon.js";import"../../icon/icons/LinkIcon.js";import"../../icon/icons/PlusIcon.js";import"../../icon/icons/QuestionIcon.js";import"../../icon/icons/RedCrossIcon.js";import"../../icon/icons/SearchIcon.js";import"../../icon/icons/SuccessIcon.js";import"../../icon/icons/WarningIcon.js";import"../../icon/icons/MinusIcon.js";import"../../icon/icons/ThumbDownIcon.js";import"../../icon/icons/ThumbUpIcon.js";import"../../icon/icons/TrashCanIcon.js";import"../../icon/icons/PenIcon.js";import"../../input-group/InputGroup.js";import"../followup/followupContext.js";import{MainQuestionContextProvider as a}from"./mainQuestionContext.js";import"../../radio-button/RadioButton.js";import"../../radio-button/radioGroupContext.js";import"../../radio-button/BaseRadioButton.js";import"../../text-input/BaseTextArea.js";import"../../text-input/BaseTextInput.js";import"../../text-input/TextArea.js";import"../../text-input/TextInput.js";import{AddonQuestion as j}from"../questions/AddonQuestion.js";import"../../../utilities/polymorphism/SlotComponent.js";import{getQuestionFromType as u}from"../utils.js";import{useMainQuestion as l}from"./useMainQuestion.js";const d={title:"Takk for tilbakemeldingen!",children:"Husk at vi ikke kan besvare meldinger fra dette skjemaet. Kontakt gjerne din forsikringsrådgiver om du har flere spørsmål."},I=({label:I,options:h,type:b,addOnQuestion:k,successMessage:f=d,helpLabel:x,onSubmit:C})=>{const g=l(C),{setFeedbackSubmitted:A,contactSubmitted:v}=m(),{handleSubmit:w,currentValue:T,setCurrentValue:S,submitted:Q}=g,[y]=e(void 0!==T);s((()=>{A(Q)}),[Q,A]);const B=u(b);return o(i,{children:[!Q&&o(a,{state:g,children:[n(B,{label:I,options:h,helpLabel:x}),o("div",{ref:y,className:t({"jkl-feedback__submit-wrapper":!0,"jkl-feedback__submit-wrapper--hidden":void 0===T}),children:[k&&n(j,{helpLabel:"object"==typeof k?k.helpLabel:void 0,label:"object"==typeof k?k.label:void 0}),o("div",{className:"jkl-spacing-xl--top",children:[n(r,{onClick:w,className:"jkl-spacing-xl--right",children:"Send"}),n(c,{onClick:()=>S(void 0),children:"Avbryt"})]})]})]}),Q&&!v&&n(p,{...f})]})};export{I as MainQuestion};
|
|
2
|
+
//# sourceMappingURL=MainQuestion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MainQuestion.js","sources":["../../../../../src/components/feedback/main-question/MainQuestion.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport React, { ReactNode, useEffect, FC, ComponentProps } from \"react\";\nimport { useAnimatedHeight } from \"../../../hooks\";\nimport { PrimaryButton, TertiaryButton } from \"../../button\";\nimport { Feedback } from \"../Feedback\";\nimport { useFeedbackContext } from \"../feedbackContext\";\nimport { FeedbackSuccess } from \"../FeedbackSuccess\";\nimport { AddonQuestion } from \"../questions\";\nimport { FeedbackOption, FeedbackType } from \"../types\";\nimport { getQuestionFromType } from \"../utils\";\nimport { MainQuestionContextProvider } from \"./mainQuestionContext\";\nimport { useMainQuestion } from \"./useMainQuestion\";\n\nconst defaultSuccessMessage = {\n title: \"Takk for tilbakemeldingen!\",\n children:\n \"Husk at vi ikke kan besvare meldinger fra dette skjemaet. Kontakt gjerne din forsikringsrådgiver om du har flere spørsmål.\",\n};\n\ntype Props = Pick<ComponentProps<typeof Feedback>, \"addOnQuestion\"> & {\n type: \"radio\" | \"smiley\";\n label: string;\n helpLabel?: string;\n options: FeedbackOption[];\n successMessage?: {\n title: string;\n children: ReactNode;\n };\n onSubmit: (value: FeedbackType) => void;\n};\n\nexport const MainQuestion: FC<Props> = ({\n label,\n options,\n type,\n addOnQuestion,\n successMessage = defaultSuccessMessage,\n helpLabel,\n onSubmit,\n}) => {\n const mainQuestionState = useMainQuestion(onSubmit);\n\n const { setFeedbackSubmitted, contactSubmitted } = useFeedbackContext();\n const { handleSubmit, currentValue, setCurrentValue, submitted } = mainQuestionState;\n const [submitWrapperRef] = useAnimatedHeight<HTMLDivElement>(currentValue !== undefined);\n\n useEffect(() => {\n setFeedbackSubmitted(submitted);\n }, [submitted, setFeedbackSubmitted]);\n\n const MainQuestionComp = getQuestionFromType(type);\n\n return (\n <>\n {!submitted && (\n <MainQuestionContextProvider state={mainQuestionState}>\n <MainQuestionComp label={label} options={options} helpLabel={helpLabel} />\n <div\n ref={submitWrapperRef}\n className={clsx({\n \"jkl-feedback__submit-wrapper\": true,\n \"jkl-feedback__submit-wrapper--hidden\": currentValue === undefined,\n })}\n >\n {addOnQuestion && (\n <AddonQuestion\n helpLabel={typeof addOnQuestion === \"object\" ? addOnQuestion.helpLabel : undefined}\n label={typeof addOnQuestion === \"object\" ? addOnQuestion.label : undefined}\n />\n )}\n <div className=\"jkl-spacing-xl--top\">\n <PrimaryButton onClick={handleSubmit} className=\"jkl-spacing-xl--right\">\n Send\n </PrimaryButton>\n <TertiaryButton onClick={() => setCurrentValue(undefined)}>Avbryt</TertiaryButton>\n </div>\n </div>\n </MainQuestionContextProvider>\n )}\n {submitted && !contactSubmitted && <FeedbackSuccess {...successMessage} />}\n </>\n );\n};\n"],"names":["defaultSuccessMessage","title","children","MainQuestion","label","options","type","addOnQuestion","successMessage","helpLabel","onSubmit","mainQuestionState","useMainQuestion","setFeedbackSubmitted","contactSubmitted","useFeedbackContext","handleSubmit","currentValue","setCurrentValue","submitted","submitWrapperRef","useAnimatedHeight","useEffect","MainQuestionComp","getQuestionFromType","jsxs","Fragment","MainQuestionContextProvider","state","jsx","ref","className","clsx","AddonQuestion","PrimaryButton","onClick","TertiaryButton","FeedbackSuccess"],"mappings":"2tFAaA,MAAMA,EAAwB,CAC1BC,MAAO,6BACPC,SACI,8HAeKC,EAA0B,EACnCC,MAAAA,EACAC,QAAAA,EACAC,KAAAA,EACAC,cAAAA,EACAC,eAAAA,EAAiBR,EACjBS,UAAAA,EACAC,SAAAA,MAEM,MAAAC,EAAoBC,EAAgBF,IAElCG,qBAAAA,EAAsBC,iBAAAA,GAAqBC,KAC3CC,aAAAA,EAAcC,aAAAA,EAAcC,gBAAAA,EAAiBC,UAAAA,GAAcR,GAC5DS,GAAoBC,OAAmD,IAAjBJ,GAE7DK,GAAU,KACNT,EAAqBM,EAAS,GAC/B,CAACA,EAAWN,IAETU,MAAAA,EAAmBC,EAAoBlB,GAE7C,OAESmB,EAAAC,EAAA,CAAAxB,SAAA,EAACiB,GACEM,EAACE,EAA4B,CAAAC,MAAOjB,EAChCT,SAAA,CAAC2B,EAAAN,EAAA,CAAiBnB,MAAAA,EAAcC,QAAAA,EAAkBI,UAAAA,IAClDgB,EAAC,MAAA,CACGK,IAAKV,EACLW,UAAWC,EAAK,CACZ,gCAAgC,EAChC,4CAAyD,IAAjBf,IAG3Cf,SAAA,CACGK,GAAAsB,EAACI,EAAA,CACGxB,UAAoC,iBAAlBF,EAA6BA,EAAcE,eAAY,EACzEL,MAAgC,iBAAlBG,EAA6BA,EAAcH,WAAQ,IAGzEqB,EAAC,MAAI,CAAAM,UAAU,sBACX7B,SAAA,CAAA2B,EAACK,EAAc,CAAAC,QAASnB,EAAce,UAAU,wBAAwB7B,SAExE,WACCkC,EAAe,CAAAD,QAAS,IAAMjB,OAAgB,GAAYhB,SAAM,oBAKhFiB,IAAcL,GAAqBe,EAAAQ,EAAA,IAAoB7B,MAC5D"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{jsx as e}from"react/jsx-runtime";import{createContext as t,useContext as o}from"react";const r=t(void 0),s=()=>o(r),a=({state:t,children:o})=>e(r.Provider,{value:t,children:o});export{a as MainQuestionContextProvider,s as useMainQuestionContext};
|
|
2
|
+
//# sourceMappingURL=mainQuestionContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mainQuestionContext.js","sources":["../../../../../src/components/feedback/main-question/mainQuestionContext.tsx"],"sourcesContent":["import React, { createContext, useContext } from \"react\";\nimport { WithChildren } from \"../../..\";\nimport { FeedbackState } from \"../types\";\n\nconst mainQuestionContext = createContext<FeedbackState | undefined>(undefined);\n\nexport const useMainQuestionContext = (): FeedbackState | undefined => useContext(mainQuestionContext);\n\ninterface Props extends WithChildren {\n state: FeedbackState;\n}\n\nexport const MainQuestionContextProvider: React.FC<Props> = ({ state, children }) => (\n <mainQuestionContext.Provider value={state}>{children}</mainQuestionContext.Provider>\n);\n"],"names":["mainQuestionContext","createContext","useMainQuestionContext","useContext","MainQuestionContextProvider","state","children","jsx","Provider","value"],"mappings":"8FAIA,MAAMA,EAAsBC,OAAyC,GAExDC,EAAyB,IAAiCC,EAAWH,GAMrEI,EAA+C,EAAGC,MAAAA,EAAOC,SAAAA,KACjEC,EAAAP,EAAoBQ,SAApB,CAA6BC,MAAOJ,EAAQC,SAAAA"}
|