Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 21 additions & 3 deletions packages/@react-spectrum/s2/src/TextField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import {
} from '@react-types/shared';
import {FormContext, useFormProps} from './Form';
import {InputContext, InputProps} from 'react-aria-components/Input';
import {isChrome} from 'react-aria/private/utils/platform';
import {mergeRefs} from 'react-aria/mergeRefs';
import {StyleString} from '../style/types';
import {TextContext} from './Content';
Expand Down Expand Up @@ -123,8 +124,18 @@ export const TextArea = forwardRef(function TextArea(
ref={ref}
fieldGroupCss={style({
alignItems: 'baseline',
height: 'auto'
})}>
height: 'auto',
paddingTop: {
// The textarea opts out of baseline alignment (see TextAreaInput) because Chrome
// computes an unstable baseline for empty textareas, causing the field height to
// jump when an overlay opens. Instead, we pad the group's hidden ::before baseline
// anchor down so its baseline lands on the textarea's first line of text, keeping
// the prefix, error icon, and side label aligned as if the textarea participated.
isChrome: {
'::before': '[calc((var(--field-height) - 1lh) / 2)]'
}
}
})({isChrome: isChrome()})}>
<TextAreaInput />
</TextFieldBase>
);
Expand Down Expand Up @@ -270,13 +281,20 @@ function TextAreaInput() {
fontSize: 'inherit',
fontWeight: 'inherit',
lineHeight: 'inherit',
// Don't baseline align with the FieldGroup - Chrome's baseline for an empty textarea
// is unstable (https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/textarea#baseline_inconsistency).
// paddingY centers the first line within --field-height, matching the padded
// ::before baseline anchor on the FieldGroup.
alignSelf: {
isChrome: 'start'
},
flexGrow: 1,
minWidth: 0,
outlineStyle: 'none',
borderStyle: 'none',
resize: 'none',
overflowX: 'hidden'
})}
})({isChrome: isChrome()})}
/>
);
}
20 changes: 20 additions & 0 deletions packages/@react-spectrum/s2/stories/TextField.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,26 @@ export const TextAreaExample: StoryTextArea = {
}
};

export const TextAreaContextualHelpExample: StoryTextArea = {
render: args => (
<TextArea
{...args}
contextualHelp={
<ContextualHelp>
<Heading>Share your thoughts!</Heading>
<Content>
<Text>Your comment will be visible to other users.</Text>
</Content>
</ContextualHelp>
}
/>
),
args: {
label: 'Comment',
placeholder: 'Enter a comment'
}
};

export const CustomWidth: StoryTextField = {
render: args => <TextField {...args} styles={style({width: 384})} />,
args: {
Expand Down
Loading