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

useBaseField: Convert component to TypeScript #45712

Merged
merged 6 commits into from
Nov 28, 2022
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
1 change: 1 addition & 0 deletions packages/components/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

- `LinkedButton`: remove unnecessary `span` tag ([#46063](https://github.com/WordPress/gutenberg/pull/46063))
- NumberControl: refactor styles/tests/stories to TypeScript, replace fireEvent with user-event ([#45990](https://github.com/WordPress/gutenberg/pull/45990)).
- `useBaseField`: Convert to TypeScript ([#45712](https://github.com/WordPress/gutenberg/pull/45712)).

## 22.1.0 (2022-11-16)

Expand Down
43 changes: 21 additions & 22 deletions packages/components/src/base-field/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,56 +12,55 @@ This feature is still experimental. “Experimental” means this is an early im

```js
function useExampleField( props ) {
const {
as = 'input',
...baseProps,
} = useBaseField( props );
const { as = 'input', ...baseProps } = useBaseField( props );

const inputProps = {
as,
// more cool stuff here
}
};

return { inputProps, ...baseProps };
}

function ExampleField( props, forwardRef ) {
const {
preFix,
affix,
disabled,
inputProps,
...baseProps
} = useExampleField( props );
const { preFix, affix, disabled, inputProps, ...baseProps } =
useExampleField( props );

return (
<View { ...baseProps } disabled={ disabled }>
{preFix}
<View
autocomplete="off"
{ ...inputProps }
disabled={ disabled }
/>
{affix}
{ preFix }
<View autocomplete="off" { ...inputProps } disabled={ disabled } />
{ affix }
</View>
);
}
```

## Props

### `disabled`: `boolean`

Whether the field is disabled.

- Required: No

### `hasError`: `boolean`

Renders an error style around the component.

### `disabled`: `boolean`

Whether the field is disabled.
- Required: No
- Default: `false`

### `isInline`: `boolean`

Renders a component that can be inlined in some text.

- Required: No
- Default: `false`

### `isSubtle`: `boolean`

Renders a subtle variant of the component.

- Required: No
- Default: `false`
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,16 @@ import { useMemo } from '@wordpress/element';
/**
* Internal dependencies
*/
import { useContextSystem } from '../ui/context';
import { useContextSystem, WordPressComponentProps } from '../ui/context';
import { useControlGroupContext } from '../ui/control-group';
import { useFlex } from '../flex';
import * as styles from './styles';
import { useCx } from '../utils/hooks/use-cx';
import type { BaseFieldProps } from './types';

/**
* @typedef OwnProps
* @property {boolean} [hasError=false] Renders an error.
* @property {boolean} [disabled] Whether the field is disabled.
* @property {boolean} [isInline=false] Renders as an inline element (layout).
* @property {boolean} [isSubtle=false] Renders a subtle variant.
*/

/** @typedef {import('../flex/types').FlexProps & OwnProps} Props */

/**
* @param {import('../ui/context').WordPressComponentProps<Props, 'div'>} props
*/
export function useBaseField( props ) {
export function useBaseField(
props: WordPressComponentProps< BaseFieldProps, 'div' >
) {
const {
className,
hasError = false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import { render, screen } from '@testing-library/react';
*/
import { useBaseField } from '../index';
import { View } from '../../view';
import type { BaseFieldProps } from '../types';

const TestField = ( props ) => {
return <View { ...useBaseField( props ) } />;
const TestField = ( props: Omit< BaseFieldProps, 'children' > ) => {
return <View { ...useBaseField( { ...props, children: '' } ) } />;
};

describe( 'base field', () => {
Expand Down Expand Up @@ -62,10 +63,14 @@ describe( 'base field', () => {
// wrap this in a component so that `useContext` calls don't fail inside the hook
// assertions will still run as normal when we `render` the component :)
const Component = () => {
const disabled = Symbol.for( 'disabled' );
const defaultValue = Symbol.for( 'defaultValue' );
const disabled = true;
const defaultValue = 'Lorem ipsum';

const result = useBaseField( { disabled, defaultValue } );
const result = useBaseField( {
disabled,
defaultValue,
children: '',
} );

expect( result.disabled ).toBe( disabled );
expect( result.defaultValue ).toBe( defaultValue );
Expand Down
29 changes: 29 additions & 0 deletions packages/components/src/base-field/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* Internal dependencies
*/
import type { FlexProps } from '../flex/types';

export type BaseFieldProps = FlexProps & {
/**
* Whether the field is disabled.
*/
disabled?: boolean;
/**
* Renders an error style around the component.
*
* @default false
*/
hasError?: boolean;
/**
* Renders a component that can be inlined in some text.
*
* @default false
*/
isInline?: boolean;
/**
* Renders a subtle variant of the component.
*
* @default false
*/
isSubtle?: boolean;
};