@octax-app/hot-date-react 0.0.6 → 0.0.7

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/README.md CHANGED
@@ -162,16 +162,55 @@ const [date, setDate] = useState<string | null>(null);
162
162
  />
163
163
  ```
164
164
 
165
- When a `value` is set, it appears as a human-readable label on the right side of the input (the ghost resolution area). The text field stays empty for natural typing. On blur, the field shows the formatted value; on focus, it restores the raw input.
165
+ When `value` is provided the input renders in display mode showing the formatted date while unfocused. Clicking into it restores the natural-language input for editing. On blur it returns to display mode automatically.
166
+
167
+ ### Uncontrolled with a default value
168
+
169
+ ```tsx
170
+ <HotDate
171
+ defaultValue="2026-06-13"
172
+ onChange={(v) => console.log(v)}
173
+ />
174
+ ```
175
+
176
+ `defaultValue` sets the initial value on mount and immediately enters display mode, but the component is uncontrolled after that — React does not drive subsequent updates.
177
+
178
+ ### Event callbacks
179
+
180
+ ```tsx
181
+ <HotDate
182
+ onFocus={(e) => console.log('focused', e)}
183
+ onBlur={(e) => console.log('blurred', e)}
184
+ onKeyDown={(e) => console.log('key', e.key)}
185
+ onInput={(rawValue) => console.log('typing', rawValue)}
186
+ onPaste={(e) => console.log('pasted')}
187
+ onClick={(e) => console.log('clicked')}
188
+ onMouseEnter={(e) => console.log('mouse in')}
189
+ onMouseLeave={(e) => console.log('mouse out')}
190
+ />
191
+ ```
166
192
 
167
193
  ## Props
168
194
 
169
195
  | Prop | Type | Default | Description |
170
196
  | --- | --- | --- | --- |
171
- | `value` | `string \| null` | — | Controlled canonical value (`YYYY-MM-DD` or `YYYY-MM-DD/YYYY-MM-DD`) |
197
+ | `value` | `string \| null` | — | Controlled canonical value (`YYYY-MM-DD` or `YYYY-MM-DD/YYYY-MM-DD`). Enters display mode while unfocused. |
198
+ | `defaultValue` | `string \| null` | — | Uncontrolled initial value. Mounts in display mode; React does not drive updates after mount. |
172
199
  | `onChange` | `(value: string \| [string, string] \| null) => void` | — | Fires on every valid parse. Range returns `[start, end]`. |
173
200
  | `onCommit` | `(value: string \| [string, string] \| null) => void` | — | Fires on Enter key commit. |
174
201
  | `onClear` | `() => void` | — | Fires when input is cleared. |
202
+ | `onFocus` | `(e: FocusEvent) => void` | — | Fires when the input gains focus. |
203
+ | `onBlur` | `(e: FocusEvent) => void` | — | Fires when the input loses focus. |
204
+ | `onKeyDown` | `(e: KeyboardEvent) => void` | — | Fires on keydown. |
205
+ | `onKeyUp` | `(e: KeyboardEvent) => void` | — | Fires on keyup. |
206
+ | `onInput` | `(rawValue: string) => void` | — | Fires on every keystroke with the raw typed string. |
207
+ | `onPaste` | `(e: ClipboardEvent) => void` | — | Fires when content is pasted into the input. |
208
+ | `onClick` | `(e: MouseEvent) => void` | — | Fires on click. |
209
+ | `onMouseEnter` | `(e: MouseEvent) => void` | — | Fires when the mouse enters the component. |
210
+ | `onMouseLeave` | `(e: MouseEvent) => void` | — | Fires when the mouse leaves the component. |
211
+ | `onMouseDown` | `(e: MouseEvent) => void` | — | Fires on mousedown. |
212
+ | `onMouseUp` | `(e: MouseEvent) => void` | — | Fires on mouseup. |
213
+ | `onMouseMove` | `(e: MouseEvent) => void` | — | Fires on mousemove. |
175
214
  | `format` | `string` | `"YYYY-MM-DD"` | Output format. Tokens: `YYYY MM DD YY M D` (case-insensitive). |
176
215
  | `dateType` | `"point" \| "range"` | `"point"` | Restrict input to single date or range. |
177
216
  | `startDate` | `Date \| string` | — | Minimum date. Accepts a JS `Date` or `"YYYY-MM-DD"` string. |
@@ -8911,6 +8911,9 @@ var Gc = class extends HTMLElement {
8911
8911
  focus() {
8912
8912
  this.inputElement.focus();
8913
8913
  }
8914
+ forceDisplayMode(e) {
8915
+ e ? (this.isDisplayMode = !0, this.inputElement.value = this.formatValue(e), this.ghostElement.hidden = !0) : (this.isDisplayMode = !1, this.inputElement.value = this.rawInputValue, this.ghostElement.hidden = !1, this.renderGhost());
8916
+ }
8914
8917
  clear() {
8915
8918
  this.isDisplayMode = !1, this.ghostElement.hidden = !1, this.rawInputValue = "", this.committedValue = null, this.removeAttribute("value"), this.internals?.setFormValue(""), this.activeSuggestionIndexValue = 0, this.syncInputPresentation(), this.parseAndRender(), this.emit("clear", {});
8916
8919
  }
@@ -1,4 +1,4 @@
1
- import { t as e } from "./hot-date-CE4exKZT.js";
1
+ import { t as e } from "./hot-date-B8i-uiIl.js";
2
2
  import { useEffect as t, useRef as n, useState as r } from "react";
3
3
  import { jsx as i } from "react/jsx-runtime";
4
4
  //#region src/react/format.ts
@@ -71,80 +71,110 @@ typeof customElements < "u" && (customElements.get("hot-date") || customElements
71
71
  function f(e) {
72
72
  if (e !== void 0) return typeof e == "string" ? e : `${e.getFullYear()}-${String(e.getMonth() + 1).padStart(2, "0")}-${String(e.getDate()).padStart(2, "0")}`;
73
73
  }
74
- function p({ value: e, onChange: a, onCommit: s, onClear: c, format: l, dateType: p = "point", startDate: m, endDate: h, className: g, style: _, placeholder: v, timezone: y, locale: b, weekStart: x, disabled: S, required: C, name: w, showHint: T, error: E, success: D, classNames: O }) {
75
- let k = n(null), [A, j] = r(!!e), [M, N] = r(!1), P = T ?? !0;
76
- return t(() => {
77
- let e = k.current;
74
+ function p({ value: e, defaultValue: a, onChange: s, onCommit: c, onClear: l, onFocus: p, onBlur: m, onKeyDown: h, onKeyUp: g, onInput: _, onPaste: v, onClick: y, onMouseEnter: b, onMouseLeave: x, onMouseDown: S, onMouseUp: C, onMouseMove: w, format: T, dateType: E = "point", startDate: D, endDate: O, className: k, style: A, placeholder: j, timezone: M, locale: N, weekStart: P, disabled: F, required: I, name: L, showHint: R, error: z, success: B, classNames: V }) {
75
+ let H = n(null), [U, W] = r(!!e), [G, K] = r(!1), q = R ?? !0;
76
+ t(() => {
77
+ let e = H.current;
78
78
  if (!e) return;
79
79
  let t = (t, n) => {
80
80
  n ? e.setAttribute(t, "") : e.removeAttribute(t);
81
81
  }, n = (t, n) => {
82
82
  n == null ? e.removeAttribute(t) : e.setAttribute(t, n);
83
83
  };
84
- n("placeholder", v), n("timezone", y), n("locale", b), n("week-start", x), n("start-date", f(m)), n("end-date", f(h)), n("mode", p), n("format", l), t("disabled", !!S), t("required", !!C), t("hide-hint", !P), n("name", w);
84
+ n("placeholder", j), n("timezone", M), n("locale", N), n("week-start", P), n("start-date", f(D)), n("end-date", f(O)), n("mode", E), n("format", T), t("disabled", !!F), t("required", !!I), t("hide-hint", !q), n("name", L);
85
85
  }, [
86
- v,
87
- y,
88
- b,
89
- x,
90
- m,
91
- h,
92
- p,
93
- l,
94
- S,
95
- C,
96
- w,
97
- P
98
- ]), t(() => {
99
- let t = k.current;
86
+ j,
87
+ M,
88
+ N,
89
+ P,
90
+ D,
91
+ O,
92
+ E,
93
+ T,
94
+ F,
95
+ I,
96
+ L,
97
+ q
98
+ ]);
99
+ let J = n(a);
100
+ return t(() => {
101
+ let e = H.current, t = J.current;
102
+ if (!e || t == null) return;
103
+ let n = T ? o(t, T) ?? t : t;
104
+ e.value = n, W(!!n), n && (e.setAttribute("display-value", u(n)), e.forceDisplayMode(n));
105
+ }, []), t(() => {
106
+ let t = H.current;
100
107
  if (!t || e === void 0) return;
101
- let n = e ? l ? o(e, l) ?? e : e : null;
102
- t.value = n, j(!!n), n ? t.setAttribute("display-value", u(n)) : t.removeAttribute("display-value");
103
- }, [e, l]), t(() => {
104
- let e = k.current;
108
+ let n = e ? T ? o(e, T) ?? e : e : null;
109
+ t.value = n, W(!!n), n ? (t.setAttribute("display-value", u(n)), G || t.forceDisplayMode(n)) : (t.removeAttribute("display-value"), G || t.forceDisplayMode(null));
110
+ }, [
111
+ e,
112
+ T,
113
+ G
114
+ ]), t(() => {
115
+ let e = H.current;
105
116
  if (!e) return;
106
117
  let t = (e) => {
107
118
  let t = e.detail;
108
- j(!!t.value), a?.(d(t.value, l));
119
+ W(!!t.value), s?.(d(t.value, T));
109
120
  }, n = (e) => {
110
121
  let t = e.detail;
111
- s?.(d(t.value, l));
122
+ c?.(d(t.value, T));
112
123
  }, r = () => {
113
- j(!1), c?.();
114
- }, i = () => N(!0), o = () => N(!1);
115
- return e.addEventListener("value-change", t), e.addEventListener("value-commit", n), e.addEventListener("clear", r), e.addEventListener("focusin", i), e.addEventListener("focusout", o), () => {
116
- e.removeEventListener("value-change", t), e.removeEventListener("value-commit", n), e.removeEventListener("clear", r), e.removeEventListener("focusin", i), e.removeEventListener("focusout", o);
124
+ W(!1), l?.();
125
+ }, i = (e) => {
126
+ K(!0), p?.(e);
127
+ }, a = (e) => {
128
+ K(!1), m?.(e);
129
+ }, o = (e) => h?.(e), u = (e) => g?.(e), f = (e) => {
130
+ let t = e.detail;
131
+ _?.(t.rawInput);
132
+ }, E = (e) => v?.(e), D = (e) => y?.(e), O = (e) => b?.(e), k = (e) => x?.(e), A = (e) => S?.(e), j = (e) => C?.(e), M = (e) => w?.(e);
133
+ return e.addEventListener("value-change", t), e.addEventListener("value-commit", n), e.addEventListener("clear", r), e.addEventListener("focusin", i), e.addEventListener("focusout", a), e.addEventListener("keydown", o), e.addEventListener("keyup", u), e.addEventListener("raw-input-change", f), e.addEventListener("paste", E), e.addEventListener("click", D), e.addEventListener("mouseenter", O), e.addEventListener("mouseleave", k), e.addEventListener("mousedown", A), e.addEventListener("mouseup", j), e.addEventListener("mousemove", M), () => {
134
+ e.removeEventListener("value-change", t), e.removeEventListener("value-commit", n), e.removeEventListener("clear", r), e.removeEventListener("focusin", i), e.removeEventListener("focusout", a), e.removeEventListener("keydown", o), e.removeEventListener("keyup", u), e.removeEventListener("raw-input-change", f), e.removeEventListener("paste", E), e.removeEventListener("click", D), e.removeEventListener("mouseenter", O), e.removeEventListener("mouseleave", k), e.removeEventListener("mousedown", A), e.removeEventListener("mouseup", j), e.removeEventListener("mousemove", M);
117
135
  };
118
136
  }, [
119
- a,
120
137
  s,
121
138
  c,
122
- l
139
+ l,
140
+ p,
141
+ m,
142
+ h,
143
+ g,
144
+ _,
145
+ v,
146
+ y,
147
+ b,
148
+ x,
149
+ S,
150
+ C,
151
+ w,
152
+ T
123
153
  ]), t(() => {
124
- let e = k.current;
154
+ let e = H.current;
125
155
  if (!e) return;
126
156
  let t = (e) => e ? typeof e == "function" ? e({
127
- active: A,
128
- disabled: !!S,
129
- focused: M,
130
- error: !!E,
131
- success: !!D
157
+ active: U,
158
+ disabled: !!F,
159
+ focused: G,
160
+ error: !!z,
161
+ success: !!B
132
162
  }) : e : null, n = (n, r) => {
133
163
  let i = t(r);
134
164
  i ? e.setAttribute(n, i) : e.removeAttribute(n);
135
165
  };
136
- n("part-class-input", O?.input), n("part-class-ghost", O?.ghost), n("part-class-hint", O?.hint);
166
+ n("part-class-input", V?.input), n("part-class-ghost", V?.ghost), n("part-class-hint", V?.hint);
137
167
  }, [
138
- O,
139
- A,
140
- M,
141
- S,
142
- E,
143
- D
168
+ V,
169
+ U,
170
+ G,
171
+ F,
172
+ z,
173
+ B
144
174
  ]), /* @__PURE__ */ i("hot-date", {
145
- ref: k,
146
- class: g,
147
- style: _
175
+ ref: H,
176
+ class: k,
177
+ style: A
148
178
  });
149
179
  }
150
180
  //#endregion
@@ -33,6 +33,7 @@ export declare class HotDateElement extends HTMLElement {
33
33
  get suggestions(): CompletionSuggestion[];
34
34
  get activeSuggestionIndex(): number;
35
35
  focus(): void;
36
+ forceDisplayMode(canonical: string | null): void;
36
37
  clear(): void;
37
38
  confirm(): boolean;
38
39
  acceptSuggestion(index?: number): boolean;
package/dist/hot-date.js CHANGED
@@ -1,2 +1,2 @@
1
- import { t as e } from "./hot-date-CE4exKZT.js";
1
+ import { t as e } from "./hot-date-B8i-uiIl.js";
2
2
  export { e as HotDateElement };
@@ -14,9 +14,22 @@ export interface ClassNamesConfig {
14
14
  type WEEK_START_MAP = 'sunday' | 'monday' | 'tuesday' | 'wednesday' | 'thursday' | 'friday' | 'saturday';
15
15
  export interface HotDateProps {
16
16
  value?: string | null;
17
+ defaultValue?: string | null;
17
18
  onChange?: (value: string | [string, string] | null) => void;
18
19
  onCommit?: (value: string | [string, string] | null) => void;
19
20
  onClear?: () => void;
21
+ onFocus?: (e: FocusEvent) => void;
22
+ onBlur?: (e: FocusEvent) => void;
23
+ onKeyDown?: (e: KeyboardEvent) => void;
24
+ onKeyUp?: (e: KeyboardEvent) => void;
25
+ onInput?: (rawValue: string) => void;
26
+ onPaste?: (e: ClipboardEvent) => void;
27
+ onClick?: (e: MouseEvent) => void;
28
+ onMouseEnter?: (e: MouseEvent) => void;
29
+ onMouseLeave?: (e: MouseEvent) => void;
30
+ onMouseDown?: (e: MouseEvent) => void;
31
+ onMouseUp?: (e: MouseEvent) => void;
32
+ onMouseMove?: (e: MouseEvent) => void;
20
33
  format?: string;
21
34
  dateType?: "point" | "range";
22
35
  startDate?: Date | string;
@@ -63,5 +76,5 @@ declare module "react" {
63
76
  }
64
77
  }
65
78
  }
66
- export declare function HotDate({ value, onChange, onCommit, onClear, format, dateType, startDate, endDate, className, style, placeholder, timezone, locale, weekStart, disabled, required, name, showHint, error, success, classNames, }: HotDateProps): import("react/jsx-runtime").JSX.Element;
79
+ export declare function HotDate({ value, defaultValue, onChange, onCommit, onClear, onFocus, onBlur, onKeyDown, onKeyUp, onInput, onPaste, onClick, onMouseEnter, onMouseLeave, onMouseDown, onMouseUp, onMouseMove, format, dateType, startDate, endDate, className, style, placeholder, timezone, locale, weekStart, disabled, required, name, showHint, error, success, classNames, }: HotDateProps): import("react/jsx-runtime").JSX.Element;
67
80
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@octax-app/hot-date-react",
3
- "version": "0.0.6",
3
+ "version": "0.0.7",
4
4
  "description": "React wrapper for the hot-date natural language date input web component.",
5
5
  "type": "module",
6
6
  "main": "./dist/hot-date-react.js",