braid-design-system
Version:
Themeable design system for the SEEK Group
181 lines (180 loc) • 5.41 kB
JavaScript
import { jsx, jsxs } from "react/jsx-runtime";
import assert from "assert";
import { isMobile } from "is-mobile";
import { createRef, Fragment } from "react";
import { Box } from "../Box/Box.mjs";
import { Column } from "../Column/Column.mjs";
import { Columns } from "../Columns/Columns.mjs";
import { Dropdown } from "../Dropdown/Dropdown.mjs";
import { Field } from "../private/Field/Field.mjs";
import { FieldGroup } from "../private/FieldGroup/FieldGroup.mjs";
import { nativeInput } from "./MonthPicker.css.mjs";
const defaultMonthNames = [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
];
const getMonths = (monthNames) => monthNames.map((monthName, i) => /* @__PURE__ */ jsx("option", { value: i + 1, children: monthName }, i));
const getYears = (min, max, ascending) => [...new Array(max - min + 1)].map((_v, i) => {
const yearStr = String(ascending ? i + min : max - i);
return /* @__PURE__ */ jsx("option", { value: yearStr, children: yearStr }, yearStr);
});
const currYear = (/* @__PURE__ */ new Date()).getFullYear();
const renderNativeInput = isMobile({ tablet: true });
const customValueToString = ({ month, year }) => month && year ? `${year}-${month < 10 ? "0" : ""}${month}` : void 0;
const stringToCustomValue = (value) => {
const [year, month] = value.split("-");
return {
month: parseInt(month, 10),
year: parseInt(year, 10)
};
};
const makeChangeHandler = (onChange, value, fieldType) => (event) => {
if (typeof onChange === "function") {
onChange(
{
month: {
year: value && value.year ? value.year : void 0,
month: parseInt(event.target.value, 10) || void 0
},
year: {
month: value && value.month ? value.month : void 0,
year: parseInt(event.target.value, 10) || void 0
},
native: stringToCustomValue(event.target.value)
}[fieldType]
);
}
};
const MonthPicker = ({
value,
onChange,
onBlur,
onFocus,
tone,
disabled,
minYear = currYear - 100,
maxYear = currYear,
ascendingYears = false,
monthLabel = "Month",
yearLabel = "Year",
tabIndex,
monthNames = defaultMonthNames,
...restProps
}) => {
assert(monthNames.length === 12, "monthNames array must contain 12 items");
const currentValue = {
month: value && value.month ? value.month : void 0,
year: value && value.year ? value.year : void 0
};
const monthRef = createRef();
const yearRef = createRef();
const blurHandler = onBlur ? (event) => {
const fireIfExternal = (element) => {
if (element !== monthRef.current && element !== yearRef.current) {
onBlur();
}
};
if (event.relatedTarget !== null) {
fireIfExternal(event.relatedTarget);
} else {
setTimeout(() => {
fireIfExternal(document.activeElement);
});
}
} : void 0;
const focusHandler = onFocus ? (event) => {
if (event.relatedTarget !== monthRef.current && event.relatedTarget !== yearRef.current) {
onFocus();
}
} : void 0;
const nativeField = /* @__PURE__ */ jsx(
Field,
{
tone,
disabled,
value: customValueToString(currentValue),
...restProps,
componentName: "MonthPicker",
tabIndex,
icon: void 0,
prefix: void 0,
name: void 0,
autoComplete: void 0,
secondaryMessage: null,
children: (overlays, { className, ...fieldProps }) => /* @__PURE__ */ jsxs(Fragment, { children: [
/* @__PURE__ */ jsx(
Box,
{
component: "input",
type: "month",
value: customValueToString(currentValue),
onChange: onChange && makeChangeHandler(onChange, value, "native"),
onBlur,
onFocus,
...fieldProps,
height: "touchable",
className: [className, nativeInput]
}
),
overlays
] })
}
);
const customFieldGroup = /* @__PURE__ */ jsx(
FieldGroup,
{
tone,
disabled,
tabIndex,
componentName: "MonthPicker",
...restProps,
children: (fieldGroupProps) => /* @__PURE__ */ jsxs(Columns, { space: "xsmall", children: [
/* @__PURE__ */ jsx(Column, { children: /* @__PURE__ */ jsx(
Dropdown,
{
value: currentValue.month || "",
onChange: makeChangeHandler(onChange, value, "month"),
onBlur: blurHandler,
onFocus: focusHandler,
tone,
placeholder: monthLabel,
"aria-label": monthLabel,
...fieldGroupProps,
ref: monthRef,
children: getMonths(monthNames)
}
) }),
/* @__PURE__ */ jsx(Column, { children: /* @__PURE__ */ jsx(
Dropdown,
{
value: currentValue.year || "",
onChange: makeChangeHandler(onChange, value, "year"),
onBlur: blurHandler,
onFocus: focusHandler,
tone,
placeholder: yearLabel,
"aria-label": yearLabel,
...fieldGroupProps,
ref: yearRef,
children: getYears(minYear, maxYear, ascendingYears)
}
) })
] })
}
);
return renderNativeInput ? nativeField : customFieldGroup;
};
MonthPicker.displayName = "MonthPicker";
export {
MonthPicker
};