@coopdigital/react 1.31.0 → 1.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/AlertBanner/AlertBanner.d.ts +0 -2
- package/dist/components/AlertBanner/AlertBanner.js +1 -2
- package/dist/components/AlertBanner/index.js +1 -2
- package/dist/components/Author/Author.d.ts +0 -2
- package/dist/components/Author/Author.js +1 -2
- package/dist/components/Author/index.js +1 -2
- package/dist/components/Box/Box.d.ts +0 -2
- package/dist/components/Box/Box.js +1 -2
- package/dist/components/Box/index.js +1 -2
- package/dist/components/Button/Button.d.ts +2 -4
- package/dist/components/Button/Button.js +1 -2
- package/dist/components/Button/index.js +1 -2
- package/dist/components/Card/Card.d.ts +0 -2
- package/dist/components/Card/Card.js +1 -2
- package/dist/components/Card/index.js +1 -2
- package/dist/components/Checkbox/Checkbox.d.ts +0 -2
- package/dist/components/Checkbox/Checkbox.js +1 -2
- package/dist/components/Checkbox/index.js +1 -2
- package/dist/components/Combobox/Combobox.context.js +1 -2
- package/dist/components/Combobox/Combobox.d.ts +0 -2
- package/dist/components/Combobox/Combobox.js +1 -2
- package/dist/components/Combobox/combobox-internal.js +1 -2
- package/dist/components/Combobox/combobox-utils.d.ts +1 -3
- package/dist/components/Combobox/index.js +1 -2
- package/dist/components/DateInput/DateInput.context.js +1 -2
- package/dist/components/DateInput/DateInput.d.ts +2 -3
- package/dist/components/DateInput/DateInput.js +2 -3
- package/dist/components/DateInput/dateinput-utils.d.ts +2 -65
- package/dist/components/DateInput/dateinput-utils.js +2 -83
- package/dist/components/DateInput/index.d.ts +2 -2
- package/dist/components/DateInput/index.js +3 -4
- package/dist/components/DatePicker/DatePicker.d.ts +0 -2
- package/dist/components/DatePicker/DatePicker.js +1 -2
- package/dist/components/DatePicker/datepicker-utils.d.ts +1 -3
- package/dist/components/DatePicker/datepicker-utils.js +1 -2
- package/dist/components/DatePicker/index.js +1 -2
- package/dist/components/Dialog/Dialog.d.ts +0 -2
- package/dist/components/Dialog/Dialog.js +1 -2
- package/dist/components/Dialog/index.js +1 -2
- package/dist/components/Expandable/Expandable.d.ts +0 -2
- package/dist/components/Expandable/Expandable.js +1 -2
- package/dist/components/Expandable/index.js +1 -2
- package/dist/components/Field/Field.context.js +1 -2
- package/dist/components/Field/Field.d.ts +0 -2
- package/dist/components/Field/Field.js +1 -2
- package/dist/components/Field/index.js +1 -2
- package/dist/components/FieldMarkers/Error.d.ts +1 -3
- package/dist/components/FieldMarkers/Error.js +1 -2
- package/dist/components/FieldMarkers/Hint.d.ts +1 -3
- package/dist/components/FieldMarkers/Hint.js +1 -2
- package/dist/components/FieldMarkers/Label.d.ts +1 -3
- package/dist/components/FieldMarkers/Label.js +1 -2
- package/dist/components/FieldMarkers/Legend.d.ts +1 -3
- package/dist/components/FieldMarkers/Legend.js +1 -2
- package/dist/components/FieldMarkers/fieldmarkers-internal.js +1 -2
- package/dist/components/Fieldset/Fieldset.context.js +1 -2
- package/dist/components/Fieldset/Fieldset.d.ts +0 -2
- package/dist/components/Fieldset/Fieldset.js +1 -2
- package/dist/components/Fieldset/index.js +1 -2
- package/dist/components/Flourish/Flourish.d.ts +0 -2
- package/dist/components/Flourish/Flourish.js +1 -2
- package/dist/components/Flourish/index.js +1 -2
- package/dist/components/Form/Form.d.ts +0 -2
- package/dist/components/Form/Form.js +1 -2
- package/dist/components/Form/index.js +1 -2
- package/dist/components/Image/Image.d.ts +0 -2
- package/dist/components/Image/Image.js +1 -2
- package/dist/components/Image/index.js +1 -2
- package/dist/components/LoadingSpinner/LoadingSpinner.d.ts +0 -2
- package/dist/components/LoadingSpinner/LoadingSpinner.js +1 -2
- package/dist/components/LoadingSpinner/index.js +1 -2
- package/dist/components/Logo/Logo.d.ts +0 -2
- package/dist/components/Logo/Logo.js +1 -2
- package/dist/components/Logo/index.js +1 -2
- package/dist/components/PasswordInput/PasswordInput.d.ts +0 -2
- package/dist/components/PasswordInput/PasswordInput.js +1 -2
- package/dist/components/PasswordInput/index.js +1 -2
- package/dist/components/Picture/Picture.d.ts +0 -2
- package/dist/components/Picture/Picture.js +1 -2
- package/dist/components/Picture/index.js +1 -2
- package/dist/components/Pill/Pill.d.ts +0 -2
- package/dist/components/Pill/Pill.js +1 -2
- package/dist/components/Pill/index.js +1 -2
- package/dist/components/Popover/Popover.d.ts +0 -2
- package/dist/components/Popover/Popover.js +1 -2
- package/dist/components/Popover/index.js +1 -2
- package/dist/components/Prose/Prose.d.ts +0 -2
- package/dist/components/Prose/Prose.js +1 -2
- package/dist/components/Prose/index.js +1 -2
- package/dist/components/Radio/Radio.d.ts +0 -2
- package/dist/components/Radio/Radio.js +1 -2
- package/dist/components/Radio/index.js +1 -2
- package/dist/components/RootSVG/RootSVG.d.ts +0 -2
- package/dist/components/RootSVG/RootSVG.js +1 -2
- package/dist/components/RootSVG/index.js +1 -2
- package/dist/components/Searchbox/Searchbox.context.js +1 -2
- package/dist/components/Searchbox/Searchbox.d.ts +0 -2
- package/dist/components/Searchbox/Searchbox.js +1 -2
- package/dist/components/Searchbox/index.js +1 -2
- package/dist/components/Section/Section.d.ts +0 -2
- package/dist/components/Section/Section.js +1 -2
- package/dist/components/Section/index.js +1 -2
- package/dist/components/Select/Select.d.ts +0 -2
- package/dist/components/Select/Select.js +1 -2
- package/dist/components/Select/index.js +1 -2
- package/dist/components/Signpost/Signpost.d.ts +0 -2
- package/dist/components/Signpost/Signpost.js +1 -2
- package/dist/components/Signpost/index.js +1 -2
- package/dist/components/SkipNav/SkipNav.d.ts +0 -2
- package/dist/components/SkipNav/SkipNav.js +1 -2
- package/dist/components/SkipNav/index.js +1 -2
- package/dist/components/Squircle/Squircle.d.ts +0 -2
- package/dist/components/Squircle/Squircle.js +1 -2
- package/dist/components/Squircle/index.js +1 -2
- package/dist/components/Tag/Tag.d.ts +0 -2
- package/dist/components/Tag/Tag.js +1 -2
- package/dist/components/Tag/index.js +1 -2
- package/dist/components/TextInput/TextInput.d.ts +0 -2
- package/dist/components/TextInput/TextInput.js +1 -2
- package/dist/components/TextInput/index.js +1 -2
- package/dist/components/Textarea/Textarea.d.ts +0 -2
- package/dist/components/Textarea/Textarea.js +1 -2
- package/dist/components/Textarea/index.js +1 -2
- package/dist/components/ValidationSummary/ValidationSummary.context.js +1 -2
- package/dist/components/ValidationSummary/ValidationSummary.d.ts +0 -2
- package/dist/components/ValidationSummary/ValidationSummary.js +1 -2
- package/dist/components/ValidationSummary/index.js +1 -2
- package/dist/components/ValidationSummary/validationsummary-internal.d.ts +1 -3
- package/dist/components/ValidationSummary/validationsummary-internal.js +1 -2
- package/dist/components/Wrapper/Wrapper.d.ts +0 -2
- package/dist/components/Wrapper/Wrapper.js +1 -2
- package/dist/components/Wrapper/index.js +1 -2
- package/dist/components/icons/AccountCircleFilledIcon.d.ts +0 -2
- package/dist/components/icons/AccountCircleFilledIcon.js +1 -2
- package/dist/components/icons/AccountCircleIcon.d.ts +0 -2
- package/dist/components/icons/AccountCircleIcon.js +1 -2
- package/dist/components/icons/AccountFilledIcon.d.ts +0 -2
- package/dist/components/icons/AccountFilledIcon.js +1 -2
- package/dist/components/icons/AccountIcon.d.ts +0 -2
- package/dist/components/icons/AccountIcon.js +1 -2
- package/dist/components/icons/AddIcon.d.ts +0 -2
- package/dist/components/icons/AddIcon.js +1 -2
- package/dist/components/icons/AppsFilledIcon.d.ts +0 -2
- package/dist/components/icons/AppsFilledIcon.js +1 -2
- package/dist/components/icons/AppsIcon.d.ts +0 -2
- package/dist/components/icons/AppsIcon.js +1 -2
- package/dist/components/icons/ArrowDownIcon.d.ts +0 -2
- package/dist/components/icons/ArrowDownIcon.js +1 -2
- package/dist/components/icons/ArrowLeftIcon.d.ts +0 -2
- package/dist/components/icons/ArrowLeftIcon.js +1 -2
- package/dist/components/icons/ArrowRightIcon.d.ts +0 -2
- package/dist/components/icons/ArrowRightIcon.js +1 -2
- package/dist/components/icons/ArrowUpIcon.d.ts +0 -2
- package/dist/components/icons/ArrowUpIcon.js +1 -2
- package/dist/components/icons/BackspaceFilledIcon.d.ts +0 -2
- package/dist/components/icons/BackspaceFilledIcon.js +1 -2
- package/dist/components/icons/BackspaceIcon.d.ts +0 -2
- package/dist/components/icons/BackspaceIcon.js +1 -2
- package/dist/components/icons/BasketFilledIcon.d.ts +0 -2
- package/dist/components/icons/BasketFilledIcon.js +1 -2
- package/dist/components/icons/BasketIcon.d.ts +0 -2
- package/dist/components/icons/BasketIcon.js +1 -2
- package/dist/components/icons/BellFilledIcon.d.ts +0 -2
- package/dist/components/icons/BellFilledIcon.js +1 -2
- package/dist/components/icons/BellIcon.d.ts +0 -2
- package/dist/components/icons/BellIcon.js +1 -2
- package/dist/components/icons/BroomIcon.d.ts +0 -2
- package/dist/components/icons/BroomIcon.js +1 -2
- package/dist/components/icons/CalendarFilledIcon.d.ts +0 -2
- package/dist/components/icons/CalendarFilledIcon.js +1 -2
- package/dist/components/icons/CalendarIcon.d.ts +0 -2
- package/dist/components/icons/CalendarIcon.js +1 -2
- package/dist/components/icons/CashFilledIcon.d.ts +0 -2
- package/dist/components/icons/CashFilledIcon.js +1 -2
- package/dist/components/icons/CashIcon.d.ts +0 -2
- package/dist/components/icons/CashIcon.js +1 -2
- package/dist/components/icons/ChevronDownIcon.d.ts +0 -2
- package/dist/components/icons/ChevronDownIcon.js +1 -2
- package/dist/components/icons/ChevronLeftIcon.d.ts +0 -2
- package/dist/components/icons/ChevronLeftIcon.js +1 -2
- package/dist/components/icons/ChevronRightIcon.d.ts +0 -2
- package/dist/components/icons/ChevronRightIcon.js +1 -2
- package/dist/components/icons/ChevronUpIcon.d.ts +0 -2
- package/dist/components/icons/ChevronUpIcon.js +1 -2
- package/dist/components/icons/CircleBurgerFilledIcon.d.ts +0 -2
- package/dist/components/icons/CircleBurgerFilledIcon.js +1 -2
- package/dist/components/icons/CircleBurgerIcon.d.ts +0 -2
- package/dist/components/icons/CircleBurgerIcon.js +1 -2
- package/dist/components/icons/ClipboardFilledIcon.d.ts +0 -2
- package/dist/components/icons/ClipboardFilledIcon.js +1 -2
- package/dist/components/icons/ClipboardIcon.d.ts +0 -2
- package/dist/components/icons/ClipboardIcon.js +1 -2
- package/dist/components/icons/ClockFilledIcon.d.ts +0 -2
- package/dist/components/icons/ClockFilledIcon.js +1 -2
- package/dist/components/icons/ClockIcon.d.ts +0 -2
- package/dist/components/icons/ClockIcon.js +1 -2
- package/dist/components/icons/CloseAltFilledIcon.d.ts +0 -2
- package/dist/components/icons/CloseAltFilledIcon.js +1 -2
- package/dist/components/icons/CloseAltIcon.d.ts +0 -2
- package/dist/components/icons/CloseAltIcon.js +1 -2
- package/dist/components/icons/CogIcon.d.ts +0 -2
- package/dist/components/icons/CogIcon.js +1 -2
- package/dist/components/icons/CommunityFilledIcon.d.ts +0 -2
- package/dist/components/icons/CommunityFilledIcon.js +1 -2
- package/dist/components/icons/CommunityIcon.d.ts +0 -2
- package/dist/components/icons/CommunityIcon.js +1 -2
- package/dist/components/icons/ComputerIcon.d.ts +0 -2
- package/dist/components/icons/ComputerIcon.js +1 -2
- package/dist/components/icons/ContactFilledIcon.d.ts +0 -2
- package/dist/components/icons/ContactFilledIcon.js +1 -2
- package/dist/components/icons/ContactIcon.d.ts +0 -2
- package/dist/components/icons/ContactIcon.js +1 -2
- package/dist/components/icons/ContactlessFilledIcon.d.ts +0 -2
- package/dist/components/icons/ContactlessFilledIcon.js +1 -2
- package/dist/components/icons/ContactlessIcon.d.ts +0 -2
- package/dist/components/icons/ContactlessIcon.js +1 -2
- package/dist/components/icons/CoopLiveIcon.d.ts +0 -2
- package/dist/components/icons/CoopLiveIcon.js +1 -2
- package/dist/components/icons/CoopLocationFilledIcon.d.ts +0 -2
- package/dist/components/icons/CoopLocationFilledIcon.js +1 -2
- package/dist/components/icons/CoopLogoIcon.d.ts +0 -2
- package/dist/components/icons/CoopLogoIcon.js +1 -2
- package/dist/components/icons/CoopMembershipCardFilledIcon.d.ts +0 -2
- package/dist/components/icons/CoopMembershipCardFilledIcon.js +1 -2
- package/dist/components/icons/CreditCardFilledIcon.d.ts +0 -2
- package/dist/components/icons/CreditCardFilledIcon.js +1 -2
- package/dist/components/icons/CreditCardIcon.d.ts +0 -2
- package/dist/components/icons/CreditCardIcon.js +1 -2
- package/dist/components/icons/CrossIcon.d.ts +0 -2
- package/dist/components/icons/CrossIcon.js +1 -2
- package/dist/components/icons/DocumentIcon.d.ts +0 -2
- package/dist/components/icons/DocumentIcon.js +1 -2
- package/dist/components/icons/DownloadIcon.d.ts +0 -2
- package/dist/components/icons/DownloadIcon.js +1 -2
- package/dist/components/icons/EnterStoreIcon.d.ts +0 -2
- package/dist/components/icons/EnterStoreIcon.js +1 -2
- package/dist/components/icons/ExitStoreIcon.d.ts +0 -2
- package/dist/components/icons/ExitStoreIcon.js +1 -2
- package/dist/components/icons/EyeFilledIcon.d.ts +0 -2
- package/dist/components/icons/EyeFilledIcon.js +1 -2
- package/dist/components/icons/EyeIcon.d.ts +0 -2
- package/dist/components/icons/EyeIcon.js +1 -2
- package/dist/components/icons/EyeStrikeFilledIcon.d.ts +0 -2
- package/dist/components/icons/EyeStrikeFilledIcon.js +1 -2
- package/dist/components/icons/EyeStrikeIcon.d.ts +0 -2
- package/dist/components/icons/EyeStrikeIcon.js +1 -2
- package/dist/components/icons/FeedbackFilledIcon.d.ts +0 -2
- package/dist/components/icons/FeedbackFilledIcon.js +1 -2
- package/dist/components/icons/FeedbackIcon.d.ts +0 -2
- package/dist/components/icons/FeedbackIcon.js +1 -2
- package/dist/components/icons/FilterIcon.d.ts +0 -2
- package/dist/components/icons/FilterIcon.js +1 -2
- package/dist/components/icons/GiftCardFilledIcon.d.ts +0 -2
- package/dist/components/icons/GiftCardFilledIcon.js +1 -2
- package/dist/components/icons/GiftCardIcon.d.ts +0 -2
- package/dist/components/icons/GiftCardIcon.js +1 -2
- package/dist/components/icons/GiftFilledIcon.d.ts +0 -2
- package/dist/components/icons/GiftFilledIcon.js +1 -2
- package/dist/components/icons/GiftIcon.d.ts +0 -2
- package/dist/components/icons/GiftIcon.js +1 -2
- package/dist/components/icons/HelpFilledIcon.d.ts +0 -2
- package/dist/components/icons/HelpFilledIcon.js +1 -2
- package/dist/components/icons/HelpIcon.d.ts +0 -2
- package/dist/components/icons/HelpIcon.js +1 -2
- package/dist/components/icons/HomeFilledIcon.d.ts +0 -2
- package/dist/components/icons/HomeFilledIcon.js +1 -2
- package/dist/components/icons/HomeIcon.d.ts +0 -2
- package/dist/components/icons/HomeIcon.js +1 -2
- package/dist/components/icons/HowDoIAssistantIcon.d.ts +0 -2
- package/dist/components/icons/HowDoIAssistantIcon.js +1 -2
- package/dist/components/icons/InfoIcon.d.ts +0 -2
- package/dist/components/icons/InfoIcon.js +1 -2
- package/dist/components/icons/KebabIcon.d.ts +0 -2
- package/dist/components/icons/KebabIcon.js +1 -2
- package/dist/components/icons/LoadingIcon.d.ts +0 -2
- package/dist/components/icons/LoadingIcon.js +1 -2
- package/dist/components/icons/LocationFilledIcon.d.ts +0 -2
- package/dist/components/icons/LocationFilledIcon.js +1 -2
- package/dist/components/icons/LocationIcon.d.ts +0 -2
- package/dist/components/icons/LocationIcon.js +1 -2
- package/dist/components/icons/LogoutIcon.d.ts +0 -2
- package/dist/components/icons/LogoutIcon.js +1 -2
- package/dist/components/icons/MailIcon.d.ts +0 -2
- package/dist/components/icons/MailIcon.js +1 -2
- package/dist/components/icons/MenuIcon.d.ts +0 -2
- package/dist/components/icons/MenuIcon.js +1 -2
- package/dist/components/icons/MessageIcon.d.ts +0 -2
- package/dist/components/icons/MessageIcon.js +1 -2
- package/dist/components/icons/MinusIcon.d.ts +0 -2
- package/dist/components/icons/MinusIcon.js +1 -2
- package/dist/components/icons/NotesFilledIcon.d.ts +0 -2
- package/dist/components/icons/NotesFilledIcon.js +1 -2
- package/dist/components/icons/NotesIcon.d.ts +0 -2
- package/dist/components/icons/NotesIcon.js +1 -2
- package/dist/components/icons/OpenNewIcon.d.ts +0 -2
- package/dist/components/icons/OpenNewIcon.js +1 -2
- package/dist/components/icons/OwnBagIcon.d.ts +0 -2
- package/dist/components/icons/OwnBagIcon.js +1 -2
- package/dist/components/icons/PadlockIcon.d.ts +0 -2
- package/dist/components/icons/PadlockIcon.js +1 -2
- package/dist/components/icons/PencilIcon.d.ts +0 -2
- package/dist/components/icons/PencilIcon.js +1 -2
- package/dist/components/icons/PhoneIcon.d.ts +0 -2
- package/dist/components/icons/PhoneIcon.js +1 -2
- package/dist/components/icons/PowerIcon.d.ts +0 -2
- package/dist/components/icons/PowerIcon.js +1 -2
- package/dist/components/icons/SaveFilledIcon.d.ts +0 -2
- package/dist/components/icons/SaveFilledIcon.js +1 -2
- package/dist/components/icons/SaveIcon.d.ts +0 -2
- package/dist/components/icons/SaveIcon.js +1 -2
- package/dist/components/icons/ScooterIcon.d.ts +0 -2
- package/dist/components/icons/ScooterIcon.js +1 -2
- package/dist/components/icons/SearchFilledIcon.d.ts +0 -2
- package/dist/components/icons/SearchFilledIcon.js +1 -2
- package/dist/components/icons/SearchIcon.d.ts +0 -2
- package/dist/components/icons/SearchIcon.js +1 -2
- package/dist/components/icons/SendIcon.d.ts +0 -2
- package/dist/components/icons/SendIcon.js +1 -2
- package/dist/components/icons/SpannerIcon.d.ts +0 -2
- package/dist/components/icons/SpannerIcon.js +1 -2
- package/dist/components/icons/StarFilledIcon.d.ts +0 -2
- package/dist/components/icons/StarFilledIcon.js +1 -2
- package/dist/components/icons/StarIcon.d.ts +0 -2
- package/dist/components/icons/StarIcon.js +1 -2
- package/dist/components/icons/TickAltFilledIcon.d.ts +0 -2
- package/dist/components/icons/TickAltFilledIcon.js +1 -2
- package/dist/components/icons/TickAltIcon.d.ts +0 -2
- package/dist/components/icons/TickAltIcon.js +1 -2
- package/dist/components/icons/TickIcon.d.ts +0 -2
- package/dist/components/icons/TickIcon.js +1 -2
- package/dist/components/icons/TruckIcon.d.ts +0 -2
- package/dist/components/icons/TruckIcon.js +1 -2
- package/dist/components/icons/UserWipeIcon.d.ts +0 -2
- package/dist/components/icons/UserWipeIcon.js +1 -2
- package/dist/components/icons/VoucherFilledIcon.d.ts +0 -2
- package/dist/components/icons/VoucherFilledIcon.js +1 -2
- package/dist/components/icons/VoucherIcon.d.ts +0 -2
- package/dist/components/icons/VoucherIcon.js +1 -2
- package/dist/components/icons/WarningCircleFilledIcon.d.ts +0 -2
- package/dist/components/icons/WarningCircleFilledIcon.js +1 -2
- package/dist/components/icons/WarningCircleIcon.d.ts +0 -2
- package/dist/components/icons/WarningCircleIcon.js +1 -2
- package/dist/components/icons/WarningFilledIcon.d.ts +0 -2
- package/dist/components/icons/WarningFilledIcon.js +1 -2
- package/dist/components/icons/WarningIcon.d.ts +0 -2
- package/dist/components/icons/WarningIcon.js +1 -2
- package/dist/components/icons/WifiIcon.d.ts +0 -2
- package/dist/components/icons/WifiIcon.js +1 -2
- package/dist/components/icons/WriteIcon.d.ts +0 -2
- package/dist/components/icons/WriteIcon.js +1 -2
- package/dist/hooks/useDebounce.d.ts +1 -3
- package/dist/hooks/useDebounce.js +1 -2
- package/dist/hooks/useFormReset.d.ts +0 -2
- package/dist/hooks/useFormReset.js +1 -2
- package/dist/hooks/useId.d.ts +1 -3
- package/dist/hooks/useId.js +1 -2
- package/dist/hooks/useSlots.d.ts +0 -2
- package/dist/hooks/useSlots.js +1 -2
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/types/colors.d.ts +1 -3
- package/dist/types/index.d.ts +1 -3
- package/dist/types/index.js +1 -2
- package/dist/utils/classes.d.ts +1 -3
- package/dist/utils/classes.js +1 -2
- package/dist/utils/slots.d.ts +1 -3
- package/dist/utils/slots.js +1 -2
- package/dist/validations/date-internal.d.ts +4 -0
- package/dist/{components/DateInput/dateinput-internal.js → validations/date-internal.js} +4 -5
- package/dist/validations/date.d.ts +58 -0
- package/dist/validations/date.js +79 -0
- package/dist/validations/index.d.ts +2 -0
- package/dist/validations/index.js +1 -0
- package/package.json +18 -12
- package/src/components/Button/Button.tsx +2 -2
- package/src/components/DateInput/DateInput.context.ts +2 -1
- package/src/components/DateInput/DateInput.tsx +4 -7
- package/src/components/DateInput/dateinput-utils.ts +1 -183
- package/src/index.ts +1 -0
- package/src/{components/DateInput/dateinput-internal.ts → validations/date-internal.ts} +15 -24
- package/src/validations/date.ts +177 -0
- package/src/validations/index.ts +1 -0
- package/dist/components/DateInput/dateinput-internal.d.ts +0 -6
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { formatLimit, getDateErrors, getInvalidParts, getMessage, getRangeError, parseDateValue, toISODate, toLimit, trimParts } from "./date-internal.js";
|
|
2
|
+
// src/validations/date.ts
|
|
3
|
+
const DATE_PARTS = [
|
|
4
|
+
"day",
|
|
5
|
+
"month",
|
|
6
|
+
"year"
|
|
7
|
+
];
|
|
8
|
+
const realDate = (subject = "Date") => `${subject} must be a real date`;
|
|
9
|
+
const DATE_ERROR_MESSAGES = {
|
|
10
|
+
"after-max": (subject = "Date", limits) => `${subject} must be on or before ${limits?.max}`,
|
|
11
|
+
"before-min": (subject = "Date", limits) => `${subject} must be on or after ${limits?.min}`,
|
|
12
|
+
"impossible-date": realDate,
|
|
13
|
+
"invalid-day": realDate,
|
|
14
|
+
"invalid-month": realDate,
|
|
15
|
+
"invalid-year": "Year must include 4 numbers",
|
|
16
|
+
"missing-date": "Enter a date",
|
|
17
|
+
"missing-day": (subject = "Date") => `${subject} must include a day`,
|
|
18
|
+
"missing-month": (subject = "Date") => `${subject} must include a month`,
|
|
19
|
+
"missing-year": (subject = "Date") => `${subject} must include a year`,
|
|
20
|
+
"unsupported-parts": realDate
|
|
21
|
+
};
|
|
22
|
+
const validateDateParts = (date, { max, messages = {}, min, parts = DATE_PARTS, subject } = {}) => {
|
|
23
|
+
const minDate = min === void 0 ? void 0 : toLimit(min, "min");
|
|
24
|
+
const maxDate = max === void 0 ? void 0 : toLimit(max, "max");
|
|
25
|
+
const values = trimParts(date);
|
|
26
|
+
const errors = getDateErrors(values, parts);
|
|
27
|
+
let value = "";
|
|
28
|
+
if (errors.length === 0) {
|
|
29
|
+
value = toISODate(values, parts);
|
|
30
|
+
const rangeError = value ? getRangeError(value, minDate, maxDate) : "unsupported-parts";
|
|
31
|
+
if (!rangeError) return {
|
|
32
|
+
valid: true,
|
|
33
|
+
value
|
|
34
|
+
};
|
|
35
|
+
errors.push(rangeError);
|
|
36
|
+
}
|
|
37
|
+
const [error] = errors;
|
|
38
|
+
const limits = {
|
|
39
|
+
max: maxDate && value ? formatLimit(maxDate, value.length) : void 0,
|
|
40
|
+
min: minDate && value ? formatLimit(minDate, value.length) : void 0
|
|
41
|
+
};
|
|
42
|
+
return {
|
|
43
|
+
error,
|
|
44
|
+
invalid: getInvalidParts(errors, parts),
|
|
45
|
+
message: getMessage(error, subject, messages, limits, DATE_ERROR_MESSAGES),
|
|
46
|
+
valid: false
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
/** Validate a date.
|
|
50
|
+
*
|
|
51
|
+
* If you are only validating a partial date (eg month-year), provide
|
|
52
|
+
* the `parts` option. */
|
|
53
|
+
const validateDate = (value, options = {}) => {
|
|
54
|
+
const date = parseDateValue(value, options.parts);
|
|
55
|
+
if (date) return validateDateParts(date, options);
|
|
56
|
+
const { messages, parts = DATE_PARTS, subject } = options;
|
|
57
|
+
return {
|
|
58
|
+
error: "impossible-date",
|
|
59
|
+
invalid: parts,
|
|
60
|
+
message: getMessage("impossible-date", subject, messages, {}, DATE_ERROR_MESSAGES),
|
|
61
|
+
valid: false
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
/** Validate a date of birth. */
|
|
65
|
+
const validateDob = (value, options = {}) => {
|
|
66
|
+
const { messages, ...rest } = options;
|
|
67
|
+
return validateDate(value, {
|
|
68
|
+
max: /* @__PURE__ */ new Date(),
|
|
69
|
+
messages: {
|
|
70
|
+
"after-max": "Date of birth must be today or in the past",
|
|
71
|
+
"missing-date": "Enter your date of birth",
|
|
72
|
+
...messages
|
|
73
|
+
},
|
|
74
|
+
parts: DATE_PARTS,
|
|
75
|
+
subject: "Date of birth",
|
|
76
|
+
...rest
|
|
77
|
+
});
|
|
78
|
+
};
|
|
79
|
+
export { DATE_ERROR_MESSAGES, DATE_PARTS, validateDate, validateDateParts, validateDob };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { DATE_ERROR_MESSAGES, DATE_PARTS, DateErrorCode, DateErrorMessage, DatePart, DateParts, DateValidation, DateValidationError, DateValidationOptions, DateValidationSuccess, validateDate, validateDateParts, validateDob } from "./date.js";
|
|
2
|
+
export { DATE_ERROR_MESSAGES, DATE_PARTS, DateErrorCode, DateErrorMessage, DatePart, DateParts, DateValidation, DateValidationError, DateValidationOptions, DateValidationSuccess, validateDate, validateDateParts, validateDob };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { DATE_ERROR_MESSAGES, DATE_PARTS, validateDate, validateDateParts, validateDob } from "./date.js";
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coopdigital/react",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.32.0",
|
|
5
5
|
"private": false,
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
|
@@ -19,6 +19,10 @@
|
|
|
19
19
|
"./icons": {
|
|
20
20
|
"types": "./dist/components/icons/index.d.ts",
|
|
21
21
|
"default": "./dist/components/icons/index.js"
|
|
22
|
+
},
|
|
23
|
+
"./validations": {
|
|
24
|
+
"types": "./dist/validations/index.d.ts",
|
|
25
|
+
"default": "./dist/validations/index.js"
|
|
22
26
|
}
|
|
23
27
|
},
|
|
24
28
|
"sideEffects": false,
|
|
@@ -41,8 +45,10 @@
|
|
|
41
45
|
"test": "vitest run",
|
|
42
46
|
"test:watch": "vitest",
|
|
43
47
|
"test:coverage": "vitest run --coverage",
|
|
44
|
-
"test:behaviour": "./test-utils/run-playwright-tests.sh -g behaviour",
|
|
48
|
+
"test:behaviour": "./test-utils/run-playwright-tests.sh -g @behaviour",
|
|
45
49
|
"test:behaviour:ui": "npm run test:behaviour -- --ui",
|
|
50
|
+
"test:recipes": "./test-utils/run-playwright-tests.sh -g @recipe",
|
|
51
|
+
"test:recipes:ui": "npm run test:recipes -- --ui",
|
|
46
52
|
"test:avt": "./test-utils/run-playwright-tests.sh -g avt --project=chromium",
|
|
47
53
|
"test:avt:ui": "npm run test:avt -- --ui",
|
|
48
54
|
"test:vrt": "ENVIRONMENT=docker ./test-utils/run-playwright-tests.sh -g vrt --workers 4 --timeout 5000 --fully-parallel",
|
|
@@ -51,7 +57,7 @@
|
|
|
51
57
|
"test:e2e:ci": "npx playwright test --shard=$CI_NODE_INDEX/$CI_NODE_TOTAL",
|
|
52
58
|
"test:avt:ci": "npm run test:e2e:ci -- -g avt --project=chromium",
|
|
53
59
|
"test:vrt:ci": "npm run test:e2e:ci -- -g vrt",
|
|
54
|
-
"test:behaviour:ci": "npm run test:e2e:ci -- -g behaviour",
|
|
60
|
+
"test:behaviour:ci": "npm run test:e2e:ci -- -g @behaviour",
|
|
55
61
|
"build": "tsx scripts build",
|
|
56
62
|
"build:docs": "tsx scripts build-docs",
|
|
57
63
|
"build:icons": "tsx scripts build-icons",
|
|
@@ -71,11 +77,11 @@
|
|
|
71
77
|
"devDependencies": {
|
|
72
78
|
"@axe-core/playwright": "^4.14.0",
|
|
73
79
|
"@playwright/test": "^1.64.1",
|
|
74
|
-
"@storybook/addon-a11y": "^10.6.
|
|
75
|
-
"@storybook/addon-docs": "^10.6.
|
|
76
|
-
"@storybook/addon-links": "^10.6.
|
|
77
|
-
"@storybook/addon-onboarding": "^10.6.
|
|
78
|
-
"@storybook/react-vite": "^10.6.
|
|
80
|
+
"@storybook/addon-a11y": "^10.6.4",
|
|
81
|
+
"@storybook/addon-docs": "^10.6.4",
|
|
82
|
+
"@storybook/addon-links": "^10.6.4",
|
|
83
|
+
"@storybook/addon-onboarding": "^10.6.4",
|
|
84
|
+
"@storybook/react-vite": "^10.6.4",
|
|
79
85
|
"@testing-library/jest-dom": "^7.0.1",
|
|
80
86
|
"@testing-library/react": "^16.3.3",
|
|
81
87
|
"@types/react": "^19.3.0",
|
|
@@ -84,10 +90,10 @@
|
|
|
84
90
|
"react": "^19.3.1",
|
|
85
91
|
"react-dom": "^19.3.1",
|
|
86
92
|
"react-element-to-jsx-string": "^18.0.0",
|
|
87
|
-
"react-hook-form": "^7.
|
|
93
|
+
"react-hook-form": "^7.91.0",
|
|
88
94
|
"resize-observer-polyfill": "^1.5.1",
|
|
89
95
|
"serve": "^14.2.6",
|
|
90
|
-
"storybook": "^10.6.
|
|
96
|
+
"storybook": "^10.6.4",
|
|
91
97
|
"storybook-addon-tag-badges": "^3.1.0"
|
|
92
98
|
},
|
|
93
99
|
"peerDependencies": {
|
|
@@ -111,7 +117,7 @@
|
|
|
111
117
|
"storybook": "$storybook"
|
|
112
118
|
},
|
|
113
119
|
"dependencies": {
|
|
114
|
-
"@coopdigital/styles": "^1.
|
|
120
|
+
"@coopdigital/styles": "^1.23.0",
|
|
115
121
|
"@radix-ui/react-popover": "^1.3.1",
|
|
116
122
|
"clsx": "^2.1.1",
|
|
117
123
|
"date-fns": "^4.4.0",
|
|
@@ -120,5 +126,5 @@
|
|
|
120
126
|
"merge-refs": "^2.0.0",
|
|
121
127
|
"react-day-picker": "^10.0.2"
|
|
122
128
|
},
|
|
123
|
-
"gitHead": "
|
|
129
|
+
"gitHead": "c826b0325c655154524a6627eb705bce9f84abae"
|
|
124
130
|
}
|
|
@@ -34,8 +34,8 @@ export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
|
34
34
|
onClick?: React.MouseEventHandler<HTMLButtonElement | HTMLAnchorElement>
|
|
35
35
|
/** Specify a custom React ref for this component. */
|
|
36
36
|
ref?: Ref<HTMLElement>
|
|
37
|
-
/** Specify the component size. */
|
|
38
|
-
size?: StandardSizes
|
|
37
|
+
/** Specify the component size. Use `xs` only in compact places, such as the actions in a calendar. */
|
|
38
|
+
size?: "xs" | StandardSizes
|
|
39
39
|
/** Specify the component variant. */
|
|
40
40
|
variant?: "solid" | "ghost" | "text"
|
|
41
41
|
}
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
import { createContext, type RefObject, useContext } from "react"
|
|
3
3
|
|
|
4
4
|
import type { StandardSizes } from "@/types"
|
|
5
|
+
import type { DatePart, DateParts } from "@/validations"
|
|
5
6
|
|
|
6
|
-
import type { DateInputMode
|
|
7
|
+
import type { DateInputMode } from "./dateinput-utils"
|
|
7
8
|
|
|
8
9
|
export interface DateInputContextValue {
|
|
9
10
|
changePart: (part: DatePart, value: string) => void
|
|
@@ -5,20 +5,17 @@ import clsx from "clsx"
|
|
|
5
5
|
import mergeRefs from "merge-refs"
|
|
6
6
|
import { useRef, useState } from "react"
|
|
7
7
|
|
|
8
|
+
import type { DatePart, DateParts } from "@/validations"
|
|
9
|
+
|
|
8
10
|
import { Field } from "@/components/Field"
|
|
9
11
|
import { TextInput, type TextInputProps } from "@/components/TextInput"
|
|
10
12
|
import { useFormReset } from "@/hooks/useFormReset"
|
|
11
13
|
import { useId } from "@/hooks/useId"
|
|
12
14
|
import { StandardSizes } from "@/types"
|
|
13
15
|
import { forEachSlot } from "@/utils"
|
|
16
|
+
import { formatDateValue, toDateParts, toDateValue } from "@/validations/date-internal"
|
|
14
17
|
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
type DateInputMode,
|
|
18
|
-
type DatePart,
|
|
19
|
-
type DateParts,
|
|
20
|
-
getAutoComplete,
|
|
21
|
-
} from "./dateinput-utils"
|
|
18
|
+
import { type DateInputMode, getAutoComplete } from "./dateinput-utils"
|
|
22
19
|
import { DateInputContext, useDateInput } from "./DateInput.context"
|
|
23
20
|
|
|
24
21
|
export interface DateInputChangeEvent {
|
|
@@ -1,189 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
// The DateInput entry exports this to server code too, so it must not import
|
|
3
|
-
// React or use "use client".
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
formatLimit,
|
|
7
|
-
getDateErrors,
|
|
8
|
-
getInvalidParts,
|
|
9
|
-
getMessage,
|
|
10
|
-
getRangeError,
|
|
11
|
-
type Limits,
|
|
12
|
-
parseDateValue,
|
|
13
|
-
toISODate,
|
|
14
|
-
toLimit,
|
|
15
|
-
trimParts,
|
|
16
|
-
} from "./dateinput-internal"
|
|
17
|
-
|
|
18
|
-
export type DatePart = "day" | "month" | "year"
|
|
19
|
-
|
|
20
|
-
export interface DateParts {
|
|
21
|
-
day?: string
|
|
22
|
-
month?: string
|
|
23
|
-
year?: string
|
|
24
|
-
}
|
|
1
|
+
import type { DatePart } from "@/validations"
|
|
25
2
|
|
|
26
3
|
export type DateInputMode = "dob" | undefined
|
|
27
4
|
|
|
28
|
-
export type DateErrorCode =
|
|
29
|
-
| "missing-date"
|
|
30
|
-
| "missing-day"
|
|
31
|
-
| "missing-month"
|
|
32
|
-
| "missing-year"
|
|
33
|
-
| "invalid-day"
|
|
34
|
-
| "invalid-month"
|
|
35
|
-
| "invalid-year"
|
|
36
|
-
| "impossible-date"
|
|
37
|
-
| "unsupported-parts"
|
|
38
|
-
| "before-min"
|
|
39
|
-
| "after-max"
|
|
40
|
-
|
|
41
|
-
/** A message, or a function that builds one from the label. */
|
|
42
|
-
export type DateErrorMessage = string | ((label?: string) => string)
|
|
43
|
-
|
|
44
|
-
export interface DateValidationOptions {
|
|
45
|
-
/** The name of the date, as it would start a sentence, such as "Date
|
|
46
|
-
* of birth".
|
|
47
|
-
*
|
|
48
|
-
* Default: `Date`. */
|
|
49
|
-
label?: string
|
|
50
|
-
/** The latest date allowed, as a `Date` or an ISO date such as `2026-12-31`.
|
|
51
|
-
*
|
|
52
|
-
* Only the parts used are compared, such as the month and year. */
|
|
53
|
-
max?: Date | string
|
|
54
|
-
/** Messages to use instead of the defaults. */
|
|
55
|
-
messages?: Partial<Record<DateErrorCode, DateErrorMessage>>
|
|
56
|
-
/** The earliest date allowed, as a `Date` or an ISO date such as `2020-01-01`.
|
|
57
|
-
*
|
|
58
|
-
* Only the parts used are compared, such as the month and year. */
|
|
59
|
-
min?: Date | string
|
|
60
|
-
/** The parts used, in the order they are entered.
|
|
61
|
-
*
|
|
62
|
-
* Default: `day`, `month`, `year`. */
|
|
63
|
-
parts?: DatePart[]
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export interface DateValidationSuccess {
|
|
67
|
-
/** Whether the date is valid. */
|
|
68
|
-
valid: true
|
|
69
|
-
/** The date as an ISO 8601 string, such as 1990-08-21. */
|
|
70
|
-
value: string
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export interface DateValidationError {
|
|
74
|
-
/** The code for the first problem, in the order the parts are entered. */
|
|
75
|
-
error: DateErrorCode
|
|
76
|
-
/** The parts with an error. Every part is invalid when the date is
|
|
77
|
-
* empty, impossible, has no ISO format or is outside `min` and `max`. */
|
|
78
|
-
invalid: DatePart[]
|
|
79
|
-
/** The message for the error. */
|
|
80
|
-
message: string
|
|
81
|
-
/** Whether the date is valid. */
|
|
82
|
-
valid: false
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export type DateValidation = DateValidationSuccess | DateValidationError
|
|
86
|
-
|
|
87
|
-
export const DATE_PARTS: DatePart[] = ["day", "month", "year"]
|
|
88
|
-
|
|
89
|
-
const realDate = (label = "Date") => `${label} must be a real date`
|
|
90
|
-
|
|
91
|
-
export const DATE_ERROR_MESSAGES: Record<
|
|
92
|
-
DateErrorCode,
|
|
93
|
-
string | ((label?: string, limits?: Limits) => string)
|
|
94
|
-
> = {
|
|
95
|
-
"after-max": (label = "Date", limits) => `${label} must be on or before ${limits?.max}`,
|
|
96
|
-
"before-min": (label = "Date", limits) => `${label} must be on or after ${limits?.min}`,
|
|
97
|
-
"impossible-date": realDate,
|
|
98
|
-
"invalid-day": realDate,
|
|
99
|
-
"invalid-month": realDate,
|
|
100
|
-
"invalid-year": "Year must include 4 numbers",
|
|
101
|
-
"missing-date": "Enter a date",
|
|
102
|
-
"missing-day": (label = "Date") => `${label} must include a day`,
|
|
103
|
-
"missing-month": (label = "Date") => `${label} must include a month`,
|
|
104
|
-
"missing-year": (label = "Date") => `${label} must include a year`,
|
|
105
|
-
"unsupported-parts": realDate,
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// Check parts and return if they make a complete, possible date with an
|
|
109
|
-
// ISO format, between min and max. A valid date has its ISO value. An
|
|
110
|
-
// invalid date has the code and message for the first problem, and the
|
|
111
|
-
// parts with an error.
|
|
112
|
-
export const validateDateParts = (
|
|
113
|
-
date: DateParts,
|
|
114
|
-
{ label, max, messages = {}, min, parts = DATE_PARTS }: DateValidationOptions = {}
|
|
115
|
-
): DateValidation => {
|
|
116
|
-
const minDate = min === undefined ? undefined : toLimit(min, "min")
|
|
117
|
-
const maxDate = max === undefined ? undefined : toLimit(max, "max")
|
|
118
|
-
const values = trimParts(date)
|
|
119
|
-
const errors = getDateErrors(values, parts)
|
|
120
|
-
let value = ""
|
|
121
|
-
|
|
122
|
-
if (errors.length === 0) {
|
|
123
|
-
value = toISODate(values, parts)
|
|
124
|
-
const rangeError = value ? getRangeError(value, minDate, maxDate) : "unsupported-parts"
|
|
125
|
-
|
|
126
|
-
if (!rangeError) return { valid: true, value }
|
|
127
|
-
errors.push(rangeError)
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
const [error] = errors
|
|
131
|
-
const limits = {
|
|
132
|
-
max: maxDate && value ? formatLimit(maxDate, value.length) : undefined,
|
|
133
|
-
min: minDate && value ? formatLimit(minDate, value.length) : undefined,
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
return {
|
|
137
|
-
error,
|
|
138
|
-
invalid: getInvalidParts(errors, parts),
|
|
139
|
-
message: getMessage(error, label, messages, limits, DATE_ERROR_MESSAGES),
|
|
140
|
-
valid: false,
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/** Check a value, such as the DateInput value or the value a form
|
|
145
|
-
* submits, the same way as `validateDateParts`. Use the same `parts` as
|
|
146
|
-
* the DateInput. */
|
|
147
|
-
export const validateDate = (
|
|
148
|
-
value: string,
|
|
149
|
-
options: DateValidationOptions = {}
|
|
150
|
-
): DateValidation => {
|
|
151
|
-
const date = parseDateValue(value, options.parts)
|
|
152
|
-
if (date) return validateDateParts(date, options)
|
|
153
|
-
|
|
154
|
-
// A dash typed in a part leaves it unclear which part is wrong, so the
|
|
155
|
-
// whole date is
|
|
156
|
-
const { label, messages, parts = DATE_PARTS } = options
|
|
157
|
-
|
|
158
|
-
return {
|
|
159
|
-
error: "impossible-date",
|
|
160
|
-
invalid: parts,
|
|
161
|
-
message: getMessage("impossible-date", label, messages, {}, DATE_ERROR_MESSAGES),
|
|
162
|
-
valid: false,
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/** As this is a more specific function for a birth of date validation, we can make some assumptions.
|
|
167
|
-
* Such as, date needs to be today or in the past and error message should reflect date of birth.
|
|
168
|
-
* Check a value, such as the DateInput value or the value a form
|
|
169
|
-
* submits, the same way as `validateDateParts`. Use the same `parts` as
|
|
170
|
-
* the DateInput. */
|
|
171
|
-
|
|
172
|
-
export const validateDob = (value: string, options: DateValidationOptions = {}): DateValidation => {
|
|
173
|
-
const { messages, ...rest } = options
|
|
174
|
-
return validateDate(value, {
|
|
175
|
-
label: "Date of birth",
|
|
176
|
-
max: new Date(),
|
|
177
|
-
messages: {
|
|
178
|
-
"after-max": "Date of birth must be today or in the past",
|
|
179
|
-
"missing-date": "Enter your date of birth",
|
|
180
|
-
...messages,
|
|
181
|
-
},
|
|
182
|
-
parts: DATE_PARTS,
|
|
183
|
-
...rest,
|
|
184
|
-
})
|
|
185
|
-
}
|
|
186
|
-
|
|
187
5
|
export const getAutoComplete = (mode: DateInputMode, part: DatePart): string | undefined => {
|
|
188
6
|
if (!mode) return undefined
|
|
189
7
|
if (mode === "dob") {
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
// Not exported from the DateInput entry. No React or "use client", as
|
|
2
|
-
// dateinput-utils imports it.
|
|
3
|
-
|
|
4
1
|
import { format, formatISO, isExists, isValid, parseISO } from "date-fns"
|
|
5
2
|
|
|
6
3
|
import type {
|
|
@@ -9,7 +6,7 @@ import type {
|
|
|
9
6
|
DatePart,
|
|
10
7
|
DateParts,
|
|
11
8
|
DateValidationOptions,
|
|
12
|
-
} from "./
|
|
9
|
+
} from "./date"
|
|
13
10
|
|
|
14
11
|
type DefaultMessages = typeof DATE_ERROR_MESSAGES
|
|
15
12
|
|
|
@@ -32,14 +29,13 @@ export const WHOLE_DATE_ERRORS = new Set<DateErrorCode>([
|
|
|
32
29
|
|
|
33
30
|
const valueParts = (parts: DatePart[]) => VALUE_ORDER.filter((part) => parts.includes(part))
|
|
34
31
|
|
|
35
|
-
// Parts as typed to a value, such as 2026-2-30. Empty if every part is empty
|
|
36
32
|
export const formatDateValue = (date: DateParts, parts: DatePart[] = VALUE_ORDER): string => {
|
|
37
33
|
const values = valueParts(parts).map((part) => date[part] ?? "")
|
|
38
34
|
|
|
39
35
|
return values.every((value) => value === "") ? "" : values.join("-")
|
|
40
36
|
}
|
|
41
37
|
|
|
42
|
-
// A
|
|
38
|
+
// A leading -- is the ISO form of a date without a year
|
|
43
39
|
const splitValue = (value: string, used: DatePart[]) => {
|
|
44
40
|
const pieces = value.split("-")
|
|
45
41
|
const iso = !used.includes("year") && value.startsWith("--") && pieces.length === used.length + 2
|
|
@@ -47,8 +43,8 @@ const splitValue = (value: string, used: DatePart[]) => {
|
|
|
47
43
|
return iso ? pieces.slice(2) : pieces
|
|
48
44
|
}
|
|
49
45
|
|
|
50
|
-
// A value or ISO date to parts
|
|
51
|
-
//
|
|
46
|
+
// A value or ISO date to parts
|
|
47
|
+
// Undefined if a part has a dash
|
|
52
48
|
export const parseDateValue = (
|
|
53
49
|
value: string,
|
|
54
50
|
parts: DatePart[] = VALUE_ORDER
|
|
@@ -66,7 +62,7 @@ export const parseDateValue = (
|
|
|
66
62
|
export const toDateValue = (input: DateParts | string = "", parts?: DatePart[]): string =>
|
|
67
63
|
typeof input === "string" ? input : formatDateValue(input, parts)
|
|
68
64
|
|
|
69
|
-
// A value, ISO date or parts to parts
|
|
65
|
+
// A value, ISO date or parts to parts
|
|
70
66
|
export const toDateParts = (input: DateParts | string = "", parts?: DatePart[]): DateParts =>
|
|
71
67
|
typeof input === "string" ? (parseDateValue(input, parts) ?? {}) : input
|
|
72
68
|
|
|
@@ -88,9 +84,7 @@ export const trimParts = (date: DateParts): Required<DateParts> => ({
|
|
|
88
84
|
year: date.year?.trim() ?? "",
|
|
89
85
|
})
|
|
90
86
|
|
|
91
|
-
// An error code for each problem, in the order the parts are entered
|
|
92
|
-
// date with every part empty only returns missing-date. impossible-date
|
|
93
|
-
// is only checked once every part is valid.
|
|
87
|
+
// An error code for each problem, in the order the parts are entered
|
|
94
88
|
export const getDateErrors = (values: Required<DateParts>, parts: DatePart[]): DateErrorCode[] => {
|
|
95
89
|
if (parts.every((part) => values[part] === "")) return ["missing-date"]
|
|
96
90
|
|
|
@@ -117,8 +111,7 @@ export const getInvalidParts = (errors: DateErrorCode[], parts: DatePart[]): Dat
|
|
|
117
111
|
// Remove extra leading zeros, such as in "008", then pad to 2 digits
|
|
118
112
|
export const pad = (value: string): string => String(Number(value)).padStart(2, "0")
|
|
119
113
|
|
|
120
|
-
// The ISO 8601 string for a valid date, using the parts given
|
|
121
|
-
// when the parts have no ISO format, such as day and year.
|
|
114
|
+
// The ISO 8601 string for a valid date, using the parts given
|
|
122
115
|
export const toISODate = ({ day, month, year }: Required<DateParts>, parts: DatePart[]): string => {
|
|
123
116
|
const has = (part: DatePart) => parts.includes(part)
|
|
124
117
|
|
|
@@ -130,8 +123,8 @@ export const toISODate = ({ day, month, year }: Required<DateParts>, parts: Date
|
|
|
130
123
|
return ""
|
|
131
124
|
}
|
|
132
125
|
|
|
133
|
-
// Read a min or max limit
|
|
134
|
-
//
|
|
126
|
+
// Read a min or max limit
|
|
127
|
+
// An ISO date string is read in local time
|
|
135
128
|
export const toLimit = (limit: Date | string, name: "max" | "min"): Date => {
|
|
136
129
|
const date = typeof limit === "string" ? parseISO(limit) : limit
|
|
137
130
|
if (!isValid(date)) {
|
|
@@ -141,13 +134,12 @@ export const toLimit = (limit: Date | string, name: "max" | "min"): Date => {
|
|
|
141
134
|
return date
|
|
142
135
|
}
|
|
143
136
|
|
|
144
|
-
// Write a limit
|
|
137
|
+
// Write a limit for a message, to the same detail as the value
|
|
145
138
|
// "1 January 2020", "January 2020" or "2020"
|
|
146
139
|
export const formatLimit = (limit: Date, length: number): string =>
|
|
147
140
|
format(limit, length === 4 ? "yyyy" : length === 7 ? "MMMM yyyy" : "d MMMM yyyy")
|
|
148
141
|
|
|
149
|
-
// Compare the value with min and max, to the same detail as the value
|
|
150
|
-
// day and month value has no year, so it is not compared.
|
|
142
|
+
// Compare the value with min and max, to the same detail as the value
|
|
151
143
|
export const getRangeError = (value: string, min?: Date, max?: Date): DateErrorCode | undefined => {
|
|
152
144
|
if (value.startsWith("--")) return undefined
|
|
153
145
|
|
|
@@ -159,18 +151,17 @@ export const getRangeError = (value: string, min?: Date, max?: Date): DateErrorC
|
|
|
159
151
|
return undefined
|
|
160
152
|
}
|
|
161
153
|
|
|
162
|
-
// A custom message, or the default
|
|
163
|
-
// defaults are passed in, as they are public and live in dateinput-utils
|
|
154
|
+
// A custom message, or the default
|
|
164
155
|
export const getMessage = (
|
|
165
156
|
code: DateErrorCode,
|
|
166
|
-
|
|
157
|
+
subject: string | undefined,
|
|
167
158
|
messages: DateValidationOptions["messages"] = {},
|
|
168
159
|
limits: Limits,
|
|
169
160
|
defaults: DefaultMessages
|
|
170
161
|
): string => {
|
|
171
162
|
const custom = messages[code]
|
|
172
|
-
if (custom !== undefined) return typeof custom === "function" ? custom(
|
|
163
|
+
if (custom !== undefined) return typeof custom === "function" ? custom(subject) : custom
|
|
173
164
|
|
|
174
165
|
const fallback = defaults[code]
|
|
175
|
-
return typeof fallback === "function" ? fallback(
|
|
166
|
+
return typeof fallback === "function" ? fallback(subject, limits) : fallback
|
|
176
167
|
}
|