@jobber/components 6.113.1 → 6.114.1

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.
@@ -1,4 +1,4 @@
1
- export declare function useFocusOnSelectedDate(portalContainerId?: string): {
1
+ export declare function useFocusOnSelectedDate(): {
2
2
  ref: import("react").RefObject<HTMLDivElement | null>;
3
- focusOnSelectedDate: () => boolean;
3
+ focusOnSelectedDate: () => void;
4
4
  };
@@ -12652,7 +12652,7 @@ var DatePicker$1 = /** @class */ (function (_super) {
12652
12652
  var PRESELECT_CHANGE_VIA_INPUT = "input";
12653
12653
  var PRESELECT_CHANGE_VIA_NAVIGATE = "navigate";
12654
12654
 
12655
- var styles = {"datePickerWrapper":"OmFI-Bfdzgw-","fullWidth":"HWDFy10kcYA-","datePicker":"Ma55F5Y-XhE-","inline":"_58kEbTu-IAA-","portalContainer":"LDxKi0E-1rg-","header":"Epg-Ub8Dn9A-","month":"Wx3NP8La95k-","spinning":"o0JLwNATy-M-"};
12655
+ var styles = {"datePickerWrapper":"OmFI-Bfdzgw-","fullWidth":"HWDFy10kcYA-","datePicker":"Ma55F5Y-XhE-","inline":"_58kEbTu-IAA-","header":"Epg-Ub8Dn9A-","month":"Wx3NP8La95k-","spinning":"o0JLwNATy-M-"};
12656
12656
 
12657
12657
  function DatePickerCustomHeader({ monthDate, decreaseMonth, increaseMonth, prevMonthButtonDisabled, nextMonthButtonDisabled, }) {
12658
12658
  return (React.createElement("div", { className: styles.header },
@@ -12691,25 +12691,25 @@ function InternalActivator(props, ref) {
12691
12691
  }
12692
12692
  }
12693
12693
 
12694
- function useFocusOnSelectedDate(portalContainerId) {
12694
+ function useFocusOnSelectedDate() {
12695
12695
  const ref = React.useRef(null);
12696
- // Moves focus to the selected/pre-selected day in the calendar ([tabindex="0"]).
12697
- const focusOnSelectedDate = React.useCallback(() => {
12698
- const portalElement = portalContainerId
12699
- ? document.getElementById(portalContainerId)
12700
- : null;
12701
- const searchRoot = portalElement !== null && portalElement !== void 0 ? portalElement : ref.current;
12702
- const day = searchRoot === null || searchRoot === void 0 ? void 0 : searchRoot.querySelector('[tabindex="0"]');
12703
- if (day instanceof HTMLElement) {
12704
- day.focus();
12705
- return true;
12696
+ function focusOnSelectedDate() {
12697
+ var _a;
12698
+ const selectedDateClass = ".react-datepicker__day--selected";
12699
+ const selectedDate = (_a = ref.current) === null || _a === void 0 ? void 0 : _a.querySelector(selectedDateClass);
12700
+ if (selectedDate instanceof HTMLDivElement) {
12701
+ selectedDate.focus();
12706
12702
  }
12707
- return false;
12708
- }, [portalContainerId]);
12703
+ }
12709
12704
  return { ref, focusOnSelectedDate };
12710
12705
  }
12711
12706
 
12712
- function getDatePickerClassNames(inline, open, fullWidth) {
12707
+ /*eslint max-statements: ["error", 14]*/
12708
+ function DatePicker({ onChange, onMonthChange, onOpenChange, activator, inline, selected, readonly = false, disabled = false, fullWidth = false, smartAutofocus = true, maxDate, minDate, highlightDates, firstDayOfWeek, }) {
12709
+ const { ref, focusOnSelectedDate } = useFocusOnSelectedDate();
12710
+ const [open, setOpen] = React.useState(false);
12711
+ const { dateFormat, firstDayOfWeek: contextFirstDayOfWeek } = AtlantisContext.useAtlantisContext();
12712
+ const effectiveFirstDayOfWeek = firstDayOfWeek !== null && firstDayOfWeek !== void 0 ? firstDayOfWeek : contextFirstDayOfWeek;
12713
12713
  const wrapperClassName = classnames(styles.datePickerWrapper, {
12714
12714
  // react-datepicker uses this class name to not close the date picker when
12715
12715
  // the activator is clicked
@@ -12724,58 +12724,44 @@ function getDatePickerClassNames(inline, open, fullWidth) {
12724
12724
  const datePickerClassNames = classnames(styles.datePicker, {
12725
12725
  [styles.inline]: inline,
12726
12726
  });
12727
- return { wrapperClassName, datePickerClassNames };
12728
- }
12729
- function useDatePickerHandlers(onChange, setOpen, onOpenChange, smartAutofocus, focusOnSelectedDate) {
12730
- const handleChange = React.useCallback((value) => {
12731
- onChange(value);
12732
- }, [onChange]);
12733
- const handleCalendarOpen = React.useCallback(() => {
12734
- setOpen(true);
12735
- onOpenChange === null || onOpenChange === void 0 ? void 0 : onOpenChange(true);
12736
- if (smartAutofocus) {
12737
- // The portal DOM may not be painted yet, so defer to the next frame
12738
- requestAnimationFrame(() => {
12739
- focusOnSelectedDate === null || focusOnSelectedDate === void 0 ? void 0 : focusOnSelectedDate();
12740
- });
12741
- }
12742
- }, [setOpen, onOpenChange, smartAutofocus, focusOnSelectedDate]);
12743
- const handleCalendarClose = React.useCallback(() => {
12744
- setOpen(false);
12745
- onOpenChange === null || onOpenChange === void 0 ? void 0 : onOpenChange(false);
12746
- }, [setOpen, onOpenChange]);
12747
- return { handleChange, handleCalendarOpen, handleCalendarClose };
12748
- }
12749
- function DatePicker({ onChange, onMonthChange, onOpenChange, activator, inline, selected, readonly = false, disabled = false, fullWidth = false, smartAutofocus = true, maxDate, minDate, highlightDates, firstDayOfWeek, }) {
12750
- const [open, setOpen] = React.useState(false);
12751
- const { dateFormat, firstDayOfWeek: contextFirstDayOfWeek } = AtlantisContext.useAtlantisContext();
12752
- const effectiveFirstDayOfWeek = firstDayOfWeek !== null && firstDayOfWeek !== void 0 ? firstDayOfWeek : contextFirstDayOfWeek;
12753
- const renderInsidePortal = !inline;
12754
- const uniquePortalId = React.useId();
12755
- const { ref, focusOnSelectedDate } = useFocusOnSelectedDate(uniquePortalId);
12756
- const { wrapperClassName, datePickerClassNames } = getDatePickerClassNames(inline !== null && inline !== void 0 ? inline : false, open, fullWidth !== null && fullWidth !== void 0 ? fullWidth : false);
12757
- const { pickerRef } = useEscapeKeyToCloseDatePicker(open, ref, focusOnSelectedDate, renderInsidePortal);
12758
- const { handleChange, handleCalendarOpen, handleCalendarClose } = useDatePickerHandlers(onChange, setOpen, onOpenChange, smartAutofocus !== null && smartAutofocus !== void 0 ? smartAutofocus : true, focusOnSelectedDate);
12759
- jobberHooks.useRefocusOnActivator(smartAutofocus ? open : false);
12760
- return (React.createElement("div", { className: wrapperClassName, ref: ref, "data-elevation": "elevated", onKeyDown: event => {
12761
- // Stop Escape from bubbling to parent floating elements (e.g. Modal).
12762
- if (event.key === "Escape" && open) {
12763
- event.stopPropagation();
12764
- }
12765
- } },
12766
- React.createElement(DatePicker$1, Object.assign({ ref: pickerRef, calendarClassName: datePickerClassNames, showPopperArrow: false, selected: selected, inline: inline, disabled: disabled, readOnly: readonly, onChange: handleChange, maxDate: maxDate, preventOpenOnFocus: true, minDate: minDate, useWeekdaysShort: true, customInput: React.createElement(DatePickerActivator, { activator: activator, fullWidth: fullWidth }), renderCustomHeader: props => React.createElement(DatePickerCustomHeader, Object.assign({}, props)), onCalendarOpen: handleCalendarOpen, onCalendarClose: handleCalendarClose, dateFormat: [
12727
+ const { pickerRef } = useEscapeKeyToCloseDatePicker(open, ref);
12728
+ if (smartAutofocus) {
12729
+ jobberHooks.useRefocusOnActivator(open);
12730
+ React.useEffect(focusOnSelectedDate, [open]);
12731
+ }
12732
+ return (React.createElement("div", { className: wrapperClassName, ref: ref, "data-elevation": "elevated" },
12733
+ React.createElement(DatePicker$1, { ref: pickerRef, calendarClassName: datePickerClassNames, showPopperArrow: false, selected: selected, inline: inline, disabled: disabled, readOnly: readonly, onChange: handleChange, maxDate: maxDate, preventOpenOnFocus: true, minDate: minDate, useWeekdaysShort: true, customInput: React.createElement(DatePickerActivator, { activator: activator, fullWidth: fullWidth }), renderCustomHeader: props => React.createElement(DatePickerCustomHeader, Object.assign({}, props)), onCalendarOpen: handleCalendarOpen, onCalendarClose: handleCalendarClose, dateFormat: [
12767
12734
  dateFormat,
12768
12735
  "P",
12769
12736
  "PP",
12770
12737
  "PPP",
12771
12738
  "MMM dd yyyy",
12772
12739
  "MMMM dd yyyy",
12773
- ], highlightDates: highlightDates, onMonthChange: onMonthChange, calendarStartDay: effectiveFirstDayOfWeek, popperPlacement: "bottom-start" }, (renderInsidePortal && { portalId: uniquePortalId }))),
12774
- renderInsidePortal && React.createElement(DatePickerPortal, { portalId: uniquePortalId })));
12740
+ ], highlightDates: highlightDates, onMonthChange: onMonthChange, calendarStartDay: effectiveFirstDayOfWeek, popperPlacement: "bottom-start" })));
12741
+ /**
12742
+ * The onChange callback on ReactDatePicker returns a Date and an Event, but
12743
+ * the onChange in our interface only provides the Date. Simplifying the code
12744
+ * by removing this function and passing it directly to the underlying
12745
+ * component breaks tests both here and downstream (i.e. the pattern
12746
+ * `expect(onChange).toHaveBeenCalledWith(date)` is commonly used and would
12747
+ * fail).
12748
+ */
12749
+ function handleChange(value) {
12750
+ // TODO: Ticket created to update all DatePicker and InputDate usages to accept Date | null
12751
+ onChange(value);
12752
+ }
12753
+ function handleCalendarOpen() {
12754
+ setOpen(true);
12755
+ onOpenChange === null || onOpenChange === void 0 ? void 0 : onOpenChange(true);
12756
+ }
12757
+ function handleCalendarClose() {
12758
+ setOpen(false);
12759
+ onOpenChange === null || onOpenChange === void 0 ? void 0 : onOpenChange(false);
12760
+ }
12775
12761
  }
12776
- function useEscapeKeyToCloseDatePicker(open, ref, focusOnSelectedDate, isPortalled) {
12762
+ function useEscapeKeyToCloseDatePicker(open, ref) {
12777
12763
  const pickerRef = React.useRef(null);
12778
- const handleKeyDown = (event) => {
12764
+ const escFunction = (event) => {
12779
12765
  var _a;
12780
12766
  if (event.key === "Escape" && open) {
12781
12767
  // Close the picker ourselves and prevent propagation so that ESC presses with the picker open
@@ -12783,38 +12769,18 @@ function useEscapeKeyToCloseDatePicker(open, ref, focusOnSelectedDate, isPortall
12783
12769
  (_a = pickerRef.current) === null || _a === void 0 ? void 0 : _a.setOpen(false);
12784
12770
  event.stopPropagation();
12785
12771
  }
12786
- if (event.key === "Tab" && open && isPortalled) {
12787
- // When portalled, Tab from the activator doesn't reach the calendar.
12788
- // Intercept Tab to move focus there (mainly when smartAutofocus is false
12789
- // and focus stayed in the input).
12790
- const focused = focusOnSelectedDate();
12791
- if (focused) {
12792
- event.preventDefault();
12793
- }
12794
- }
12795
12772
  };
12796
12773
  React.useEffect(() => {
12797
12774
  var _a;
12798
- (_a = ref.current) === null || _a === void 0 ? void 0 : _a.addEventListener("keydown", handleKeyDown);
12775
+ (_a = ref.current) === null || _a === void 0 ? void 0 : _a.addEventListener("keydown", escFunction);
12799
12776
  return () => {
12800
12777
  var _a;
12801
- (_a = ref.current) === null || _a === void 0 ? void 0 : _a.removeEventListener("keydown", handleKeyDown);
12778
+ (_a = ref.current) === null || _a === void 0 ? void 0 : _a.removeEventListener("keydown", escFunction);
12802
12779
  };
12803
- }, [open, ref, pickerRef, isPortalled]);
12780
+ }, [open, ref, pickerRef]);
12804
12781
  return {
12805
12782
  pickerRef,
12806
12783
  };
12807
12784
  }
12808
- function DatePickerPortal({ portalId }) {
12809
- const nodeId = floatingUi_react.useFloatingNodeId();
12810
- const parentNodeId = floatingUi_react.useFloatingParentNodeId();
12811
- const portalDiv = React.createElement("div", { id: portalId, className: styles.portalContainer });
12812
- if (parentNodeId) {
12813
- return (React.createElement(floatingUi_react.FloatingTree, null,
12814
- React.createElement(floatingUi_react.FloatingNode, { id: nodeId },
12815
- React.createElement(floatingUi_react.FloatingPortal, null, portalDiv))));
12816
- }
12817
- return React.createElement(floatingUi_react.FloatingPortal, null, portalDiv);
12818
- }
12819
12785
 
12820
12786
  exports.DatePicker = DatePicker;
@@ -1,7 +1,7 @@
1
- import React__default, { cloneElement, Component, createRef, useRef, useCallback, useEffect, createElement, forwardRef, isValidElement, useState, useId } from 'react';
1
+ import React__default, { cloneElement, Component, createRef, useRef, useCallback, useEffect, createElement, forwardRef, isValidElement, useState } from 'react';
2
2
  import classnames from 'classnames';
3
3
  import { c as clsx } from './clsx-es.js';
4
- import { u as useFloating, b as autoUpdate, f as flip, o as offset, a as arrow, w as FloatingArrow, j as useFloatingNodeId, i as useFloatingParentNodeId, k as FloatingTree, m as FloatingNode, F as FloatingPortal } from './floating-ui.react-es.js';
4
+ import { u as useFloating, b as autoUpdate, f as flip, o as offset, a as arrow, w as FloatingArrow } from './floating-ui.react-es.js';
5
5
  import ReactDOM__default from 'react-dom';
6
6
  import { useRefocusOnActivator } from '@jobber/hooks';
7
7
  import { T as Typography } from './Typography-es.js';
@@ -12650,7 +12650,7 @@ var DatePicker$1 = /** @class */ (function (_super) {
12650
12650
  var PRESELECT_CHANGE_VIA_INPUT = "input";
12651
12651
  var PRESELECT_CHANGE_VIA_NAVIGATE = "navigate";
12652
12652
 
12653
- var styles = {"datePickerWrapper":"OmFI-Bfdzgw-","fullWidth":"HWDFy10kcYA-","datePicker":"Ma55F5Y-XhE-","inline":"_58kEbTu-IAA-","portalContainer":"LDxKi0E-1rg-","header":"Epg-Ub8Dn9A-","month":"Wx3NP8La95k-","spinning":"o0JLwNATy-M-"};
12653
+ var styles = {"datePickerWrapper":"OmFI-Bfdzgw-","fullWidth":"HWDFy10kcYA-","datePicker":"Ma55F5Y-XhE-","inline":"_58kEbTu-IAA-","header":"Epg-Ub8Dn9A-","month":"Wx3NP8La95k-","spinning":"o0JLwNATy-M-"};
12654
12654
 
12655
12655
  function DatePickerCustomHeader({ monthDate, decreaseMonth, increaseMonth, prevMonthButtonDisabled, nextMonthButtonDisabled, }) {
12656
12656
  return (React__default.createElement("div", { className: styles.header },
@@ -12689,25 +12689,25 @@ function InternalActivator(props, ref) {
12689
12689
  }
12690
12690
  }
12691
12691
 
12692
- function useFocusOnSelectedDate(portalContainerId) {
12692
+ function useFocusOnSelectedDate() {
12693
12693
  const ref = useRef(null);
12694
- // Moves focus to the selected/pre-selected day in the calendar ([tabindex="0"]).
12695
- const focusOnSelectedDate = useCallback(() => {
12696
- const portalElement = portalContainerId
12697
- ? document.getElementById(portalContainerId)
12698
- : null;
12699
- const searchRoot = portalElement !== null && portalElement !== void 0 ? portalElement : ref.current;
12700
- const day = searchRoot === null || searchRoot === void 0 ? void 0 : searchRoot.querySelector('[tabindex="0"]');
12701
- if (day instanceof HTMLElement) {
12702
- day.focus();
12703
- return true;
12694
+ function focusOnSelectedDate() {
12695
+ var _a;
12696
+ const selectedDateClass = ".react-datepicker__day--selected";
12697
+ const selectedDate = (_a = ref.current) === null || _a === void 0 ? void 0 : _a.querySelector(selectedDateClass);
12698
+ if (selectedDate instanceof HTMLDivElement) {
12699
+ selectedDate.focus();
12704
12700
  }
12705
- return false;
12706
- }, [portalContainerId]);
12701
+ }
12707
12702
  return { ref, focusOnSelectedDate };
12708
12703
  }
12709
12704
 
12710
- function getDatePickerClassNames(inline, open, fullWidth) {
12705
+ /*eslint max-statements: ["error", 14]*/
12706
+ function DatePicker({ onChange, onMonthChange, onOpenChange, activator, inline, selected, readonly = false, disabled = false, fullWidth = false, smartAutofocus = true, maxDate, minDate, highlightDates, firstDayOfWeek, }) {
12707
+ const { ref, focusOnSelectedDate } = useFocusOnSelectedDate();
12708
+ const [open, setOpen] = useState(false);
12709
+ const { dateFormat, firstDayOfWeek: contextFirstDayOfWeek } = useAtlantisContext();
12710
+ const effectiveFirstDayOfWeek = firstDayOfWeek !== null && firstDayOfWeek !== void 0 ? firstDayOfWeek : contextFirstDayOfWeek;
12711
12711
  const wrapperClassName = classnames(styles.datePickerWrapper, {
12712
12712
  // react-datepicker uses this class name to not close the date picker when
12713
12713
  // the activator is clicked
@@ -12722,58 +12722,44 @@ function getDatePickerClassNames(inline, open, fullWidth) {
12722
12722
  const datePickerClassNames = classnames(styles.datePicker, {
12723
12723
  [styles.inline]: inline,
12724
12724
  });
12725
- return { wrapperClassName, datePickerClassNames };
12726
- }
12727
- function useDatePickerHandlers(onChange, setOpen, onOpenChange, smartAutofocus, focusOnSelectedDate) {
12728
- const handleChange = useCallback((value) => {
12729
- onChange(value);
12730
- }, [onChange]);
12731
- const handleCalendarOpen = useCallback(() => {
12732
- setOpen(true);
12733
- onOpenChange === null || onOpenChange === void 0 ? void 0 : onOpenChange(true);
12734
- if (smartAutofocus) {
12735
- // The portal DOM may not be painted yet, so defer to the next frame
12736
- requestAnimationFrame(() => {
12737
- focusOnSelectedDate === null || focusOnSelectedDate === void 0 ? void 0 : focusOnSelectedDate();
12738
- });
12739
- }
12740
- }, [setOpen, onOpenChange, smartAutofocus, focusOnSelectedDate]);
12741
- const handleCalendarClose = useCallback(() => {
12742
- setOpen(false);
12743
- onOpenChange === null || onOpenChange === void 0 ? void 0 : onOpenChange(false);
12744
- }, [setOpen, onOpenChange]);
12745
- return { handleChange, handleCalendarOpen, handleCalendarClose };
12746
- }
12747
- function DatePicker({ onChange, onMonthChange, onOpenChange, activator, inline, selected, readonly = false, disabled = false, fullWidth = false, smartAutofocus = true, maxDate, minDate, highlightDates, firstDayOfWeek, }) {
12748
- const [open, setOpen] = useState(false);
12749
- const { dateFormat, firstDayOfWeek: contextFirstDayOfWeek } = useAtlantisContext();
12750
- const effectiveFirstDayOfWeek = firstDayOfWeek !== null && firstDayOfWeek !== void 0 ? firstDayOfWeek : contextFirstDayOfWeek;
12751
- const renderInsidePortal = !inline;
12752
- const uniquePortalId = useId();
12753
- const { ref, focusOnSelectedDate } = useFocusOnSelectedDate(uniquePortalId);
12754
- const { wrapperClassName, datePickerClassNames } = getDatePickerClassNames(inline !== null && inline !== void 0 ? inline : false, open, fullWidth !== null && fullWidth !== void 0 ? fullWidth : false);
12755
- const { pickerRef } = useEscapeKeyToCloseDatePicker(open, ref, focusOnSelectedDate, renderInsidePortal);
12756
- const { handleChange, handleCalendarOpen, handleCalendarClose } = useDatePickerHandlers(onChange, setOpen, onOpenChange, smartAutofocus !== null && smartAutofocus !== void 0 ? smartAutofocus : true, focusOnSelectedDate);
12757
- useRefocusOnActivator(smartAutofocus ? open : false);
12758
- return (React__default.createElement("div", { className: wrapperClassName, ref: ref, "data-elevation": "elevated", onKeyDown: event => {
12759
- // Stop Escape from bubbling to parent floating elements (e.g. Modal).
12760
- if (event.key === "Escape" && open) {
12761
- event.stopPropagation();
12762
- }
12763
- } },
12764
- React__default.createElement(DatePicker$1, Object.assign({ ref: pickerRef, calendarClassName: datePickerClassNames, showPopperArrow: false, selected: selected, inline: inline, disabled: disabled, readOnly: readonly, onChange: handleChange, maxDate: maxDate, preventOpenOnFocus: true, minDate: minDate, useWeekdaysShort: true, customInput: React__default.createElement(DatePickerActivator, { activator: activator, fullWidth: fullWidth }), renderCustomHeader: props => React__default.createElement(DatePickerCustomHeader, Object.assign({}, props)), onCalendarOpen: handleCalendarOpen, onCalendarClose: handleCalendarClose, dateFormat: [
12725
+ const { pickerRef } = useEscapeKeyToCloseDatePicker(open, ref);
12726
+ if (smartAutofocus) {
12727
+ useRefocusOnActivator(open);
12728
+ useEffect(focusOnSelectedDate, [open]);
12729
+ }
12730
+ return (React__default.createElement("div", { className: wrapperClassName, ref: ref, "data-elevation": "elevated" },
12731
+ React__default.createElement(DatePicker$1, { ref: pickerRef, calendarClassName: datePickerClassNames, showPopperArrow: false, selected: selected, inline: inline, disabled: disabled, readOnly: readonly, onChange: handleChange, maxDate: maxDate, preventOpenOnFocus: true, minDate: minDate, useWeekdaysShort: true, customInput: React__default.createElement(DatePickerActivator, { activator: activator, fullWidth: fullWidth }), renderCustomHeader: props => React__default.createElement(DatePickerCustomHeader, Object.assign({}, props)), onCalendarOpen: handleCalendarOpen, onCalendarClose: handleCalendarClose, dateFormat: [
12765
12732
  dateFormat,
12766
12733
  "P",
12767
12734
  "PP",
12768
12735
  "PPP",
12769
12736
  "MMM dd yyyy",
12770
12737
  "MMMM dd yyyy",
12771
- ], highlightDates: highlightDates, onMonthChange: onMonthChange, calendarStartDay: effectiveFirstDayOfWeek, popperPlacement: "bottom-start" }, (renderInsidePortal && { portalId: uniquePortalId }))),
12772
- renderInsidePortal && React__default.createElement(DatePickerPortal, { portalId: uniquePortalId })));
12738
+ ], highlightDates: highlightDates, onMonthChange: onMonthChange, calendarStartDay: effectiveFirstDayOfWeek, popperPlacement: "bottom-start" })));
12739
+ /**
12740
+ * The onChange callback on ReactDatePicker returns a Date and an Event, but
12741
+ * the onChange in our interface only provides the Date. Simplifying the code
12742
+ * by removing this function and passing it directly to the underlying
12743
+ * component breaks tests both here and downstream (i.e. the pattern
12744
+ * `expect(onChange).toHaveBeenCalledWith(date)` is commonly used and would
12745
+ * fail).
12746
+ */
12747
+ function handleChange(value) {
12748
+ // TODO: Ticket created to update all DatePicker and InputDate usages to accept Date | null
12749
+ onChange(value);
12750
+ }
12751
+ function handleCalendarOpen() {
12752
+ setOpen(true);
12753
+ onOpenChange === null || onOpenChange === void 0 ? void 0 : onOpenChange(true);
12754
+ }
12755
+ function handleCalendarClose() {
12756
+ setOpen(false);
12757
+ onOpenChange === null || onOpenChange === void 0 ? void 0 : onOpenChange(false);
12758
+ }
12773
12759
  }
12774
- function useEscapeKeyToCloseDatePicker(open, ref, focusOnSelectedDate, isPortalled) {
12760
+ function useEscapeKeyToCloseDatePicker(open, ref) {
12775
12761
  const pickerRef = useRef(null);
12776
- const handleKeyDown = (event) => {
12762
+ const escFunction = (event) => {
12777
12763
  var _a;
12778
12764
  if (event.key === "Escape" && open) {
12779
12765
  // Close the picker ourselves and prevent propagation so that ESC presses with the picker open
@@ -12781,38 +12767,18 @@ function useEscapeKeyToCloseDatePicker(open, ref, focusOnSelectedDate, isPortall
12781
12767
  (_a = pickerRef.current) === null || _a === void 0 ? void 0 : _a.setOpen(false);
12782
12768
  event.stopPropagation();
12783
12769
  }
12784
- if (event.key === "Tab" && open && isPortalled) {
12785
- // When portalled, Tab from the activator doesn't reach the calendar.
12786
- // Intercept Tab to move focus there (mainly when smartAutofocus is false
12787
- // and focus stayed in the input).
12788
- const focused = focusOnSelectedDate();
12789
- if (focused) {
12790
- event.preventDefault();
12791
- }
12792
- }
12793
12770
  };
12794
12771
  useEffect(() => {
12795
12772
  var _a;
12796
- (_a = ref.current) === null || _a === void 0 ? void 0 : _a.addEventListener("keydown", handleKeyDown);
12773
+ (_a = ref.current) === null || _a === void 0 ? void 0 : _a.addEventListener("keydown", escFunction);
12797
12774
  return () => {
12798
12775
  var _a;
12799
- (_a = ref.current) === null || _a === void 0 ? void 0 : _a.removeEventListener("keydown", handleKeyDown);
12776
+ (_a = ref.current) === null || _a === void 0 ? void 0 : _a.removeEventListener("keydown", escFunction);
12800
12777
  };
12801
- }, [open, ref, pickerRef, isPortalled]);
12778
+ }, [open, ref, pickerRef]);
12802
12779
  return {
12803
12780
  pickerRef,
12804
12781
  };
12805
12782
  }
12806
- function DatePickerPortal({ portalId }) {
12807
- const nodeId = useFloatingNodeId();
12808
- const parentNodeId = useFloatingParentNodeId();
12809
- const portalDiv = React__default.createElement("div", { id: portalId, className: styles.portalContainer });
12810
- if (parentNodeId) {
12811
- return (React__default.createElement(FloatingTree, null,
12812
- React__default.createElement(FloatingNode, { id: nodeId },
12813
- React__default.createElement(FloatingPortal, null, portalDiv))));
12814
- }
12815
- return React__default.createElement(FloatingPortal, null, portalDiv);
12816
- }
12817
12783
 
12818
12784
  export { DatePicker as D };
@@ -8,6 +8,8 @@ require('../LightBox-cjs.js');
8
8
  require('framer-motion');
9
9
  require('react-dom');
10
10
  require('@jobber/hooks');
11
+ require('../noop-cjs.js');
12
+ require('../_commonjsHelpers-cjs.js');
11
13
  require('../ButtonDismiss-cjs.js');
12
14
  require('../Button-cjs.js');
13
15
  require('react-router-dom');
@@ -17,7 +19,6 @@ require('../Typography-cjs.js');
17
19
  require('../Text-cjs.js');
18
20
  require('../Heading-cjs.js');
19
21
  require('../AtlantisThemeContext-cjs.js');
20
- require('../_commonjsHelpers-cjs.js');
21
22
  require('../identity-cjs.js');
22
23
  require('../isTypedArray-cjs.js');
23
24
  require('../isObjectLike-cjs.js');
@@ -34,7 +35,6 @@ require('../Content-cjs.js');
34
35
  require('../ProgressBar-cjs.js');
35
36
  require('../ConfirmationModal-cjs.js');
36
37
  require('../Modal/index.cjs');
37
- require('../noop-cjs.js');
38
38
  require('../floating-ui.react-cjs.js');
39
39
  require('react/jsx-runtime');
40
40
  require('../AtlantisPortalContent-cjs.js');
@@ -6,6 +6,8 @@ import '../LightBox-es.js';
6
6
  import 'framer-motion';
7
7
  import 'react-dom';
8
8
  import '@jobber/hooks';
9
+ import '../noop-es.js';
10
+ import '../_commonjsHelpers-es.js';
9
11
  import '../ButtonDismiss-es.js';
10
12
  import '../Button-es.js';
11
13
  import 'react-router-dom';
@@ -15,7 +17,6 @@ import '../Typography-es.js';
15
17
  import '../Text-es.js';
16
18
  import '../Heading-es.js';
17
19
  import '../AtlantisThemeContext-es.js';
18
- import '../_commonjsHelpers-es.js';
19
20
  import '../identity-es.js';
20
21
  import '../isTypedArray-es.js';
21
22
  import '../isObjectLike-es.js';
@@ -32,7 +33,6 @@ import '../Content-es.js';
32
33
  import '../ProgressBar-es.js';
33
34
  import '../ConfirmationModal-es.js';
34
35
  import '../Modal/index.mjs';
35
- import '../noop-es.js';
36
36
  import '../floating-ui.react-es.js';
37
37
  import 'react/jsx-runtime';
38
38
  import '../AtlantisPortalContent-es.js';
@@ -0,0 +1,22 @@
1
+ import type { RefObject } from "react";
2
+ export declare const BUTTON_DEBOUNCE_DELAY = 250;
3
+ export declare const MOVEMENT_DEBOUNCE_DELAY = 1000;
4
+ export declare const swipeConfidenceThreshold = 10000;
5
+ export declare const swipePower: (offset: number, velocity: number) => number;
6
+ export declare const slideVariants: {
7
+ enter: (directionRef: RefObject<number>) => {
8
+ x: string;
9
+ };
10
+ center: {
11
+ x: number;
12
+ };
13
+ exit: (directionRef: RefObject<number>) => {
14
+ x: string;
15
+ };
16
+ };
17
+ export declare const imageTransition: {
18
+ x: {
19
+ duration: number;
20
+ ease: number[];
21
+ };
22
+ };
@@ -1,56 +1,120 @@
1
- import type { CSSProperties } from "react";
2
1
  import React from "react";
3
- interface PresentedImage {
4
- title?: string;
5
- caption?: string;
6
- alt?: string;
7
- url: string;
2
+ import type { LightBoxNavigationProps, LightBoxProps } from "./LightBox.types";
3
+ import { LightBoxProvider } from "./LightBoxContext";
4
+ export declare function LightBoxContent(): React.JSX.Element;
5
+ /**
6
+ * Blurred, desaturated copy of the current image rendered as a full-bleed
7
+ * background behind the lightbox. Pass `className` to apply additional styles.
8
+ */
9
+ declare function LightBoxBackground({ className }: {
10
+ readonly className?: string;
11
+ }): React.JSX.Element;
12
+ /**
13
+ * Semi-transparent blur backdrop. Clicking it calls `onRequestClose`.
14
+ * Pass `className` to apply additional styles.
15
+ */
16
+ declare function LightBoxOverlay({ className }: {
17
+ readonly className?: string;
18
+ }): React.JSX.Element;
19
+ /**
20
+ * Top bar showing the current image counter (`1/3`) and a close button.
21
+ * Styled for dark backgrounds.
22
+ */
23
+ declare function LightBoxToolbar(): React.JSX.Element;
24
+ /**
25
+ * The animated hero image with swipe-to-navigate and slide animation.
26
+ *
27
+ * Pass `className` to add styles to the image wrapper. Supports
28
+ * swipe-to-navigate (drag). Keyboard arrow navigation is handled by
29
+ * `LightBox.Provider`.
30
+ *
31
+ * @example
32
+ * ```tsx
33
+ * <LightBox.Slides className={styles.imageArea} />
34
+ * <LightBox.Navigation
35
+ * prevButtonClassName={styles.prev}
36
+ * nextButtonClassName={styles.next}
37
+ * />
38
+ * ```
39
+ */
40
+ declare function LightBoxSlides({ className }: {
41
+ readonly className?: string;
42
+ }): React.JSX.Element;
43
+ /**
44
+ * Previous and next navigation buttons. Returns `null` when the image set
45
+ * has only one image.
46
+ *
47
+ * Use `prevButtonClassName` and `nextButtonClassName` to override the styles
48
+ * on each button's wrapper for custom layouts.
49
+ *
50
+ * @example
51
+ * ```tsx
52
+ * <LightBox.Navigation
53
+ * prevButtonClassName={styles.prev}
54
+ * nextButtonClassName={styles.next}
55
+ * />
56
+ * ```
57
+ */
58
+ declare function LightBoxNavigation({ prevButtonClassName, nextButtonClassName, }: LightBoxNavigationProps): React.JSX.Element | null;
59
+ /**
60
+ * Title and caption text for the current image. Only renders when the current
61
+ * image has a `title` or `caption`. Styled for dark backgrounds.
62
+ */
63
+ declare function LightBoxCaption(): React.JSX.Element | null;
64
+ /**
65
+ * Scrollable thumbnail strip. Only renders when there are two or more images.
66
+ */
67
+ declare function LightBoxThumbnails(): React.JSX.Element | null;
68
+ /**
69
+ * LightBox displays images in a fullscreen overlay.
70
+ *
71
+ * **Self-contained (legacy) usage:**
72
+ * ```tsx
73
+ * <LightBox
74
+ * open={isOpen}
75
+ * images={images}
76
+ * imageIndex={imageIndex}
77
+ * onRequestClose={({ lastPosition }) => { setIsOpen(false); }}
78
+ * />
79
+ * ```
80
+ *
81
+ * **Full composable (fullscreen) usage:**
82
+ * ```tsx
83
+ * <LightBox.Provider open={isOpen} images={images} onRequestClose={onClose}>
84
+ * <LightBox.Content />
85
+ * </LightBox.Provider>
86
+ * ```
87
+ *
88
+ * **Inline gallery usage (no overlay, no close):**
89
+ * ```tsx
90
+ * <LightBox.Provider
91
+ * open={true}
92
+ * images={images}
93
+ * imageIndex={activeIndex}
94
+ * onImageChange={onImageChange}
95
+ * >
96
+ * <div className={styles.lightboxWrapper} onMouseMove={handleMouseMove}>
97
+ * <LightBox.Background className={styles.backgroundImage} />
98
+ * <LightBox.Overlay className={styles.blurOverlay} />
99
+ * <LightBox.Slides className={styles.imageArea} />
100
+ * <LightBox.Navigation
101
+ * prevButtonClassName={styles.prev}
102
+ * nextButtonClassName={styles.next}
103
+ * />
104
+ * </div>
105
+ * </LightBox.Provider>
106
+ * ```
107
+ */
108
+ declare function LightBox(props: LightBoxProps): React.JSX.Element;
109
+ declare namespace LightBox {
110
+ var Provider: typeof LightBoxProvider;
111
+ var Content: typeof LightBoxContent;
112
+ var Background: typeof LightBoxBackground;
113
+ var Overlay: typeof LightBoxOverlay;
114
+ var Toolbar: typeof LightBoxToolbar;
115
+ var Slides: typeof LightBoxSlides;
116
+ var Navigation: typeof LightBoxNavigation;
117
+ var Caption: typeof LightBoxCaption;
118
+ var Thumbnails: typeof LightBoxThumbnails;
8
119
  }
9
- interface RequestCloseOptions {
10
- lastPosition: number;
11
- }
12
- interface LightBoxProps {
13
- /**
14
- * Specify if the Lightbox is open or closed.
15
- */
16
- readonly open: boolean;
17
- /**
18
- * Images is an array of objects defining a LightBox image. This object consists of
19
- * `title`, `caption`, `alt` and `url`. `title`, `alt` and `caption` are optional, `url` is
20
- * required, for each image.
21
- */
22
- readonly images: PresentedImage[];
23
- /**
24
- * Use this to specify which image in `images` to initialize the lightbox with.
25
- * This is useful when you have a collection of thumbnails as you only need one
26
- * collection of image urls, order doesn't matter.
27
- */
28
- readonly imageIndex?: number;
29
- /**
30
- * This function must set open to false in order to close the lightbox. Note there
31
- * is a 300ms easing animation on lightbox close that occurs before this function
32
- * is called.
33
- * This function receives an object as an argument with the key `lastPosition`
34
- * that has the index of the image the user was on when LightBox was closed.
35
- */
36
- onRequestClose(options: RequestCloseOptions): void;
37
- /**
38
- * Sets the box-sizing for the thumbnails in the lightbox. This is a solution for a problem where
39
- * tailwind was setting the box-sizing to `border-box` and causing issues with the lightbox.
40
- * @default "content-box"
41
- */
42
- readonly boxSizing?: CSSProperties["boxSizing"];
43
- }
44
- export declare const slideVariants: {
45
- enter: (directionRef: React.RefObject<number>) => {
46
- x: string;
47
- };
48
- center: {
49
- x: number;
50
- };
51
- exit: (directionRef: React.RefObject<number>) => {
52
- x: string;
53
- };
54
- };
55
- export declare function LightBox({ boxSizing, open, images, imageIndex, onRequestClose, }: LightBoxProps): React.JSX.Element;
56
- export {};
120
+ export { LightBox };