Skip to content

Commit

Permalink
fix: add missing optional props to forms
Browse files Browse the repository at this point in the history
  • Loading branch information
digitalsadhu committed Sep 26, 2022
1 parent 1d135eb commit b6415d2
Show file tree
Hide file tree
Showing 15 changed files with 120 additions and 5 deletions.
29 changes: 29 additions & 0 deletions packages/combobox/docs/Combobox.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,35 @@ function Example() {
}
```

### Optional prop

Add the optional prop to indicate that the combobox field is not required.

```jsx example
function Example() {
const [value, setValue] = useState('');

return (
<Combobox
label="Choose a fruit"
optional
value={value}
onChange={(val) => setValue(val)}
onSelect={(val) => {
alert(val);
setValue('');
}}
options={[
{ value: 'Apple' },
{ value: 'Banana' },
{ value: 'Orange' },
{ value: 'Pineapple' },
]}
/>
);
}
```

## Combobox Props

```props packages/combobox/src/component.tsx
Expand Down
2 changes: 2 additions & 0 deletions packages/combobox/src/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export const Combobox = forwardRef<HTMLInputElement, ComboboxProps>(
onChange,
onFocus,
onBlur,
optional,
...rest
} = props;

Expand Down Expand Up @@ -183,6 +184,7 @@ export const Combobox = forwardRef<HTMLInputElement, ComboboxProps>(
id,
value: navigationValueOrInputValue,
label,
optional,
invalid,
helpText,
placeholder,
Expand Down
3 changes: 3 additions & 0 deletions packages/combobox/src/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ export type ComboboxProps = {

/** For affix use */
children?: React.ReactNode;

/** Whether to show optional text */
optional?: boolean;
} & Omit<
React.PropsWithoutRef<JSX.IntrinsicElements['input']>,
'onChange' | 'type' | 'value' | 'label'
Expand Down
29 changes: 29 additions & 0 deletions packages/combobox/stories/Combobox.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -327,3 +327,32 @@ export const AsyncFetch = () => {
</Combobox>
);
};

export const Optional = () => {
const [value, setValue] = React.useState('');

return (
<>
<p>
When the user clicks inside the text box the current value will be
selected (like the URL bar in browsers).
</p>
<Combobox
value={value}
onChange={(val) => setValue(val)}
onSelect={(val) => {
setValue(val);
action('select')(val);
}}
label="Stillingstittel"
optional
options={[
{ value: 'Product manager' },
{ value: 'Produktledelse' },
{ value: 'Prosessoperatør' },
{ value: 'Prosjekteier' },
]}
/>
</>
);
};
12 changes: 12 additions & 0 deletions packages/select/docs/Select.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,18 @@ Select for accessibility. If the field is labeled by a separate element, an
`aria-labelledby` prop should be provided using the id of the labeling element
instead.

### Optional

Add the optional prop to indicate that the select is not required.

```jsx example
<Select label="Berries" optional>
<option value="s">Strawberries</option>
<option value="r">Raspberries</option>
<option value="c">Cloudberries</option>
</Select>
```

## Hint text

Selects can provide additional context with `hint` if the label and placeholder
Expand Down
7 changes: 4 additions & 3 deletions packages/select/src/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { classNames } from '@chbphone55/classnames';
import type { SelectProps } from './props';

const setup = (props) => {
const { className, invalid, id, hint, always, label, style, ...rest } = props;
const { className, invalid, id, hint, always, label, style, optional, ...rest } = props;

const helpId = hint ? `${id}__hint` : undefined;

Expand All @@ -24,6 +24,7 @@ const setup = (props) => {
'aria-invalid': invalid,
id,
},
optional,
help:
always || invalid
? {
Expand All @@ -45,11 +46,11 @@ const setup = (props) => {
function Select(props: SelectProps, ref: React.Ref<HTMLSelectElement>) {
const id = useId(props.id);
const { attrs, classes } = setup({ ...props, id });
const { div, label, select, help } = attrs;
const { div, label, select, help, optional } = attrs;

return (
<div className={classes} {...div}>
{label.children && <label {...label} />}
{label.children && <label htmlFor={label.htmlFor}>{label.children}{optional && <span className="pl-8 font-normal text-14 text-gray-500"> (valgfritt)</span>}</label>}
<div className="input--select__wrap">
<select ref={ref} {...select} />
</div>
Expand Down
2 changes: 2 additions & 0 deletions packages/select/stories/Select.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,5 @@ export const noLabel = () => (
</FabricSelect>
</div>
);

export const optional = () => <Select optional />;
8 changes: 8 additions & 0 deletions packages/textarea/docs/TextArea.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ TextArea for accessibility. If the field is labeled by a separate element, an
`aria-labelledby` prop must be provided using the id of the labeling element
instead.

### Optional

Add the optional prop to indicate that the textarea is not required.

```jsx example
<TextField label="Description" optiona />
```

## Help text

TextAreas can provide additional context with `helpText` if the label and
Expand Down
3 changes: 2 additions & 1 deletion packages/textarea/src/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export const TextArea = forwardRef<HTMLTextAreaElement, TextAreaProps>(
readOnly,
style,
value,
optional,
...rest
} = props;

Expand All @@ -48,7 +49,7 @@ export const TextArea = forwardRef<HTMLTextAreaElement, TextAreaProps>(
})}
style={style}
>
{label && <label htmlFor={id}>{label}</label>}
{label && <label htmlFor={id}>{label}{optional && <span className="pl-8 font-normal text-14 text-gray-500"> (valgfritt)</span>}</label>}
<textarea
{...rest}
aria-describedby={helpId}
Expand Down
3 changes: 3 additions & 0 deletions packages/textarea/src/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ export type TextAreaProps = {

/** The current value (controlled). */
value?: string;

/** Whether to show optional text */
optional?: boolean;
} & Omit<
React.PropsWithoutRef<JSX.IntrinsicElements['textarea']>,
// omit these, otherwise they seem to form a union type (in the prop table docs)
Expand Down
4 changes: 4 additions & 0 deletions packages/textarea/stories/TextArea.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,7 @@ export const minimumRows3 = () => (
export const maximumRows3 = () => (
<TextArea label="Description" maximumRows={3} />
);

export const optional = () => (
<TextArea label="Description" optional />
);
11 changes: 11 additions & 0 deletions packages/textfield/docs/TextField.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,17 @@ TextField for accessibility. If the field is labeled by a separate element, an
`aria-labelledby` prop must be provided using the id of the labeling element
instead.

### Optional

Add the optional prop to indicate that the textfield is not required.

```jsx example
<TextField
label="Telefonnummer"
optional
/>
```

## Help text

TextFields can provide additional context with `helpText` if the label and
Expand Down
3 changes: 2 additions & 1 deletion packages/textfield/src/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
readOnly,
type = 'text',
style,
optional,
...rest
} = props;

Expand Down Expand Up @@ -46,7 +47,7 @@ export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
'input--is-read-only': readOnly,
})}
>
{label && <label htmlFor={id}>{label}</label>}
{label && <label htmlFor={id}>{label}{optional && <span className="pl-8 font-normal text-14 text-gray-500"> (valgfritt)</span>}</label>}
<div className="relative">
<input
{...rest}
Expand Down
3 changes: 3 additions & 0 deletions packages/textfield/src/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ export type TextFieldProps = {

/** The current value (controlled). */
value?: string;

/** Mark label to indicate that filling in this field is optional */
optional?: boolean;
} & Omit<
React.PropsWithoutRef<JSX.IntrinsicElements['input']>,
// omit these, otherwise they seem to form a union type (in the prop table docs)
Expand Down
6 changes: 6 additions & 0 deletions packages/textfield/stories/Textfield.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,9 @@ export const invalid = () => (
<TextField helpText="Error text" invalid />
</div>
);

export const optional = () => (
<div className="flex flex-col space-y-48">
<TextField label="Address" optional />
</div>
);

0 comments on commit b6415d2

Please sign in to comment.