@autoguru/overdrive 4.47.1 → 4.48.0-next.0

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.
@@ -0,0 +1,3 @@
1
+ export declare const segmentStyle: string;
2
+ export declare const verticalCenterStyle: string;
3
+ //# sourceMappingURL=DateInput.css.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DateInput.css.d.ts","sourceRoot":"","sources":["../../../lib/components/DateInput/DateInput.css.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,YAAY,QAevB,CAAC;AAEH,eAAO,MAAM,mBAAmB,QAI9B,CAAC"}
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+
3
+ import * as __vanilla_filescope__ from '@vanilla-extract/css/fileScope';
4
+ __vanilla_filescope__.setFileScope("lib/components/DateInput/DateInput.css.ts", "@autoguru/overdrive");
5
+ import { style } from '@vanilla-extract/css';
6
+ import { cssLayerComponent } from "../../styles/layers.css.js";
7
+ import { selectors } from "../../styles/selectors.js";
8
+ import { sprinkles } from "../../styles/sprinkles.css.js";
9
+ export const segmentStyle = style({
10
+ '@layer': {
11
+ [cssLayerComponent]: {
12
+ fontVariantNumeric: 'tabular-nums',
13
+ userSelect: 'none',
14
+ selectors: {
15
+ [selectors.focusVisible]: {
16
+ outlineOffset: '3px'
17
+ },
18
+ '&:nth-child(even)': {
19
+ padding: '0 2.5px'
20
+ }
21
+ }
22
+ }
23
+ }
24
+ }, "segmentStyle");
25
+ export const verticalCenterStyle = sprinkles({
26
+ alignSelf: 'center',
27
+ display: 'flex',
28
+ justifyContent: 'center'
29
+ });
30
+ __vanilla_filescope__.endFileScope();
@@ -1,3 +1,47 @@
1
- import * as React from 'react';
2
- export declare const DateInput: React.ForwardRefExoticComponent<Partial<Pick<HTMLInputElement, "min" | "max">> & import("../private/InputBase/withEnhancedInput").EnhanceInputPrimitiveProps<HTMLInputElement> & import("../private/InputBase/withEnhancedInput").EventHandlers<HTMLInputElement> & import("../private/InputBase/withEnhancedInput").ValidationProps & React.RefAttributes<HTMLInputElement>>;
1
+ import React from 'react';
2
+ import { type DatePickerProps } from '../DatePicker/DatePicker';
3
+ type FilteredDatePickerProps = Pick<DatePickerProps, 'calendarOptions' | 'lang'>;
4
+ /**
5
+ * Input component for structured date entry with integrated calendar date picker.
6
+ *
7
+ * ## Dates and internationalization
8
+ * - Uses ISO date strings (YYYY-MM-DD) for `value`, `min`, and `max`
9
+ * - Extends DatePicker text values via `lang` props
10
+ * - Also extends Calendar options including calendar-specific text values via `calendarOptions` prop
11
+ * - Advanced i18n and localization handled by [React Aria I18Provider](https://react-spectrum.adobe.com/react-aria/I18nProvider.html)
12
+ * - Read more about [International calendars](https://react-spectrum.adobe.com/react-aria/useDatePicker.html#international-calendars)
13
+ * - Date formatting helper available in `...utils/dateFormat.ts` or use `@internationalized/date` utils
14
+ *
15
+ * **Note:** By default, past dates are allowed. To restrict past date selection, use
16
+ * the `calendarOptions` prop: `<DateInput calendarOptions={{ allowPastDate: false }} />`
17
+ *
18
+ * @example
19
+ * ```tsx
20
+ * // Basic usage
21
+ * <DateInput
22
+ * value="2025-10-15"
23
+ * onChange={(e) => setValue(e.target.value)}
24
+ * />
25
+ *
26
+ * // With restrictions
27
+ * <DateInput
28
+ * min="2025-01-01"
29
+ * max="2025-12-31"
30
+ * calendarOptions={{ allowPastDate: false }}
31
+ * />
32
+ *
33
+ * // With translated text values
34
+ * <DateInput
35
+ * lang={{ openCalendar: 'kalendar offnen' }}
36
+ * calendarOptions={{
37
+ * lang: {
38
+ * prevMonthAriaLabel: 'nachster monat',
39
+ * nextMonthAriaLabel: 'vorheriger monat'
40
+ * }
41
+ * }}
42
+ * />
43
+ * ```
44
+ */
45
+ export declare const DateInput: React.ForwardRefExoticComponent<FilteredDatePickerProps & Partial<Pick<HTMLInputElement, "min" | "max">> & import("../private/InputBase/withEnhancedInput").EnhanceInputPrimitiveProps<HTMLInputElement> & import("../private/InputBase/withEnhancedInput").EventHandlers<HTMLInputElement> & import("../private/InputBase/withEnhancedInput").ValidationProps & React.RefAttributes<HTMLInputElement>>;
46
+ export {};
3
47
  //# sourceMappingURL=DateInput.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DateInput.d.ts","sourceRoot":"","sources":["../../../lib/components/DateInput/DateInput.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,eAAO,MAAM,SAAS,+WAgCrB,CAAC"}
1
+ {"version":3,"file":"DateInput.d.ts","sourceRoot":"","sources":["../../../lib/components/DateInput/DateInput.tsx"],"names":[],"mappings":"AAEA,OAAO,KAMN,MAAM,OAAO,CAAC;AAWf,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAM5E,KAAK,uBAAuB,GAAG,IAAI,CAClC,eAAe,EACf,iBAAiB,GAAG,MAAM,CAC1B,CAAC;AAmCF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,eAAO,MAAM,SAAS,yYAmJrB,CAAC"}
@@ -1,33 +1,207 @@
1
1
  "use strict";
2
2
 
3
- import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
4
3
  import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
5
- const _excluded = ["field", "eventHandlers", "validation", "isLoading", "suffixed", "prefixed", "size"];
4
+ import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
5
+ const _excluded = ["defaultValue", "id", "ref"];
6
6
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
7
7
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
8
- import { warning } from '@autoguru/utilities';
9
- import * as React from 'react';
10
- import { Box } from "../Box/Box.js";
8
+ import { GregorianCalendar } from '@internationalized/date';
9
+ import clsx from 'clsx';
10
+ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
11
+ import { useDateField, useDateSegment, useLocale } from 'react-aria';
12
+ import { useDateFieldState } from 'react-stately';
13
+ import { useDateInputRef } from "../../hooks/useDateInputRef.js";
14
+ import { sprinkles } from "../../styles/sprinkles.css.js";
15
+ import { formatDateValue, safeParseDateString } from "../../utils/dateFormat.js";
16
+ import { DatePicker } from "../DatePicker/DatePicker.js";
17
+ import { inline } from "../Flex/flex.js";
11
18
  import { withEnhancedInput } from "../private/InputBase/index.js";
12
- import { jsx as _jsx } from "react/jsx-runtime";
13
- export const DateInput = withEnhancedInput(_ref => {
14
- let {
15
- field,
16
- eventHandlers,
17
- validation,
18
- isLoading,
19
- suffixed,
20
- prefixed,
21
- size
22
- } = _ref,
23
- rest = _objectWithoutProperties(_ref, _excluded);
24
- process.env.NODE_ENV !== "production" ? warning(field.value !== '', 'Date Input does not support empty values.') : void 0;
25
- return /*#__PURE__*/_jsx(Box, _objectSpread(_objectSpread(_objectSpread(_objectSpread({
26
- as: "input"
27
- }, eventHandlers), field), rest), {}, {
28
- autoComplete: "off",
29
- type: "date"
19
+ import * as styles from "./DateInput.css.js";
20
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
21
+ function createCalendar(identifier) {
22
+ if (identifier === 'gregory') {
23
+ return new GregorianCalendar();
24
+ }
25
+ throw new Error(`Unsupported calendar configured ${identifier}`);
26
+ }
27
+ const defaultCalendarOptions = {
28
+ allowPastDate: true
29
+ };
30
+ const DateSegment = /*#__PURE__*/React.memo(({
31
+ segment,
32
+ state,
33
+ className
34
+ }) => {
35
+ const ref = useRef(null);
36
+ const {
37
+ segmentProps
38
+ } = useDateSegment(segment, state, ref);
39
+ return /*#__PURE__*/_jsx("span", _objectSpread(_objectSpread({}, segmentProps), {}, {
40
+ ref: ref,
41
+ className: className,
42
+ "data-placeholder": segment.isPlaceholder || undefined,
43
+ children: segment.text
44
+ }));
45
+ });
46
+ DateSegment.displayName = 'DateInput.DateSegment';
47
+
48
+ /**
49
+ * Input component for structured date entry with integrated calendar date picker.
50
+ *
51
+ * ## Dates and internationalization
52
+ * - Uses ISO date strings (YYYY-MM-DD) for `value`, `min`, and `max`
53
+ * - Extends DatePicker text values via `lang` props
54
+ * - Also extends Calendar options including calendar-specific text values via `calendarOptions` prop
55
+ * - Advanced i18n and localization handled by [React Aria I18Provider](https://react-spectrum.adobe.com/react-aria/I18nProvider.html)
56
+ * - Read more about [International calendars](https://react-spectrum.adobe.com/react-aria/useDatePicker.html#international-calendars)
57
+ * - Date formatting helper available in `...utils/dateFormat.ts` or use `@internationalized/date` utils
58
+ *
59
+ * **Note:** By default, past dates are allowed. To restrict past date selection, use
60
+ * the `calendarOptions` prop: `<DateInput calendarOptions={{ allowPastDate: false }} />`
61
+ *
62
+ * @example
63
+ * ```tsx
64
+ * // Basic usage
65
+ * <DateInput
66
+ * value="2025-10-15"
67
+ * onChange={(e) => setValue(e.target.value)}
68
+ * />
69
+ *
70
+ * // With restrictions
71
+ * <DateInput
72
+ * min="2025-01-01"
73
+ * max="2025-12-31"
74
+ * calendarOptions={{ allowPastDate: false }}
75
+ * />
76
+ *
77
+ * // With translated text values
78
+ * <DateInput
79
+ * lang={{ openCalendar: 'kalendar offnen' }}
80
+ * calendarOptions={{
81
+ * lang: {
82
+ * prevMonthAriaLabel: 'nachster monat',
83
+ * nextMonthAriaLabel: 'vorheriger monat'
84
+ * }
85
+ * }}
86
+ * />
87
+ * ```
88
+ */
89
+ export const DateInput = withEnhancedInput(({
90
+ calendarOptions,
91
+ eventHandlers,
92
+ field,
93
+ lang,
94
+ max,
95
+ min,
96
+ size
97
+ }) => {
98
+ const {
99
+ defaultValue,
100
+ id,
101
+ ref
102
+ } = field,
103
+ filteredProps = _objectWithoutProperties(field, _excluded);
104
+ const {
105
+ disabled,
106
+ name,
107
+ onChange,
108
+ value
109
+ } = field;
110
+ const datePickerRef = useRef(null);
111
+ const dateFieldRef = useRef(null);
112
+ const {
113
+ locale
114
+ } = useLocale();
115
+ const [selectedDate, setSelectedDate] = useState(value ? safeParseDateString(value) : null);
116
+ const minMaxValues = {
117
+ minValue: min ? safeParseDateString(min) : undefined,
118
+ maxValue: max ? safeParseDateString(max) : undefined
119
+ };
120
+ useEffect(() => {
121
+ const parsedDate = value ? safeParseDateString(value) : null;
122
+ setSelectedDate(parsedDate);
123
+ }, [value]);
124
+ const handleDateChange = useCallback(date => {
125
+ setSelectedDate(date);
126
+ const dateString = formatDateValue(date);
127
+
128
+ // Trigger the withEnhancedInput onChange mechanism
129
+ if (eventHandlers.onChange && typeof onChange === 'function') {
130
+ // Create a synthetic event for compatibility with withEnhancedInput
131
+ const event = {
132
+ currentTarget: {
133
+ value: dateString
134
+ },
135
+ target: {
136
+ value: dateString
137
+ }
138
+ };
139
+ eventHandlers.onChange(event);
140
+ }
141
+ }, [eventHandlers, onChange]);
142
+ const createSyntheticHandler = useCallback(handler => {
143
+ if (!handler) return;
144
+ return e => {
145
+ const syntheticEvent = _objectSpread(_objectSpread({}, e), {}, {
146
+ target: dateFieldRef.current,
147
+ currentTarget: dateFieldRef.current
148
+ });
149
+ handler(syntheticEvent);
150
+ };
151
+ }, []);
152
+ const handleFocus = useMemo(() => createSyntheticHandler(eventHandlers.onFocus), [createSyntheticHandler, eventHandlers.onFocus]);
153
+ const handleBlur = useMemo(() => createSyntheticHandler(eventHandlers.onBlur), [createSyntheticHandler, eventHandlers.onBlur]);
154
+ const hookProps = _objectSpread(_objectSpread({}, filteredProps), {}, {
155
+ isDisabled: field.disabled,
156
+ onBlur: handleBlur,
157
+ onChange: handleDateChange,
158
+ onFocus: handleFocus,
159
+ value: selectedDate
160
+ }, minMaxValues);
161
+ const dateFieldState = useDateFieldState(_objectSpread(_objectSpread({}, hookProps), {}, {
162
+ locale,
163
+ createCalendar
30
164
  }));
165
+ const {
166
+ fieldProps
167
+ } = useDateField(hookProps, dateFieldState, dateFieldRef);
168
+ useDateInputRef(ref, datePickerRef, dateFieldRef);
169
+ const handleDatePickerChange = useCallback(dateString => {
170
+ const parsedDate = dateString ? safeParseDateString(dateString) : null;
171
+ handleDateChange(parsedDate);
172
+ }, [handleDateChange]);
173
+ return /*#__PURE__*/_jsxs("div", {
174
+ className: clsx(field.className, inline({
175
+ gap: '2',
176
+ spaceBetween: true
177
+ }), disabled && sprinkles({
178
+ colour: 'muted'
179
+ })),
180
+ children: [/*#__PURE__*/_jsx("div", _objectSpread(_objectSpread({}, fieldProps), {}, {
181
+ className: styles.verticalCenterStyle,
182
+ ref: dateFieldRef,
183
+ children: dateFieldState.segments.map((segment, idx) => {
184
+ var _segment$minValue;
185
+ return /*#__PURE__*/_jsx(DateSegment, {
186
+ className: styles.segmentStyle,
187
+ segment: segment,
188
+ state: dateFieldState
189
+ }, `${segment.type}-${(_segment$minValue = segment.minValue) !== null && _segment$minValue !== void 0 ? _segment$minValue : idx}`);
190
+ })
191
+ })), /*#__PURE__*/_jsx(DatePicker, {
192
+ className: styles.verticalCenterStyle,
193
+ ref: datePickerRef,
194
+ id: id,
195
+ name: name,
196
+ value: formatDateValue(selectedDate),
197
+ calendarOptions: _objectSpread(_objectSpread(_objectSpread({}, defaultCalendarOptions), calendarOptions), minMaxValues),
198
+ disabled: disabled,
199
+ lang: lang,
200
+ size: size,
201
+ onChange: handleDatePickerChange
202
+ })]
203
+ });
31
204
  }, {
32
205
  primitiveType: 'date'
33
- });
206
+ });
207
+ DateInput.displayName = 'DateInput';
@@ -2,5 +2,5 @@ export declare const inputContainer: string;
2
2
  export declare const input: string;
3
3
  export declare const inputOverlay: string;
4
4
  export declare const contents: Record<"default" | "withLabel", string>;
5
- export declare const disabled: Record<"default" | "root", string>;
5
+ export declare const disabled: Record<"cursor" | "native", string>;
6
6
  //# sourceMappingURL=DatePicker.css.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DatePicker.css.d.ts","sourceRoot":"","sources":["../../../lib/components/DatePicker/DatePicker.css.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,cAAc,QAOzB,CAAC;AAEH,eAAO,MAAM,KAAK,QAsBhB,CAAC;AAEH,eAAO,MAAM,YAAY,QAQvB,CAAC;AAEH,eAAO,MAAM,QAAQ,yCAmBnB,CAAC;AAEH,eAAO,MAAM,QAAQ,oCAenB,CAAC"}
1
+ {"version":3,"file":"DatePicker.css.d.ts","sourceRoot":"","sources":["../../../lib/components/DatePicker/DatePicker.css.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,cAAc,QAOzB,CAAC;AAEH,eAAO,MAAM,KAAK,QAsBhB,CAAC;AAEH,eAAO,MAAM,YAAY,QAQvB,CAAC;AAEH,eAAO,MAAM,QAAQ,yCAmBnB,CAAC;AAEH,eAAO,MAAM,QAAQ,qCAenB,CAAC"}
@@ -66,14 +66,14 @@ export const contents = styleVariants({
66
66
  }
67
67
  }, "contents");
68
68
  export const disabled = styleVariants({
69
- default: {
69
+ cursor: {
70
70
  '@layer': {
71
71
  [cssLayerComponent]: {
72
72
  cursor: 'not-allowed'
73
73
  }
74
74
  }
75
75
  },
76
- root: {
76
+ native: {
77
77
  '@layer': {
78
78
  [cssLayerComponent]: {
79
79
  opacity: '0.3'
@@ -1,5 +1,6 @@
1
1
  import { IconType } from '@autoguru/icons';
2
2
  import React from 'react';
3
+ import type { AriaPopoverProps } from 'react-aria';
3
4
  import type { TestIdProp } from '../../types';
4
5
  import { type CalendarProps } from '../Calendar';
5
6
  type SizeScale = 'small' | 'medium' | 'large';
@@ -38,6 +39,10 @@ export interface DatePickerProps extends TestIdProp {
38
39
  */
39
40
  name?: string;
40
41
  onChange(date: string): void;
42
+ /**
43
+ * Calendar popover placement relative to the trigger ('bottom left', 'top', etc.)
44
+ */
45
+ placement?: AriaPopoverProps['placement'];
41
46
  /**
42
47
  * Visual size of the picker control (small, medium, large)
43
48
  */
@@ -76,7 +81,7 @@ export interface DatePickerProps extends TestIdProp {
76
81
  *
77
82
  * ## Internationalization
78
83
  * - Override text values via `lang={{ openCalendar: 'open calendar' }}`
79
- * - Calendar options including `lang`can be passed via `calendarOptions` prop
84
+ * - Calendar options including `lang` can be passed via `calendarOptions` prop
80
85
  * - Date formatting helper available in `...utils/dateFormat.ts` or use `@internationalized/date` utils
81
86
  * - Advanced i18n and localization handled by [React Aria I18Provider](https://react-spectrum.adobe.com/react-aria/I18nProvider.html)
82
87
  * - Read more about [International calendars](https://react-spectrum.adobe.com/react-aria/useDatePicker.html#international-calendars)
@@ -1 +1 @@
1
- {"version":3,"file":"DatePicker.d.ts","sourceRoot":"","sources":["../../../lib/components/DatePicker/DatePicker.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAgB,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAQzD,OAAO,KAMN,MAAM,OAAO,CAAC;AAIf,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAY,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAS3D,KAAK,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE9C,QAAA,MAAM,cAAc;;CAEV,CAAC;AAEX,KAAK,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,OAAO,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC;AAE5E,MAAM,WAAW,eAAgB,SAAQ,UAAU;IAClD;;OAEG;IACH,eAAe,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB;;OAEG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B;;OAEG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;OAEG;IACH,IAAI,CAAC,EAAE,eAAe,CAAC;CACvB;AAqBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,eAAO,MAAM,UAAU,0FAqLtB,CAAC"}
1
+ {"version":3,"file":"DatePicker.d.ts","sourceRoot":"","sources":["../../../lib/components/DatePicker/DatePicker.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAgB,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAQzD,OAAO,KAON,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAInD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAY,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAS3D,KAAK,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE9C,QAAA,MAAM,cAAc;;CAEV,CAAC;AAEX,KAAK,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,OAAO,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC;AAE5E,MAAM,WAAW,eAAgB,SAAQ,UAAU;IAClD;;OAEG;IACH,eAAe,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB;;OAEG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B;;OAEG;IACH,SAAS,CAAC,EAAE,gBAAgB,CAAC,WAAW,CAAC,CAAC;IAC1C;;OAEG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;OAEG;IACH,IAAI,CAAC,EAAE,eAAe,CAAC;CACvB;AAqBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,eAAO,MAAM,UAAU,0FAqLtB,CAAC"}
@@ -2,13 +2,13 @@
2
2
 
3
3
  import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
4
4
  import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
5
- const _excluded = ["calendarOptions", "className", "defaultValue", "disabled", "icon", "isLoading", "lang", "onChange", "size", "testId", "useNativePicker", "value", "valueLabel"];
5
+ const _excluded = ["calendarOptions", "className", "defaultValue", "disabled", "icon", "isLoading", "lang", "onChange", "placement", "size", "testId", "useNativePicker", "value", "valueLabel"];
6
6
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
7
7
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
8
8
  import { CalendarIcon } from '@autoguru/icons';
9
9
  import { getLocalTimeZone, parseDate, today } from '@internationalized/date';
10
10
  import clsx from 'clsx';
11
- import React, { useEffect, useMemo, useState, forwardRef } from 'react';
11
+ import React, { useCallback, useEffect, useMemo, useState, forwardRef } from 'react';
12
12
  import { elementStyles } from "../../styles/elementStyles.js";
13
13
  import { sprinkles } from "../../styles/sprinkles.css.js";
14
14
  import { Calendar } from "../Calendar/index.js";
@@ -55,7 +55,7 @@ const parseDateString = dateString => {
55
55
  *
56
56
  * ## Internationalization
57
57
  * - Override text values via `lang={{ openCalendar: 'open calendar' }}`
58
- * - Calendar options including `lang`can be passed via `calendarOptions` prop
58
+ * - Calendar options including `lang` can be passed via `calendarOptions` prop
59
59
  * - Date formatting helper available in `...utils/dateFormat.ts` or use `@internationalized/date` utils
60
60
  * - Advanced i18n and localization handled by [React Aria I18Provider](https://react-spectrum.adobe.com/react-aria/I18nProvider.html)
61
61
  * - Read more about [International calendars](https://react-spectrum.adobe.com/react-aria/useDatePicker.html#international-calendars)
@@ -101,6 +101,7 @@ export const DatePicker = /*#__PURE__*/forwardRef((_ref, ref) => {
101
101
  isLoading = false,
102
102
  lang,
103
103
  onChange,
104
+ placement = 'bottom left',
104
105
  size = 'medium',
105
106
  testId,
106
107
  useNativePicker = false,
@@ -134,12 +135,6 @@ export const DatePicker = /*#__PURE__*/forwardRef((_ref, ref) => {
134
135
  onChange(dateString);
135
136
  }
136
137
  };
137
- const containerStyle = elementStyles({
138
- className: [className, {
139
- [styles.disabled.default]: disabled,
140
- [styles.disabled.root]: disabled
141
- }]
142
- });
143
138
  const indicator = isLoading ? /*#__PURE__*/_jsx(ProgressSpinner, {
144
139
  size: size
145
140
  }) : /*#__PURE__*/_jsx(Icon, {
@@ -147,37 +142,40 @@ export const DatePicker = /*#__PURE__*/forwardRef((_ref, ref) => {
147
142
  size: size
148
143
  });
149
144
  const label = valueLabel ? /*#__PURE__*/_jsx(Text, {
145
+ colour: !useNativePicker && disabled ? 'muted' : undefined,
150
146
  size: textSizeMap[size],
151
147
  children: valueLabel
152
148
  }) : null;
153
- const calendarProps = useMemo(() => ({
154
- calendarOptions: _objectSpread(_objectSpread({}, isControlled ? {
149
+ const handleCalendarChange = useCallback(date => {
150
+ setSelectedDate(date);
151
+ if (typeof onChange === 'function') {
152
+ onChange(formatDateToString(date));
153
+ }
154
+ // Close the popover after date selection
155
+ if (popoverState) {
156
+ popoverState.close();
157
+ }
158
+ }, [onChange, popoverState]);
159
+ const calendarProps = useMemo(() => _objectSpread(_objectSpread({
160
+ calendarOptions: _objectSpread({}, isControlled ? {
155
161
  value: selectedDate || today(getLocalTimeZone())
156
162
  } : {
157
163
  defaultValue: selectedDate || today(getLocalTimeZone())
158
- }), calendarOptions),
159
- onChange: date => {
160
- setSelectedDate(date);
161
- if (typeof onChange === 'function') {
162
- onChange(formatDateToString(date));
163
- }
164
- // Close the popover after date selection
165
- if (popoverState) {
166
- popoverState.close();
167
- }
168
- }
169
- }), [selectedDate, calendarOptions, onChange, popoverState, isControlled]);
164
+ })
165
+ }, calendarOptions), {}, {
166
+ onChange: handleCalendarChange
167
+ }), [selectedDate, calendarOptions, handleCalendarChange, isControlled]);
170
168
  const contentCalendar = useMemo(() => /*#__PURE__*/_jsx(Calendar, _objectSpread({}, calendarProps)), [calendarProps]);
171
169
 
172
170
  // Use native picker only if explicitly requested
173
171
  if (useNativePicker) {
174
172
  return /*#__PURE__*/_jsxs("div", {
175
- className: clsx(containerStyle, styles.inputContainer),
173
+ className: clsx(className, styles.inputContainer, disabled && styles.disabled.native),
176
174
  children: [/*#__PURE__*/_jsx("input", _objectSpread(_objectSpread({}, inputProps), {}, {
177
175
  ref: ref,
178
176
  className: elementStyles({
179
177
  className: [styles.input, {
180
- [styles.disabled.default]: disabled
178
+ [styles.disabled.cursor]: disabled
181
179
  }]
182
180
  }),
183
181
  type: "date",
@@ -195,21 +193,24 @@ export const DatePicker = /*#__PURE__*/forwardRef((_ref, ref) => {
195
193
  });
196
194
  }
197
195
  return /*#__PURE__*/_jsxs("div", {
198
- className: clsx(containerStyle, sprinkles({
199
- display: 'flex',
200
- alignItems: 'center',
201
- gap: '1'
202
- })),
196
+ className: className,
203
197
  children: [/*#__PURE__*/_jsxs(PopoverTrigger, {
204
198
  content: contentCalendar,
205
- placement: "bottom left",
199
+ placement: placement,
206
200
  testId: testId,
207
201
  isDisabled: disabled,
208
202
  onStateReady: setPopoverState,
209
- children: [indicator, /*#__PURE__*/_jsx(VisuallyHidden, {
203
+ children: [/*#__PURE__*/_jsxs("div", {
204
+ className: sprinkles({
205
+ display: 'flex',
206
+ alignItems: 'center',
207
+ gap: '1'
208
+ }),
209
+ children: [indicator, label]
210
+ }), /*#__PURE__*/_jsx(VisuallyHidden, {
210
211
  children: (_lang$openCalendar = lang === null || lang === void 0 ? void 0 : lang.openCalendar) !== null && _lang$openCalendar !== void 0 ? _lang$openCalendar : defaultEnglish.openCalendar
211
212
  })]
212
- }), label, /*#__PURE__*/_jsx("input", _objectSpread(_objectSpread({}, inputProps), {}, {
213
+ }), /*#__PURE__*/_jsx("input", _objectSpread(_objectSpread({}, inputProps), {}, {
213
214
  ref: ref,
214
215
  value: formatDateToString(selectedDate),
215
216
  type: "hidden"
@@ -60,20 +60,20 @@ export declare const OptionList: {
60
60
  onKeyDown?: ((e: import("@react-types/shared").KeyboardEvent) => void) | undefined;
61
61
  onKeyUp?: ((e: import("@react-types/shared").KeyboardEvent) => void) | undefined;
62
62
  onClick?: ((e: React.MouseEvent<import("@react-types/shared").FocusableElement>) => void) | undefined;
63
- excludeFromTabOrder?: boolean | undefined;
64
63
  isDisabled?: boolean | undefined;
65
- isRequired?: boolean | undefined;
66
- isInvalid?: boolean | undefined;
67
- validationState?: import("react-stately").ValidationState | undefined;
68
- onFocusChange?: ((isFocused: boolean) => void) | undefined;
69
- isReadOnly?: boolean | undefined;
70
64
  onPress?: ((e: import("react-aria").PressEvent) => void) | undefined;
71
65
  onPressStart?: ((e: import("react-aria").PressEvent) => void) | undefined;
72
66
  onPressEnd?: ((e: import("react-aria").PressEvent) => void) | undefined;
73
67
  onPressChange?: ((isPressed: boolean) => void) | undefined;
74
68
  onPressUp?: ((e: import("react-aria").PressEvent) => void) | undefined;
75
- validationBehavior?: "aria" | "native" | undefined;
69
+ onFocusChange?: ((isFocused: boolean) => void) | undefined;
70
+ excludeFromTabOrder?: boolean | undefined;
76
71
  validate?: ((value: boolean) => import("@react-types/shared").ValidationError | true | null | undefined) | undefined;
72
+ isReadOnly?: boolean | undefined;
73
+ isRequired?: boolean | undefined;
74
+ isInvalid?: boolean | undefined;
75
+ validationState?: import("react-stately").ValidationState | undefined;
76
+ validationBehavior?: "aria" | "native" | undefined;
77
77
  }): React.JSX.Element;
78
78
  displayName: string;
79
79
  };
@@ -1 +1 @@
1
- {"version":3,"file":"Popover.css.d.ts","sourceRoot":"","sources":["../../../lib/components/Popover/Popover.css.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,YAAY,QAiBvB,CAAC;AAEH,eAAO,MAAM,YAAY,QASvB,CAAC;AAEH,eAAO,MAAM,eAAe,QAW1B,CAAC"}
1
+ {"version":3,"file":"Popover.css.d.ts","sourceRoot":"","sources":["../../../lib/components/Popover/Popover.css.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,YAAY,QAiBvB,CAAC;AAEH,eAAO,MAAM,YAAY,QAcvB,CAAC;AAEH,eAAO,MAAM,eAAe,QAY1B,CAAC"}
@@ -4,6 +4,7 @@ import * as __vanilla_filescope__ from '@vanilla-extract/css/fileScope';
4
4
  __vanilla_filescope__.setFileScope("lib/components/Popover/Popover.css.ts", "@autoguru/overdrive");
5
5
  import { style } from '@vanilla-extract/css';
6
6
  import { cssLayerComponent } from "../../styles/layers.css.js";
7
+ import { selectors } from "../../styles/selectors.js";
7
8
  import { sprinkles } from "../../styles/sprinkles.css.js";
8
9
  import { overdriveTokens as tokens } from "../../themes/theme.css.js";
9
10
  export const overlayStyle = style([sprinkles({
@@ -27,7 +28,12 @@ export const triggerStyle = style({
27
28
  background: 'transparent',
28
29
  border: 'none',
29
30
  cursor: 'pointer',
30
- padding: 0
31
+ padding: 0,
32
+ selectors: {
33
+ [selectors.disabled]: {
34
+ cursor: 'not-allowed'
35
+ }
36
+ }
31
37
  }
32
38
  }
33
39
  }, "triggerStyle");
@@ -39,7 +45,8 @@ export const fullScreenStyle = style({
39
45
  left: 0,
40
46
  position: 'fixed',
41
47
  right: 0,
42
- top: 0
48
+ top: 0,
49
+ zIndex: 3
43
50
  }
44
51
  }
45
52
  }, "fullScreenStyle");
@@ -1,6 +1,7 @@
1
1
  import { IconType } from '@autoguru/icons';
2
2
  import React, { type ChangeEventHandler, type ComponentProps, type ComponentType, type FocusEventHandler, type ForwardedRef, type InputHTMLAttributes, type KeyboardEventHandler, type MouseEventHandler, type ReactNode, type Ref, type RefObject } from 'react';
3
- import { Box } from '../../Box/Box';
3
+ import { type Sprinkles } from '../../../styles/sprinkles.css';
4
+ import type { TestIdProp } from '../../../types';
4
5
  import { NotchedBase } from './NotchedBase';
5
6
  import type { InputSize } from './withEnhancedInput.css';
6
7
  type ElementTypes = HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement;
@@ -15,7 +16,7 @@ export interface EventHandlers<E extends ElementTypes> {
15
16
  onMouseLeave?: MouseEventHandler<E>;
16
17
  onReset?(): void;
17
18
  }
18
- export interface EnhanceInputPrimitiveProps<E extends ElementTypes> extends NativeAttributes<E>, Pick<ComponentProps<typeof NotchedBase>, 'notch' | 'placeholder' | 'attach' | 'borderMerged' | 'isFocused'>, Pick<ComponentProps<typeof Box>, 'backgroundColour'> {
19
+ export interface EnhanceInputPrimitiveProps<E extends ElementTypes> extends NativeAttributes<E>, Pick<ComponentProps<typeof NotchedBase>, 'notch' | 'placeholder' | 'attach' | 'borderMerged' | 'isFocused'>, Pick<Sprinkles, 'backgroundColour'>, TestIdProp {
19
20
  name: string;
20
21
  id?: string;
21
22
  className?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"withEnhancedInput.d.ts","sourceRoot":"","sources":["../../../../lib/components/private/InputBase/withEnhancedInput.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"withEnhancedInput.d.ts","sourceRoot":"","sources":["../../../../lib/components/private/InputBase/withEnhancedInput.tsx"],"names":[],"mappings":"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"}
@@ -2,15 +2,16 @@
2
2
 
3
3
  import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
4
4
  import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
5
- const _excluded = ["placeholder", "name", "id", "hintText", "disabled", "className", "isTouched", "isValid", "isLoading", "notch", "reserveHintSpace", "size", "backgroundColour", "value", "onChange", "onReset", "onMouseLeave", "onMouseEnter", "onBlur", "onFocus", "onKeyDown", "prefixIcon", "suffixIcon", "wrapperRef", "autoFocus", "attach", "borderMerged"];
5
+ const _excluded = ["placeholder", "name", "id", "hintText", "disabled", "className", "isTouched", "isValid", "isLoading", "notch", "reserveHintSpace", "size", "backgroundColour", "testId", "value", "onChange", "onReset", "onMouseLeave", "onMouseEnter", "onBlur", "onFocus", "onKeyDown", "prefixIcon", "suffixIcon", "wrapperRef", "autoFocus", "attach", "borderMerged"];
6
6
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
7
7
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
8
8
  import { invariant, wrapEvent } from '@autoguru/utilities';
9
9
  import clsx from 'clsx';
10
10
  import React, { forwardRef, useCallback, useState } from 'react';
11
- import { sprinkles, elementStyles } from "../../../styles/index.js";
11
+ import { elementStyles } from "../../../styles/elementStyles.js";
12
+ import { sprinkles } from "../../../styles/sprinkles.css.js";
12
13
  import { useInputControlledState } from "../../../utils/index.js";
13
- import { Box } from "../../Box/Box.js";
14
+ import { useBox } from "../../Box/useBox/useBox.js";
14
15
  import { Icon } from "../../Icon/Icon.js";
15
16
  import { ProgressSpinner } from "../../ProgressSpinner/ProgressSpinner.js";
16
17
  import { HintText } from "./HintText.js";
@@ -49,6 +50,7 @@ forwardRef((_ref, ref) => {
49
50
  reserveHintSpace = false,
50
51
  size = 'medium',
51
52
  backgroundColour = 'transparent',
53
+ testId,
52
54
  value: incomingValue = defaultValue || '',
53
55
  onChange: incomingOnChange,
54
56
  onReset,
@@ -151,11 +153,18 @@ forwardRef((_ref, ref) => {
151
153
  pointerEvents: 'none',
152
154
  position: 'absolute'
153
155
  });
154
- return /*#__PURE__*/_jsxs(Box, {
155
- width: "full",
156
- className: className,
156
+ const {
157
+ Component: ComponentRoot,
158
+ componentProps: rootComponentProps
159
+ } = useBox({
160
+ width: 'full',
161
+ className,
157
162
  onMouseEnter: onMouseOver,
158
163
  onMouseLeave: onMouseOut,
164
+ odComponent: `${primitiveType}-input`,
165
+ testId
166
+ });
167
+ return /*#__PURE__*/_jsxs(ComponentRoot, _objectSpread(_objectSpread({}, rootComponentProps), {}, {
159
168
  children: [/*#__PURE__*/_jsx(NotchedBase, {
160
169
  id: id,
161
170
  prefixed: Boolean(prefixIcon),
@@ -172,11 +181,12 @@ forwardRef((_ref, ref) => {
172
181
  [derivedColours.colour]: !isEmpty
173
182
  }),
174
183
  borderColourClassName: derivedColours.borderColour,
175
- children: /*#__PURE__*/_jsxs(Box, {
184
+ children: /*#__PURE__*/_jsxs("div", {
185
+ className: clsx(styles.inputWrapperSize[size].root[primitiveType], sprinkles({
186
+ height: 'full',
187
+ width: 'full'
188
+ })),
176
189
  ref: wrapperRef,
177
- className: styles.inputWrapperSize[size].root[primitiveType],
178
- width: "full",
179
- height: "full",
180
190
  children: [prefixIcon ? /*#__PURE__*/_jsx(Icon, {
181
191
  icon: prefixIcon,
182
192
  size: iconSize,
@@ -198,7 +208,7 @@ forwardRef((_ref, ref) => {
198
208
  reserveHintSpace: reserveHintSpace,
199
209
  size: size
200
210
  }) : null]
201
- });
211
+ }));
202
212
  });
203
213
  const stateNodeGetter = styles => (isHovered, isActive) => {
204
214
  if (isHovered) return styles.hover;
@@ -0,0 +1,9 @@
1
+ import { type RefObject, type ForwardedRef } from 'react';
2
+ type ElementTypes = HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement;
3
+ /**
4
+ * Custom hook for creating a composite ref that provides HTMLInputElement compatibility
5
+ * for the DateInput component while maintaining proper focus management for the date field segments.
6
+ */
7
+ export declare const useDateInputRef: (ref: ForwardedRef<ElementTypes> | RefObject<ElementTypes>, hiddenInputRef: RefObject<HTMLInputElement | null>, dateFieldRef: RefObject<HTMLDivElement | null>) => void;
8
+ export {};
9
+ //# sourceMappingURL=useDateInputRef.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDateInputRef.d.ts","sourceRoot":"","sources":["../../lib/hooks/useDateInputRef.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,SAAS,EAAE,KAAK,YAAY,EAAE,MAAM,OAAO,CAAC;AAE/E,KAAK,YAAY,GAAG,gBAAgB,GAAG,mBAAmB,GAAG,iBAAiB,CAAC;AAE/E;;;GAGG;AACH,eAAO,MAAM,eAAe,GAC3B,KAAK,YAAY,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC,YAAY,CAAC,EACzD,gBAAgB,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,EAClD,cAAc,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,SAuC9C,CAAC"}
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+
3
+ import { useImperativeHandle } from 'react';
4
+ /**
5
+ * Custom hook for creating a composite ref that provides HTMLInputElement compatibility
6
+ * for the DateInput component while maintaining proper focus management for the date field segments.
7
+ */
8
+ export const useDateInputRef = (ref, hiddenInputRef, dateFieldRef) => {
9
+ useImperativeHandle(ref, () => {
10
+ const hiddenInput = hiddenInputRef.current;
11
+ const dateField = dateFieldRef.current;
12
+ if (!hiddenInput) return {};
13
+
14
+ // Use Proxy for cleaner implementation that inherits all HTMLInputElement properties
15
+ return new Proxy(hiddenInput, {
16
+ get(target, prop) {
17
+ switch (prop) {
18
+ case 'focus':
19
+ {
20
+ return options => {
21
+ var _ref;
22
+ const firstSegment = dateField === null || dateField === void 0 ? void 0 : dateField.querySelector('[role="spinbutton"]');
23
+ (_ref = firstSegment || dateField) === null || _ref === void 0 ? void 0 : _ref.focus(options);
24
+ };
25
+ }
26
+ case 'click':
27
+ {
28
+ return () => {
29
+ var _ref2;
30
+ const firstSegment = dateField === null || dateField === void 0 ? void 0 : dateField.querySelector('[role="spinbutton"]');
31
+ (_ref2 = firstSegment || dateField) === null || _ref2 === void 0 ? void 0 : _ref2.click();
32
+ };
33
+ }
34
+ case 'type':
35
+ {
36
+ return 'date';
37
+ }
38
+ default:
39
+ {
40
+ // Pass through to the hidden input for all other properties
41
+ return target[prop];
42
+ }
43
+ }
44
+ }
45
+ });
46
+ }, []);
47
+ };
@@ -5,6 +5,18 @@ import { type DateValue } from '@internationalized/date';
5
5
  * @returns boolean
6
6
  */
7
7
  export declare function isToday(date: DateValue | string | null | undefined): boolean;
8
+ /**
9
+ * Safely parses a date string into a DateValue
10
+ * @param dateString - ISO date string to parse
11
+ * @returns DateValue or null if parsing fails
12
+ */
13
+ export declare function safeParseDateString(dateString: string): DateValue | null;
14
+ /**
15
+ * Formats a DateValue to its string representation
16
+ * @param date - DateValue or null
17
+ * @returns String representation of the date or empty string for null
18
+ */
19
+ export declare function formatDateValue(date: DateValue | null): string;
8
20
  /**
9
21
  * Formats a date value or ISO date string for display, with special handling for "today"
10
22
  *
@@ -1 +1 @@
1
- {"version":3,"file":"dateFormat.d.ts","sourceRoot":"","sources":["../../lib/utils/dateFormat.ts"],"names":[],"mappings":"AAAA,OAAO,EAIN,KAAK,SAAS,EACd,MAAM,yBAAyB,CAAC;AAEjC;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,WAUlE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CACnC,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,EAC3C,MAAM,GAAE,IAAI,CAAC,qBAAqB,CAAC,WAAW,CAAY,EAC1D,OAAO,GAAE,IAAI,CAAC,eAAyB,GACrC,MAAM,CAmBR"}
1
+ {"version":3,"file":"dateFormat.d.ts","sourceRoot":"","sources":["../../lib/utils/dateFormat.ts"],"names":[],"mappings":"AAAA,OAAO,EAIN,KAAK,SAAS,EACd,MAAM,yBAAyB,CAAC;AAEjC;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,WAUlE;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAOxE;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,GAAG,MAAM,CAE9D;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CACnC,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,EAC3C,MAAM,GAAE,IAAI,CAAC,qBAAqB,CAAC,WAAW,CAAY,EAC1D,OAAO,GAAE,IAAI,CAAC,eAAyB,GACrC,MAAM,CAmBR"}
@@ -19,6 +19,30 @@ export function isToday(date) {
19
19
  return date.compare(today(getLocalTimeZone())) === 0;
20
20
  }
21
21
 
22
+ /**
23
+ * Safely parses a date string into a DateValue
24
+ * @param dateString - ISO date string to parse
25
+ * @returns DateValue or null if parsing fails
26
+ */
27
+ export function safeParseDateString(dateString) {
28
+ if (!dateString) return null;
29
+ try {
30
+ return parseDate(dateString);
31
+ } catch {
32
+ return null;
33
+ }
34
+ }
35
+
36
+ /**
37
+ * Formats a DateValue to its string representation
38
+ * @param date - DateValue or null
39
+ * @returns String representation of the date or empty string for null
40
+ */
41
+ export function formatDateValue(date) {
42
+ var _date$toString;
43
+ return (_date$toString = date === null || date === void 0 ? void 0 : date.toString()) !== null && _date$toString !== void 0 ? _date$toString : '';
44
+ }
45
+
22
46
  /**
23
47
  * Formats a date value or ISO date string for display, with special handling for "today"
24
48
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autoguru/overdrive",
3
- "version": "4.47.1",
3
+ "version": "4.48.0-next.0",
4
4
  "description": "Overdrive is a product component library, and design system for AutoGuru.",
5
5
  "types": "dist/index.d.ts",
6
6
  "main": "dist/index.js",
@@ -79,7 +79,7 @@
79
79
  "@babel/preset-react": "7.27.1",
80
80
  "@babel/preset-typescript": "7.27.1",
81
81
  "@babel/runtime-corejs3": "7.28.4",
82
- "@changesets/cli": "2.29.6",
82
+ "@changesets/cli": "2.29.7",
83
83
  "@chromatic-com/storybook": "4.1.1",
84
84
  "@internationalized/date": "3.9.0",
85
85
  "@octokit/rest": "22.0.0",
@@ -96,8 +96,8 @@
96
96
  "@testing-library/react": "16.3.0",
97
97
  "@testing-library/react-hooks": "8.0.1",
98
98
  "@testing-library/user-event": "14.6.1",
99
- "@types/node": "24.3.1",
100
- "@types/react": "19.1.12",
99
+ "@types/node": "24.4.0",
100
+ "@types/react": "19.1.13",
101
101
  "@types/react-dom": "19.1.9",
102
102
  "@types/webpack-env": "1.18.8",
103
103
  "@typescript-eslint/utils": "8.41.0",
@@ -139,8 +139,8 @@
139
139
  "prop-types": "15.8.1",
140
140
  "rand-seed": "3.0.0",
141
141
  "react": "19.1.1",
142
- "react-aria": "3.43.1",
143
- "react-aria-components": "1.12.1",
142
+ "react-aria": "3.43.2",
143
+ "react-aria-components": "1.12.2",
144
144
  "react-dom": "19.1.1",
145
145
  "react-focus-lock": "2.13.6",
146
146
  "react-intersection-observer": "9.16.0",