Skip to content

Commit

Permalink
TextField: VR layout adjusments (#3845)
Browse files Browse the repository at this point in the history
  • Loading branch information
AlbertCarreras authored Nov 4, 2024
1 parent cc11ebf commit aa4e9bb
Show file tree
Hide file tree
Showing 6 changed files with 343 additions and 139 deletions.
71 changes: 47 additions & 24 deletions packages/gestalt/src/TextField.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { forwardRef, ReactElement, ReactNode, useEffect, useState } from 'react';
import { useDefaultLabelContext } from './contexts/DefaultLabelProvider';
import TagArea from './TagArea/TagArea';
import PasswordIconButton from './TextField/IconButtonEnd';
import IconButtonEnd from './TextField/IconButtonEnd';
import InternalTextField, { autoCompleteType } from './TextField/InternalTextField';
import VRIconButtonEnd from './TextField/VRIconButtonEnd';
import VRInternalTextField from './TextField/VRInternalTextField';
import useInExperiment from './useInExperiment';

Expand Down Expand Up @@ -168,27 +169,6 @@ const TextFieldWithForwardRef = forwardRef<HTMLInputElement, Props>(function Tex
const { accessibilityHidePasswordLabel, accessibilityShowPasswordLabel } =
useDefaultLabelContext('TextField');

const iconButton = isPasswordField ? (
<PasswordIconButton
accessibilityChecked={!isCurrentlyPasswordType}
accessibilityLabel={
isCurrentlyPasswordType
? accessibilityShowPasswordLabel ?? ''
: accessibilityHidePasswordLabel ?? ''
}
icon={isCurrentlyPasswordType ? 'eye' : 'eye-hide'}
onClick={() => {
setType(isCurrentlyPasswordType ? 'text' : 'password');
}}
role="switch"
tooltipText={
isCurrentlyPasswordType
? accessibilityShowPasswordLabel ?? ''
: accessibilityHidePasswordLabel ?? ''
}
/>
) : undefined;

if (isInVRExperiment && !tags) {
return (
<VRInternalTextField
Expand All @@ -199,7 +179,29 @@ const TextFieldWithForwardRef = forwardRef<HTMLInputElement, Props>(function Tex
errorMessage={errorMessage}
hasError={hasError}
helperText={helperText}
iconButton={iconButton}
iconButton={
isPasswordField ? (
<VRIconButtonEnd
accessibilityChecked={!isCurrentlyPasswordType}
accessibilityLabel={
isCurrentlyPasswordType
? accessibilityShowPasswordLabel ?? ''
: accessibilityHidePasswordLabel ?? ''
}
icon={isCurrentlyPasswordType ? 'eye' : 'eye-hide'}
onClick={() => {
setType(isCurrentlyPasswordType ? 'text' : 'password');
}}
role="switch"
size={size}
tooltipText={
isCurrentlyPasswordType
? accessibilityShowPasswordLabel ?? ''
: accessibilityHidePasswordLabel ?? ''
}
/>
) : undefined
}
id={id}
label={label}
labelDisplay={labelDisplay}
Expand Down Expand Up @@ -257,7 +259,28 @@ const TextFieldWithForwardRef = forwardRef<HTMLInputElement, Props>(function Tex
errorMessage={errorMessage}
hasError={hasError}
helperText={helperText}
iconButton={iconButton}
iconButton={
isPasswordField ? (
<IconButtonEnd
accessibilityChecked={!isCurrentlyPasswordType}
accessibilityLabel={
isCurrentlyPasswordType
? accessibilityShowPasswordLabel ?? ''
: accessibilityHidePasswordLabel ?? ''
}
icon={isCurrentlyPasswordType ? 'eye' : 'eye-hide'}
onClick={() => {
setType(isCurrentlyPasswordType ? 'text' : 'password');
}}
role="switch"
tooltipText={
isCurrentlyPasswordType
? accessibilityShowPasswordLabel ?? ''
: accessibilityHidePasswordLabel ?? ''
}
/>
) : undefined
}
id={id}
label={label}
labelDisplay={labelDisplay}
Expand Down
25 changes: 2 additions & 23 deletions packages/gestalt/src/TextField/InternalTextField.css
Original file line number Diff line number Diff line change
Expand Up @@ -90,31 +90,10 @@ html[dir="rtl"] .actionButton {
top: var(--space-0);
}

.vr_sm_actionButtonContainer {
bottom: var(--sema-space-100);
position: absolute;
}

.vr_md_actionButtonContainer {
bottom: var(--sema-space-200);
position: absolute;
}

.vr_lg_actionButtonContainer {
bottom: var(--sema-space-300);
position: absolute;
}

html:not([dir="rtl"]) .actionButtonContainer,
html:not([dir="rtl"]) .vr_sm_actionButtonContainer,
html:not([dir="rtl"]) .vr_md_actionButtonContainer,
html:not([dir="rtl"]) .vr_lg_actionButtonContainer {
html:not([dir="rtl"]) .actionButtonContainer {
right: var(--space-0);
}

html[dir="rtl"] .actionButtonContainer,
html[dir="rtl"] .vr_sm_actionButtonContainer,
html[dir="rtl"] .vr_md_actionButtonContainer,
html[dir="rtl"] .vr_lg_actionButtonContainer {
html[dir="rtl"] .actionButtonContainer {
left: var(--space-0);
}
95 changes: 95 additions & 0 deletions packages/gestalt/src/TextField/VRIconButtonEnd.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { ComponentProps, ReactNode, useState } from 'react';
import classnames from 'classnames';
import styles from './VRInternalTextField.css';
import { ENTER, SPACE, TAB } from '../keyCodes';
import Pog from '../Pog';
import TapArea from '../TapArea';
import Tooltip from '../Tooltip';

function MaybeTooltip({
children,
tooltipText,
}: {
children: ReactNode;
tooltipText: string | null | undefined;
}) {
return tooltipText ? (
<Tooltip inline text={tooltipText}>
{children}
</Tooltip>
) : (
children
);
}

type Props = {
accessibilityChecked?: boolean;
accessibilityHidden?: boolean;
accessibilityLabel?: string;
hoverStyle?: 'default' | 'none';
icon: 'arrow-down' | 'cancel' | 'eye' | 'eye-hide';
onClick: () => void;
pogPadding?: 1 | 2;
role?: 'switch';
size?: 'sm' | 'md' | 'lg';
tapStyle?: ComponentProps<typeof TapArea>['tapStyle'];
tooltipText?: string;
};

export default function IconButtonEnd({
accessibilityChecked,
accessibilityHidden,
accessibilityLabel,
hoverStyle = 'default',
icon,
onClick,
pogPadding = 1,
role,
tapStyle,
tooltipText,
size,
}: Props) {
const [focused, setFocused] = useState(false);
const isSM = size === 'sm';
const isMD = size === 'md';
const isLG = size === 'lg';

return (
<div
className={classnames(styles.endIconContainer, {
[styles.sm_endIconContainer]: isSM,
[styles.md_endIconContainer]: isMD,
[styles.lg_endIconContainer]: isLG,
})}
>
<MaybeTooltip tooltipText={tooltipText}>
<TapArea
accessibilityChecked={accessibilityChecked}
accessibilityLabel={accessibilityLabel}
onBlur={() => setFocused(false)}
onFocus={() => setFocused(true)}
onKeyDown={({ event }) => {
if ([ENTER, SPACE].includes(event.keyCode)) onClick();
if (event.keyCode !== TAB) event.preventDefault();
}}
onMouseEnter={() => setFocused(true)}
onMouseLeave={() => setFocused(false)}
onTap={onClick}
role={role}
rounding={1}
tabIndex={accessibilityHidden ? -1 : 0}
tapStyle={tapStyle}
>
<Pog
accessibilityLabel=""
bgColor={focused && hoverStyle === 'default' ? 'lightGray' : 'transparent'}
icon={icon}
iconColor="darkGray"
padding={pogPadding}
size="sm"
/>
</TapArea>
</MaybeTooltip>
</div>
);
}
Loading

0 comments on commit aa4e9bb

Please sign in to comment.