@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.
Files changed (2) hide show
  1. package/dist/index.js +86 -1
  2. 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 handleChange = (d) => props.onChange(toCanonicalString(d, formatStr));
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,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@campfire-interactive/inputs",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Shared input components for Campfire Suite (date picker, etc.)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",