refactor(calendar): cell tab index fixed, width property added (#2744)

* refactor(calendar): cell tab index fixed, width property added

* chore(date-picker): remove needless omit
This commit is contained in:
Junior Garcia 2024-04-16 16:39:19 -03:00 committed by GitHub
parent ccd8f730e1
commit 158c2aa004
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 52 additions and 42 deletions

View File

@ -0,0 +1,7 @@
---
"@nextui-org/calendar": patch
"@nextui-org/date-picker": patch
"@nextui-org/theme": patch
---
Refactor calendar cell tab index, add calendar default width

View File

@ -23,11 +23,10 @@ A calendar consists of a grouping element containing one or more date grids (e.g
npm: "npm install @nextui-org/calendar",
yarn: "yarn add @nextui-org/calendar",
pnpm: "pnpm add @nextui-org/calendar",
bun: "bun add @nextui-org/calendar"
bun: "bun add @nextui-org/calendar",
}}
/>
## Import
<ImportTabs
@ -209,6 +208,7 @@ Here's the example to customize `topContent` and `bottomContent` to have some pr
| visibleMonths | `number` | The number of months to display at once. Up to 3 months are supported. Passing a number greater than 1 will disable the `showMonthAndYearPickers` prop | `1` |
| focusedValue | `DateValue` | Controls the currently focused date within the calendar. | - |
| defaultFocusedValue | `DateValue` | The date that is focused when the calendar first mounts (uncountrolled). | - |
| calendarWidth | `number` \| `string` | The width to be applied to the calendar component. This value is multiplied by the `visibleMonths` number to determine the total width of the calendar. | `256` |
| pageBehavior | `single` \| `visible` | Controls the behavior of paging. Pagination either works by advancing the visible page by visibleDuration (default) or one unit of visibleDuration. | `visible` |
| weekdayStyle | `narrow` \|`short` \| `long` \| `undefined` | The style of weekday names to display in the calendar grid header, e.g. single letter, abbreviation, or full day name. | `narrow` |
| showMonthAndYearPickers | `boolean` | Whether the label should be crossed out. | `false` |

View File

@ -23,7 +23,7 @@ A range calendar consists of a grouping element containing one or more date grid
npm: "npm install @nextui-org/calendar",
yarn: "yarn add @nextui-org/calendar",
pnpm: "pnpm add @nextui-org/calendar",
bun: "bun add @nextui-org/calendar"
bun: "bun add @nextui-org/calendar",
}}
/>
@ -210,6 +210,7 @@ Here's the example to customize `topContent` and `bottomContent` to have some pr
| visibleMonths | `number` | The number of months to display at once. Up to 3 months are supported. Passing a number greater than 1 will disable the `showMonthAndYearPickers` prop | `1` | |
| focusedValue | `DateValue` | Controls the currently focused date within the calendar. | - | |
| defaultFocusedValue | `DateValue` | The date that is focused when the calendar first mounts (uncountrolled). | - | |
| calendarWidth | `number` \| `string` | The width to be applied to the calendar component. This value is multiplied by the `visibleMonths` number to determine the total width of the calendar. | `256` |
| pageBehavior | `PageBehavior` | Controls the behavior of paging. Pagination either works by advancing the visible page by visibleDuration (default) or one unit of visibleDuration. | `visible` | |
| weekdayStyle | `"narrow" \|"short" \| "long" \| undefined` | The style of weekday names to display in the calendar grid header, e.g. single letter, abbreviation, or full day name. | `narrow` | |
| allowsNonContiguousRanges | `boolean` | When combined with `isDateUnavailable`, determines whether non-contiguous ranges, i.e. ranges containing unavailable dates, may be selected. | `false` | |

View File

@ -69,7 +69,7 @@ export function CalendarCell(originalProps: CalendarCellProps) {
return (
<td className={slots?.cell({class: classNames?.cell})} data-slot="cell" {...cellProps}>
<button
<span
{...mergeProps(buttonProps, hoverProps, focusProps)}
ref={ref}
className={slots?.cellButton({class: classNames?.cellButton})}
@ -88,10 +88,9 @@ export function CalendarCell(originalProps: CalendarCellProps) {
data-selection-start={dataAttr(isSelectionStart)}
data-today={dataAttr(isToday(props.date, state.timeZone))}
data-unavailable={dataAttr(isUnavailable)}
tabIndex={isDisabled ? -1 : 0}
>
<span>{formattedDate}</span>
</button>
</span>
</td>
);
}

View File

@ -63,6 +63,9 @@ export function CalendarMonth(props: CalendarMonthProps) {
key={weekIndex}
className={slots?.gridBodyRow({class: classNames?.gridBodyRow})}
data-slot="grid-body-row"
// makes the browser ignore the element and its children when tabbing
// @ts-ignore
inert={isHeaderExpanded ? true : undefined}
>
{state
.getDatesInWeek(weekIndex, startDate)

View File

@ -65,6 +65,9 @@ export function CalendarPicker(props: CalendarPickerProps) {
class: classNames?.pickerWrapper,
})}
data-slot="picker-wrapper"
// makes the browser ignore the element and its children when tabbing
// @ts-ignore
inert={isHeaderExpanded ? true : undefined}
>
<div
ref={highlightRef}

View File

@ -16,7 +16,7 @@ import {calendar} from "@nextui-org/theme";
import {useControlledState} from "@react-stately/utils";
import {ReactRef, useDOMRef} from "@nextui-org/react-utils";
import {useLocale} from "@react-aria/i18n";
import {clamp, objectToDeps} from "@nextui-org/shared-utils";
import {clamp, dataAttr, objectToDeps} from "@nextui-org/shared-utils";
import {mergeProps} from "@react-aria/utils";
import {useProviderContext} from "@nextui-org/system";
@ -42,6 +42,13 @@ interface Props extends NextUIBaseProps {
* @default 1
*/
visibleMonths?: number;
/**
* The width to be applied to the calendar component. This value is multiplied by the number
* of visible months to determine the total width of the calendar.
*
* @default 256
*/
calendarWidth?: number | string;
/**
* Props for the navigation button, prev button and next button.
*/
@ -185,6 +192,7 @@ export function useCalendarBase(originalProps: UseCalendarBasePropsComplete) {
topContent,
bottomContent,
showHelper = true,
calendarWidth = 256,
visibleMonths: visibleMonthsProp = 1,
weekdayStyle = "narrow",
navButtonProps = {},
@ -229,6 +237,7 @@ export function useCalendarBase(originalProps: UseCalendarBasePropsComplete) {
);
const visibleDuration = useMemo(() => ({months: visibleMonths}), [visibleMonths]);
const hasMultipleMonths = visibleMonths > 1;
const shouldFilterDOMProps = typeof Component === "string";
const {locale} = useLocale();
@ -256,6 +265,16 @@ export function useCalendarBase(originalProps: UseCalendarBasePropsComplete) {
...navButtonProps,
};
const baseProps = {
"data-slot": "base",
"data-has-multiple-months": dataAttr(hasMultipleMonths),
style: {
// @ts-ignore
"--visible-months": visibleMonths,
"--calendar-width": calendarWidth,
} as React.CSSProperties,
};
const getPrevButtonProps = (props = {}) => {
return {
"data-slot": "prev-button",
@ -290,6 +309,7 @@ export function useCalendarBase(originalProps: UseCalendarBasePropsComplete) {
locale,
minValue,
maxValue,
baseProps,
showHelper,
weekdayStyle,
visibleMonths,

View File

@ -38,6 +38,7 @@ export function useCalendar<T extends DateValue>({
showHelper,
weekdayStyle,
visibleDuration,
baseProps,
shouldFilterDOMProps,
isHeaderExpanded,
visibleMonths,
@ -81,6 +82,7 @@ export function useCalendar<T extends DateValue>({
const getBaseCalendarProps = (props = {}): CalendarBaseProps => {
return {
...baseProps,
Component,
showHelper,
topContent,

View File

@ -40,6 +40,7 @@ export function useRangeCalendar<T extends DateValue>({
isHeaderExpanded,
visibleMonths,
createCalendar: createCalendarProp,
baseProps,
getPrevButtonProps,
getNextButtonProps,
getErrorMessageProps,
@ -73,6 +74,7 @@ export function useRangeCalendar<T extends DateValue>({
const getBaseCalendarProps = (props = {}): CalendarBaseProps => {
return {
...baseProps,
Component,
showHelper,
topContent,

View File

@ -12,8 +12,7 @@ import {CalendarBoldIcon} from "@nextui-org/shared-icons";
import {UseDatePickerProps, useDatePicker} from "./use-date-picker";
export interface Props<T extends DateValue>
extends Omit<UseDatePickerProps<T>, "hasMultipleMonths"> {}
export interface Props<T extends DateValue> extends UseDatePickerProps<T> {}
function DatePicker<T extends DateValue>(props: Props<T>, ref: ForwardedRef<HTMLDivElement>) {
const {

View File

@ -13,8 +13,7 @@ import {CalendarBoldIcon} from "@nextui-org/shared-icons";
import DateRangePickerField from "./date-range-picker-field";
import {UseDateRangePickerProps, useDateRangePicker} from "./use-date-range-picker";
export interface Props<T extends DateValue>
extends Omit<UseDateRangePickerProps<T>, "hasMultipleMonths"> {}
export interface Props<T extends DateValue> extends UseDateRangePickerProps<T> {}
function DateRangePicker<T extends DateValue>(props: Props<T>, ref: ForwardedRef<HTMLDivElement>) {
const {

View File

@ -236,18 +236,8 @@ export function useDatePickerBase<T extends DateValue>(originalProps: UseDatePic
const calendarProps = {
...slotsProps.calendarProps,
calendarWidth,
"data-slot": "calendar",
"data-has-multiple-months": dataAttr(hasMultipleMonths),
style: mergeProps(
hasMultipleMonths
? {
// @ts-ignore
"--visible-months": visibleMonths,
}
: {},
{"--calendar-width": `${calendarWidth}px`},
slotsProps.calendarProps.style,
),
} as CalendarProps;
const selectorButtonProps = {

View File

@ -59,7 +59,6 @@ export function useDatePicker<T extends DateValue>({
endContent,
selectorIcon,
createCalendar,
hasMultipleMonths,
isCalendarHeaderExpanded,
disableAnimation,
CalendarTopContent,
@ -88,10 +87,9 @@ export function useDatePicker<T extends DateValue>({
() =>
datePicker({
...variantProps,
hasMultipleMonths,
className,
}),
[objectToDeps(variantProps), hasMultipleMonths, className],
[objectToDeps(variantProps), className],
);
let {

View File

@ -116,10 +116,9 @@ export function useDateRangePicker<T extends DateValue>({
() =>
dateRangePicker({
...variantProps,
hasMultipleMonths,
className,
}),
[objectToDeps(variantProps), hasMultipleMonths, className],
[objectToDeps(variantProps), className],
);
// Time field values
@ -258,7 +257,7 @@ export function useDateRangePicker<T extends DateValue>({
labelPlacement,
className,
}),
[objectToDeps(variantProps), hasMultipleMonths, className],
[objectToDeps(variantProps), className],
);
const getStartDateInputProps = (props: DOMAttributes = {}) => {

View File

@ -8,6 +8,7 @@ const calendar = tv({
base: [
"relative w-fit max-w-full shadow-small inline-block overflow-y-hidden",
"rounded-large overflow-x-auto bg-default-50 dark:bg-background",
"w-[calc(var(--visible-months)_*_var(--calendar-width))]",
],
prevButton: [],
nextButton: [],
@ -22,7 +23,7 @@ const calendar = tv({
],
header: "flex w-full items-center justify-center gap-2 z-10",
title: "text-default-500 text-small font-medium",
content: "w-fit",
content: "w-[calc(var(--visible-months)_*_var(--calendar-width))]",
gridWrapper: "flex max-w-full overflow-hidden pb-2 h-auto relative",
grid: "w-full border-collapse z-0",
gridHeader: "bg-content1 shadow-[0px_20px_20px_0px_rgb(0_0_0/0.05)]",

View File

@ -18,19 +18,6 @@ const datePicker = tv({
timeInputLabel: "font-medium",
timeInput: "px-5 pb-4 flex-wrap gap-x-6",
},
variants: {
// @internal
hasMultipleMonths: {
true: {
calendar: "w-[calc(var(--visible-months)_*_var(--calendar-width))]",
calendarContent: "w-[calc(var(--visible-months)_*_var(--calendar-width))]",
},
false: {},
},
},
defaultVariants: {
hasMultipleMonths: false,
},
});
const dateRangePicker = tv({