Skip to content

Instantly share code, notes, and snippets.

@rchowe
Created August 28, 2022 21:18
Show Gist options
  • Save rchowe/65fb0ec18c22a5cd636653f405f2ce39 to your computer and use it in GitHub Desktop.
Save rchowe/65fb0ec18c22a5cd636653f405f2ce39 to your computer and use it in GitHub Desktop.
.datepicker-cell.selected, .datepicker-cell.selected:hover
{
background-color: var(--amplify-colors-brand-primary-80);
}
.datepicker-cell.day.today:not(.selected)
{
color: unset;
background-color: var(--amplify-colors-neutral-20);
}
import React from "react";
import { TextField } from "@aws-amplify/ui-react";
import { Datepicker } from "vanillajs-datepicker";
import { DatepickerOptions } from "vanillajs-datepicker/Datepicker";
import "./node_modules/vanillajs-datepicker/dist/css/datepicker.css";
import "./DatePickerField.css";
type AmplifyTextFieldProperties = Parameters<typeof TextField>[0];
interface Properties extends AmplifyTextFieldProperties
{
datePickerOptions?: DatepickerOptions;
}
/**
* Wraps a vanillajs-datepicker as a React component.
*/
class DatePickerField extends React.Component<Properties>
{
textFieldRef: React.RefObject<HTMLInputElement>;
datepicker?: Datepicker;
constructor(props: Readonly<Properties>) {
super(props);
this.textFieldRef = React.createRef();
this.onChangeDate = this.onChangeDate.bind(this);
}
componentDidMount() {
if (!this.textFieldRef.current)
return;
this.datepicker = new Datepicker(this.textFieldRef.current, this.props.datePickerOptions);
this.textFieldRef.current.addEventListener("changeDate", this.onChangeDate);
}
componentWillUnmount() {
this.textFieldRef.current?.removeEventListener("changeDate", this.onChangeDate);
this.datepicker?.destroy();
}
componentDidUpdate(prevProps: Properties) {
if (this.props.datePickerOptions !== prevProps.datePickerOptions && this.datepicker && this.props.datePickerOptions)
this.datepicker.config = this.props.datePickerOptions;
}
private onChangeDate(e: any) {
const value = e.target.value as string;
// FIXME: The non-react library sets the value of the input, then we have to set it to something else and then
// set it back to get the event in React to trigger. There should be a way to do this without having to
// set the input three times.
const nativeSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value")?.set;
nativeSetter?.call(this.textFieldRef.current, "");
const newEvent1 = new Event("input", { bubbles: true });
this.textFieldRef.current?.dispatchEvent(newEvent1);
nativeSetter?.call(this.textFieldRef.current, value);
const newEvent2 = new Event("input", { bubbles: true });
this.textFieldRef.current?.dispatchEvent(newEvent2);
}
render() {
return (
<TextField
{...{ ...this.props, datePickerOptions: undefined }}
label={this.props.label}
ref={this.textFieldRef} />
);
}
}
export default DatePickerField;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment