Skip to content

Commit

Permalink
HelpButton: VR adjusments (#3899)
Browse files Browse the repository at this point in the history
  • Loading branch information
AlbertCarreras authored Nov 29, 2024
1 parent 775343a commit 5425244
Showing 1 changed file with 49 additions and 44 deletions.
93 changes: 49 additions & 44 deletions packages/gestalt/src/HelpButton.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ComponentProps, ReactElement, Ref, useId, useRef, useState } from 'react';
import { ComponentProps, ReactElement, useId, useRef, useState } from 'react';
import Box from './Box';
import { useColorScheme } from './contexts/ColorSchemeProvider';
import { useDefaultLabelContext } from './contexts/DefaultLabelProvider';
Expand All @@ -12,31 +12,25 @@ import InternalPopover from './Popover/InternalPopover';
import TapArea from './TapArea';
import Text from './Text';
import Tooltip from './Tooltip';
import useInExperiment from './useInExperiment';
import { CompositeZIndex, FixedZIndex, Indexable } from './zIndex';

type LinkType = {
accessibilityLabel?: string;
accessibilityLabel?: ComponentProps<typeof Link>['accessibilityLabel'];
externalLinkIcon?:
| 'none'
| 'default'
| {
color: ComponentProps<typeof Icon>['color'];
size: ComponentProps<typeof Text>['size'];
};
href: string;
onClick?: (arg1: {
event: React.MouseEvent<HTMLAnchorElement> | React.KeyboardEvent<HTMLAnchorElement>;
dangerouslyDisableOnNavigation: () => void;
}) => void;
ref?: Ref<'a'>;
href: ComponentProps<typeof Link>['href'];
onClick?: ComponentProps<typeof Link>['onClick'];
ref?: ComponentProps<typeof Link>['ref'];
text: string;
target?: null | 'self' | 'blank';
target?: ComponentProps<typeof Link>['target'];
};

type OnTapType = (arg1: {
event: React.MouseEvent<HTMLDivElement> | React.KeyboardEvent<HTMLDivElement>;
}) => void;

type Props = {
/**
* Supply a short, descriptive label screen readers. Follow the pattern `Click to learn more about [description]`. See [Accessibility](https://gestalt.pinterest.systems/web/helpbutton#Accessibility) section for guidance.
Expand Down Expand Up @@ -66,7 +60,9 @@ type Props = {
/**
* Callback fired when HelpIcon is clicked (pressed and released) with a mouse or keyboard.
*/
onClick?: OnTapType;
onClick?: (arg1: {
event: React.MouseEvent<HTMLDivElement> | React.KeyboardEvent<HTMLDivElement>;
}) => void;
/**
* Informational content that's displayed when the user clicks on HelpButton.
*/
Expand All @@ -90,18 +86,25 @@ export default function HelpButton({
text,
zIndex,
}: Props) {
const tapAreaRef = useRef<null | HTMLAnchorElement | HTMLDivElement>(null);
const tapAreaRef = useRef<null | HTMLDivElement>(null);
const textRef = useRef<null | HTMLElement>(null);

const [open, setOpen] = useState(false);
const [hovered, setHovered] = useState(false);
const [focused, setFocused] = useState(false);

// Define where the focused content stays
const [innerModalFocus, setInnerModalFocus] = useState(false);

const isInVRExperiment = useInExperiment({
webExperimentName: 'web_gestalt_visualRefresh',
mwebExperimentName: 'web_gestalt_visualRefresh',
});
const { colorSchemeName } = useColorScheme();
const popoverId = useId();
const { tooltipMessage } = useDefaultLabelContext('HelpButton');

const handlePopoverKeyDown = ({ event }: { event: React.KeyboardEvent<HTMLElement> }) => {
const handlePopoverKeyDown: ComponentProps<typeof InternalPopover>['onKeyDown'] = ({ event }) => {
// Avoid others KeyDown events to listen this call
if (innerModalFocus) event.stopPropagation();

Expand All @@ -114,6 +117,7 @@ export default function HelpButton({
`a[href="${link?.href ?? ''}"]`, // Link query
].join(' ,'),
);

const lastElement = elementsInnerPopover[elementsInnerPopover.length - 1];
if (innerModalFocus && event.keyCode === TAB && lastElement === event.target) {
event.preventDefault();
Expand All @@ -127,7 +131,7 @@ export default function HelpButton({
}
};

const handleTapAreaKeyDown = ({ event }: { event: React.KeyboardEvent<HTMLDivElement> }) => {
const handleTapAreaKeyDown: ComponentProps<typeof TapArea>['onKeyDown'] = ({ event }) => {
if (event.keyCode === TAB && open) {
event.preventDefault();
textRef.current?.focus();
Expand All @@ -137,38 +141,28 @@ export default function HelpButton({
event.stopPropagation();
};

const toggleView = () => {
setOpen((currVal) => !currVal);
};
const toggleView = () => setOpen((currVal) => !currVal);

const onHandleTap = (
...args: ReadonlyArray<{
event: React.MouseEvent<HTMLDivElement> | React.KeyboardEvent<HTMLDivElement>;
}>
) => {
toggleView();
// @ts-expect-error - TS2556 - A spread argument must either have a tuple type or be passed to a rest parameter.
onClick?.(...args);
};
let bgIconColor: ComponentProps<typeof Box>['color'] = isInVRExperiment ? 'default' : 'tertiary';
let iconColor: ComponentProps<typeof Icon>['color'] = isInVRExperiment ? 'subtle' : 'inverse';

const bgIconColor = open || hovered || focused ? 'selected' : 'tertiary';
if (!isInVRExperiment && (open || hovered || focused)) {
bgIconColor = 'selected';
}

const tooltipZIndex = zIndex ?? new FixedZIndex(1);

const zIndexWrapper = new CompositeZIndex([tooltipZIndex]);
if (isInVRExperiment && (open || hovered || focused)) {
iconColor = 'default';
}

// Overriding color of `Text` components
const isDarkMode = colorSchemeName === 'darkMode';
const textColorOverrideStyles = isDarkMode
? styles.textColorOverrideLight
: styles.textColorOverrideDark;

const textElement =
typeof text === 'string' ? (
<Text align="start">{text}</Text>
) : (
<span className={textColorOverrideStyles}>{text}</span>
);
const tooltipZIndex = zIndex ?? new FixedZIndex(1);

const zIndexWrapper = new CompositeZIndex([tooltipZIndex]);

const popoverElement = (
<InternalPopover
Expand All @@ -192,13 +186,16 @@ export default function HelpButton({
* `tabIndex={0}` - It's used to make the text element as a focusable element
*/}
<Box ref={textRef} id={`helpButtonText-${popoverId}`} tabIndex={0}>
{textElement}
{typeof text === 'string' ? (
<Text align="start">{text}</Text>
) : (
<span className={textColorOverrideStyles}>{text}</span>
)}
</Box>
{link && link?.href && (
<Box display="block" marginTop={3} width="100%">
<Text>
<Link
// @ts-expect-error - TS2322 - Type 'Ref<"a"> | undefined' is not assignable to type 'LegacyRef<HTMLAnchorElement> | undefined'.
ref={link.ref}
accessibilityLabel={link.accessibilityLabel}
externalLinkIcon={link.externalLinkIcon}
Expand Down Expand Up @@ -228,18 +225,21 @@ export default function HelpButton({
zIndex={tooltipZIndex}
>
<TapArea
// @ts-expect-error - TS2322 - Type 'MutableRefObject<HTMLDivElement | HTMLAnchorElement | null>' is not assignable to type 'LegacyRef<HTMLDivElement> | undefined'.
ref={tapAreaRef}
accessibilityControls={popoverId}
accessibilityExpanded={open}
accessibilityLabel={accessibilityLabel}
fullWidth={false}
innerFocusColor={isInVRExperiment ? 'default' : undefined}
onBlur={() => setFocused(false)}
onFocus={() => setFocused(true)}
onKeyDown={handleTapAreaKeyDown}
onMouseEnter={() => setHovered(true)}
onMouseLeave={() => setHovered(false)}
onTap={onHandleTap}
onTap={({ event }) => {
toggleView();
onClick?.({ event });
}}
role="button"
rounding="circle"
>
Expand All @@ -252,7 +252,12 @@ export default function HelpButton({
rounding="circle"
width={16}
>
<Icon accessibilityLabel="" color="inverse" icon="question-mark" size={8} />
<Icon
accessibilityLabel=""
color={iconColor}
icon="question-mark"
size={isInVRExperiment ? 16 : 8}
/>
</Box>
</TapArea>
</Tooltip>
Expand Down

0 comments on commit 5425244

Please sign in to comment.