@mezzanine-ui/react 1.0.0-beta.4 → 1.0.0-beta.5
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/AutoComplete/AutoComplete.js +17 -1
- package/Calendar/Calendar.js +2 -6
- package/Calendar/CalendarCell.d.ts +22 -0
- package/Calendar/CalendarCell.js +6 -2
- package/Calendar/CalendarControls.js +1 -1
- package/Calendar/CalendarDayOfWeek.js +3 -2
- package/Calendar/CalendarDays.js +5 -1
- package/Calendar/CalendarHalfYears.js +13 -7
- package/Calendar/CalendarMonths.js +13 -6
- package/Calendar/CalendarQuarters.js +13 -7
- package/Calendar/CalendarWeeks.js +87 -34
- package/Calendar/CalendarYears.js +13 -12
- package/Calendar/useCalendarControlModifiers.d.ts +1 -1
- package/Calendar/useCalendarControlModifiers.js +12 -12
- package/Calendar/useCalendarControls.d.ts +4 -4
- package/Calendar/useCalendarControls.js +33 -19
- package/Calendar/useRangeCalendarControls.d.ts +8 -8
- package/Calendar/useRangeCalendarControls.js +42 -31
- package/DateRangePicker/useDateRangeCalendarControls.js +8 -2
- package/Dropdown/Dropdown.d.ts +31 -0
- package/Dropdown/Dropdown.js +11 -1
- package/Dropdown/DropdownItem.d.ts +32 -0
- package/Dropdown/DropdownItem.js +112 -10
- package/Dropdown/DropdownItemCard.d.ts +5 -0
- package/Dropdown/DropdownItemCard.js +2 -2
- package/Form/useSelectValueControl.d.ts +3 -4
- package/Form/useSelectValueControl.js +51 -39
- package/Popper/Popper.js +2 -1
- package/Scrollbar/Scrollbar.js +1 -0
- package/Select/Select.d.ts +37 -18
- package/Select/Select.js +165 -51
- package/Select/index.d.ts +8 -9
- package/Select/index.js +3 -3
- package/package.json +4 -4
|
@@ -203,17 +203,33 @@ const AutoComplete = forwardRef(function AutoComplete(props, ref) {
|
|
|
203
203
|
// Don't let Dropdown's onBlur close the dropdown when controlled
|
|
204
204
|
// Only call onFocus(false) to update internal state
|
|
205
205
|
onFocus(false);
|
|
206
|
+
// Clear search text and insert text when blur if keepSearchTextOnBlur is false
|
|
207
|
+
if (!keepSearchTextOnBlur) {
|
|
208
|
+
resetCreationInputs();
|
|
209
|
+
}
|
|
206
210
|
(_a = inputProps === null || inputProps === void 0 ? void 0 : inputProps.onBlur) === null || _a === void 0 ? void 0 : _a.call(inputProps, e);
|
|
207
211
|
return;
|
|
208
212
|
}
|
|
209
213
|
// For uncontrolled mode, let Dropdown handle it normally
|
|
210
214
|
// Dropdown's inlineTriggerElement will handle the blur and close logic
|
|
215
|
+
// Clear search text and insert text when blur if keepSearchTextOnBlur is false
|
|
216
|
+
if (!keepSearchTextOnBlur) {
|
|
217
|
+
resetCreationInputs();
|
|
218
|
+
}
|
|
211
219
|
(_b = inputProps === null || inputProps === void 0 ? void 0 : inputProps.onBlur) === null || _b === void 0 ? void 0 : _b.call(inputProps, e);
|
|
212
220
|
return;
|
|
213
221
|
}
|
|
214
222
|
onFocus(false);
|
|
223
|
+
// Clear search text and insert text when blur if keepSearchTextOnBlur is false
|
|
224
|
+
if (!keepSearchTextOnBlur) {
|
|
225
|
+
resetCreationInputs();
|
|
226
|
+
}
|
|
215
227
|
(_c = inputProps === null || inputProps === void 0 ? void 0 : inputProps.onBlur) === null || _c === void 0 ? void 0 : _c.call(inputProps, e);
|
|
216
228
|
};
|
|
229
|
+
const handleClear = useCallback((e) => {
|
|
230
|
+
onClear(e);
|
|
231
|
+
resetCreationInputs();
|
|
232
|
+
}, [onClear, resetCreationInputs]);
|
|
217
233
|
const onClickSuffixActionIcon = () => {
|
|
218
234
|
toggleOpen((prev) => !prev);
|
|
219
235
|
};
|
|
@@ -414,7 +430,7 @@ const AutoComplete = forwardRef(function AutoComplete(props, ref) {
|
|
|
414
430
|
: createActionTextTemplate.replace('{text}', insertText))
|
|
415
431
|
: undefined, activeIndex: activeIndex, disabled: isInputDisabled, emptyText: emptyText, followText: searchText, inputPosition: inputPosition, isMatchInputValue: true, listboxId: menuId, loadingText: loadingText, maxHeight: menuMaxHeight, mode: mode, onActionCustom: shouldShowCreateAction
|
|
416
432
|
? handleActionCustom
|
|
417
|
-
: undefined, onItemHover: setActiveIndex, onSelect: handleDropdownSelect, onVisibilityChange: handleVisibilityChange, open: open, options: dropdownOptionsForRender, placement: "bottom", sameWidth: true, showDropdownActions: shouldShowCreateAction, showActionShowTopBar: shouldShowCreateAction, status: dropdownStatus, type: "default", value: dropdownValue, zIndex: dropdownZIndex, onReachBottom: onReachBottom, onLeaveBottom: onLeaveBottom, children: jsx(SelectTrigger, { ref: composedRef, active: open, className: className, clearable: true, isForceClearable: true, disabled: isInputDisabled, fullWidth: fullWidth, inputRef: inputRef, mode: mode, onTagClose: wrappedOnChange, onClear:
|
|
433
|
+
: undefined, onItemHover: setActiveIndex, onSelect: handleDropdownSelect, onVisibilityChange: handleVisibilityChange, open: open, options: dropdownOptionsForRender, placement: "bottom", sameWidth: true, showDropdownActions: shouldShowCreateAction, showActionShowTopBar: shouldShowCreateAction, status: dropdownStatus, type: "default", value: dropdownValue, zIndex: dropdownZIndex, onReachBottom: onReachBottom, onLeaveBottom: onLeaveBottom, children: jsx(SelectTrigger, { ref: composedRef, active: open, className: className, clearable: true, isForceClearable: true, disabled: isInputDisabled, fullWidth: fullWidth, inputRef: inputRef, mode: mode, onTagClose: wrappedOnChange, onClear: handleClear, placeholder: getPlaceholder(), prefix: prefix, readOnly: false, required: required, type: error ? 'error' : 'default', inputProps: {
|
|
418
434
|
...resolvedInputProps,
|
|
419
435
|
onClick: (e) => {
|
|
420
436
|
var _a;
|
package/Calendar/Calendar.js
CHANGED
|
@@ -93,9 +93,7 @@ const Calendar = forwardRef(function Calendar(props, ref) {
|
|
|
93
93
|
? () => {
|
|
94
94
|
onDoubleNext(mode);
|
|
95
95
|
}
|
|
96
|
-
: undefined, onNext:
|
|
97
|
-
// Only day and week modes have single next/prev (for month navigation)
|
|
98
|
-
onNext && (mode === 'day' || mode === 'week')
|
|
96
|
+
: undefined, onNext: onNext
|
|
99
97
|
? () => {
|
|
100
98
|
onNext(mode);
|
|
101
99
|
}
|
|
@@ -103,9 +101,7 @@ const Calendar = forwardRef(function Calendar(props, ref) {
|
|
|
103
101
|
? () => {
|
|
104
102
|
onDoublePrev(mode);
|
|
105
103
|
}
|
|
106
|
-
: undefined, onPrev:
|
|
107
|
-
// Only day and week modes have single next/prev (for month navigation)
|
|
108
|
-
onPrev && (mode === 'day' || mode === 'week')
|
|
104
|
+
: undefined, onPrev: onPrev
|
|
109
105
|
? () => {
|
|
110
106
|
onPrev(mode);
|
|
111
107
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CalendarMode } from '@mezzanine-ui/core/calendar';
|
|
1
2
|
import { NativeElementPropsWithoutKeyAndRef } from '../utils/jsx-types';
|
|
2
3
|
export interface CalendarCellProps extends NativeElementPropsWithoutKeyAndRef<'div'> {
|
|
3
4
|
/**
|
|
@@ -8,6 +9,11 @@ export interface CalendarCellProps extends NativeElementPropsWithoutKeyAndRef<'d
|
|
|
8
9
|
* Apply disabled styles if true.
|
|
9
10
|
*/
|
|
10
11
|
disabled?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Calendar mode for applying mode specific styles.
|
|
14
|
+
* @default 'day'
|
|
15
|
+
*/
|
|
16
|
+
mode?: CalendarMode;
|
|
11
17
|
/**
|
|
12
18
|
* Apply today styles if true.
|
|
13
19
|
*/
|
|
@@ -16,6 +22,22 @@ export interface CalendarCellProps extends NativeElementPropsWithoutKeyAndRef<'d
|
|
|
16
22
|
* The role attribute for accessibility
|
|
17
23
|
*/
|
|
18
24
|
role?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Apply range start styles if true.
|
|
27
|
+
*/
|
|
28
|
+
isRangeStart?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Apply range end styles if true.
|
|
31
|
+
*/
|
|
32
|
+
isRangeEnd?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Apply weekend styles if true.
|
|
35
|
+
*/
|
|
36
|
+
isWeekend?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Apply annotation styles if true.
|
|
39
|
+
*/
|
|
40
|
+
withAnnotation?: boolean;
|
|
19
41
|
}
|
|
20
42
|
/**
|
|
21
43
|
* The react component for `mezzanine` calendar cell.
|
package/Calendar/CalendarCell.js
CHANGED
|
@@ -7,11 +7,15 @@ import cx from 'clsx';
|
|
|
7
7
|
* You may use it to compose your own calendar.
|
|
8
8
|
*/
|
|
9
9
|
function CalendarCell(props) {
|
|
10
|
-
const { active, children, className, disabled, today, role, ...restCalendarCellProps } = props;
|
|
11
|
-
return (jsx("div", { role: role, className: cx(calendarClasses.cell, {
|
|
10
|
+
const { active, children, className, disabled, mode = 'day', today, role, isRangeStart, isRangeEnd, isWeekend, withAnnotation, ...restCalendarCellProps } = props;
|
|
11
|
+
return (jsx("div", { role: role, className: cx(calendarClasses.cell, calendarClasses.cellMode(mode), {
|
|
12
12
|
[calendarClasses.cellToday]: today,
|
|
13
13
|
[calendarClasses.cellActive]: active,
|
|
14
14
|
[calendarClasses.cellDisabled]: disabled,
|
|
15
|
+
[calendarClasses.cellWithAnnotation]: withAnnotation,
|
|
16
|
+
[calendarClasses.cellWeekend]: isWeekend,
|
|
17
|
+
[calendarClasses.cellRangeStart]: isRangeStart,
|
|
18
|
+
[calendarClasses.cellRangeEnd]: isRangeEnd,
|
|
15
19
|
}, className), ...restCalendarCellProps, children: jsx("span", { className: calendarClasses.cellInner, children: children }) }));
|
|
16
20
|
}
|
|
17
21
|
|
|
@@ -10,7 +10,7 @@ import cx from 'clsx';
|
|
|
10
10
|
*/
|
|
11
11
|
function CalendarControls(props) {
|
|
12
12
|
const { children, className, disableOnNext, disableOnDoubleNext, disableOnPrev, disableOnDoublePrev, onPrev, onNext, onDoubleNext, onDoublePrev, ...restElementProps } = props;
|
|
13
|
-
return (jsxs("div", { ...restElementProps, className: cx(calendarClasses.controls, className), children: [jsxs("div", { className: cx(calendarClasses.controlsActions), children: [onDoublePrev
|
|
13
|
+
return (jsxs("div", { ...restElementProps, className: cx(calendarClasses.controls, className), children: [jsxs("div", { className: cx(calendarClasses.controlsActions), children: [onDoublePrev ? (jsx("button", { type: "button", "aria-disabled": disableOnDoublePrev, disabled: disableOnDoublePrev, onClick: onDoublePrev, "aria-label": "Go to previous year", title: "Previous Year", className: cx(calendarClasses.controlsButton), children: jsx(Icon, { icon: DoubleChevronLeftIcon, "aria-hidden": "true" }) })) : null, onPrev ? (jsx("button", { type: "button", "aria-disabled": disableOnPrev, disabled: disableOnPrev, onClick: onPrev, "aria-label": "Go to previous month", title: "Previous Month", className: cx(calendarClasses.controlsButton), children: jsx(Icon, { icon: ChevronLeftIcon, "aria-hidden": "true" }) })) : null, !onPrev && !onDoublePrev ? (jsx("div", { className: calendarClasses.controlsButton, style: { pointerEvents: 'none' } })) : null] }), jsx("div", { className: cx(calendarClasses.controlsMain), children: children }), jsxs("div", { className: cx(calendarClasses.controlsActions), children: [onNext ? (jsx("button", { type: "button", "aria-disabled": disableOnNext, disabled: disableOnNext, onClick: onNext, "aria-label": "Go to next month", title: "Next Month", className: cx(calendarClasses.controlsButton), children: jsx(Icon, { icon: ChevronRightIcon, "aria-hidden": "true" }) })) : null, onDoubleNext ? (jsx("button", { type: "button", "aria-disabled": disableOnDoubleNext, disabled: disableOnDoubleNext, onClick: onDoubleNext, "aria-label": "Go to next year", title: "Next Year", className: cx(calendarClasses.controlsButton), children: jsx(Icon, { icon: DoubleChevronRightIcon, "aria-hidden": "true" }) })) : null, !onNext && !onDoubleNext ? (jsx("div", { className: calendarClasses.controlsButton, style: { pointerEvents: 'none' } })) : null] })] }));
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
export { CalendarControls as default };
|
|
@@ -10,10 +10,11 @@ import cx from 'clsx';
|
|
|
10
10
|
* You may use it to compose your own calendar.
|
|
11
11
|
*/
|
|
12
12
|
function CalendarDayOfWeek(props) {
|
|
13
|
-
const { getWeekDayNames, locale } = useCalendarContext();
|
|
13
|
+
const { getWeekDayNames, getWeekends, locale } = useCalendarContext();
|
|
14
14
|
const { displayWeekDayLocale = locale, className, ...restRowProps } = props;
|
|
15
15
|
const weekDayNames = getWeekDayNames(displayWeekDayLocale);
|
|
16
|
-
|
|
16
|
+
const weekends = getWeekends(displayWeekDayLocale);
|
|
17
|
+
return (jsx("div", { className: cx(calendarClasses.row, className), role: "row", "aria-label": "Days of the week", ...restRowProps, children: weekDayNames.map((name, idx) => (jsx(CalendarCell, { role: "columnheader", isWeekend: weekends[idx], children: name }, `CALENDAR_DAY_OF_WEEK/${name}-${idx}`))) }));
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
export { CalendarDayOfWeek as default };
|
package/Calendar/CalendarDays.js
CHANGED
|
@@ -33,6 +33,10 @@ function CalendarDays(props) {
|
|
|
33
33
|
false;
|
|
34
34
|
const inactive = !disabled && (isPrevMonth || isNextMonth);
|
|
35
35
|
const inRange = !inactive && isDateInRange && isDateInRange(date);
|
|
36
|
+
const inRangeStart = inRange && value ? isSameDate(date, value[0]) : false;
|
|
37
|
+
const inRangeEnd = inRange && value
|
|
38
|
+
? isSameDate(date, value[value.length - 1])
|
|
39
|
+
: false;
|
|
36
40
|
const active = !disabled && !inactive && value && isDateIncluded(date, value);
|
|
37
41
|
const onMouseEnter = onDateHover
|
|
38
42
|
? () => {
|
|
@@ -62,7 +66,7 @@ function CalendarDays(props) {
|
|
|
62
66
|
]
|
|
63
67
|
.filter(Boolean)
|
|
64
68
|
.join(', ');
|
|
65
|
-
return (jsx(CalendarCell, { today: isSameDate(date, getNow()), active: active, disabled: isPrevMonth || isNextMonth, children: jsxs("button", { type: "button", "aria-disabled": disabled, disabled: disabled, "aria-label": ariaLabel, "aria-pressed": active, "aria-current": isToday ? 'date' : undefined, onMouseEnter: onMouseEnter, className: cx(calendarClasses.button, {
|
|
69
|
+
return (jsx(CalendarCell, { mode: "day", today: isSameDate(date, getNow()), active: active, disabled: isPrevMonth || isNextMonth, withAnnotation: Boolean(renderAnnotations), isRangeStart: inRangeStart, isRangeEnd: inRangeEnd, children: jsxs("button", { type: "button", "aria-disabled": disabled, disabled: disabled, "aria-label": ariaLabel, "aria-pressed": active, "aria-current": isToday ? 'date' : undefined, onMouseEnter: onMouseEnter, className: cx(calendarClasses.button, {
|
|
66
70
|
[calendarClasses.buttonInRange]: inRange,
|
|
67
71
|
[calendarClasses.buttonActive]: active,
|
|
68
72
|
[calendarClasses.buttonDisabled]: disabled,
|
|
@@ -12,7 +12,7 @@ import cx from 'clsx';
|
|
|
12
12
|
* You may use it to compose your own calendar.
|
|
13
13
|
*/
|
|
14
14
|
function CalendarHalfYears(props) {
|
|
15
|
-
const { getYear, getCurrentHalfYearFirstDate, isHalfYearIncluded, setYear, setMonth, } = useCalendarContext();
|
|
15
|
+
const { getNow, getYear, getCurrentHalfYearFirstDate, isHalfYearIncluded, setYear, setMonth, } = useCalendarContext();
|
|
16
16
|
const { className, isHalfYearDisabled, isHalfYearInRange, onClick: onClickProp, onHalfYearHover, referenceDate, value, ...rest } = props;
|
|
17
17
|
const currentYear = getYear(referenceDate);
|
|
18
18
|
const [start] = useMemo(() => getYearRange(currentYear, calendarHalfYearYearsCount), [currentYear]);
|
|
@@ -22,7 +22,7 @@ function CalendarHalfYears(props) {
|
|
|
22
22
|
return (jsx("div", { className: cx(calendarClasses.board, className), ...rest, children: years.map((year, yearIndex) => {
|
|
23
23
|
return (jsxs("div", { className: cx(calendarClasses.row, {
|
|
24
24
|
[calendarClasses.rowWithBorder]: yearIndex > 0,
|
|
25
|
-
}), children: [jsx(CalendarCell, { disabled: true, children: year }), calendarHalfYears.map((halfYear) => {
|
|
25
|
+
}), children: [jsx(CalendarCell, { disabled: true, mode: "half-year", children: year }), calendarHalfYears.map((halfYear) => {
|
|
26
26
|
const halfYearStartMonth = (halfYear - 1) * 6;
|
|
27
27
|
const halfYearDate = setMonth(setYear(getCurrentHalfYearFirstDate(referenceDate), year), halfYearStartMonth);
|
|
28
28
|
const disabled = isHalfYearDisabled && isHalfYearDisabled(halfYearDate);
|
|
@@ -30,6 +30,12 @@ function CalendarHalfYears(props) {
|
|
|
30
30
|
isHalfYearInRange &&
|
|
31
31
|
isHalfYearInRange(halfYearDate);
|
|
32
32
|
const active = !disabled && value && isHalfYearIncluded(halfYearDate, value);
|
|
33
|
+
const isRangeStart = value && value.length > 0
|
|
34
|
+
? isHalfYearIncluded(halfYearDate, [value[0]])
|
|
35
|
+
: false;
|
|
36
|
+
const isRangeEnd = value && value.length > 0
|
|
37
|
+
? isHalfYearIncluded(halfYearDate, [value[value.length - 1]])
|
|
38
|
+
: false;
|
|
33
39
|
const onClick = () => {
|
|
34
40
|
if (disabled)
|
|
35
41
|
return;
|
|
@@ -50,11 +56,11 @@ function CalendarHalfYears(props) {
|
|
|
50
56
|
]
|
|
51
57
|
.filter(Boolean)
|
|
52
58
|
.join(', ');
|
|
53
|
-
return (jsxs("button", { type: "button", disabled: disabled, "aria-disabled": disabled, "aria-label": ariaLabel, "aria-pressed": active, className: cx(calendarClasses.button, {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
59
|
+
return (jsx(CalendarCell, { mode: "half-year", today: isHalfYearIncluded(halfYearDate, [getNow()]), active: active, isRangeStart: isRangeStart, isRangeEnd: isRangeEnd, children: jsxs("button", { type: "button", disabled: disabled, "aria-disabled": disabled, "aria-label": ariaLabel, "aria-pressed": active, className: cx(calendarClasses.button, {
|
|
60
|
+
[calendarClasses.buttonDisabled]: disabled,
|
|
61
|
+
[calendarClasses.buttonInRange]: inRange,
|
|
62
|
+
[calendarClasses.buttonActive]: active,
|
|
63
|
+
}), onClick: onClick, onMouseEnter: onMouseEnter, children: ["H", halfYear] }) }, halfYear));
|
|
58
64
|
})] }, year));
|
|
59
65
|
}) }));
|
|
60
66
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { jsx } from 'react/jsx-runtime';
|
|
3
3
|
import { calendarMonths, calendarClasses } from '@mezzanine-ui/core/calendar';
|
|
4
4
|
import { useCalendarContext } from './CalendarContext.js';
|
|
5
|
+
import CalendarCell from './CalendarCell.js';
|
|
5
6
|
import cx from 'clsx';
|
|
6
7
|
|
|
7
8
|
/**
|
|
@@ -10,7 +11,7 @@ import cx from 'clsx';
|
|
|
10
11
|
* You may use it to compose your own calendar.
|
|
11
12
|
*/
|
|
12
13
|
function CalendarMonths(props) {
|
|
13
|
-
const { locale, getMonthShortNames, isMonthIncluded, getCurrentMonthFirstDate, setMonth, } = useCalendarContext();
|
|
14
|
+
const { locale, getNow, getMonth, getMonthShortNames, isInMonth, isMonthIncluded, getCurrentMonthFirstDate, setMonth, } = useCalendarContext();
|
|
14
15
|
const { className, displayMonthLocale = locale, isMonthDisabled, isMonthInRange, isYearDisabled, onClick: onClickProp, onMonthHover, referenceDate, value, ...rest } = props;
|
|
15
16
|
const monthNames = getMonthShortNames(displayMonthLocale);
|
|
16
17
|
return (jsx("div", { className: cx(calendarClasses.board, className), ...rest, children: jsx("div", { className: calendarClasses.twelveGrid, children: calendarMonths.map((month) => {
|
|
@@ -21,6 +22,12 @@ function CalendarMonths(props) {
|
|
|
21
22
|
(isMonthDisabled === null || isMonthDisabled === void 0 ? void 0 : isMonthDisabled(monthDateType)) ||
|
|
22
23
|
false;
|
|
23
24
|
const inRange = isMonthInRange && isMonthInRange(monthDateType);
|
|
25
|
+
const isRangeStart = value && value.length > 0
|
|
26
|
+
? isMonthIncluded(monthDateType, [value[0]])
|
|
27
|
+
: false;
|
|
28
|
+
const isRangeEnd = value && value.length > 0
|
|
29
|
+
? isMonthIncluded(monthDateType, [value[value.length - 1]])
|
|
30
|
+
: false;
|
|
24
31
|
const onClick = onClickProp
|
|
25
32
|
? () => {
|
|
26
33
|
onClickProp(monthDateType);
|
|
@@ -42,11 +49,11 @@ function CalendarMonths(props) {
|
|
|
42
49
|
]
|
|
43
50
|
.filter(Boolean)
|
|
44
51
|
.join(', ');
|
|
45
|
-
return (jsx("button", { type: "button", "aria-disabled": disabled, disabled: disabled, "aria-label": ariaLabel, "aria-pressed": active, className: cx(calendarClasses.button, {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
52
|
+
return (jsx(CalendarCell, { mode: "month", today: isInMonth(monthDateType, getMonth(getNow())), active: active, isRangeStart: isRangeStart, isRangeEnd: isRangeEnd, children: jsx("button", { type: "button", "aria-disabled": disabled, disabled: disabled, "aria-label": ariaLabel, "aria-pressed": active, className: cx(calendarClasses.button, {
|
|
53
|
+
[calendarClasses.buttonActive]: active,
|
|
54
|
+
[calendarClasses.buttonInRange]: inRange,
|
|
55
|
+
[calendarClasses.buttonDisabled]: disabled,
|
|
56
|
+
}), onClick: onClick, onMouseEnter: onMouseEnter, children: monthNames[month] }) }, month));
|
|
50
57
|
}) }) }));
|
|
51
58
|
}
|
|
52
59
|
|
|
@@ -10,7 +10,7 @@ import cx from 'clsx';
|
|
|
10
10
|
* The react component for `mezzanine` calendar quarters.
|
|
11
11
|
*/
|
|
12
12
|
function CalendarQuarters(props) {
|
|
13
|
-
const { getYear, getCurrentQuarterFirstDate, isQuarterIncluded, setYear, setMonth, } = useCalendarContext();
|
|
13
|
+
const { getNow, getYear, getCurrentQuarterFirstDate, isQuarterIncluded, setYear, setMonth, } = useCalendarContext();
|
|
14
14
|
const { className, isQuarterDisabled, isQuarterInRange, onClick: onClickProp, onQuarterHover, referenceDate, value, ...rest } = props;
|
|
15
15
|
const currentYear = getYear(referenceDate);
|
|
16
16
|
const [start] = useMemo(() => getYearRange(currentYear, calendarQuarterYearsCount), [currentYear]);
|
|
@@ -20,12 +20,18 @@ function CalendarQuarters(props) {
|
|
|
20
20
|
return (jsx("div", { className: cx(calendarClasses.board, className), ...rest, children: years.map((year, yearIndex) => {
|
|
21
21
|
return (jsxs("div", { className: cx(calendarClasses.row, {
|
|
22
22
|
[calendarClasses.rowWithBorder]: yearIndex > 0,
|
|
23
|
-
}), children: [jsx(CalendarCell, { disabled: true, children: year }), calendarQuarters.map((quarter) => {
|
|
23
|
+
}), children: [jsx(CalendarCell, { disabled: true, mode: "quarter", children: year }), calendarQuarters.map((quarter) => {
|
|
24
24
|
const quarterStartMonth = (quarter - 1) * 3;
|
|
25
25
|
const quarterDate = setMonth(setYear(getCurrentQuarterFirstDate(getCurrentQuarterFirstDate(referenceDate)), year), quarterStartMonth);
|
|
26
26
|
const active = value && isQuarterIncluded(quarterDate, value);
|
|
27
27
|
const disabled = isQuarterDisabled && isQuarterDisabled(quarterDate);
|
|
28
28
|
const inRange = isQuarterInRange && isQuarterInRange(quarterDate);
|
|
29
|
+
const isRangeStart = value && value.length > 0
|
|
30
|
+
? isQuarterIncluded(quarterDate, [value[0]])
|
|
31
|
+
: false;
|
|
32
|
+
const isRangeEnd = value && value.length > 0
|
|
33
|
+
? isQuarterIncluded(quarterDate, [value[value.length - 1]])
|
|
34
|
+
: false;
|
|
29
35
|
const onClick = onClickProp
|
|
30
36
|
? () => {
|
|
31
37
|
onClickProp(quarterDate);
|
|
@@ -52,11 +58,11 @@ function CalendarQuarters(props) {
|
|
|
52
58
|
]
|
|
53
59
|
.filter(Boolean)
|
|
54
60
|
.join(', ');
|
|
55
|
-
return (jsxs("button", { type: "button", disabled: disabled, "aria-disabled": disabled, "aria-label": ariaLabel, "aria-pressed": active, className: cx(calendarClasses.button, {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
61
|
+
return (jsx(CalendarCell, { mode: "quarter", today: isQuarterIncluded(quarterDate, [getNow()]), active: active, isRangeStart: isRangeStart, isRangeEnd: isRangeEnd, children: jsxs("button", { type: "button", disabled: disabled, "aria-disabled": disabled, "aria-label": ariaLabel, "aria-pressed": active, className: cx(calendarClasses.button, {
|
|
62
|
+
[calendarClasses.buttonActive]: active,
|
|
63
|
+
[calendarClasses.buttonInRange]: inRange,
|
|
64
|
+
[calendarClasses.buttonDisabled]: disabled,
|
|
65
|
+
}), onClick: onClick, onMouseEnter: onMouseEnter, children: ["Q", quarter] }) }, quarter));
|
|
60
66
|
})] }, year));
|
|
61
67
|
}) }));
|
|
62
68
|
}
|
|
@@ -16,19 +16,32 @@ function CalendarWeeks(props) {
|
|
|
16
16
|
const { locale, getCalendarGrid, getWeek, getDate, getMonth, getNow, isInMonth, isSameDate, isWeekIncluded, setDate, setMonth, setHour, setMinute, setSecond, setMillisecond, getCurrentWeekFirstDate, } = useCalendarContext();
|
|
17
17
|
const { className, displayWeekDayLocale = locale, isYearDisabled, isMonthDisabled, isWeekDisabled, isWeekInRange, onClick: onClickProp, onWeekHover, referenceDate, value, ...rest } = props;
|
|
18
18
|
const daysGrid = useMemo(() => getCalendarGrid(referenceDate, displayWeekDayLocale), [getCalendarGrid, referenceDate, displayWeekDayLocale]);
|
|
19
|
-
|
|
19
|
+
// Pre-calculate all weeks data including dates and week first dates
|
|
20
|
+
const weeksData = useMemo(() => {
|
|
21
|
+
const thisMonth = getMonth(referenceDate);
|
|
20
22
|
return daysGrid.map((week, index) => {
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
? thisMonth
|
|
29
|
-
:
|
|
30
|
-
|
|
31
|
-
|
|
23
|
+
const dates = [];
|
|
24
|
+
const weekStartInPrevMonth = index === 0 && week[0] > 7;
|
|
25
|
+
const weekStartInNextMonth = index > 3 && week[0] <= 14;
|
|
26
|
+
week.forEach((dateNum) => {
|
|
27
|
+
const isPrevMonth = index === 0 && dateNum > 7;
|
|
28
|
+
const isNextMonth = index > 3 && dateNum <= 14;
|
|
29
|
+
const month = isPrevMonth
|
|
30
|
+
? thisMonth - 1
|
|
31
|
+
: isNextMonth
|
|
32
|
+
? thisMonth + 1
|
|
33
|
+
: thisMonth;
|
|
34
|
+
const date = setMillisecond(setSecond(setMinute(setHour(setDate(setMonth(referenceDate, month), dateNum), 0), 0), 0), 0);
|
|
35
|
+
dates.push(date);
|
|
36
|
+
});
|
|
37
|
+
const weekFirstDate = getCurrentWeekFirstDate(dates[0], displayWeekDayLocale);
|
|
38
|
+
return {
|
|
39
|
+
week,
|
|
40
|
+
dates,
|
|
41
|
+
weekStartInPrevMonth,
|
|
42
|
+
weekStartInNextMonth,
|
|
43
|
+
weekFirstDate,
|
|
44
|
+
};
|
|
32
45
|
});
|
|
33
46
|
}, [
|
|
34
47
|
daysGrid,
|
|
@@ -36,35 +49,52 @@ function CalendarWeeks(props) {
|
|
|
36
49
|
referenceDate,
|
|
37
50
|
setDate,
|
|
38
51
|
setMonth,
|
|
52
|
+
setHour,
|
|
53
|
+
setMinute,
|
|
54
|
+
setSecond,
|
|
55
|
+
setMillisecond,
|
|
39
56
|
getCurrentWeekFirstDate,
|
|
40
57
|
displayWeekDayLocale,
|
|
41
58
|
]);
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
59
|
+
// Pre-calculate last week dates for range end comparison
|
|
60
|
+
const lastWeekDatesMap = useMemo(() => {
|
|
61
|
+
if (!value || value.length === 0)
|
|
62
|
+
return null;
|
|
63
|
+
const rangeLastDate = value.length === 1
|
|
64
|
+
? setDate(value[0], getDate(value[0]) + 6)
|
|
65
|
+
: value[value.length - 1];
|
|
66
|
+
const lastWeekFirstDate = getCurrentWeekFirstDate(rangeLastDate, displayWeekDayLocale);
|
|
67
|
+
const lastWeekDates = [];
|
|
68
|
+
for (let i = 0; i < 7; i++) {
|
|
69
|
+
lastWeekDates.push(setDate(setMonth(lastWeekFirstDate, getMonth(lastWeekFirstDate)), getDate(lastWeekFirstDate) + i));
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
rangeLastDate,
|
|
73
|
+
lastWeekDates,
|
|
74
|
+
};
|
|
75
|
+
}, [
|
|
76
|
+
value,
|
|
77
|
+
setDate,
|
|
78
|
+
setMonth,
|
|
79
|
+
getDate,
|
|
80
|
+
getMonth,
|
|
81
|
+
getCurrentWeekFirstDate,
|
|
82
|
+
displayWeekDayLocale,
|
|
83
|
+
]);
|
|
84
|
+
return (jsxs("div", { ...rest, className: cx(calendarClasses.board, className), children: [jsx("div", { className: calendarClasses.week, children: weeksData.map(({ weekFirstDate }, idx) => (jsx("div", { className: calendarClasses.weekRow, children: jsx(CalendarCell, { disabled: true, children: getWeek(weekFirstDate, displayWeekDayLocale) }) }, idx))) }), jsxs("div", { className: calendarClasses.daysGrid, children: [jsx(CalendarDayOfWeek, { displayWeekDayLocale: displayWeekDayLocale }), weeksData.map(({ week, dates, weekStartInPrevMonth, weekStartInNextMonth }, index) => {
|
|
85
|
+
var _a;
|
|
58
86
|
const disabled = (isYearDisabled === null || isYearDisabled === void 0 ? void 0 : isYearDisabled(dates[0])) ||
|
|
59
87
|
(isMonthDisabled === null || isMonthDisabled === void 0 ? void 0 : isMonthDisabled(dates[0])) ||
|
|
60
88
|
(isWeekDisabled === null || isWeekDisabled === void 0 ? void 0 : isWeekDisabled(dates[0])) ||
|
|
61
89
|
false;
|
|
62
90
|
const inactive = !disabled && (weekStartInPrevMonth || weekStartInNextMonth);
|
|
63
|
-
const
|
|
91
|
+
const weekIncluded = !disabled &&
|
|
64
92
|
!inactive &&
|
|
65
93
|
value &&
|
|
66
94
|
isWeekIncluded(dates[0], value, displayWeekDayLocale);
|
|
67
|
-
const
|
|
95
|
+
const rangeFirstDate = value && value.length > 0 ? value[0] : null;
|
|
96
|
+
const rangeLastDate = (_a = lastWeekDatesMap === null || lastWeekDatesMap === void 0 ? void 0 : lastWeekDatesMap.rangeLastDate) !== null && _a !== void 0 ? _a : null;
|
|
97
|
+
const inRange = !disabled && isWeekInRange && isWeekInRange(dates[0]);
|
|
68
98
|
const onMouseEnter = onWeekHover
|
|
69
99
|
? () => {
|
|
70
100
|
onWeekHover(getCurrentWeekFirstDate(dates[0], displayWeekDayLocale));
|
|
@@ -88,18 +118,41 @@ function CalendarWeeks(props) {
|
|
|
88
118
|
const ariaLabel = [
|
|
89
119
|
`Week ${weekNum}`,
|
|
90
120
|
`${startMonth} ${startDay} to ${endMonth} ${endDay}`,
|
|
91
|
-
|
|
121
|
+
weekIncluded && 'Selected',
|
|
92
122
|
disabled && 'Not available',
|
|
93
123
|
inactive && 'Outside current month',
|
|
94
124
|
]
|
|
95
125
|
.filter(Boolean)
|
|
96
126
|
.join(', ');
|
|
97
127
|
return (jsx("button", { type: "button", className: cx(calendarClasses.button, calendarClasses.row, {
|
|
98
|
-
[calendarClasses.buttonActive]: active,
|
|
99
128
|
[calendarClasses.buttonInRange]: inRange,
|
|
100
129
|
[calendarClasses.buttonDisabled]: disabled,
|
|
101
|
-
}), disabled: disabled, "aria-disabled": disabled, "aria-label": ariaLabel, "aria-pressed":
|
|
102
|
-
|
|
130
|
+
}), disabled: disabled, "aria-disabled": disabled, "aria-label": ariaLabel, "aria-pressed": weekIncluded, onClick: onClick, onMouseEnter: onMouseEnter, children: week.map((dateNum, dateIndex) => {
|
|
131
|
+
let cellActive = false;
|
|
132
|
+
let isFirstWeekFirstDate = false;
|
|
133
|
+
let isLastWeekLastDate = false;
|
|
134
|
+
if (weekIncluded &&
|
|
135
|
+
rangeFirstDate &&
|
|
136
|
+
rangeLastDate &&
|
|
137
|
+
lastWeekDatesMap) {
|
|
138
|
+
const currentDate = dates[dateIndex];
|
|
139
|
+
isFirstWeekFirstDate =
|
|
140
|
+
isWeekIncluded(currentDate, [rangeFirstDate], displayWeekDayLocale) && isSameDate(currentDate, rangeFirstDate);
|
|
141
|
+
isLastWeekLastDate =
|
|
142
|
+
isWeekIncluded(currentDate, [rangeLastDate], displayWeekDayLocale) &&
|
|
143
|
+
isSameDate(currentDate, lastWeekDatesMap.lastWeekDates[6]);
|
|
144
|
+
cellActive = isFirstWeekFirstDate || isLastWeekLastDate;
|
|
145
|
+
}
|
|
146
|
+
return (jsx(CalendarCell, { mode: "week", today: isSameDate(dates[dateIndex], getNow()), disabled: disabled ||
|
|
147
|
+
!isInMonth(dates[dateIndex], getMonth(referenceDate)), active: cellActive, isRangeStart: isFirstWeekFirstDate, isRangeEnd: isLastWeekLastDate, children: jsx("div", { className: cx(calendarClasses.button, {
|
|
148
|
+
[calendarClasses.buttonInRange]: weekIncluded,
|
|
149
|
+
[calendarClasses.buttonActive]: cellActive,
|
|
150
|
+
}), style: {
|
|
151
|
+
width: '100%',
|
|
152
|
+
height: '100%',
|
|
153
|
+
pointerEvents: 'none',
|
|
154
|
+
}, children: dateNum }) }, `${getMonth(dates[dateIndex])}/${getDate(dates[dateIndex])}`));
|
|
155
|
+
}) }, `CALENDAR_WEEKS/WEEK_OF/${index}`));
|
|
103
156
|
})] })] }));
|
|
104
157
|
}
|
|
105
158
|
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { jsx } from 'react/jsx-runtime';
|
|
3
3
|
import { getCalendarYearRange, calendarYearsBase, calendarClasses } from '@mezzanine-ui/core/calendar';
|
|
4
4
|
import { useMemo } from 'react';
|
|
5
|
+
import CalendarCell from './CalendarCell.js';
|
|
5
6
|
import { useCalendarContext } from './CalendarContext.js';
|
|
6
7
|
import cx from 'clsx';
|
|
7
8
|
|
|
@@ -18,12 +19,14 @@ function CalendarYears(props) {
|
|
|
18
19
|
const thisYear = base + start;
|
|
19
20
|
const yearDateType = setYear(getCurrentYearFirstDate(getNow()), thisYear);
|
|
20
21
|
const disabled = isYearDisabled && isYearDisabled(yearDateType);
|
|
21
|
-
const
|
|
22
|
-
const active = !disabled &&
|
|
23
|
-
!inactive &&
|
|
24
|
-
value &&
|
|
25
|
-
isYearIncluded(yearDateType, value);
|
|
22
|
+
const active = !disabled && value && isYearIncluded(yearDateType, value);
|
|
26
23
|
const inRange = isYearInRange && isYearInRange(yearDateType);
|
|
24
|
+
const isRangeStart = value && value.length > 0
|
|
25
|
+
? isYearIncluded(yearDateType, [value[0]])
|
|
26
|
+
: false;
|
|
27
|
+
const isRangeEnd = value && value.length > 0
|
|
28
|
+
? isYearIncluded(yearDateType, [value[value.length - 1]])
|
|
29
|
+
: false;
|
|
27
30
|
const onClick = onClickProp
|
|
28
31
|
? () => {
|
|
29
32
|
onClickProp(yearDateType);
|
|
@@ -39,16 +42,14 @@ function CalendarYears(props) {
|
|
|
39
42
|
`Year ${thisYear}`,
|
|
40
43
|
active && 'Selected',
|
|
41
44
|
disabled && 'Not available',
|
|
42
|
-
inactive && 'Outside range',
|
|
43
45
|
]
|
|
44
46
|
.filter(Boolean)
|
|
45
47
|
.join(', ');
|
|
46
|
-
return (jsx("button", { type: "button", "aria-disabled": disabled, disabled: disabled, "aria-label": ariaLabel, "aria-pressed": active, className: cx(calendarClasses.button, {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}), onClick: onClick, onMouseEnter: onMouseEnter, children: thisYear }, base + start));
|
|
48
|
+
return (jsx(CalendarCell, { mode: "year", today: getYear(getNow()) === thisYear, active: active, isRangeStart: isRangeStart, isRangeEnd: isRangeEnd, children: jsx("button", { type: "button", "aria-disabled": disabled, disabled: disabled, "aria-label": ariaLabel, "aria-pressed": active, className: cx(calendarClasses.button, {
|
|
49
|
+
[calendarClasses.buttonActive]: active,
|
|
50
|
+
[calendarClasses.buttonInRange]: inRange,
|
|
51
|
+
[calendarClasses.buttonDisabled]: disabled,
|
|
52
|
+
}), onClick: onClick, onMouseEnter: onMouseEnter, children: thisYear }) }, base + start));
|
|
52
53
|
}) }) }));
|
|
53
54
|
}
|
|
54
55
|
|
|
@@ -2,6 +2,6 @@ import { CalendarMode, DateType } from '@mezzanine-ui/core/calendar';
|
|
|
2
2
|
export type CalendarControlModifier = (value: DateType) => DateType;
|
|
3
3
|
export type UseCalendarControlModifiersResult = Record<CalendarMode, {
|
|
4
4
|
single: [CalendarControlModifier, CalendarControlModifier] | null;
|
|
5
|
-
double: [CalendarControlModifier, CalendarControlModifier];
|
|
5
|
+
double: [CalendarControlModifier, CalendarControlModifier] | null;
|
|
6
6
|
}>;
|
|
7
7
|
export declare function useCalendarControlModifiers(): UseCalendarControlModifiersResult;
|
|
@@ -15,34 +15,34 @@ function useCalendarControlModifiers() {
|
|
|
15
15
|
single: [(date) => addMonth(date, -1), (date) => addMonth(date, 1)],
|
|
16
16
|
double: [(date) => addYear(date, -1), (date) => addYear(date, 1)],
|
|
17
17
|
},
|
|
18
|
-
// month mode: only
|
|
18
|
+
// month mode: only single
|
|
19
19
|
month: {
|
|
20
|
-
single:
|
|
21
|
-
double:
|
|
20
|
+
single: [(date) => addYear(date, -1), (date) => addYear(date, 1)],
|
|
21
|
+
double: null,
|
|
22
22
|
},
|
|
23
|
-
// year mode: only
|
|
23
|
+
// year mode: only single
|
|
24
24
|
year: {
|
|
25
|
-
single:
|
|
26
|
-
double: [
|
|
25
|
+
single: [
|
|
27
26
|
(date) => addYear(date, -calendarYearModuler),
|
|
28
27
|
(date) => addYear(date, calendarYearModuler),
|
|
29
28
|
],
|
|
29
|
+
double: null,
|
|
30
30
|
},
|
|
31
|
-
// quarter mode: only
|
|
31
|
+
// quarter mode: only single
|
|
32
32
|
quarter: {
|
|
33
|
-
single:
|
|
34
|
-
double: [
|
|
33
|
+
single: [
|
|
35
34
|
(date) => addYear(date, -calendarQuarterYearsCount),
|
|
36
35
|
(date) => addYear(date, calendarQuarterYearsCount),
|
|
37
36
|
],
|
|
37
|
+
double: null,
|
|
38
38
|
},
|
|
39
|
-
// half-year mode: only
|
|
39
|
+
// half-year mode: only single
|
|
40
40
|
'half-year': {
|
|
41
|
-
single:
|
|
42
|
-
double: [
|
|
41
|
+
single: [
|
|
43
42
|
(date) => addYear(date, -calendarHalfYearYearsCount),
|
|
44
43
|
(date) => addYear(date, calendarHalfYearYearsCount),
|
|
45
44
|
],
|
|
45
|
+
double: null,
|
|
46
46
|
},
|
|
47
47
|
}), [addYear, addMonth]);
|
|
48
48
|
}
|
|
@@ -2,10 +2,10 @@ import { DateType, CalendarMode } from '@mezzanine-ui/core/calendar';
|
|
|
2
2
|
export declare function useCalendarControls(referenceDateProp: DateType, mode?: CalendarMode): {
|
|
3
3
|
currentMode: CalendarMode;
|
|
4
4
|
onMonthControlClick: () => void;
|
|
5
|
-
onNext: () => void;
|
|
6
|
-
onPrev: () => void;
|
|
7
|
-
onDoubleNext: () => void;
|
|
8
|
-
onDoublePrev: () => void;
|
|
5
|
+
onNext: (() => void) | undefined;
|
|
6
|
+
onPrev: (() => void) | undefined;
|
|
7
|
+
onDoubleNext: (() => void) | undefined;
|
|
8
|
+
onDoublePrev: (() => void) | undefined;
|
|
9
9
|
onYearControlClick: () => void;
|
|
10
10
|
popModeStack: () => void;
|
|
11
11
|
referenceDate: string;
|