UNPKG

@intility/bifrost-react-datepicker

Version:

React detepicker for Intility's design system, Bifrost.

171 lines (170 loc) 7.74 kB
"use client"; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { createContext, forwardRef, useContext, useMemo, useState } from "react"; import classNames from "classnames"; import { faExclamationTriangle } from "@fortawesome/free-solid-svg-icons/faExclamationTriangle"; import { faCheck } from "@fortawesome/free-solid-svg-icons/faCheck"; import { faClock } from "@fortawesome/free-solid-svg-icons/faClock"; import { faCalendarAlt } from "@fortawesome/free-solid-svg-icons/faCalendarAlt"; import ReactDatePickerDefaultExport, { CalendarContainer } from "react-datepicker"; import Label from "@intility/bifrost-react/Label"; import Icon from "@intility/bifrost-react/Icon"; import Feedback from "@intility/bifrost-react/Feedback"; import Description from "@intility/bifrost-react/Description"; import Dropdown from "@intility/bifrost-react/Dropdown"; import useLocale from "@intility/bifrost-react/hooks/useLocale"; import useUniqueId from "@intility/bifrost-react/hooks/useUniqueId"; import enGbLocale from "./locales/en-gb.js"; import nbNoLocale from "./locales/nb-no.js"; import svSeLocale from "./locales/sv-se.js"; function CalendarContainerOverride(props) { const { ref, placement } = useContext(DatePickerCtx); return /*#__PURE__*/ _jsx(Dropdown, { unstyled: true, noArrow: true, offset: [ 0, 4 ], visible: true, content: /*#__PURE__*/ _jsx(CalendarContainer, { ...props }), placement: placement || "bottom", reference: ref?.input }); } const DatePickerCtx = /*#__PURE__*/ createContext({ ref: null }); const ReactDatePicker = ReactDatePickerDefaultExport.default ?? ReactDatePickerDefaultExport; export const DatePicker = /*#__PURE__*/ forwardRef(({ label, hideLabel = false, icon, rightIcon = false, disabled = false, readOnly = false, state = "default", feedback, required = false, description, requiredNoLabel = false, optional = false, className, style, isClearable = false, id, timeIntervals = 30, inline = false, small = false, ...props }, ref)=>{ const { dateOptions } = useLocale(); const inputId = useUniqueId(id); const [datePickerRef, setDatePickerRef] = useState(null); const contextValue = useMemo(()=>({ placement: props.popperPlacement, ref: datePickerRef }), [ props.popperPlacement, datePickerRef ]); let datepickerLocale = enGbLocale; switch(dateOptions.locale){ case "nb-no": datepickerLocale = nbNoLocale; break; case "sv-se": datepickerLocale = svSeLocale; break; } const mode = props?.showYearPicker && "year" || props?.showMonthYearPicker && "monthYear" || props?.showTimeSelectOnly && "time" || (props?.showTimeSelect || props?.showTimeInput) && "dateTime" || "date"; let displayIcon; if (state === "warning" || state === "alert") { displayIcon = faExclamationTriangle; } else if (state === "success") { displayIcon = faCheck; } else if (icon) { displayIcon = icon; } else if (mode === "time") { displayIcon = faClock; } else { displayIcon = faCalendarAlt; } const placeholderText = datepickerLocale.placeholder[mode]; const dateFormat = datepickerLocale.format[mode]; // apparently, some versions (within the same major release) of `react-datepicker` passes a // Date object to `formatWeekDay` instead of a string function firstLetterOfDay(day) { if (typeof day === "string") return day.slice(0, 1).toUpperCase(); if (day instanceof Date) { return day.toLocaleString(dateOptions.locale, { weekday: "narrow" }).toUpperCase(); } return day; } return /*#__PURE__*/ _jsx(DatePickerCtx.Provider, { value: contextValue, children: /*#__PURE__*/ _jsxs("div", { className: classNames(className, "bf-datepicker-container", { "bf-datepicker-disabled": disabled, "bf-datepicker-success": state === "success", "bf-datepicker-warning": state === "warning", "bf-datepicker-alert": state === "alert", "bf-datepicker-small": small }), style: style, "data-testid": "bf-datepicker-container", children: [ !hideLabel && /*#__PURE__*/ _jsx(Label, { htmlFor: inputId, required: required && !requiredNoLabel, optional: optional, disabled: disabled, readOnly: readOnly, children: label }), /*#__PURE__*/ _jsx(Description, { children: description }), /*#__PURE__*/ _jsxs("div", { className: classNames("bf-datepicker-icon-container", { "bf-datepicker-icon-right": rightIcon, "bf-datepicker-icon-left": !rightIcon, "bf-show-time-select": props.showTimeSelect, "bf-show-time-select-only": props.showTimeSelectOnly, "bf-datepicker-clearable": isClearable }), children: [ /*#__PURE__*/ _jsx(ReactDatePicker, { readOnly: readOnly, className: classNames("bf-datepicker", "bf-open-sans", className), id: inputId, dateFormat: dateFormat, timeFormat: datepickerLocale.format.time, showMonthDropdown: true, useShortMonthInDropdown: true, showYearDropdown: true, yearDropdownItemNumber: 5, disabled: disabled, locale: datepickerLocale.locale, placeholderText: placeholderText, isClearable: isClearable, inline: inline, formatWeekDay: firstLetterOfDay, ...props?.showTimeSelect && { fixedHeight: true }, timeIntervals: timeIntervals, autoComplete: "off", ref: (r)=>{ setDatePickerRef(r); if (typeof ref === "function") { ref(r); } else if (ref) { ref.current = r; } }, calendarContainer: inline ? undefined : CalendarContainerOverride, ...props }), !inline && /*#__PURE__*/ _jsx("span", { className: classNames("bf-datepicker-icon", { "bf-state-icon": state }), children: /*#__PURE__*/ _jsx(Icon, { icon: displayIcon }) }) ] }), /*#__PURE__*/ _jsx(Feedback, { children: feedback }) ] }) }); }); DatePicker.displayName = "DatePicker"; export default DatePicker;