Skip to content

Commit

Permalink
Conditionally render field label only if label is provided (adobe#6833)
Browse files Browse the repository at this point in the history
* do not render field label if no children (string) provided

* add label-less story for testing

* add more examples to form story

* add story with form with labeled and non-labeled components

* hide value label when label is hidden for meter and progress bar

Will need warning in eventual docs that this is not accessible unless the value is displayed visually externally

* Improve labeling in example

---------

Co-authored-by: Devon Govett <[email protected]>
  • Loading branch information
jluyau and devongovett committed Aug 15, 2024
1 parent 665ba22 commit a02fe15
Show file tree
Hide file tree
Showing 4 changed files with 167 additions and 5 deletions.
4 changes: 4 additions & 0 deletions packages/@react-spectrum/s2/src/Field.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ function FieldLabel(props: FieldLabelProps, ref: DOMRef<HTMLLabelElement>) {
labelProps.id = fallbackLabelPropsId;
}

if (!props.children) {
return null;
}

return (
<div
className={style({
Expand Down
4 changes: 2 additions & 2 deletions packages/@react-spectrum/s2/src/Meter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ function Meter(props: MeterProps, ref: DOMRef<HTMLDivElement>) {
}, styles)}>
{({percentage, valueText}) => (
<>
<FieldLabel size={size} labelAlign="start" labelPosition="top" staticColor={staticColor}>{label}</FieldLabel>
<span className={valueStyles({size, labelAlign: 'end', staticColor})}>{valueText}</span>
{label && <FieldLabel size={size} labelAlign="start" labelPosition="top" staticColor={staticColor}>{label}</FieldLabel>}
{label && <span className={valueStyles({size, labelAlign: 'end', staticColor})}>{valueText}</span>}
<div className={trackStyles({staticColor, size})}>
<div className={fillStyles({staticColor, variant})} style={{width: percentage + '%'}} />
</div>
Expand Down
4 changes: 2 additions & 2 deletions packages/@react-spectrum/s2/src/ProgressBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,8 @@ function ProgressBar(props: ProgressBarProps, ref: DOMRef<HTMLDivElement>) {
className={UNSAFE_className + wrapper({...props, size}, props.styles)}>
{({percentage, valueText}) => (
<>
<FieldLabel size={size} labelAlign="start" labelPosition="top" staticColor={staticColor}>{label}</FieldLabel>
<span className={valueStyles({size, labelAlign: 'end', staticColor})}>{valueText}</span>
{label && <FieldLabel size={size} labelAlign="start" labelPosition="top" staticColor={staticColor}>{label}</FieldLabel>}
{label && <span className={valueStyles({size, labelAlign: 'end', staticColor})}>{valueText}</span>}
<div className={trackStyles({...props})}>
<div
className={mergeStyles(fill({...props, staticColor}), (isIndeterminate ? indeterminateAnimation : null))}
Expand Down
160 changes: 159 additions & 1 deletion packages/@react-spectrum/s2/stories/Form.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,43 @@
* governing permissions and limitations under the License.
*/

import {Button, Checkbox, CheckboxGroup, Form, Radio, RadioGroup, RangeSlider, SearchField, Slider, Switch, TextArea, TextField} from '../src';
import {
ActionButton,
Button,
Checkbox,
CheckboxGroup,
ColorField,
ColorSlider,
ComboBox,
ComboBoxItem,
Content,
ContextualHelp,
Divider,
Form,
Heading,
Meter,
NumberField,
Picker,
PickerItem,
ProgressBar,
Radio,
RadioGroup,
RangeSlider,
SearchField,
Slider,
Switch,
Tag,
TagGroup,
TextArea,
TextField,
ToggleButton
} from '../src';
import {categorizeArgTypes} from './utils';
import type {Meta} from '@storybook/react';
import SortDown from '../s2wf-icons/S2_Icon_SortDown_20_N.svg';
import SortUp from '../s2wf-icons/S2_Icon_SortUp_20_N.svg';
import {style} from '../style/spectrum-theme' with {type: 'macro'};
import {useState} from 'react';

const meta: Meta<typeof Form> = {
component: Form,
Expand Down Expand Up @@ -54,3 +87,128 @@ export const Example = (args: any) => (
<Button type="submit" variant="primary" styles={style({gridColumnStart: 'field', width: 'fit'})}>Submit</Button>
</Form>
);

export const MixedForm = (args: any) => (
<Form {...args}>
<TextField label="First Name" name="firstName" />
<TextField label="Last Name" name="firstName" />
<TextField label="Email" name="email" type="email" description="Enter an email" />
<CheckboxGroup aria-label="Favorite sports">
<Checkbox value="soccer">Soccer</Checkbox>
<Checkbox value="baseball">Baseball</Checkbox>
<Checkbox value="basketball">Basketball</Checkbox>
</CheckboxGroup>
<RadioGroup aria-label="Favorite pet">
<Radio value="cat">Cat</Radio>
<Radio value="dog">Dog</Radio>
<Radio value="plant" isDisabled>Plant</Radio>
</RadioGroup>
<SearchField label="Search" name="search" />
</Form>
);

MixedForm.parameters = {
docs: {
disable: true
}
};


export const CustomLabelsExample = (args: any) => {
const [isSortAscending, setIsSortAscending] = useState(true);
return (
<Form {...args}>
<div role="group" aria-labelledby="sortOrder" className={style({display: 'flex', alignItems: 'center', gap: 8, font: 'ui'})}>
<span id="sortOrder">Sort order</span>
<ActionButton aria-label="Sort direction" onPress={() => setIsSortAscending(!isSortAscending)}>
{
isSortAscending ? <SortUp /> : <SortDown />
}
</ActionButton>
<Picker aria-label="Sort by" styles={style({width: 208})}>
<PickerItem id="name">Name</PickerItem>
<PickerItem id="created">Created</PickerItem>
</Picker>
</div>
<div role="group" aria-labelledby="filterTerms" className={style({display: 'flex', alignItems: 'center', gap: 8, font: 'ui'})}>
<span id="filterTerms">Filter terms</span>
<TagGroup aria-label="Keywords" styles={style({minWidth: 208})}>
<Tag>keyword 1</Tag>
<Tag>keyword 2</Tag>
</TagGroup>
</div>
<Divider size="S" />
<div role="group" aria-labelledby="colorLabel" className={style({display: 'flex', alignItems: 'center', gap: 8, font: 'ui'})}>
<span id="colorLabel">Color settings</span>
<ToggleButton>
Enable color
</ToggleButton>
<ColorField aria-label="Fill color" styles={style({width: 144})} />
<ColorSlider channel="alpha" defaultValue="#000" />
</div>
<Divider size="S" />
<div role="group" aria-labelledby="searchLabel" className={style({display: 'flex', alignItems: 'center', gap: 8, font: 'ui'})}>
<span id="searchLabel">Search</span>
<ToggleButton>
Enable search
</ToggleButton>
<TextField aria-label="Query" styles={style({width: 144})} />
<ComboBox aria-label="Search terms" styles={style({width: 144})}>
<ComboBoxItem>search term 1</ComboBoxItem>
<ComboBoxItem>search term 2</ComboBoxItem>
</ComboBox>
<NumberField aria-label="Number of results" defaultValue={50} styles={style({width: 96})} />
</div>
<div role="group" aria-labelledby="searchParameters" className={style({display: 'flex', alignItems: 'center', gap: 16, font: 'ui'})}>
<span id="searchParameters">Search parameters</span>
<RadioGroup aria-label="Search range" orientation="horizontal" styles={style({width: 208})}>
<Radio value="text">Text</Radio>
<Radio value="images">Images</Radio>
<Radio value="video">Video</Radio>
</RadioGroup>
<CheckboxGroup aria-label="Content display" orientation="horizontal" styles={style({width: 256})}>
<Checkbox value="summary">Summary</Checkbox>
<Checkbox value="date">Date</Checkbox>
<Checkbox value="author">Author</Checkbox>
</CheckboxGroup>
</div>
<Divider size="S" />
<div role="group" aria-label="Progress" className={style({display: 'flex', alignItems: 'center', gap: 16, font: 'ui'})}>
<span>28% complete</span>
<ProgressBar aria-label="Percent complete" value={28} styles={style({width: 144})} />
<span>44% confidence</span>
<Meter aria-label="Search confidence" variant="positive" value={44} styles={style({width: 144})} />
</div>
<Divider size="S" />
<div role="group" aria-labelledby="sliders" className={style({font: 'ui'})}>
<div id="sliders">Sliders (with and without label)</div>
<Slider
aria-label="Days to search"
label="With label"
labelPosition="side"
contextualHelp={
<ContextualHelp>
<Heading>Help</Heading>
<Content>Help content</Content>
</ContextualHelp>
} />
<Slider
aria-label="Days to search"
labelPosition="side"
contextualHelp={
<ContextualHelp>
<Heading>Help</Heading>
<Content>Help content</Content>
</ContextualHelp>
} />
</div>
<Button type="submit" variant="primary" styles={style({gridColumnStart: 'field', width: 'fit'})}>Submit</Button>
</Form>
);
};

CustomLabelsExample.parameters = {
docs: {
disable: true
}
};

0 comments on commit a02fe15

Please sign in to comment.