@autoguru/overdrive 4.47.0 → 4.47.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.
@@ -43,18 +43,23 @@ export interface CalendarProps extends TestIdProp {
43
43
  * - Custom default values and date ranges
44
44
  * - Flexible styling and theming
45
45
  *
46
+ * ## Working with dates
47
+ * - Use `parseDate('YYYY-MM-DD')` from `@internationalized/date` to create
48
+ * DateValue objects.
49
+ * - Other useful utilities include `today(getLocalTimeZone())` for current
50
+ * date, and `date.add({ days: 7, months: 1 })` for date arithmetic.
51
+ *
46
52
  * ## Date Restrictions
47
53
  * You can restrict date selection using the `calendar` prop with react-aria calendar properties:
48
54
  * - `minValue` / `maxValue`: Define selectable date range
49
55
  * - `isDateUnavailable`: Function to disable specific dates
50
56
  * - `allowPastDate` prop: Convenient way to allow/disallow past dates
51
57
  *
52
- * ## Examples
53
- * See the Calendar stories for comprehensive examples including:
54
- * - Disabled specific dates and weekends
55
- * - Disabled date ranges
56
- * - Custom validation rules
57
- * - Localization examples
58
+ * ## Internationalization
59
+ * - Override text values via `lang={{ openCalendar: 'open calendar' }}`
60
+ * - Date formatting helper available in `...utils/dateFormat.ts` or use `@internationalized/date` utils
61
+ * - Advanced i18n and localization handled by [React Aria I18Provider](https://react-spectrum.adobe.com/react-aria/I18nProvider.html)
62
+ * - Read more about [International calendars](https://react-spectrum.adobe.com/react-aria/useDatePicker.html#international-calendars)
58
63
  */
59
64
  export declare const Calendar: {
60
65
  ({ allowPastDate, calendarOptions, lang, onChange, testId, }: CalendarProps): React.JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"Calendar.d.ts","sourceRoot":"","sources":["../../../lib/components/Calendar/Calendar.tsx"],"names":[],"mappings":"AAOA,OAAO,KAA4B,MAAM,OAAO,CAAC;AACjD,OAAO,EAGN,KAAK,iBAAiB,EACtB,KAAK,SAAS,EACd,MAAM,YAAY,CAAC;AAGpB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAS9C,QAAA,MAAM,cAAc;;;CAGV,CAAC;AAEX,KAAK,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,OAAO,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC;AAE5E,MAAM,WAAW,aAAc,SAAQ,UAAU;IAChD;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,SAAS,CAAC,EAAE,UAAU,CAAC,CAAC;IACpE;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;IACtC;;OAEG;IACH,IAAI,CAAC,EAAE,eAAe,CAAC;CACvB;AAUD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,QAAQ;kEAMlB,aAAa;;CA0Df,CAAC"}
1
+ {"version":3,"file":"Calendar.d.ts","sourceRoot":"","sources":["../../../lib/components/Calendar/Calendar.tsx"],"names":[],"mappings":"AAOA,OAAO,KAA4B,MAAM,OAAO,CAAC;AACjD,OAAO,EAGN,KAAK,iBAAiB,EACtB,KAAK,SAAS,EACd,MAAM,YAAY,CAAC;AAGpB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAS9C,QAAA,MAAM,cAAc;;;CAGV,CAAC;AAEX,KAAK,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,OAAO,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC;AAE5E,MAAM,WAAW,aAAc,SAAQ,UAAU;IAChD;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,SAAS,CAAC,EAAE,UAAU,CAAC,CAAC;IACpE;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;IACtC;;OAEG;IACH,IAAI,CAAC,EAAE,eAAe,CAAC;CACvB;AAUD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,eAAO,MAAM,QAAQ;kEAMlB,aAAa;;CA8Df,CAAC"}
@@ -42,18 +42,23 @@ function createCalendar(identifier) {
42
42
  * - Custom default values and date ranges
43
43
  * - Flexible styling and theming
44
44
  *
45
+ * ## Working with dates
46
+ * - Use `parseDate('YYYY-MM-DD')` from `@internationalized/date` to create
47
+ * DateValue objects.
48
+ * - Other useful utilities include `today(getLocalTimeZone())` for current
49
+ * date, and `date.add({ days: 7, months: 1 })` for date arithmetic.
50
+ *
45
51
  * ## Date Restrictions
46
52
  * You can restrict date selection using the `calendar` prop with react-aria calendar properties:
47
53
  * - `minValue` / `maxValue`: Define selectable date range
48
54
  * - `isDateUnavailable`: Function to disable specific dates
49
55
  * - `allowPastDate` prop: Convenient way to allow/disallow past dates
50
56
  *
51
- * ## Examples
52
- * See the Calendar stories for comprehensive examples including:
53
- * - Disabled specific dates and weekends
54
- * - Disabled date ranges
55
- * - Custom validation rules
56
- * - Localization examples
57
+ * ## Internationalization
58
+ * - Override text values via `lang={{ openCalendar: 'open calendar' }}`
59
+ * - Date formatting helper available in `...utils/dateFormat.ts` or use `@internationalized/date` utils
60
+ * - Advanced i18n and localization handled by [React Aria I18Provider](https://react-spectrum.adobe.com/react-aria/I18nProvider.html)
61
+ * - Read more about [International calendars](https://react-spectrum.adobe.com/react-aria/useDatePicker.html#international-calendars)
57
62
  */
58
63
  export const Calendar = ({
59
64
  allowPastDate = false,
@@ -64,15 +69,18 @@ export const Calendar = ({
64
69
  }) => {
65
70
  var _lang$prevLabel, _lang$nextLabel;
66
71
  const selectedDate = useRef(null);
67
- const calendarComponentProps = _objectSpread({
68
- defaultValue: today(getLocalTimeZone()),
72
+ const hasValue = !!(calendarOptions !== null && calendarOptions !== void 0 && calendarOptions.value) || !!(calendarOptions !== null && calendarOptions !== void 0 && calendarOptions.defaultValue);
73
+ const fallbackDefaultValue = hasValue ? {} : {
74
+ defaultValue: today(getLocalTimeZone())
75
+ };
76
+ const calendarComponentProps = _objectSpread(_objectSpread({
69
77
  firstDayOfWeek: FIRST_DAY_OF_WEEK,
70
78
  minValue: allowPastDate ? undefined : today(getLocalTimeZone()),
71
79
  onChange: value => {
72
80
  selectedDate.current = value;
73
81
  onChange === null || onChange === void 0 ? void 0 : onChange(value);
74
82
  }
75
- }, calendarOptions);
83
+ }, calendarOptions), fallbackDefaultValue);
76
84
  const {
77
85
  locale
78
86
  } = useLocale();
@@ -90,8 +98,7 @@ export const Calendar = ({
90
98
  if (state.value) {
91
99
  selectedDate.current = state.value;
92
100
  }
93
- // eslint-disable-next-line react-hooks/exhaustive-deps -- run only once
94
- }, []);
101
+ }, [state.value]);
95
102
  return /*#__PURE__*/_jsxs("div", _objectSpread(_objectSpread({}, dataAttrs({
96
103
  testid: testId
97
104
  })), {}, {
@@ -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';
@@ -7,12 +8,16 @@ declare const defaultEnglish: {
7
8
  readonly openCalendar: "open calendar";
8
9
  };
9
10
  type LanguageEntries = Partial<Record<keyof typeof defaultEnglish, string>>;
10
- export interface DatePickerProps extends Pick<HTMLInputElement, 'id' | 'name'>, TestIdProp {
11
+ export interface DatePickerProps extends TestIdProp {
11
12
  /**
12
13
  * Options to customise the calendar: `allowPastDate`, `lang`, etc.
13
14
  */
14
15
  calendarOptions?: Omit<CalendarProps, 'onChange'>;
15
16
  className?: string;
17
+ /**
18
+ * Default selected date as an ISO string YYYY-MM-DD (uncontrolled)
19
+ */
20
+ defaultValue?: string;
16
21
  /**
17
22
  * Whether the picker is disabled and non-interactive
18
23
  */
@@ -21,15 +26,32 @@ export interface DatePickerProps extends Pick<HTMLInputElement, 'id' | 'name'>,
21
26
  * Icon to render inside the picker (defaults to calendar icon)
22
27
  */
23
28
  icon?: IconType;
29
+ /**
30
+ * Form field id
31
+ */
32
+ id?: string;
24
33
  /**
25
34
  * Show a loading state spinner instead of the icon
26
35
  */
27
36
  isLoading?: boolean;
37
+ /**
38
+ * Input field name recommended for form usage
39
+ */
40
+ name?: string;
28
41
  onChange(date: string): void;
42
+ /**
43
+ * Calendar popover placement relative to the trigger ('bottom left', 'top', etc.)
44
+ */
45
+ placement?: AriaPopoverProps['placement'];
29
46
  /**
30
47
  * Visual size of the picker control (small, medium, large)
31
48
  */
32
49
  size?: SizeScale;
50
+ /**
51
+ * The selected date as an ISO string (YYYY-MM-DD). Use `undefined` for an empty value
52
+ * (controlled)
53
+ */
54
+ value?: string;
33
55
  /**
34
56
  * Fallback label to display when no date value is selected.
35
57
  */
@@ -64,12 +86,21 @@ export interface DatePickerProps extends Pick<HTMLInputElement, 'id' | 'name'>,
64
86
  * - Advanced i18n and localization handled by [React Aria I18Provider](https://react-spectrum.adobe.com/react-aria/I18nProvider.html)
65
87
  * - Read more about [International calendars](https://react-spectrum.adobe.com/react-aria/useDatePicker.html#international-calendars)
66
88
  *
89
+ * @example
90
+ * // Uncontrolled component with default value
91
+ * <DatePicker
92
+ * name="eventDate"
93
+ * defaultValue="2025-03-15"
94
+ * onChange={(isoDate) => console.log('Selected date:', isoDate)}
95
+ * />
67
96
  *
68
97
  * @example
98
+ * // Controlled component
69
99
  * <DatePicker
70
100
  * name="bookingDate"
101
+ * value={selectedDate}
71
102
  * valueLabel="Select a date"
72
- * onChange={(isoDate) => console.log('Selected date:', isoDate)}
103
+ * onChange={(isoDate) => setSelectedDate(isoDate)}
73
104
  * calendarOptions={{
74
105
  * allowPastDate: false,
75
106
  * weekdayFormat: 'short',
@@ -81,13 +112,10 @@ export interface DatePickerProps extends Pick<HTMLInputElement, 'id' | 'name'>,
81
112
  * <DatePicker
82
113
  * name="startDate"
83
114
  * useNativePicker
84
- * value={initialDateISO} // e.g., "2025-03-12"
115
+ * defaultValue="2025-03-12"
85
116
  * onChange={(isoDate) => console.log('Native picked date:', isoDate)}
86
117
  * />
87
118
  */
88
- export declare const DatePicker: {
89
- ({ calendarOptions, className, disabled, icon, isLoading, lang, onChange, size, testId, useNativePicker, valueLabel, ...inputProps }: DatePickerProps): React.JSX.Element;
90
- displayName: string;
91
- };
119
+ export declare const DatePicker: React.ForwardRefExoticComponent<DatePickerProps & React.RefAttributes<HTMLInputElement>>;
92
120
  export {};
93
121
  //# sourceMappingURL=DatePicker.d.ts.map
@@ -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,KAA8C,MAAM,OAAO,CAAC;AAInE,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,eAChB,SAAQ,IAAI,CAAC,gBAAgB,EAAE,IAAI,GAAG,MAAM,CAAC,EAC5C,UAAU;IACX;;OAEG;IACH,eAAe,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B;;OAEG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,eAAO,MAAM,UAAU;0IAcpB,eAAe;;CA2HjB,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", "disabled", "icon", "isLoading", "lang", "onChange", "size", "testId", "useNativePicker", "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, { useMemo, useState } 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";
@@ -60,12 +60,21 @@ const parseDateString = dateString => {
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)
62
62
  *
63
+ * @example
64
+ * // Uncontrolled component with default value
65
+ * <DatePicker
66
+ * name="eventDate"
67
+ * defaultValue="2025-03-15"
68
+ * onChange={(isoDate) => console.log('Selected date:', isoDate)}
69
+ * />
63
70
  *
64
71
  * @example
72
+ * // Controlled component
65
73
  * <DatePicker
66
74
  * name="bookingDate"
75
+ * value={selectedDate}
67
76
  * valueLabel="Select a date"
68
- * onChange={(isoDate) => console.log('Selected date:', isoDate)}
77
+ * onChange={(isoDate) => setSelectedDate(isoDate)}
69
78
  * calendarOptions={{
70
79
  * allowPastDate: false,
71
80
  * weekdayFormat: 'short',
@@ -77,28 +86,43 @@ const parseDateString = dateString => {
77
86
  * <DatePicker
78
87
  * name="startDate"
79
88
  * useNativePicker
80
- * value={initialDateISO} // e.g., "2025-03-12"
89
+ * defaultValue="2025-03-12"
81
90
  * onChange={(isoDate) => console.log('Native picked date:', isoDate)}
82
91
  * />
83
92
  */
84
- export const DatePicker = _ref => {
93
+ export const DatePicker = /*#__PURE__*/forwardRef((_ref, ref) => {
85
94
  var _lang$openCalendar;
86
95
  let {
87
96
  calendarOptions,
88
97
  className,
98
+ defaultValue,
89
99
  disabled = false,
90
100
  icon = CalendarIcon,
91
101
  isLoading = false,
92
102
  lang,
93
103
  onChange,
104
+ placement = 'bottom left',
94
105
  size = 'medium',
95
106
  testId,
96
107
  useNativePicker = false,
108
+ value,
97
109
  valueLabel
98
110
  } = _ref,
99
111
  inputProps = _objectWithoutProperties(_ref, _excluded);
100
- const [selectedDate, setSelectedDate] = useState(null);
112
+ const isControlled = value !== undefined;
113
+ const [selectedDate, setSelectedDate] = useState(() => {
114
+ const initialValue = isControlled ? value : defaultValue;
115
+ return initialValue ? parseDateString(initialValue) : null;
116
+ });
101
117
  const [popoverState, setPopoverState] = useState(null);
118
+
119
+ // Sync external value changes (only for controlled components)
120
+ useEffect(() => {
121
+ if (isControlled) {
122
+ const parsedDate = value ? parseDateString(value) : null;
123
+ setSelectedDate(parsedDate);
124
+ }
125
+ }, [value, isControlled]);
102
126
  const onChangeEvent = event => {
103
127
  const dateString = event.currentTarget.value;
104
128
  if (dateString) {
@@ -111,12 +135,6 @@ export const DatePicker = _ref => {
111
135
  onChange(dateString);
112
136
  }
113
137
  };
114
- const containerStyle = elementStyles({
115
- className: [className, {
116
- [styles.disabled.default]: disabled,
117
- [styles.disabled.root]: disabled
118
- }]
119
- });
120
138
  const indicator = isLoading ? /*#__PURE__*/_jsx(ProgressSpinner, {
121
139
  size: size
122
140
  }) : /*#__PURE__*/_jsx(Icon, {
@@ -124,34 +142,40 @@ export const DatePicker = _ref => {
124
142
  size: size
125
143
  });
126
144
  const label = valueLabel ? /*#__PURE__*/_jsx(Text, {
145
+ colour: !useNativePicker && disabled ? 'muted' : undefined,
127
146
  size: textSizeMap[size],
128
147
  children: valueLabel
129
148
  }) : null;
130
- const calendarProps = useMemo(() => ({
131
- calendar: _objectSpread({
132
- defaultValue: selectedDate || today(getLocalTimeZone())
133
- }, calendarOptions),
134
- onChange: date => {
135
- setSelectedDate(date);
136
- if (typeof onChange === 'function') {
137
- onChange(formatDateToString(date));
138
- }
139
- // Close the popover after date selection
140
- if (popoverState) {
141
- popoverState.close();
142
- }
149
+ const handleCalendarChange = useCallback(date => {
150
+ setSelectedDate(date);
151
+ if (typeof onChange === 'function') {
152
+ onChange(formatDateToString(date));
143
153
  }
144
- }), [selectedDate, calendarOptions, onChange, popoverState]);
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 ? {
161
+ value: selectedDate || today(getLocalTimeZone())
162
+ } : {
163
+ defaultValue: selectedDate || today(getLocalTimeZone())
164
+ })
165
+ }, calendarOptions), {}, {
166
+ onChange: handleCalendarChange
167
+ }), [selectedDate, calendarOptions, handleCalendarChange, isControlled]);
145
168
  const contentCalendar = useMemo(() => /*#__PURE__*/_jsx(Calendar, _objectSpread({}, calendarProps)), [calendarProps]);
146
169
 
147
170
  // Use native picker only if explicitly requested
148
171
  if (useNativePicker) {
149
172
  return /*#__PURE__*/_jsxs("div", {
150
- className: clsx(containerStyle, styles.inputContainer),
173
+ className: clsx(className, styles.inputContainer, disabled && styles.disabled.native),
151
174
  children: [/*#__PURE__*/_jsx("input", _objectSpread(_objectSpread({}, inputProps), {}, {
175
+ ref: ref,
152
176
  className: elementStyles({
153
177
  className: [styles.input, {
154
- [styles.disabled.default]: disabled
178
+ [styles.disabled.cursor]: disabled
155
179
  }]
156
180
  }),
157
181
  type: "date",
@@ -169,24 +193,28 @@ export const DatePicker = _ref => {
169
193
  });
170
194
  }
171
195
  return /*#__PURE__*/_jsxs("div", {
172
- className: clsx(containerStyle, sprinkles({
173
- display: 'flex',
174
- alignItems: 'center',
175
- gap: '1'
176
- })),
196
+ className: className,
177
197
  children: [/*#__PURE__*/_jsxs(PopoverTrigger, {
178
198
  content: contentCalendar,
179
- placement: "bottom left",
199
+ placement: placement,
180
200
  testId: testId,
181
201
  isDisabled: disabled,
182
202
  onStateReady: setPopoverState,
183
- 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, {
184
211
  children: (_lang$openCalendar = lang === null || lang === void 0 ? void 0 : lang.openCalendar) !== null && _lang$openCalendar !== void 0 ? _lang$openCalendar : defaultEnglish.openCalendar
185
212
  })]
186
- }), label, /*#__PURE__*/_jsx("input", _objectSpread(_objectSpread({}, inputProps), {}, {
213
+ }), /*#__PURE__*/_jsx("input", _objectSpread(_objectSpread({}, inputProps), {}, {
214
+ ref: ref,
187
215
  value: formatDateToString(selectedDate),
188
216
  type: "hidden"
189
217
  }))]
190
218
  });
191
- };
219
+ });
192
220
  DatePicker.displayName = 'DatePicker';
@@ -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");
@@ -3,9 +3,9 @@ import { type AriaSliderProps, type AriaSliderThumbProps } from 'react-aria';
3
3
  import type { TestIdProp } from '../../types';
4
4
  export interface SliderProps extends AriaSliderProps, Pick<AriaSliderThumbProps, 'name'>, TestIdProp {
5
5
  /**
6
- * Optional label for the slider
6
+ * Label for the slider. Can be a string or custom child element.
7
7
  */
8
- label?: string;
8
+ label?: React.ReactNode;
9
9
  /**
10
10
  * Unit text to display with the value (e.g., 'kms', 'miles', '%')
11
11
  */
@@ -25,11 +25,11 @@ export interface SliderProps extends AriaSliderProps, Pick<AriaSliderThumbProps,
25
25
  * supports configurable step values and value unit post-fix. Use the `onChange` handler
26
26
  * in most instances for retrieving the current value.
27
27
  *
28
- * @example
29
- * const handleOnChange = (value) => {
30
- * console.log('Distance changed to:', value);
31
- * };
28
+ * Supports flexible label approach:
29
+ * - Pre-styled label `label="Distance"`
30
+ * - Custom label content: `label={<label className={customlabelStyles}>Distance</label>}`
32
31
  *
32
+ * @example
33
33
  * <Slider
34
34
  * label="Distance"
35
35
  * value={distance}
@@ -41,7 +41,7 @@ export interface SliderProps extends AriaSliderProps, Pick<AriaSliderThumbProps,
41
41
  * />;
42
42
  */
43
43
  export declare const Slider: {
44
- ({ testId, unitText, step, formatOptions, ...props }: SliderProps): React.JSX.Element;
44
+ ({ formatOptions, label, step, testId, unitText, ...props }: SliderProps): React.JSX.Element;
45
45
  displayName: string;
46
46
  };
47
47
  //# sourceMappingURL=Slider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Slider.d.ts","sourceRoot":"","sources":["../../../lib/components/Slider/Slider.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAMN,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,MAAM,YAAY,CAAC;AAGpB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAQ9C,MAAM,WAAW,WAChB,SAAQ,eAAe,EACtB,IAAI,CAAC,oBAAoB,EAAE,MAAM,CAAC,EAClC,UAAU;IACX;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,aAAa,CAAC,EAAE,IAAI,CAAC,mBAAmB,CAAC;CACzC;AAqCD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,MAAM;0DAMhB,WAAW;;CA0Db,CAAC"}
1
+ {"version":3,"file":"Slider.d.ts","sourceRoot":"","sources":["../../../lib/components/Slider/Slider.tsx"],"names":[],"mappings":"AACA,OAAO,KAAyB,MAAM,OAAO,CAAC;AAC9C,OAAO,EAMN,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,MAAM,YAAY,CAAC;AAGpB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAQ9C,MAAM,WAAW,WAChB,SAAQ,eAAe,EACtB,IAAI,CAAC,oBAAoB,EAAE,MAAM,CAAC,EAClC,UAAU;IACX;;OAEG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,aAAa,CAAC,EAAE,IAAI,CAAC,mBAAmB,CAAC;CACzC;AAqCD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,MAAM;iEAOhB,WAAW;;CAqEb,CAAC"}
@@ -2,11 +2,11 @@
2
2
 
3
3
  import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
4
4
  import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
5
- const _excluded = ["testId", "unitText", "step", "formatOptions"];
5
+ const _excluded = ["formatOptions", "label", "step", "testId", "unitText"];
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 { MinusIcon, PlusIcon } from '@autoguru/icons';
9
- import React from 'react';
9
+ import React, { isValidElement } from 'react';
10
10
  import { mergeProps, useFocusRing, useNumberFormatter, useSlider, useSliderThumb } from 'react-aria';
11
11
  import { useSliderState } from 'react-stately';
12
12
  import { dataAttrs } from "../../utils/dataAttrs.js";
@@ -57,11 +57,11 @@ const SliderThumb = ({
57
57
  * supports configurable step values and value unit post-fix. Use the `onChange` handler
58
58
  * in most instances for retrieving the current value.
59
59
  *
60
- * @example
61
- * const handleOnChange = (value) => {
62
- * console.log('Distance changed to:', value);
63
- * };
60
+ * Supports flexible label approach:
61
+ * - Pre-styled label `label="Distance"`
62
+ * - Custom label content: `label={<label className={customlabelStyles}>Distance</label>}`
64
63
  *
64
+ * @example
65
65
  * <Slider
66
66
  * label="Distance"
67
67
  * value={distance}
@@ -74,14 +74,17 @@ const SliderThumb = ({
74
74
  */
75
75
  export const Slider = _ref => {
76
76
  let {
77
- testId,
78
- unitText = '',
77
+ formatOptions,
78
+ label,
79
79
  step = 5,
80
- formatOptions
80
+ testId,
81
+ unitText
81
82
  } = _ref,
82
83
  props = _objectWithoutProperties(_ref, _excluded);
83
84
  const trackRef = React.useRef(null);
84
85
  const numberFormatter = useNumberFormatter(formatOptions);
86
+ const hasTextLabel = !!label && typeof label === 'string' && label !== '';
87
+ const hasCustomLabel = !hasTextLabel && /*#__PURE__*/isValidElement(label);
85
88
  const state = useSliderState(_objectSpread(_objectSpread({}, props), {}, {
86
89
  step,
87
90
  numberFormatter
@@ -92,16 +95,17 @@ export const Slider = _ref => {
92
95
  labelProps,
93
96
  outputProps
94
97
  } = useSlider(_objectSpread(_objectSpread({}, props), {}, {
98
+ label,
95
99
  step
96
100
  }), state, trackRef);
97
101
  return /*#__PURE__*/_jsxs(Box, _objectSpread(_objectSpread({}, groupProps), {}, {
98
102
  className: styles.container,
99
103
  odComponent: "slider",
100
104
  testId: testId,
101
- children: [props.label && /*#__PURE__*/_jsx("label", _objectSpread(_objectSpread({}, labelProps), {}, {
105
+ children: [hasTextLabel && /*#__PURE__*/_jsx("label", _objectSpread(_objectSpread({}, labelProps), {}, {
102
106
  className: styles.label,
103
- children: props.label
104
- })), /*#__PURE__*/_jsx("div", {
107
+ children: label
108
+ })), hasCustomLabel && /*#__PURE__*/React.cloneElement(label, _objectSpread({}, labelProps)), /*#__PURE__*/_jsx("div", {
105
109
  className: styles.valueDisplay,
106
110
  children: /*#__PURE__*/_jsxs("output", _objectSpread(_objectSpread({}, outputProps), {}, {
107
111
  className: styles.valueText,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autoguru/overdrive",
3
- "version": "4.47.0",
3
+ "version": "4.47.2",
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",