@availity/mui-datepicker
Version:
Availity MUI Datepicker Component - part of the @availity/element design system
342 lines (331 loc) • 10.6 kB
JavaScript
// src/lib/Datepicker.tsx
import { CalendarDaysIcon } from "@availity/mui-icon";
import { DatePicker as MuiDatePicker } from "@mui/x-date-pickers/DatePicker";
// src/lib/PickersTextField.tsx
import { PickersTextField as MuiPickersTextField } from "@mui/x-date-pickers/PickersTextField";
// ../../node_modules/@availity/message-core/dist/index.js
var AvMessage = class {
subscribers = {};
constructor() {
window.addEventListener("message", this.getEventData);
}
enabled(value) {
if (arguments.length > 0) {
this.isEnabled = !!value;
}
return this.isEnabled;
}
getEventData = (event) => {
const isSameWindow = event.source === window;
if (!this.isEnabled || // do nothing if not enabled
!event || !event.data || !event.origin || !event.source || // check event exists and has necessary properties
!this.isDomain(event.origin)) {
return;
}
let { data } = event;
if (typeof data === "string") {
try {
data = JSON.parse(data);
} catch {
}
}
if (typeof data === "string") {
event = data;
data = void 0;
} else {
event = data && data.event || this.DEFAULT_EVENT;
}
const metadata = { isSameWindow };
this.onMessage(event, data, metadata);
};
#lastId = 0;
subscribe(event, callback, options) {
if (!this.subscribers[event]) {
this.subscribers[event] = [];
}
this.#lastId += 1;
const id = this.#lastId;
const ignoreSameWindow = options?.ignoreSameWindow ?? true;
const subscriber = { id, callback, options: { ignoreSameWindow } };
this.subscribers[event].push(subscriber);
return () => {
this.subscribers[event] = this.subscribers[event].filter((subscriber2) => subscriber2.id !== id);
};
}
// remove all subscribers for this event
unsubscribe(event) {
delete this.subscribers[event];
}
unsubscribeAll() {
this.subscribers = {};
}
onMessage(event, data, metadata) {
const { isSameWindow } = metadata;
if (this.subscribers[event]) {
for (const subscriber of this.subscribers[event]) {
const { ignoreSameWindow } = subscriber.options;
const skip = isSameWindow && ignoreSameWindow;
if (!skip) {
subscriber.callback(data);
}
}
}
}
// if current domain doesn't match regex DOMAIN, return true.
isDomain(url) {
return !this.DOMAIN.test(this.domain()) || this.DOMAIN.test(url);
}
/**
* Attempts to get origin from top window
* @private
* @returns {string|null}
*/
getOriginFromTop() {
try {
return window.top.location.origin;
} catch {
return null;
}
}
/**
* Swaps between 'apps' and 'essentials' in the domain
* @private
* @param {string} url
* @returns {string}
*/
swapDomain(url) {
if (url.includes("essentials")) {
return url.replace("essentials", "apps");
}
return url.replace("apps", "essentials");
}
/**
* Gets the domain
* @private
* @returns {string}
*/
domain() {
const topOrigin = this.getOriginFromTop();
if (topOrigin) {
return topOrigin;
}
if (window.location.origin) {
const url = window.location.origin;
return this.swapDomain(url);
}
if (window.location.hostname) {
const url = `${window.location.protocol}//${window.location.hostname}${window.location.port ? `:${window.location.port}` : ""}`;
return this.swapDomain(url);
}
return "*";
}
send(payload, target = window.top) {
if (!this.isEnabled || !payload) {
return;
}
try {
const message = typeof payload === "string" ? payload : JSON.stringify(payload);
target.postMessage(message, this.domain());
} catch (error) {
console.warn("AvMessage.send()", error);
}
}
/**
* Remove the message event listener. Call this when your app or component
* unmounts to prevent memory leaks.
*/
destroy() {
window.removeEventListener("message", this.getEventData);
}
isEnabled = true;
DEFAULT_EVENT = "avMessage";
DOMAIN = /https?:\/\/([\w-]+\.)?availity\.(com|net)/;
};
var AvMessage_default = AvMessage;
var index_default = new AvMessage_default();
// ../form-utils/src/lib/FieldHelpIcon.tsx
import { HelpCircleIcon } from "@availity/mui-icon";
// ../button/src/lib/IconButton.tsx
import { forwardRef } from "react";
import { default as MuiIconButton } from "@mui/material/IconButton";
import Tooltip from "@mui/material/Tooltip";
import { jsx } from "react/jsx-runtime";
var outlinedStyles = {
borderRadius: ".25rem",
border: 1
};
var IconButton = forwardRef((props, ref) => {
const { title, variant = "text", sx, size = "medium", ...rest } = props;
const styles = {
...sx,
...variant === "outlined" && outlinedStyles
};
return /* @__PURE__ */ jsx(Tooltip, { title, children: /* @__PURE__ */ jsx(MuiIconButton, { "aria-label": title, sx: { ...styles }, ...rest, ref, size }) });
});
// ../form-utils/src/lib/FieldHelpIcon.tsx
import { jsx as jsx2 } from "react/jsx-runtime";
var triggerFieldHelp = (id) => {
index_default.send({
event: "nav:help:field",
id
});
};
var FieldHelpIcon = ({ helpTopicId, labelId, sx, ...rest }) => /* @__PURE__ */ jsx2(
IconButton,
{
...rest,
color: "primary",
title: "Help",
role: "link",
onClick: () => triggerFieldHelp(helpTopicId),
"aria-describedby": labelId,
size: "small",
sx: { ...sx, fontSize: "inherit", marginTop: "-2px", opacity: 1 },
children: /* @__PURE__ */ jsx2(HelpCircleIcon, { "aria-hidden": true, titleAccess: void 0 })
}
);
// ../form-utils/src/lib/FormHelperText.tsx
import MuiFormHelperText from "@mui/material/FormHelperText";
import { WarningTriangleIcon } from "@availity/mui-icon";
import { jsx as jsx3, jsxs } from "react/jsx-runtime";
var FormHelperText = ({ children, ...props }) => /* @__PURE__ */ jsxs(MuiFormHelperText, { ...props, children: [
/* @__PURE__ */ jsx3(WarningTriangleIcon, { sx: { marginRight: "4px" }, titleAccess: "Error", "aria-hidden": false }),
children
] });
// ../form-utils/src/lib/FormLabel.tsx
import { forwardRef as forwardRef2 } from "react";
import { default as MuiFormLabel } from "@mui/material/FormLabel";
import { styled } from "@mui/material/styles";
import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
var Wrapper = styled("div", {
name: "MuiFormLabel",
slot: "AvWrapper",
overridesResolver: (props, styles) => styles.avWrapper
})({});
var StyleOverrides = {
position: "relative !important",
transform: "none !important",
transition: "none !important",
animation: "none !important"
};
var FormLabel = forwardRef2((props, ref) => {
const { helpTopicId, id, sx, ...rest } = props;
const labelId = id || (rest.htmlFor ? `${rest.htmlFor}-label` : void 0);
return /* @__PURE__ */ jsxs2(Wrapper, { className: "MuiFormLabel-avWrapper", sx, children: [
/* @__PURE__ */ jsx4(MuiFormLabel, { id: labelId, sx: { ...StyleOverrides }, ...rest, ref }),
helpTopicId ? /* @__PURE__ */ jsx4(FieldHelpIcon, { helpTopicId, labelId, sx: { px: 0.5 } }) : null
] });
});
// src/lib/PickersTextField.tsx
import { forwardRef as forwardRef3 } from "react";
import { Fragment, jsx as jsx5 } from "react/jsx-runtime";
var PickersTextField = forwardRef3((props, ref) => {
const { helperText = /* @__PURE__ */ jsx5(Fragment, {}), helpTopicId, InputLabelProps: InputLabelPropsIN, inputProps: inputPropsIN, FormHelperTextProps: FormHelperTextPropsIN, required, ...params } = props;
const PickersLabel = (props2) => /* @__PURE__ */ jsx5(FormLabel, { helpTopicId, required, ...props2 });
return /* @__PURE__ */ jsx5(
MuiPickersTextField,
{
...params,
helperText,
InputLabelProps: {
component: PickersLabel,
...InputLabelPropsIN
},
inputProps: {
"aria-required": required,
...inputPropsIN
},
FormHelperTextProps: {
component: FormHelperText,
error: params.error,
...FormHelperTextPropsIN
},
ref
}
);
});
// src/lib/Datepicker.tsx
import { jsx as jsx6 } from "react/jsx-runtime";
var paperProps = { elevation: 8, variant: "elevation", sx: { marginTop: "4px" } };
var Datepicker = ({
FieldProps,
placement = "bottom-start",
clearable,
...props
}) => /* @__PURE__ */ jsx6(
MuiDatePicker,
{
...props,
dayOfWeekFormatter: (weekday) => weekday.format("dd"),
slotProps: {
// TODO: v3 BREAKING CHANGE remove action bar
actionBar: {
actions: clearable ? ["clear"] : []
},
desktopPaper: paperProps,
mobilePaper: {
...paperProps,
"aria-label": FieldProps?.label?.toString() || FieldProps?.inputProps?.["aria-label"] || "Date picker",
"aria-labelledby": FieldProps?.inputProps?.["aria-labelledby"] || void 0
},
// TODO: v3 add onClear to field
field: { clearable },
textField: FieldProps,
popper: {
placement,
"aria-label": FieldProps?.label?.toString() || FieldProps?.inputProps?.["aria-label"] || "Date picker",
"aria-labelledby": FieldProps?.inputProps?.["aria-labelledby"] || void 0
},
openPickerIcon: {
fontSize: "xsmall"
}
},
slots: {
openPickerIcon: CalendarDaysIcon,
textField: PickersTextField
}
}
);
// src/lib/Timepicker.tsx
import { ClockIcon } from "@availity/mui-icon";
import { TimePicker as MuiTimePicker } from "@mui/x-date-pickers/TimePicker";
import { jsx as jsx7 } from "react/jsx-runtime";
var paperProps2 = { elevation: 8, variant: "elevation", sx: { marginTop: "4px" } };
var Timepicker = ({
FieldProps,
placement = "bottom-start",
clearable,
onClear,
...props
}) => /* @__PURE__ */ jsx7(
MuiTimePicker,
{
...props,
slotProps: {
desktopPaper: paperProps2,
mobilePaper: {
...paperProps2,
"aria-label": FieldProps?.label?.toString() || FieldProps?.inputProps?.["aria-label"] || "Time picker",
"aria-labelledby": FieldProps?.inputProps?.["aria-labelledby"] || void 0
},
field: { clearable, onClear },
textField: FieldProps,
popper: {
placement,
"aria-label": FieldProps?.label?.toString() || FieldProps?.inputProps?.["aria-label"] || "Time picker",
"aria-labelledby": FieldProps?.inputProps?.["aria-labelledby"] || void 0
},
openPickerIcon: {
fontSize: "xsmall"
}
},
slots: {
openPickerIcon: ClockIcon,
textField: PickersTextField
}
}
);
export {
Datepicker,
Timepicker
};