Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BaseControl: Migrate to TypeScript #39468

Merged
merged 15 commits into from
Mar 23, 2022
4 changes: 4 additions & 0 deletions packages/components/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Internal

- `BaseControl`: Convert to TypeScript ([#39468](https://github.com/WordPress/gutenberg/pull/39468)).

## 19.7.0 (2022-03-23)

### Enhancements
Expand Down
22 changes: 11 additions & 11 deletions packages/components/src/base-control/README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
# BaseControl

BaseControl component is used to generate labels and help text for components handling user inputs.
`BaseControl` is a component used to generate labels and help text for components handling user inputs.

## Usage

Render a BaseControl for a textarea input:
Render a `BaseControl` for a textarea input:

```jsx
import { BaseControl } from '@wordpress/components';

// The `id` prop is necessary to accessibly associate the label with the textarea
const MyBaseControl = () => (
<BaseControl id="textarea-1" label="Text" help="Enter some text" __nextHasNoMarginBottom={ true }>
<textarea id="textarea-1" />
Expand All @@ -22,10 +23,10 @@ The component accepts the following props:

### id

The id of the element to which labels and help text are being generated. That element should be passed as a child.
The HTML `id` of the element (passed in as a child to `BaseControl`) to which labels and help text are being generated. This is necessary to accessibly associate the label with that element.

- Type: `String`
- Required: Yes
- Required: No

### label

Expand All @@ -50,8 +51,7 @@ If this property is added, a help text will be generated using help property as

### className

The class that will be added with "components-base-control" to the classes of the wrapper div.
If no className is passed only components-base-control is used.
mirka marked this conversation as resolved.
Show resolved Hide resolved
Any other classes to add to the wrapper div.

- Type: `String`
- Required: No
Expand All @@ -73,16 +73,17 @@ Start opting into the new margin-free styles that will become the default in a f

## BaseControl.VisualLabel

`BaseControl.VisualLabel` component is used to render a purely visual label inside a `BaseControl` component.
It should only be used in cases where the children being rendered inside BaseControl are already properly labeled, e.g., a button, but we want an additional visual label for that section equivalent to the labels BaseControl would otherwise use if the label prop was passed.
`BaseControl.VisualLabel` is used to render a purely visual label inside a `BaseControl` component.

It should only be used in cases where the children being rendered inside BaseControl are already accessibly labeled, e.g., a button, but we want an additional visual label for that section equivalent to the labels `BaseControl` would otherwise use if the `label` prop was passed.

## Usage

```jsx
import { BaseControl } from '@wordpress/components';

const MyBaseControl = () => (
<BaseControl help="Pressing the Select an author button will open a modal that allows an advanced mechanism for author selection">
<BaseControl help="This button is already accessibly labeled.">
<BaseControl.VisualLabel>Author</BaseControl.VisualLabel>
<Button>Select an author</Button>
</BaseControl>
Expand All @@ -93,8 +94,7 @@ const MyBaseControl = () => (

#### className

The class that will be added with `components-base-control__label` to the classes of the wrapper div.
If no className is passed only `components-base-control__label` is used.
Any other classes to add to the wrapper div.

- Type: `String`
- Required: No
Expand Down
118 changes: 0 additions & 118 deletions packages/components/src/base-control/index.js

This file was deleted.

124 changes: 124 additions & 0 deletions packages/components/src/base-control/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/**
* External dependencies
*/
import classnames from 'classnames';
import type { FunctionComponent } from 'react';

/**
* Internal dependencies
*/
import { VisuallyHidden } from '../visually-hidden';
import type { BaseControlProps, BaseControlVisualLabelProps } from './types';
import {
Wrapper,
StyledField,
StyledLabel,
StyledHelp,
StyledVisualLabel,
} from './styles/base-control-styles';

/**
* `BaseControl` is a component used to generate labels and help text for components handling user inputs.
*
* @example
* // Render a `BaseControl` for a textarea input
* import { BaseControl } from '@wordpress/components';
*
* // The `id` prop is necessary to accessibly associate the label with the textarea
* const MyBaseControl = () => (
* <BaseControl id="textarea-1" label="Text" help="Enter some text" __nextHasNoMarginBottom={ true }>
* <textarea id="textarea-1" />
* </BaseControl>
* );
*/
export const BaseControl = ( {
__nextHasNoMarginBottom = false,
id,
mirka marked this conversation as resolved.
Show resolved Hide resolved
label,
hideLabelFromVision = false,
help,
className,
children,
}: BaseControlProps ) => {
return (
<Wrapper
className={ classnames( 'components-base-control', className ) }
>
<StyledField
className="components-base-control__field"
// TODO: Official deprecation for this should start after all internal usages have been migrated
__nextHasNoMarginBottom={ __nextHasNoMarginBottom }
>
{ label &&
id &&
( hideLabelFromVision ? (
mirka marked this conversation as resolved.
Show resolved Hide resolved
<VisuallyHidden as="label" htmlFor={ id }>
{ label }
</VisuallyHidden>
) : (
<StyledLabel
className="components-base-control__label"
htmlFor={ id }
>
{ label }
</StyledLabel>
) ) }
{ label &&
! id &&
( hideLabelFromVision ? (
<VisuallyHidden as="label">{ label }</VisuallyHidden>
) : (
<BaseControl.VisualLabel>
{ label }
</BaseControl.VisualLabel>
) ) }
{ children }
</StyledField>
{ !! help && (
<StyledHelp
id={ id ? id + '__help' : undefined }
className="components-base-control__help"
__nextHasNoMarginBottom={ __nextHasNoMarginBottom }
>
{ help }
</StyledHelp>
) }
</Wrapper>
);
};

/**
* `BaseControl.VisualLabel` is used to render a purely visual label inside a `BaseControl` component.
*
* It should only be used in cases where the children being rendered inside `BaseControl` are already accessibly labeled,
* e.g., a button, but we want an additional visual label for that section equivalent to the labels `BaseControl` would
* otherwise use if the `label` prop was passed.
*
* @example
* import { BaseControl } from '@wordpress/components';
*
* const MyBaseControl = () => (
* <BaseControl help="This button is already accessibly labeled.">
* <BaseControl.VisualLabel>Author</BaseControl.VisualLabel>
* <Button>Select an author</Button>
* </BaseControl>
* );
*/
export const VisualLabel: FunctionComponent< BaseControlVisualLabelProps > = ( {
className,
children,
} ) => {
return (
<StyledVisualLabel
className={ classnames(
'components-base-control__label',
className
) }
>
{ children }
</StyledVisualLabel>
);
};
BaseControl.VisualLabel = VisualLabel;

export default BaseControl;
Loading