@campfire-interactive/inputs 0.2.1 → 0.2.2
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/index.js +86 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// src/DatePicker.tsx
|
|
2
|
+
import * as React from "react";
|
|
2
3
|
import ReactDatePicker from "react-datepicker";
|
|
3
4
|
import { format as fmt, parse as parseDate, isValid } from "date-fns";
|
|
4
5
|
import "react-datepicker/dist/react-datepicker.css";
|
|
@@ -45,6 +46,70 @@ var toDate = (value, formatStr) => {
|
|
|
45
46
|
return isValid(d) ? d : null;
|
|
46
47
|
};
|
|
47
48
|
var toCanonicalString = (date, formatStr) => date && isValid(date) ? fmt(date, formatStr) : null;
|
|
49
|
+
var DATE_ALTS = [
|
|
50
|
+
"MM/dd/yyyy",
|
|
51
|
+
"M/d/yyyy",
|
|
52
|
+
"MM/dd/yy",
|
|
53
|
+
"M/d/yy",
|
|
54
|
+
"MM-dd-yyyy",
|
|
55
|
+
"M-d-yyyy",
|
|
56
|
+
"yyyy/MM/dd",
|
|
57
|
+
"yyyy-M-d",
|
|
58
|
+
"MMM d yyyy",
|
|
59
|
+
"MMM d, yyyy",
|
|
60
|
+
"MMMM d yyyy",
|
|
61
|
+
"MMMM d, yyyy"
|
|
62
|
+
];
|
|
63
|
+
var TIME_ALTS = ["H:mm", "h:mm a", "h:mma", "h a", "ha", "HHmm"];
|
|
64
|
+
var TYPED_ALTERNATES = {
|
|
65
|
+
date: DATE_ALTS,
|
|
66
|
+
datetime: DATE_ALTS.flatMap((d) => TIME_ALTS.map((t) => `${d} ${t}`)),
|
|
67
|
+
time: TIME_ALTS,
|
|
68
|
+
month: [
|
|
69
|
+
"yyyy-M",
|
|
70
|
+
"yyyy/MM",
|
|
71
|
+
"yyyy/M",
|
|
72
|
+
"MM/yyyy",
|
|
73
|
+
"M/yyyy",
|
|
74
|
+
"MM-yyyy",
|
|
75
|
+
"M-yyyy",
|
|
76
|
+
"MM/yy",
|
|
77
|
+
"M/yy",
|
|
78
|
+
"MMM yyyy",
|
|
79
|
+
"MMMM yyyy",
|
|
80
|
+
"MMM yy"
|
|
81
|
+
],
|
|
82
|
+
quarter: ["'Q'Q yyyy", "'Q'Q/yyyy", "'Q'Q-yyyy", "'Q'Qyyyy", "yyyy 'Q'Q", "yyyy-'Q'Q", "yyyy/'Q'Q"],
|
|
83
|
+
year: ["yyyy"]
|
|
84
|
+
};
|
|
85
|
+
var parseTyped = (text, formatStr, mode, ref = /* @__PURE__ */ new Date()) => {
|
|
86
|
+
let value = text.trim().replace(/\s+/g, " ");
|
|
87
|
+
if (!value) return null;
|
|
88
|
+
if (mode === "quarter") value = value.toUpperCase();
|
|
89
|
+
for (const f of [formatStr, ...TYPED_ALTERNATES[mode]]) {
|
|
90
|
+
const d = parseDate(value, f, ref);
|
|
91
|
+
if (!isValid(d)) continue;
|
|
92
|
+
if (/y/.test(f) && d.getFullYear() < 1e3) continue;
|
|
93
|
+
if (/yy/.test(f) && !/yyyy/.test(f) && fmt(d, f).toUpperCase() !== value.toUpperCase()) continue;
|
|
94
|
+
return d;
|
|
95
|
+
}
|
|
96
|
+
return null;
|
|
97
|
+
};
|
|
98
|
+
var grainKey = (x, mode) => {
|
|
99
|
+
switch (mode) {
|
|
100
|
+
case "year":
|
|
101
|
+
return x.getFullYear() * 1e4;
|
|
102
|
+
case "quarter":
|
|
103
|
+
return x.getFullYear() * 1e4 + Math.floor(x.getMonth() / 3) * 300;
|
|
104
|
+
case "month":
|
|
105
|
+
return x.getFullYear() * 1e4 + x.getMonth() * 100;
|
|
106
|
+
case "time":
|
|
107
|
+
return 0;
|
|
108
|
+
default:
|
|
109
|
+
return x.getFullYear() * 1e4 + x.getMonth() * 100 + x.getDate();
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
var outOfRange = (d, mode, min, max) => !!min && grainKey(d, mode) < grainKey(min, mode) || !!max && grainKey(d, mode) > grainKey(max, mode);
|
|
48
113
|
function DatePicker(props) {
|
|
49
114
|
const mode = props.mode ?? "date";
|
|
50
115
|
const defaults = MODE_DEFAULTS[mode];
|
|
@@ -58,7 +123,24 @@ function DatePicker(props) {
|
|
|
58
123
|
modeProps.timeIntervals = 15;
|
|
59
124
|
}
|
|
60
125
|
const selected = toDate(props.value ?? null, formatStr);
|
|
61
|
-
const
|
|
126
|
+
const typed = React.useRef(null);
|
|
127
|
+
const handleChange = (d) => {
|
|
128
|
+
typed.current = null;
|
|
129
|
+
props.onChange(toCanonicalString(d, formatStr));
|
|
130
|
+
};
|
|
131
|
+
const handleChangeRaw = (event) => {
|
|
132
|
+
const target = event?.target;
|
|
133
|
+
typed.current = event?.type === "change" && target instanceof HTMLInputElement ? target.value : null;
|
|
134
|
+
};
|
|
135
|
+
const commitTyped = () => {
|
|
136
|
+
const text = typed.current;
|
|
137
|
+
typed.current = null;
|
|
138
|
+
if (text == null || !text.trim()) return;
|
|
139
|
+
const d = parseTyped(text, formatStr, mode, selected ?? /* @__PURE__ */ new Date());
|
|
140
|
+
if (!d || outOfRange(d, mode, props.minDate, props.maxDate)) return;
|
|
141
|
+
const next = toCanonicalString(d, formatStr);
|
|
142
|
+
if (next !== (props.value ?? null)) props.onChange(next);
|
|
143
|
+
};
|
|
62
144
|
const Picker = ReactDatePicker;
|
|
63
145
|
return /* @__PURE__ */ jsx(
|
|
64
146
|
Picker,
|
|
@@ -66,6 +148,9 @@ function DatePicker(props) {
|
|
|
66
148
|
id: props.id,
|
|
67
149
|
selected: selected ?? void 0,
|
|
68
150
|
onChange: handleChange,
|
|
151
|
+
onChangeRaw: handleChangeRaw,
|
|
152
|
+
onBlur: commitTyped,
|
|
153
|
+
onCalendarClose: commitTyped,
|
|
69
154
|
placeholderText: placeholder,
|
|
70
155
|
disabled: props.disabled,
|
|
71
156
|
minDate: props.minDate,
|