@jobber/components 6.112.0 → 6.112.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.
- package/dist/DatePicker/useFocusOnSelectedDate.d.ts +2 -2
- package/dist/DatePicker-cjs.js +82 -48
- package/dist/DatePicker-es.js +84 -50
- package/dist/Page/Page.d.ts +70 -70
- package/dist/Page/index.cjs +2 -1
- package/dist/Page/index.d.ts +2 -1
- package/dist/Page/index.mjs +2 -1
- package/dist/Page/types.d.ts +120 -0
- package/dist/Page-cjs.js +148 -16
- package/dist/Page-es.js +148 -16
- package/dist/styles.css +6 -3
- package/dist/utils/meta/meta.json +14 -0
- package/package.json +2 -2
package/dist/DatePicker-cjs.js
CHANGED
|
@@ -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-","header":"Epg-Ub8Dn9A-","month":"Wx3NP8La95k-","spinning":"o0JLwNATy-M-"};
|
|
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-"};
|
|
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() {
|
|
12694
|
+
function useFocusOnSelectedDate(portalContainerId) {
|
|
12695
12695
|
const ref = React.useRef(null);
|
|
12696
|
-
|
|
12697
|
-
|
|
12698
|
-
const
|
|
12699
|
-
|
|
12700
|
-
|
|
12701
|
-
|
|
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;
|
|
12702
12706
|
}
|
|
12703
|
-
|
|
12707
|
+
return false;
|
|
12708
|
+
}, [portalContainerId]);
|
|
12704
12709
|
return { ref, focusOnSelectedDate };
|
|
12705
12710
|
}
|
|
12706
12711
|
|
|
12707
|
-
|
|
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;
|
|
12712
|
+
function getDatePickerClassNames(inline, open, fullWidth) {
|
|
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,44 +12724,58 @@ function DatePicker({ onChange, onMonthChange, onOpenChange, activator, inline,
|
|
|
12724
12724
|
const datePickerClassNames = classnames(styles.datePicker, {
|
|
12725
12725
|
[styles.inline]: inline,
|
|
12726
12726
|
});
|
|
12727
|
-
|
|
12728
|
-
|
|
12729
|
-
|
|
12730
|
-
|
|
12731
|
-
|
|
12732
|
-
|
|
12733
|
-
|
|
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: [
|
|
12734
12767
|
dateFormat,
|
|
12735
12768
|
"P",
|
|
12736
12769
|
"PP",
|
|
12737
12770
|
"PPP",
|
|
12738
12771
|
"MMM dd yyyy",
|
|
12739
12772
|
"MMMM dd yyyy",
|
|
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
|
-
}
|
|
12773
|
+
], highlightDates: highlightDates, onMonthChange: onMonthChange, calendarStartDay: effectiveFirstDayOfWeek, popperPlacement: "bottom-start" }, (renderInsidePortal && { portalId: uniquePortalId }))),
|
|
12774
|
+
renderInsidePortal && React.createElement(DatePickerPortal, { portalId: uniquePortalId })));
|
|
12761
12775
|
}
|
|
12762
|
-
function useEscapeKeyToCloseDatePicker(open, ref) {
|
|
12776
|
+
function useEscapeKeyToCloseDatePicker(open, ref, focusOnSelectedDate, isPortalled) {
|
|
12763
12777
|
const pickerRef = React.useRef(null);
|
|
12764
|
-
const
|
|
12778
|
+
const handleKeyDown = (event) => {
|
|
12765
12779
|
var _a;
|
|
12766
12780
|
if (event.key === "Escape" && open) {
|
|
12767
12781
|
// Close the picker ourselves and prevent propagation so that ESC presses with the picker open
|
|
@@ -12769,18 +12783,38 @@ function useEscapeKeyToCloseDatePicker(open, ref) {
|
|
|
12769
12783
|
(_a = pickerRef.current) === null || _a === void 0 ? void 0 : _a.setOpen(false);
|
|
12770
12784
|
event.stopPropagation();
|
|
12771
12785
|
}
|
|
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
|
+
}
|
|
12772
12795
|
};
|
|
12773
12796
|
React.useEffect(() => {
|
|
12774
12797
|
var _a;
|
|
12775
|
-
(_a = ref.current) === null || _a === void 0 ? void 0 : _a.addEventListener("keydown",
|
|
12798
|
+
(_a = ref.current) === null || _a === void 0 ? void 0 : _a.addEventListener("keydown", handleKeyDown);
|
|
12776
12799
|
return () => {
|
|
12777
12800
|
var _a;
|
|
12778
|
-
(_a = ref.current) === null || _a === void 0 ? void 0 : _a.removeEventListener("keydown",
|
|
12801
|
+
(_a = ref.current) === null || _a === void 0 ? void 0 : _a.removeEventListener("keydown", handleKeyDown);
|
|
12779
12802
|
};
|
|
12780
|
-
}, [open, ref, pickerRef]);
|
|
12803
|
+
}, [open, ref, pickerRef, isPortalled]);
|
|
12781
12804
|
return {
|
|
12782
12805
|
pickerRef,
|
|
12783
12806
|
};
|
|
12784
12807
|
}
|
|
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
|
+
}
|
|
12785
12819
|
|
|
12786
12820
|
exports.DatePicker = DatePicker;
|
package/dist/DatePicker-es.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import React__default, { cloneElement, Component, createRef, useRef, useCallback, useEffect, createElement, forwardRef, isValidElement, useState } from 'react';
|
|
1
|
+
import React__default, { cloneElement, Component, createRef, useRef, useCallback, useEffect, createElement, forwardRef, isValidElement, useState, useId } 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 } 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, j as useFloatingNodeId, i as useFloatingParentNodeId, k as FloatingTree, m as FloatingNode, F as FloatingPortal } 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-","header":"Epg-Ub8Dn9A-","month":"Wx3NP8La95k-","spinning":"o0JLwNATy-M-"};
|
|
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-"};
|
|
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() {
|
|
12692
|
+
function useFocusOnSelectedDate(portalContainerId) {
|
|
12693
12693
|
const ref = useRef(null);
|
|
12694
|
-
|
|
12695
|
-
|
|
12696
|
-
const
|
|
12697
|
-
|
|
12698
|
-
|
|
12699
|
-
|
|
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;
|
|
12700
12704
|
}
|
|
12701
|
-
|
|
12705
|
+
return false;
|
|
12706
|
+
}, [portalContainerId]);
|
|
12702
12707
|
return { ref, focusOnSelectedDate };
|
|
12703
12708
|
}
|
|
12704
12709
|
|
|
12705
|
-
|
|
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;
|
|
12710
|
+
function getDatePickerClassNames(inline, open, fullWidth) {
|
|
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,44 +12722,58 @@ function DatePicker({ onChange, onMonthChange, onOpenChange, activator, inline,
|
|
|
12722
12722
|
const datePickerClassNames = classnames(styles.datePicker, {
|
|
12723
12723
|
[styles.inline]: inline,
|
|
12724
12724
|
});
|
|
12725
|
-
|
|
12726
|
-
|
|
12727
|
-
|
|
12728
|
-
|
|
12729
|
-
|
|
12730
|
-
|
|
12731
|
-
|
|
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: [
|
|
12732
12765
|
dateFormat,
|
|
12733
12766
|
"P",
|
|
12734
12767
|
"PP",
|
|
12735
12768
|
"PPP",
|
|
12736
12769
|
"MMM dd yyyy",
|
|
12737
12770
|
"MMMM dd yyyy",
|
|
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
|
-
}
|
|
12771
|
+
], highlightDates: highlightDates, onMonthChange: onMonthChange, calendarStartDay: effectiveFirstDayOfWeek, popperPlacement: "bottom-start" }, (renderInsidePortal && { portalId: uniquePortalId }))),
|
|
12772
|
+
renderInsidePortal && React__default.createElement(DatePickerPortal, { portalId: uniquePortalId })));
|
|
12759
12773
|
}
|
|
12760
|
-
function useEscapeKeyToCloseDatePicker(open, ref) {
|
|
12774
|
+
function useEscapeKeyToCloseDatePicker(open, ref, focusOnSelectedDate, isPortalled) {
|
|
12761
12775
|
const pickerRef = useRef(null);
|
|
12762
|
-
const
|
|
12776
|
+
const handleKeyDown = (event) => {
|
|
12763
12777
|
var _a;
|
|
12764
12778
|
if (event.key === "Escape" && open) {
|
|
12765
12779
|
// Close the picker ourselves and prevent propagation so that ESC presses with the picker open
|
|
@@ -12767,18 +12781,38 @@ function useEscapeKeyToCloseDatePicker(open, ref) {
|
|
|
12767
12781
|
(_a = pickerRef.current) === null || _a === void 0 ? void 0 : _a.setOpen(false);
|
|
12768
12782
|
event.stopPropagation();
|
|
12769
12783
|
}
|
|
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
|
+
}
|
|
12770
12793
|
};
|
|
12771
12794
|
useEffect(() => {
|
|
12772
12795
|
var _a;
|
|
12773
|
-
(_a = ref.current) === null || _a === void 0 ? void 0 : _a.addEventListener("keydown",
|
|
12796
|
+
(_a = ref.current) === null || _a === void 0 ? void 0 : _a.addEventListener("keydown", handleKeyDown);
|
|
12774
12797
|
return () => {
|
|
12775
12798
|
var _a;
|
|
12776
|
-
(_a = ref.current) === null || _a === void 0 ? void 0 : _a.removeEventListener("keydown",
|
|
12799
|
+
(_a = ref.current) === null || _a === void 0 ? void 0 : _a.removeEventListener("keydown", handleKeyDown);
|
|
12777
12800
|
};
|
|
12778
|
-
}, [open, ref, pickerRef]);
|
|
12801
|
+
}, [open, ref, pickerRef, isPortalled]);
|
|
12779
12802
|
return {
|
|
12780
12803
|
pickerRef,
|
|
12781
12804
|
};
|
|
12782
12805
|
}
|
|
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
|
+
}
|
|
12783
12817
|
|
|
12784
12818
|
export { DatePicker as D };
|
package/dist/Page/Page.d.ts
CHANGED
|
@@ -1,74 +1,74 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ReactElement } from "react";
|
|
2
2
|
import React from "react";
|
|
3
|
-
import type {
|
|
3
|
+
import type { ButtonActionProps, PageActionButtonProps, PageActionsProps, PageBodyProps, PageComposableProps, PageHeaderContentProps, PageHeaderProps, PageIntroProps, PageLegacyProps, PageMenuProps, PageSlotProps, PageSubtitleProps, PageTitleBarProps, PageTitleProps } from "./types";
|
|
4
4
|
import { type ButtonProps } from "../Button";
|
|
5
|
-
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
* TitleMetaData component to be displayed
|
|
23
|
-
* next to the title. Only compatible with string titles.
|
|
24
|
-
*/
|
|
25
|
-
readonly titleMetaData?: ReactNode;
|
|
26
|
-
/**
|
|
27
|
-
* Subtitle of the page.
|
|
28
|
-
*/
|
|
29
|
-
readonly subtitle?: string;
|
|
30
|
-
/**
|
|
31
|
-
* Determines the width of the page.
|
|
32
|
-
*
|
|
33
|
-
* Fill makes the width grow to 100%.
|
|
34
|
-
*
|
|
35
|
-
* Standard caps out at 1280px.
|
|
36
|
-
*
|
|
37
|
-
* Narrow caps out at 1024px.
|
|
38
|
-
*
|
|
39
|
-
* @default standard
|
|
40
|
-
*/
|
|
41
|
-
readonly width?: "fill" | "standard" | "narrow";
|
|
42
|
-
/**
|
|
43
|
-
* Page title primary action button settings.
|
|
44
|
-
*/
|
|
45
|
-
readonly primaryAction?: ButtonActionProps;
|
|
46
|
-
/**
|
|
47
|
-
* Page title secondary action button settings.
|
|
48
|
-
*/
|
|
49
|
-
readonly secondaryAction?: ButtonActionProps;
|
|
50
|
-
/**
|
|
51
|
-
* Page title Action menu.
|
|
52
|
-
*/
|
|
53
|
-
readonly moreActionsMenu?: SectionProps[];
|
|
5
|
+
export declare function Page(props: PageLegacyProps): ReactElement;
|
|
6
|
+
export declare function Page(props: PageComposableProps): ReactElement;
|
|
7
|
+
export declare namespace Page {
|
|
8
|
+
var Header: typeof PageHeader;
|
|
9
|
+
var HeaderContent: typeof PageHeaderContent;
|
|
10
|
+
var TitleBar: typeof PageTitleBar;
|
|
11
|
+
var Title: typeof PageTitle;
|
|
12
|
+
var Subtitle: typeof PageSubtitle;
|
|
13
|
+
var Intro: typeof PageIntro;
|
|
14
|
+
var Actions: typeof PageActions;
|
|
15
|
+
var ActionPrimary: typeof PageActionPrimary;
|
|
16
|
+
var ActionSecondary: typeof PageActionSecondary;
|
|
17
|
+
var ActionMenu: typeof PageActionMenu;
|
|
18
|
+
var PrimaryButton: typeof PagePrimaryButton;
|
|
19
|
+
var SecondaryButton: typeof PageSecondaryButton;
|
|
20
|
+
var Menu: typeof PageMenu;
|
|
21
|
+
var Body: typeof PageBody;
|
|
54
22
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Groups the title area and actions into the page header layout.
|
|
25
|
+
* Place non-action content (title, subtitle) inside `Page.HeaderContent`
|
|
26
|
+
* and actions inside `Page.Actions`.
|
|
27
|
+
*/
|
|
28
|
+
declare function PageHeader({ children, ...rest }: PageHeaderProps): React.JSX.Element;
|
|
29
|
+
/** Wraps the title area (title, subtitle) inside `Page.Header`. Use when the header contains more than one content element to keep them stacked vertically. */
|
|
30
|
+
declare function PageHeaderContent({ children, ...rest }: PageHeaderContentProps): React.JSX.Element;
|
|
31
|
+
/**
|
|
32
|
+
* Flex container for the page title and optional sibling elements such as
|
|
33
|
+
* status badges. Use when you need to display metadata alongside the heading.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```tsx
|
|
37
|
+
* <Page.TitleBar>
|
|
38
|
+
* <Page.Title>Clients</Page.Title>
|
|
39
|
+
* <StatusLabel label="Active" status="success" />
|
|
40
|
+
* </Page.TitleBar>
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
declare function PageTitleBar({ children, ...rest }: PageTitleBarProps): React.JSX.Element;
|
|
44
|
+
/**
|
|
45
|
+
* Renders the page heading as an H1. When metadata is present alongside the
|
|
46
|
+
* title, wrap both in `Page.TitleBar`.
|
|
47
|
+
*/
|
|
48
|
+
declare function PageTitle({ children, ...rest }: PageTitleProps): React.JSX.Element;
|
|
49
|
+
/** Secondary text below the title. Always applies default Text/Emphasis styling. */
|
|
50
|
+
declare function PageSubtitle({ children, ...rest }: PageSubtitleProps): React.JSX.Element;
|
|
51
|
+
/** Introduction text between the header and body. Always applies default Text styling. */
|
|
52
|
+
declare function PageIntro({ children }: PageIntroProps): React.JSX.Element;
|
|
53
|
+
/** Container for action buttons and menu. Applies responsive actionGroup layout. */
|
|
54
|
+
declare function PageActions({ children, ...rest }: PageActionsProps): React.JSX.Element;
|
|
55
|
+
/** Positional container for the primary action. Should contain a Button element, e.g. <Page.PrimaryButton>. */
|
|
56
|
+
declare function PageActionPrimary({ children, ref }: PageSlotProps): React.JSX.Element;
|
|
57
|
+
/** Positional container for the secondary action. Should contain a Button element, e.g. <Page.SecondaryButton>. */
|
|
58
|
+
declare function PageActionSecondary({ children, ref }: PageSlotProps): React.JSX.Element;
|
|
59
|
+
/** Positional container for the menu action. Should contain Page.Menu or a custom Menu. */
|
|
60
|
+
declare function PageActionMenu({ children, ref }: PageSlotProps): React.JSX.Element;
|
|
61
|
+
/** Default primary Button with opinionated styling. Use inside Page.ActionPrimary. */
|
|
62
|
+
declare function PagePrimaryButton({ ref, label, onClick, icon, disabled, loading, ariaLabel, ...rest }: PageActionButtonProps): React.JSX.Element;
|
|
63
|
+
/** Default secondary Button with opinionated styling. Use inside Page.ActionSecondary. */
|
|
64
|
+
declare function PageSecondaryButton({ ref, label, onClick, icon, disabled, loading, ariaLabel, ...rest }: PageActionButtonProps): React.JSX.Element;
|
|
65
|
+
/**
|
|
66
|
+
* "More Actions" menu with a default trigger button.
|
|
67
|
+
* Consumers supply Menu.Item children (in case custom routing is needed,
|
|
68
|
+
* e.g. wrapping Menu.Item with createLink() from TanStack Router).
|
|
69
|
+
*/
|
|
70
|
+
declare function PageMenu({ children, triggerLabel, ...rest }: PageMenuProps): React.JSX.Element;
|
|
71
|
+
/** Main content area of the page. */
|
|
72
|
+
declare function PageBody({ children }: PageBodyProps): React.JSX.Element;
|
|
73
|
+
export declare const getActionProps: (actionProps?: ButtonActionProps) => ButtonProps;
|
|
74
74
|
export {};
|
package/dist/Page/index.cjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var Page = require('../Page-cjs.js');
|
|
4
|
+
require('../tslib.es6-cjs.js');
|
|
4
5
|
require('react');
|
|
5
6
|
require('classnames');
|
|
6
7
|
require('@jobber/hooks');
|
|
@@ -14,7 +15,6 @@ require('react/jsx-runtime');
|
|
|
14
15
|
require('../_commonjsHelpers-cjs.js');
|
|
15
16
|
require('../Button-cjs.js');
|
|
16
17
|
require('react-router-dom');
|
|
17
|
-
require('../tslib.es6-cjs.js');
|
|
18
18
|
require('../Icon-cjs.js');
|
|
19
19
|
require('@jobber/design');
|
|
20
20
|
require('../Menu-cjs.js');
|
|
@@ -25,6 +25,7 @@ require('../Tree-cjs.js');
|
|
|
25
25
|
require('../clsx-cjs.js');
|
|
26
26
|
require('../useFormFieldFocus-cjs.js');
|
|
27
27
|
require('../maxHeight-cjs.js');
|
|
28
|
+
require('../filterDataAttributes-cjs.js');
|
|
28
29
|
|
|
29
30
|
|
|
30
31
|
|
package/dist/Page/index.d.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export { Page
|
|
1
|
+
export { Page } from "./Page";
|
|
2
|
+
export type { ButtonActionProps, PageActionButtonProps, PageComposableProps, PageLegacyProps, PageMenuProps, PageProps, PageSlotProps, } from "./types";
|
package/dist/Page/index.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { P as Page } from '../Page-es.js';
|
|
2
|
+
import '../tslib.es6-es.js';
|
|
2
3
|
import 'react';
|
|
3
4
|
import 'classnames';
|
|
4
5
|
import '@jobber/hooks';
|
|
@@ -12,7 +13,6 @@ import 'react/jsx-runtime';
|
|
|
12
13
|
import '../_commonjsHelpers-es.js';
|
|
13
14
|
import '../Button-es.js';
|
|
14
15
|
import 'react-router-dom';
|
|
15
|
-
import '../tslib.es6-es.js';
|
|
16
16
|
import '../Icon-es.js';
|
|
17
17
|
import '@jobber/design';
|
|
18
18
|
import '../Menu-es.js';
|
|
@@ -23,3 +23,4 @@ import '../Tree-es.js';
|
|
|
23
23
|
import '../clsx-es.js';
|
|
24
24
|
import '../useFormFieldFocus-es.js';
|
|
25
25
|
import '../maxHeight-es.js';
|
|
26
|
+
import '../filterDataAttributes-es.js';
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import type { ReactNode, RefObject } from "react";
|
|
2
|
+
import { type ButtonProps } from "../Button";
|
|
3
|
+
import { type SectionProps } from "../Menu";
|
|
4
|
+
export type ButtonActionProps = ButtonProps & {
|
|
5
|
+
ref?: React.RefObject<HTMLDivElement | null>;
|
|
6
|
+
};
|
|
7
|
+
interface PageBaseProps {
|
|
8
|
+
readonly children: ReactNode | ReactNode[];
|
|
9
|
+
/**
|
|
10
|
+
* Title of the page.
|
|
11
|
+
*
|
|
12
|
+
* Supports any React node. If a string is provided, it will be rendered as an H1 heading.
|
|
13
|
+
* Otherwise it will be rendered as is.
|
|
14
|
+
*
|
|
15
|
+
* **Important**: If you're passing a custom element, it must include an H1-level heading within it.
|
|
16
|
+
* Ideally <Heading level={1}> should be used here.
|
|
17
|
+
*/
|
|
18
|
+
readonly title: ReactNode;
|
|
19
|
+
/**
|
|
20
|
+
* TitleMetaData component to be displayed
|
|
21
|
+
* next to the title. Only compatible with string titles.
|
|
22
|
+
*/
|
|
23
|
+
readonly titleMetaData?: ReactNode;
|
|
24
|
+
/**
|
|
25
|
+
* Subtitle of the page.
|
|
26
|
+
*/
|
|
27
|
+
readonly subtitle?: string;
|
|
28
|
+
/**
|
|
29
|
+
* Determines the width of the page.
|
|
30
|
+
*
|
|
31
|
+
* Fill makes the width grow to 100%.
|
|
32
|
+
*
|
|
33
|
+
* Standard caps out at 1280px.
|
|
34
|
+
*
|
|
35
|
+
* Narrow caps out at 1024px.
|
|
36
|
+
*
|
|
37
|
+
* @default standard
|
|
38
|
+
*/
|
|
39
|
+
readonly width?: "fill" | "standard" | "narrow";
|
|
40
|
+
/**
|
|
41
|
+
* Page title primary action button settings.
|
|
42
|
+
*/
|
|
43
|
+
readonly primaryAction?: ButtonActionProps;
|
|
44
|
+
/**
|
|
45
|
+
* Page title secondary action button settings.
|
|
46
|
+
*/
|
|
47
|
+
readonly secondaryAction?: ButtonActionProps;
|
|
48
|
+
/**
|
|
49
|
+
* Page title Action menu.
|
|
50
|
+
*/
|
|
51
|
+
readonly moreActionsMenu?: SectionProps[];
|
|
52
|
+
}
|
|
53
|
+
interface PageWithIntroProps extends PageBaseProps {
|
|
54
|
+
/**
|
|
55
|
+
* Content of the page. This supports basic markdown node types
|
|
56
|
+
* such as `_italic_`, `**bold**`, and `[link name](url)`.
|
|
57
|
+
*/
|
|
58
|
+
readonly intro: string;
|
|
59
|
+
/**
|
|
60
|
+
* Causes any markdown links in the `intro` prop to open in a new
|
|
61
|
+
* tab, i.e. with `target="_blank"`.
|
|
62
|
+
*
|
|
63
|
+
* Can only be used if `intro` prop is also specified.
|
|
64
|
+
*
|
|
65
|
+
* Defaults to `false`.
|
|
66
|
+
*/
|
|
67
|
+
readonly externalIntroLinks?: boolean;
|
|
68
|
+
}
|
|
69
|
+
interface PageWithoutIntroProps extends PageBaseProps {
|
|
70
|
+
readonly intro?: never;
|
|
71
|
+
readonly externalIntroLinks?: never;
|
|
72
|
+
}
|
|
73
|
+
export type PageLegacyProps = PageWithIntroProps | PageWithoutIntroProps;
|
|
74
|
+
export interface PageComposableProps {
|
|
75
|
+
readonly children: ReactNode;
|
|
76
|
+
readonly width?: "fill" | "standard" | "narrow";
|
|
77
|
+
}
|
|
78
|
+
export type PageProps = PageLegacyProps | PageComposableProps;
|
|
79
|
+
export interface PageHeaderProps {
|
|
80
|
+
readonly children: ReactNode;
|
|
81
|
+
}
|
|
82
|
+
export interface PageHeaderContentProps {
|
|
83
|
+
readonly children: ReactNode;
|
|
84
|
+
}
|
|
85
|
+
export interface PageTitleBarProps {
|
|
86
|
+
readonly children: ReactNode;
|
|
87
|
+
}
|
|
88
|
+
export interface PageTitleProps {
|
|
89
|
+
readonly children: ReactNode;
|
|
90
|
+
}
|
|
91
|
+
export interface PageSubtitleProps {
|
|
92
|
+
readonly children: ReactNode;
|
|
93
|
+
}
|
|
94
|
+
export interface PageIntroProps {
|
|
95
|
+
readonly children: ReactNode;
|
|
96
|
+
}
|
|
97
|
+
export interface PageActionsProps {
|
|
98
|
+
readonly children: ReactNode;
|
|
99
|
+
}
|
|
100
|
+
export interface PageSlotProps {
|
|
101
|
+
readonly children: ReactNode;
|
|
102
|
+
readonly ref?: RefObject<HTMLDivElement | null>;
|
|
103
|
+
}
|
|
104
|
+
export interface PageActionButtonProps {
|
|
105
|
+
readonly ref?: RefObject<HTMLDivElement | null>;
|
|
106
|
+
readonly label: string;
|
|
107
|
+
readonly onClick?: () => void;
|
|
108
|
+
readonly icon?: ButtonProps["icon"];
|
|
109
|
+
readonly disabled?: boolean;
|
|
110
|
+
readonly loading?: boolean;
|
|
111
|
+
readonly ariaLabel?: string;
|
|
112
|
+
}
|
|
113
|
+
export interface PageMenuProps {
|
|
114
|
+
readonly children: ReactNode;
|
|
115
|
+
readonly triggerLabel?: string;
|
|
116
|
+
}
|
|
117
|
+
export interface PageBodyProps {
|
|
118
|
+
readonly children: ReactNode;
|
|
119
|
+
}
|
|
120
|
+
export {};
|
package/dist/Page-cjs.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var tslib_es6 = require('./tslib.es6-cjs.js');
|
|
3
4
|
var React = require('react');
|
|
4
5
|
var classnames = require('classnames');
|
|
5
6
|
var jobberHooks = require('@jobber/hooks');
|
|
@@ -10,11 +11,27 @@ var Markdown = require('./Markdown-cjs.js');
|
|
|
10
11
|
var Button = require('./Button-cjs.js');
|
|
11
12
|
var Menu = require('./Menu-cjs.js');
|
|
12
13
|
var Emphasis = require('./Emphasis-cjs.js');
|
|
14
|
+
var filterDataAttributes = require('./filterDataAttributes-cjs.js');
|
|
13
15
|
|
|
14
16
|
var styles = {"page":"BLYnKItuM3c-","fill":"n5WRRhMkoLs-","standard":"WziKEWW9nA8-","narrow":"qgGzgDyS2NY-","titleBar":"lbmoDvdtQO4-","titleRow":"k9y5NuqTcks-","actionGroup":"_7t53-bnzh98-","large":"SH0aNOLVhE8-","medium":"Lc7Z0FsBa6w-","small":"iF5IA1SYKoA-","primaryAction":"g-H7CKkX-LA-","actionButton":"RSP7jHjP-mw-","subtitle":"EqsNMrZVL-8-","spinning":"MJZVhEmx6h4-"};
|
|
15
17
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
/** Discriminates between the props-based API and the composable children API. */
|
|
19
|
+
function isLegacy(props) {
|
|
20
|
+
return "title" in props;
|
|
21
|
+
}
|
|
22
|
+
function Page(props) {
|
|
23
|
+
var _a;
|
|
24
|
+
const pageStyles = classnames(styles.page, styles[(_a = props.width) !== null && _a !== void 0 ? _a : "standard"]);
|
|
25
|
+
if (isLegacy(props)) {
|
|
26
|
+
return React.createElement(PageLegacy, Object.assign({}, props, { pageStyles: pageStyles }));
|
|
27
|
+
}
|
|
28
|
+
return (React.createElement("div", { className: pageStyles },
|
|
29
|
+
React.createElement(Content.Content, null, props.children)));
|
|
30
|
+
}
|
|
31
|
+
/** Props-based renderer. Preserves the original Page behavior for existing consumers. */
|
|
32
|
+
function PageLegacy(_a) {
|
|
33
|
+
var { title, titleMetaData, intro, externalIntroLinks, subtitle, children, primaryAction, secondaryAction, moreActionsMenu = [], pageStyles } = _a, rest = tslib_es6.__rest(_a, ["title", "titleMetaData", "intro", "externalIntroLinks", "subtitle", "children", "primaryAction", "secondaryAction", "moreActionsMenu", "pageStyles"]);
|
|
34
|
+
const dataAttrs = filterDataAttributes.filterDataAttributes(rest);
|
|
18
35
|
const [titleBarRef, { width: titleBarWidth = jobberHooks.Breakpoints.large }] = jobberHooks.useResizeObserver();
|
|
19
36
|
const titleBarClasses = classnames(styles.titleBar, {
|
|
20
37
|
[styles.small]: titleBarWidth > jobberHooks.Breakpoints.smaller,
|
|
@@ -23,16 +40,7 @@ function Page({ title, titleMetaData, intro, externalIntroLinks, subtitle, child
|
|
|
23
40
|
});
|
|
24
41
|
const showMenu = moreActionsMenu.length > 0;
|
|
25
42
|
const showActionGroup = showMenu || primaryAction || secondaryAction;
|
|
26
|
-
|
|
27
|
-
primaryAction = Object.assign({ fullWidth: true }, primaryAction);
|
|
28
|
-
}
|
|
29
|
-
if (secondaryAction != undefined) {
|
|
30
|
-
secondaryAction = Object.assign({ type: "secondary", fullWidth: true }, secondaryAction);
|
|
31
|
-
}
|
|
32
|
-
if (secondaryAction != undefined) {
|
|
33
|
-
secondaryAction = Object.assign({ type: "secondary", fullWidth: true }, secondaryAction);
|
|
34
|
-
}
|
|
35
|
-
return (React.createElement("div", { className: pageStyles },
|
|
43
|
+
return (React.createElement("div", Object.assign({ className: pageStyles }, dataAttrs),
|
|
36
44
|
React.createElement(Content.Content, null,
|
|
37
45
|
React.createElement(Content.Content, null,
|
|
38
46
|
React.createElement("div", { className: titleBarClasses, ref: titleBarRef },
|
|
@@ -46,20 +54,144 @@ function Page({ title, titleMetaData, intro, externalIntroLinks, subtitle, child
|
|
|
46
54
|
React.createElement(Markdown.Markdown, { content: subtitle, basicUsage: true })))))),
|
|
47
55
|
showActionGroup && (React.createElement("div", { className: styles.actionGroup },
|
|
48
56
|
primaryAction && (React.createElement("div", { className: styles.primaryAction, ref: primaryAction.ref },
|
|
49
|
-
React.createElement(Button.Button, Object.assign({}, getActionProps(primaryAction))))),
|
|
57
|
+
React.createElement(Button.Button, Object.assign({}, getActionProps(primaryAction), { fullWidth: true })))),
|
|
50
58
|
secondaryAction && (React.createElement("div", { className: styles.actionButton, ref: secondaryAction.ref },
|
|
51
|
-
React.createElement(Button.Button, Object.assign({}, getActionProps(secondaryAction))))),
|
|
59
|
+
React.createElement(Button.Button, Object.assign({}, getActionProps(secondaryAction), { fullWidth: true, type: "secondary" })))),
|
|
52
60
|
showMenu && (React.createElement("div", { className: styles.actionButton },
|
|
53
61
|
React.createElement(Menu.Menu, { items: moreActionsMenu })))))),
|
|
54
62
|
intro && (React.createElement(Text.Text, { size: "large" },
|
|
55
63
|
React.createElement(Markdown.Markdown, { content: intro, basicUsage: true, externalLink: externalIntroLinks })))),
|
|
56
64
|
React.createElement(Content.Content, null, children))));
|
|
57
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Groups the title area and actions into the page header layout.
|
|
68
|
+
* Place non-action content (title, subtitle) inside `Page.HeaderContent`
|
|
69
|
+
* and actions inside `Page.Actions`.
|
|
70
|
+
*/
|
|
71
|
+
function PageHeader(_a) {
|
|
72
|
+
var { children } = _a, rest = tslib_es6.__rest(_a, ["children"]);
|
|
73
|
+
const dataAttrs = filterDataAttributes.filterDataAttributes(rest);
|
|
74
|
+
const [titleBarRef, { width: titleBarWidth = jobberHooks.Breakpoints.large }] = jobberHooks.useResizeObserver();
|
|
75
|
+
const titleBarClasses = classnames(styles.titleBar, {
|
|
76
|
+
[styles.small]: titleBarWidth > jobberHooks.Breakpoints.smaller,
|
|
77
|
+
[styles.medium]: titleBarWidth > jobberHooks.Breakpoints.small,
|
|
78
|
+
[styles.large]: titleBarWidth > jobberHooks.Breakpoints.base,
|
|
79
|
+
});
|
|
80
|
+
return (React.createElement("div", Object.assign({ className: titleBarClasses, ref: titleBarRef }, dataAttrs), children));
|
|
81
|
+
}
|
|
82
|
+
/** Wraps the title area (title, subtitle) inside `Page.Header`. Use when the header contains more than one content element to keep them stacked vertically. */
|
|
83
|
+
function PageHeaderContent(_a) {
|
|
84
|
+
var { children } = _a, rest = tslib_es6.__rest(_a, ["children"]);
|
|
85
|
+
const dataAttrs = filterDataAttributes.filterDataAttributes(rest);
|
|
86
|
+
return React.createElement("div", Object.assign({}, dataAttrs), children);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Flex container for the page title and optional sibling elements such as
|
|
90
|
+
* status badges. Use when you need to display metadata alongside the heading.
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* ```tsx
|
|
94
|
+
* <Page.TitleBar>
|
|
95
|
+
* <Page.Title>Clients</Page.Title>
|
|
96
|
+
* <StatusLabel label="Active" status="success" />
|
|
97
|
+
* </Page.TitleBar>
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
function PageTitleBar(_a) {
|
|
101
|
+
var { children } = _a, rest = tslib_es6.__rest(_a, ["children"]);
|
|
102
|
+
const dataAttrs = filterDataAttributes.filterDataAttributes(rest);
|
|
103
|
+
return (React.createElement("div", Object.assign({ className: styles.titleRow }, dataAttrs), children));
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Renders the page heading as an H1. When metadata is present alongside the
|
|
107
|
+
* title, wrap both in `Page.TitleBar`.
|
|
108
|
+
*/
|
|
109
|
+
function PageTitle(_a) {
|
|
110
|
+
var { children } = _a, rest = tslib_es6.__rest(_a, ["children"]);
|
|
111
|
+
const dataAttrs = filterDataAttributes.filterDataAttributes(rest);
|
|
112
|
+
return (React.createElement(Heading.Heading, Object.assign({ level: 1 }, dataAttrs), children));
|
|
113
|
+
}
|
|
114
|
+
/** Secondary text below the title. Always applies default Text/Emphasis styling. */
|
|
115
|
+
function PageSubtitle(_a) {
|
|
116
|
+
var { children } = _a, rest = tslib_es6.__rest(_a, ["children"]);
|
|
117
|
+
const dataAttrs = filterDataAttributes.filterDataAttributes(rest);
|
|
118
|
+
return (React.createElement("div", Object.assign({ className: styles.subtitle }, dataAttrs),
|
|
119
|
+
React.createElement(Text.Text, { size: "large", variation: "subdued" },
|
|
120
|
+
React.createElement(Emphasis.Emphasis, { variation: "bold" }, children))));
|
|
121
|
+
}
|
|
122
|
+
/** Introduction text between the header and body. Always applies default Text styling. */
|
|
123
|
+
function PageIntro({ children }) {
|
|
124
|
+
return React.createElement(Text.Text, { size: "large" }, children);
|
|
125
|
+
}
|
|
126
|
+
/** Container for action buttons and menu. Applies responsive actionGroup layout. */
|
|
127
|
+
function PageActions(_a) {
|
|
128
|
+
var { children } = _a, rest = tslib_es6.__rest(_a, ["children"]);
|
|
129
|
+
const dataAttrs = filterDataAttributes.filterDataAttributes(rest);
|
|
130
|
+
return (React.createElement("div", Object.assign({ className: styles.actionGroup }, dataAttrs), children));
|
|
131
|
+
}
|
|
132
|
+
/** Positional container for the primary action. Should contain a Button element, e.g. <Page.PrimaryButton>. */
|
|
133
|
+
function PageActionPrimary({ children, ref }) {
|
|
134
|
+
return (React.createElement("div", { className: styles.primaryAction, ref: ref }, children));
|
|
135
|
+
}
|
|
136
|
+
/** Positional container for the secondary action. Should contain a Button element, e.g. <Page.SecondaryButton>. */
|
|
137
|
+
function PageActionSecondary({ children, ref }) {
|
|
138
|
+
return (React.createElement("div", { className: styles.actionButton, ref: ref }, children));
|
|
139
|
+
}
|
|
140
|
+
/** Positional container for the menu action. Should contain Page.Menu or a custom Menu. */
|
|
141
|
+
function PageActionMenu({ children, ref }) {
|
|
142
|
+
return (React.createElement("div", { className: styles.actionButton, ref: ref }, children));
|
|
143
|
+
}
|
|
144
|
+
/** Default primary Button with opinionated styling. Use inside Page.ActionPrimary. */
|
|
145
|
+
function PagePrimaryButton(_a) {
|
|
146
|
+
var { ref, label, onClick, icon, disabled, loading, ariaLabel } = _a, rest = tslib_es6.__rest(_a, ["ref", "label", "onClick", "icon", "disabled", "loading", "ariaLabel"]);
|
|
147
|
+
const dataAttrs = filterDataAttributes.filterDataAttributes(rest);
|
|
148
|
+
return (React.createElement("div", Object.assign({ ref: ref }, dataAttrs),
|
|
149
|
+
React.createElement(Button.Button, { label: label, onClick: onClick, icon: icon, disabled: disabled, loading: loading, ariaLabel: ariaLabel, fullWidth: true })));
|
|
150
|
+
}
|
|
151
|
+
/** Default secondary Button with opinionated styling. Use inside Page.ActionSecondary. */
|
|
152
|
+
function PageSecondaryButton(_a) {
|
|
153
|
+
var { ref, label, onClick, icon, disabled, loading, ariaLabel } = _a, rest = tslib_es6.__rest(_a, ["ref", "label", "onClick", "icon", "disabled", "loading", "ariaLabel"]);
|
|
154
|
+
const dataAttrs = filterDataAttributes.filterDataAttributes(rest);
|
|
155
|
+
return (React.createElement("div", Object.assign({ ref: ref }, dataAttrs),
|
|
156
|
+
React.createElement(Button.Button, { label: label, onClick: onClick, icon: icon, disabled: disabled, loading: loading, ariaLabel: ariaLabel, fullWidth: true, type: "secondary" })));
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* "More Actions" menu with a default trigger button.
|
|
160
|
+
* Consumers supply Menu.Item children (in case custom routing is needed,
|
|
161
|
+
* e.g. wrapping Menu.Item with createLink() from TanStack Router).
|
|
162
|
+
*/
|
|
163
|
+
function PageMenu(_a) {
|
|
164
|
+
var { children, triggerLabel = "More Actions" } = _a, rest = tslib_es6.__rest(_a, ["children", "triggerLabel"]);
|
|
165
|
+
const dataAttrs = filterDataAttributes.filterDataAttributes(rest);
|
|
166
|
+
return (React.createElement("div", Object.assign({}, dataAttrs),
|
|
167
|
+
React.createElement(Menu.Menu, null,
|
|
168
|
+
React.createElement(Menu.Menu.Trigger, { UNSAFE_style: { display: "block" } },
|
|
169
|
+
React.createElement(Button.Button, { icon: "more", label: triggerLabel, type: "secondary", fullWidth: true })),
|
|
170
|
+
React.createElement(Menu.Menu.Content, null, children))));
|
|
171
|
+
}
|
|
172
|
+
/** Main content area of the page. */
|
|
173
|
+
function PageBody({ children }) {
|
|
174
|
+
return React.createElement(Content.Content, null, children);
|
|
175
|
+
}
|
|
58
176
|
const getActionProps = (actionProps) => {
|
|
59
|
-
const buttonProps =
|
|
60
|
-
if (actionProps.ref)
|
|
177
|
+
const buttonProps = (actionProps !== null && actionProps !== void 0 ? actionProps : {});
|
|
178
|
+
if (actionProps === null || actionProps === void 0 ? void 0 : actionProps.ref)
|
|
61
179
|
delete buttonProps.ref;
|
|
62
180
|
return buttonProps;
|
|
63
181
|
};
|
|
182
|
+
Page.Header = PageHeader;
|
|
183
|
+
Page.HeaderContent = PageHeaderContent;
|
|
184
|
+
Page.TitleBar = PageTitleBar;
|
|
185
|
+
Page.Title = PageTitle;
|
|
186
|
+
Page.Subtitle = PageSubtitle;
|
|
187
|
+
Page.Intro = PageIntro;
|
|
188
|
+
Page.Actions = PageActions;
|
|
189
|
+
Page.ActionPrimary = PageActionPrimary;
|
|
190
|
+
Page.ActionSecondary = PageActionSecondary;
|
|
191
|
+
Page.ActionMenu = PageActionMenu;
|
|
192
|
+
Page.PrimaryButton = PagePrimaryButton;
|
|
193
|
+
Page.SecondaryButton = PageSecondaryButton;
|
|
194
|
+
Page.Menu = PageMenu;
|
|
195
|
+
Page.Body = PageBody;
|
|
64
196
|
|
|
65
197
|
exports.Page = Page;
|
package/dist/Page-es.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { _ as __rest } from './tslib.es6-es.js';
|
|
1
2
|
import React__default from 'react';
|
|
2
3
|
import classnames from 'classnames';
|
|
3
4
|
import { useResizeObserver, Breakpoints } from '@jobber/hooks';
|
|
@@ -8,11 +9,27 @@ import { M as Markdown } from './Markdown-es.js';
|
|
|
8
9
|
import { B as Button } from './Button-es.js';
|
|
9
10
|
import { M as Menu } from './Menu-es.js';
|
|
10
11
|
import { E as Emphasis } from './Emphasis-es.js';
|
|
12
|
+
import { f as filterDataAttributes } from './filterDataAttributes-es.js';
|
|
11
13
|
|
|
12
14
|
var styles = {"page":"BLYnKItuM3c-","fill":"n5WRRhMkoLs-","standard":"WziKEWW9nA8-","narrow":"qgGzgDyS2NY-","titleBar":"lbmoDvdtQO4-","titleRow":"k9y5NuqTcks-","actionGroup":"_7t53-bnzh98-","large":"SH0aNOLVhE8-","medium":"Lc7Z0FsBa6w-","small":"iF5IA1SYKoA-","primaryAction":"g-H7CKkX-LA-","actionButton":"RSP7jHjP-mw-","subtitle":"EqsNMrZVL-8-","spinning":"MJZVhEmx6h4-"};
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
+
/** Discriminates between the props-based API and the composable children API. */
|
|
17
|
+
function isLegacy(props) {
|
|
18
|
+
return "title" in props;
|
|
19
|
+
}
|
|
20
|
+
function Page(props) {
|
|
21
|
+
var _a;
|
|
22
|
+
const pageStyles = classnames(styles.page, styles[(_a = props.width) !== null && _a !== void 0 ? _a : "standard"]);
|
|
23
|
+
if (isLegacy(props)) {
|
|
24
|
+
return React__default.createElement(PageLegacy, Object.assign({}, props, { pageStyles: pageStyles }));
|
|
25
|
+
}
|
|
26
|
+
return (React__default.createElement("div", { className: pageStyles },
|
|
27
|
+
React__default.createElement(Content, null, props.children)));
|
|
28
|
+
}
|
|
29
|
+
/** Props-based renderer. Preserves the original Page behavior for existing consumers. */
|
|
30
|
+
function PageLegacy(_a) {
|
|
31
|
+
var { title, titleMetaData, intro, externalIntroLinks, subtitle, children, primaryAction, secondaryAction, moreActionsMenu = [], pageStyles } = _a, rest = __rest(_a, ["title", "titleMetaData", "intro", "externalIntroLinks", "subtitle", "children", "primaryAction", "secondaryAction", "moreActionsMenu", "pageStyles"]);
|
|
32
|
+
const dataAttrs = filterDataAttributes(rest);
|
|
16
33
|
const [titleBarRef, { width: titleBarWidth = Breakpoints.large }] = useResizeObserver();
|
|
17
34
|
const titleBarClasses = classnames(styles.titleBar, {
|
|
18
35
|
[styles.small]: titleBarWidth > Breakpoints.smaller,
|
|
@@ -21,16 +38,7 @@ function Page({ title, titleMetaData, intro, externalIntroLinks, subtitle, child
|
|
|
21
38
|
});
|
|
22
39
|
const showMenu = moreActionsMenu.length > 0;
|
|
23
40
|
const showActionGroup = showMenu || primaryAction || secondaryAction;
|
|
24
|
-
|
|
25
|
-
primaryAction = Object.assign({ fullWidth: true }, primaryAction);
|
|
26
|
-
}
|
|
27
|
-
if (secondaryAction != undefined) {
|
|
28
|
-
secondaryAction = Object.assign({ type: "secondary", fullWidth: true }, secondaryAction);
|
|
29
|
-
}
|
|
30
|
-
if (secondaryAction != undefined) {
|
|
31
|
-
secondaryAction = Object.assign({ type: "secondary", fullWidth: true }, secondaryAction);
|
|
32
|
-
}
|
|
33
|
-
return (React__default.createElement("div", { className: pageStyles },
|
|
41
|
+
return (React__default.createElement("div", Object.assign({ className: pageStyles }, dataAttrs),
|
|
34
42
|
React__default.createElement(Content, null,
|
|
35
43
|
React__default.createElement(Content, null,
|
|
36
44
|
React__default.createElement("div", { className: titleBarClasses, ref: titleBarRef },
|
|
@@ -44,20 +52,144 @@ function Page({ title, titleMetaData, intro, externalIntroLinks, subtitle, child
|
|
|
44
52
|
React__default.createElement(Markdown, { content: subtitle, basicUsage: true })))))),
|
|
45
53
|
showActionGroup && (React__default.createElement("div", { className: styles.actionGroup },
|
|
46
54
|
primaryAction && (React__default.createElement("div", { className: styles.primaryAction, ref: primaryAction.ref },
|
|
47
|
-
React__default.createElement(Button, Object.assign({}, getActionProps(primaryAction))))),
|
|
55
|
+
React__default.createElement(Button, Object.assign({}, getActionProps(primaryAction), { fullWidth: true })))),
|
|
48
56
|
secondaryAction && (React__default.createElement("div", { className: styles.actionButton, ref: secondaryAction.ref },
|
|
49
|
-
React__default.createElement(Button, Object.assign({}, getActionProps(secondaryAction))))),
|
|
57
|
+
React__default.createElement(Button, Object.assign({}, getActionProps(secondaryAction), { fullWidth: true, type: "secondary" })))),
|
|
50
58
|
showMenu && (React__default.createElement("div", { className: styles.actionButton },
|
|
51
59
|
React__default.createElement(Menu, { items: moreActionsMenu })))))),
|
|
52
60
|
intro && (React__default.createElement(Text, { size: "large" },
|
|
53
61
|
React__default.createElement(Markdown, { content: intro, basicUsage: true, externalLink: externalIntroLinks })))),
|
|
54
62
|
React__default.createElement(Content, null, children))));
|
|
55
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* Groups the title area and actions into the page header layout.
|
|
66
|
+
* Place non-action content (title, subtitle) inside `Page.HeaderContent`
|
|
67
|
+
* and actions inside `Page.Actions`.
|
|
68
|
+
*/
|
|
69
|
+
function PageHeader(_a) {
|
|
70
|
+
var { children } = _a, rest = __rest(_a, ["children"]);
|
|
71
|
+
const dataAttrs = filterDataAttributes(rest);
|
|
72
|
+
const [titleBarRef, { width: titleBarWidth = Breakpoints.large }] = useResizeObserver();
|
|
73
|
+
const titleBarClasses = classnames(styles.titleBar, {
|
|
74
|
+
[styles.small]: titleBarWidth > Breakpoints.smaller,
|
|
75
|
+
[styles.medium]: titleBarWidth > Breakpoints.small,
|
|
76
|
+
[styles.large]: titleBarWidth > Breakpoints.base,
|
|
77
|
+
});
|
|
78
|
+
return (React__default.createElement("div", Object.assign({ className: titleBarClasses, ref: titleBarRef }, dataAttrs), children));
|
|
79
|
+
}
|
|
80
|
+
/** Wraps the title area (title, subtitle) inside `Page.Header`. Use when the header contains more than one content element to keep them stacked vertically. */
|
|
81
|
+
function PageHeaderContent(_a) {
|
|
82
|
+
var { children } = _a, rest = __rest(_a, ["children"]);
|
|
83
|
+
const dataAttrs = filterDataAttributes(rest);
|
|
84
|
+
return React__default.createElement("div", Object.assign({}, dataAttrs), children);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Flex container for the page title and optional sibling elements such as
|
|
88
|
+
* status badges. Use when you need to display metadata alongside the heading.
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```tsx
|
|
92
|
+
* <Page.TitleBar>
|
|
93
|
+
* <Page.Title>Clients</Page.Title>
|
|
94
|
+
* <StatusLabel label="Active" status="success" />
|
|
95
|
+
* </Page.TitleBar>
|
|
96
|
+
* ```
|
|
97
|
+
*/
|
|
98
|
+
function PageTitleBar(_a) {
|
|
99
|
+
var { children } = _a, rest = __rest(_a, ["children"]);
|
|
100
|
+
const dataAttrs = filterDataAttributes(rest);
|
|
101
|
+
return (React__default.createElement("div", Object.assign({ className: styles.titleRow }, dataAttrs), children));
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Renders the page heading as an H1. When metadata is present alongside the
|
|
105
|
+
* title, wrap both in `Page.TitleBar`.
|
|
106
|
+
*/
|
|
107
|
+
function PageTitle(_a) {
|
|
108
|
+
var { children } = _a, rest = __rest(_a, ["children"]);
|
|
109
|
+
const dataAttrs = filterDataAttributes(rest);
|
|
110
|
+
return (React__default.createElement(Heading, Object.assign({ level: 1 }, dataAttrs), children));
|
|
111
|
+
}
|
|
112
|
+
/** Secondary text below the title. Always applies default Text/Emphasis styling. */
|
|
113
|
+
function PageSubtitle(_a) {
|
|
114
|
+
var { children } = _a, rest = __rest(_a, ["children"]);
|
|
115
|
+
const dataAttrs = filterDataAttributes(rest);
|
|
116
|
+
return (React__default.createElement("div", Object.assign({ className: styles.subtitle }, dataAttrs),
|
|
117
|
+
React__default.createElement(Text, { size: "large", variation: "subdued" },
|
|
118
|
+
React__default.createElement(Emphasis, { variation: "bold" }, children))));
|
|
119
|
+
}
|
|
120
|
+
/** Introduction text between the header and body. Always applies default Text styling. */
|
|
121
|
+
function PageIntro({ children }) {
|
|
122
|
+
return React__default.createElement(Text, { size: "large" }, children);
|
|
123
|
+
}
|
|
124
|
+
/** Container for action buttons and menu. Applies responsive actionGroup layout. */
|
|
125
|
+
function PageActions(_a) {
|
|
126
|
+
var { children } = _a, rest = __rest(_a, ["children"]);
|
|
127
|
+
const dataAttrs = filterDataAttributes(rest);
|
|
128
|
+
return (React__default.createElement("div", Object.assign({ className: styles.actionGroup }, dataAttrs), children));
|
|
129
|
+
}
|
|
130
|
+
/** Positional container for the primary action. Should contain a Button element, e.g. <Page.PrimaryButton>. */
|
|
131
|
+
function PageActionPrimary({ children, ref }) {
|
|
132
|
+
return (React__default.createElement("div", { className: styles.primaryAction, ref: ref }, children));
|
|
133
|
+
}
|
|
134
|
+
/** Positional container for the secondary action. Should contain a Button element, e.g. <Page.SecondaryButton>. */
|
|
135
|
+
function PageActionSecondary({ children, ref }) {
|
|
136
|
+
return (React__default.createElement("div", { className: styles.actionButton, ref: ref }, children));
|
|
137
|
+
}
|
|
138
|
+
/** Positional container for the menu action. Should contain Page.Menu or a custom Menu. */
|
|
139
|
+
function PageActionMenu({ children, ref }) {
|
|
140
|
+
return (React__default.createElement("div", { className: styles.actionButton, ref: ref }, children));
|
|
141
|
+
}
|
|
142
|
+
/** Default primary Button with opinionated styling. Use inside Page.ActionPrimary. */
|
|
143
|
+
function PagePrimaryButton(_a) {
|
|
144
|
+
var { ref, label, onClick, icon, disabled, loading, ariaLabel } = _a, rest = __rest(_a, ["ref", "label", "onClick", "icon", "disabled", "loading", "ariaLabel"]);
|
|
145
|
+
const dataAttrs = filterDataAttributes(rest);
|
|
146
|
+
return (React__default.createElement("div", Object.assign({ ref: ref }, dataAttrs),
|
|
147
|
+
React__default.createElement(Button, { label: label, onClick: onClick, icon: icon, disabled: disabled, loading: loading, ariaLabel: ariaLabel, fullWidth: true })));
|
|
148
|
+
}
|
|
149
|
+
/** Default secondary Button with opinionated styling. Use inside Page.ActionSecondary. */
|
|
150
|
+
function PageSecondaryButton(_a) {
|
|
151
|
+
var { ref, label, onClick, icon, disabled, loading, ariaLabel } = _a, rest = __rest(_a, ["ref", "label", "onClick", "icon", "disabled", "loading", "ariaLabel"]);
|
|
152
|
+
const dataAttrs = filterDataAttributes(rest);
|
|
153
|
+
return (React__default.createElement("div", Object.assign({ ref: ref }, dataAttrs),
|
|
154
|
+
React__default.createElement(Button, { label: label, onClick: onClick, icon: icon, disabled: disabled, loading: loading, ariaLabel: ariaLabel, fullWidth: true, type: "secondary" })));
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* "More Actions" menu with a default trigger button.
|
|
158
|
+
* Consumers supply Menu.Item children (in case custom routing is needed,
|
|
159
|
+
* e.g. wrapping Menu.Item with createLink() from TanStack Router).
|
|
160
|
+
*/
|
|
161
|
+
function PageMenu(_a) {
|
|
162
|
+
var { children, triggerLabel = "More Actions" } = _a, rest = __rest(_a, ["children", "triggerLabel"]);
|
|
163
|
+
const dataAttrs = filterDataAttributes(rest);
|
|
164
|
+
return (React__default.createElement("div", Object.assign({}, dataAttrs),
|
|
165
|
+
React__default.createElement(Menu, null,
|
|
166
|
+
React__default.createElement(Menu.Trigger, { UNSAFE_style: { display: "block" } },
|
|
167
|
+
React__default.createElement(Button, { icon: "more", label: triggerLabel, type: "secondary", fullWidth: true })),
|
|
168
|
+
React__default.createElement(Menu.Content, null, children))));
|
|
169
|
+
}
|
|
170
|
+
/** Main content area of the page. */
|
|
171
|
+
function PageBody({ children }) {
|
|
172
|
+
return React__default.createElement(Content, null, children);
|
|
173
|
+
}
|
|
56
174
|
const getActionProps = (actionProps) => {
|
|
57
|
-
const buttonProps =
|
|
58
|
-
if (actionProps.ref)
|
|
175
|
+
const buttonProps = (actionProps !== null && actionProps !== void 0 ? actionProps : {});
|
|
176
|
+
if (actionProps === null || actionProps === void 0 ? void 0 : actionProps.ref)
|
|
59
177
|
delete buttonProps.ref;
|
|
60
178
|
return buttonProps;
|
|
61
179
|
};
|
|
180
|
+
Page.Header = PageHeader;
|
|
181
|
+
Page.HeaderContent = PageHeaderContent;
|
|
182
|
+
Page.TitleBar = PageTitleBar;
|
|
183
|
+
Page.Title = PageTitle;
|
|
184
|
+
Page.Subtitle = PageSubtitle;
|
|
185
|
+
Page.Intro = PageIntro;
|
|
186
|
+
Page.Actions = PageActions;
|
|
187
|
+
Page.ActionPrimary = PageActionPrimary;
|
|
188
|
+
Page.ActionSecondary = PageActionSecondary;
|
|
189
|
+
Page.ActionMenu = PageActionMenu;
|
|
190
|
+
Page.PrimaryButton = PagePrimaryButton;
|
|
191
|
+
Page.SecondaryButton = PageSecondaryButton;
|
|
192
|
+
Page.Menu = PageMenu;
|
|
193
|
+
Page.Body = PageBody;
|
|
62
194
|
|
|
63
195
|
export { Page as P };
|
package/dist/styles.css
CHANGED
|
@@ -7383,9 +7383,12 @@ h2.react-datepicker__current-month {
|
|
|
7383
7383
|
width: 100%;
|
|
7384
7384
|
max-width: 100%;
|
|
7385
7385
|
}
|
|
7386
|
-
.
|
|
7387
|
-
|
|
7388
|
-
|
|
7386
|
+
.LDxKi0E-1rg- {
|
|
7387
|
+
position: fixed;
|
|
7388
|
+
top: 0;
|
|
7389
|
+
left: 0;
|
|
7390
|
+
z-index: 1001;
|
|
7391
|
+
z-index: var(--elevation-modal);
|
|
7389
7392
|
}
|
|
7390
7393
|
.Ma55F5Y-XhE- .react-datepicker__header {
|
|
7391
7394
|
padding: 0;
|
|
@@ -158,6 +158,20 @@
|
|
|
158
158
|
"MultiSelect",
|
|
159
159
|
"Option",
|
|
160
160
|
"Page",
|
|
161
|
+
"Page.ActionMenu",
|
|
162
|
+
"Page.ActionPrimary",
|
|
163
|
+
"Page.ActionSecondary",
|
|
164
|
+
"Page.Actions",
|
|
165
|
+
"Page.Body",
|
|
166
|
+
"Page.Header",
|
|
167
|
+
"Page.HeaderContent",
|
|
168
|
+
"Page.Intro",
|
|
169
|
+
"Page.Menu",
|
|
170
|
+
"Page.PrimaryButton",
|
|
171
|
+
"Page.SecondaryButton",
|
|
172
|
+
"Page.Subtitle",
|
|
173
|
+
"Page.Title",
|
|
174
|
+
"Page.TitleBar",
|
|
161
175
|
"Popover",
|
|
162
176
|
"Popover.Arrow",
|
|
163
177
|
"Popover.DismissButton",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jobber/components",
|
|
3
|
-
"version": "6.112.
|
|
3
|
+
"version": "6.112.2",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -538,5 +538,5 @@
|
|
|
538
538
|
"> 1%",
|
|
539
539
|
"IE 10"
|
|
540
540
|
],
|
|
541
|
-
"gitHead": "
|
|
541
|
+
"gitHead": "5c6d2a8ba2313768db2fd1147c74de0b4e8c3710"
|
|
542
542
|
}
|