Skip to content

Commit

Permalink
Tooltip refactor (finos#1080)
Browse files Browse the repository at this point in the history
Co-authored-by: ImmanuelBaskaran <immanuel.baskaran.16@ucl.ac.uk>
Co-authored-by: sion-docs <104632245+sion-docs@users.noreply.github.com>
Co-authored-by: Josh Wooding <12938082+joshwooding@users.noreply.github.com>
  • Loading branch information
4 people authored and junaidzm13 committed Jan 5, 2024
1 parent 0ce3d64 commit acfd664
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 118 deletions.
72 changes: 31 additions & 41 deletions internal/CalendarDay.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { makePrefixer, useForkRef } from "@salt-ds/core";
import { makePrefixer } from "@salt-ds/core";
import { CloseIcon } from "@salt-ds/icons";
import { clsx } from "clsx";
import { ComponentPropsWithRef, forwardRef, ReactElement, useRef } from "react";
import { DateValue } from "@internationalized/date";

import { Tooltip, TooltipProps } from "../../tooltip";
import { DayStatus, useCalendarDay } from "../useCalendarDay";
import "./CalendarDay.css";
import { formatDate } from "./utils";
import { Tooltip, TooltipProps, useTooltip } from "../../tooltip";

export type DateFormatter = (day: Date) => string | undefined;

Expand Down Expand Up @@ -38,45 +38,35 @@ export const CalendarDay = forwardRef<HTMLButtonElement, CalendarDayProps>(
);
const { outOfRange, today, unselectable, hidden } = status;

const { getTriggerProps, getTooltipProps } = useTooltip({
disabled: !unselectableReason,
placement: "top",
enterDelay: 300,
});

const { ref: triggerRef, ...triggerProps } = getTriggerProps<"button">({
"aria-label": formatDate(day),
...dayProps,
...rest,
className: clsx(
withBaseName(),
{
[withBaseName("hidden")]: hidden,
[withBaseName("outOfRange")]: outOfRange,
[withBaseName("today")]: today,
[withBaseName("unselectable")]: !!unselectable,
[withBaseName("unselectableLow")]: unselectable === "low",
[withBaseName("unselectableMedium")]: unselectable === "medium",
},
dayProps.className,
className
),
});

const handleTriggerRef = useForkRef(triggerRef, dayRef);
const handleRef = useForkRef(handleTriggerRef, ref);

return (
<>
<Tooltip
{...getTooltipProps({
hideIcon: true,
status: "error",
title: unselectableReason,
...TooltipProps,
})}
/>
<button {...triggerProps} ref={handleRef}>
<Tooltip
hideIcon
status="error"
content={unselectableReason}
disabled={!unselectableReason}
placement="top"
enterDelay={300}
{...TooltipProps}
>
<button
aria-label={formatDate(day)}
{...dayProps}
ref={dayRef}
{...rest}
className={clsx(
withBaseName(),
{
[withBaseName("hidden")]: hidden,
[withBaseName("outOfRange")]: outOfRange,
[withBaseName("today")]: today,
[withBaseName("unselectable")]: !!unselectable,
[withBaseName("unselectableLow")]: unselectable === "low",
[withBaseName("unselectableMedium")]: unselectable === "medium",
},
dayProps.className,
className
)}
>
{unselectable === "medium" && (
<CloseIcon
aria-hidden
Expand All @@ -89,7 +79,7 @@ export const CalendarDay = forwardRef<HTMLButtonElement, CalendarDayProps>(
? renderDayContents(day, status)
: formatDate(day, { day: "numeric" })}
</button>
</>
</Tooltip>
);
}
);
126 changes: 49 additions & 77 deletions internal/CalendarNavigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
} from "react";
import { Dropdown, DropdownProps } from "../../dropdown";
import { ListItem, ListItemType } from "../../list";
import { Tooltip, useTooltip } from "../../tooltip";
import { Tooltip } from "../../tooltip";

import { useCalendarContext } from "./CalendarContext";

Expand Down Expand Up @@ -112,26 +112,15 @@ const ListItemWithTooltip: ListItemType<DropdownItem> = ({
item,
label,
...props
}) => {
const { getTooltipProps, getTriggerProps } = useTooltip({
placement: "right",
disabled: !item?.disabled,
});

const { ref: triggerRef, ...triggerProps } =
getTriggerProps<typeof ListItem>(props);

return (
<ListItem ref={triggerRef} {...triggerProps}>
{label}
<Tooltip
{...getTooltipProps({
title: "This month is out of range",
})}
/>
</ListItem>
);
};
}) => (
<Tooltip
placement="right"
disabled={!item?.disabled}
content="This month is out of range"
>
<ListItem {...props}>{label}</ListItem>
</Tooltip>
);

export const CalendarNavigation = forwardRef<
HTMLDivElement,
Expand Down Expand Up @@ -186,14 +175,15 @@ export const CalendarNavigation = forwardRef<
}
};

const monthDropdownId = useId(MonthDropdownProps?.id);
const monthDropdownId = useId(MonthDropdownProps?.id) || "";
const monthDropdownLabelledBy = clsx(
MonthDropdownProps?.["aria-labelledby"],
// TODO need a prop on Dropdown to allow buttonId to be passed, should not make assumptions about internal
// id assignment like this
`${monthDropdownId}-control`
);
const yearDropdownId = useId(YearDropdownProps?.id);

const yearDropdownId = useId(YearDropdownProps?.id) || "";
const yearDropdownLabelledBy = clsx(
YearDropdownProps?.["aria-labelledby"],
`${yearDropdownId}-control`
Expand All @@ -210,22 +200,6 @@ export const CalendarNavigation = forwardRef<
return formatDate(date.value, { year: "numeric" });
};

const {
getTriggerProps: getPreviousButtonProps,
getTooltipProps: getPreviousButtonTooltipProps,
} = useTooltip({
placement: "top",
disabled: canNavigatePrevious,
});

const {
getTriggerProps: getNextButtonProps,
getTooltipProps: getNextButtonTooltipProps,
} = useTooltip({
placement: "top",
disabled: canNavigateNext,
});

return (
<div
className={clsx(
Expand All @@ -236,26 +210,25 @@ export const CalendarNavigation = forwardRef<
ref={ref}
{...rest}
>
<Button
{...getPreviousButtonProps<typeof Button>({
disabled: !canNavigatePrevious,
variant: "secondary",
onClick: handleNavigatePrevious,
className: withBaseName("previousButton"),
focusableWhenDisabled: true,
})}
>
<ChevronLeftIcon
aria-label={`Previous Month, ${formatDate(
visibleMonth.subtract({ months: 1 })
)}`}
/>
</Button>
<Tooltip
{...getPreviousButtonTooltipProps({
title: "Past dates are out of range",
})}
/>
placement="top"
disabled={canNavigatePrevious}
content="Past dates are out of range"
>
<Button
disabled={!canNavigatePrevious}
variant="secondary"
onClick={handleNavigatePrevious}
className={withBaseName("previousButton")}
focusableWhenDisabled={true}
>
<ChevronLeftIcon
aria-label={`Previous Month, ${formatDate(
visibleMonth.subtract({ months: 1 })
)}`}
/>
</Button>
</Tooltip>
<Dropdown<DropdownItem>
source={months}
id={monthDropdownId}
Expand All @@ -282,26 +255,25 @@ export const CalendarNavigation = forwardRef<
fullWidth
/>
)}
<Button
{...getNextButtonProps<typeof Button>({
disabled: !canNavigateNext,
variant: "secondary",
onClick: handleNavigateNext,
className: withBaseName("nextButton"),
focusableWhenDisabled: true,
})}
>
<ChevronRightIcon
aria-label={`Next Month, ${formatDate(
visibleMonth.add({ months: 1 })
)}`}
/>
</Button>
<Tooltip
{...getNextButtonTooltipProps({
title: "Future dates are out of range",
})}
/>
placement="top"
disabled={canNavigateNext}
content="Future dates are out of range"
>
<Button
disabled={!canNavigateNext}
variant="secondary"
onClick={handleNavigateNext}
className={withBaseName("nextButton")}
focusableWhenDisabled={true}
>
<ChevronRightIcon
aria-label={`Next Month, ${formatDate(
visibleMonth.add({ months: 1 })
)}`}
/>
</Button>
</Tooltip>
</div>
);
});

0 comments on commit acfd664

Please sign in to comment.