Skip to content

Commit

Permalink
Heading: Complete TypeScript migration of component (#41921)
Browse files Browse the repository at this point in the history
  • Loading branch information
Petter Walbø Johnsgård committed Jun 28, 2022
1 parent 8854214 commit 443e8cb
Show file tree
Hide file tree
Showing 9 changed files with 110 additions and 115 deletions.
1 change: 1 addition & 0 deletions packages/components/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
- `AlignmentMatrixControl`: Refactor away from `_.flattenDeep()` in utils ([#41814](https://github.com/WordPress/gutenberg/pull/41814/)).
- `AutoComplete`: Revert recent `exhaustive-deps` refactor ([#41820](https://github.com/WordPress/gutenberg/pull/41820)).
- `Spacer`: Convert knobs to controls in Storybook ([#41851](https://github.com/WordPress/gutenberg/pull/41851)).
- `Heading`: Complete TypeScript migration ([#41921](https://github.com/WordPress/gutenberg/pull/41921)).
- `Navigation`: Refactor away from Lodash functions ([#41865](https://github.com/WordPress/gutenberg/pull/41865/)).
- `CustomGradientPicker`: Refactor away from Lodash ([#41901](https://github.com/WordPress/gutenberg/pull/41901/)).
- `SegmentedControl`: Refactor away from `_.values()` ([#41905](https://github.com/WordPress/gutenberg/pull/41905/)).
Expand Down
7 changes: 4 additions & 3 deletions packages/components/src/heading/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ function Example() {

`Heading` uses `Text` underneath, so we have access to all of `Text`'s props except for `size` which is replaced by `level`. For a complete list of those props, check out [`Text`](/packages/components/src/text/README.md#props).

##### level

**Type**: `1 | 2 | 3 | 4 | 5 | 6`
##### `level`: `1 | 2 | 3 | 4 | 5 | 6 | '1' | '2' | '3' | '4' | '5' | '6'`

Passing any of the heading levels to `level` will both render the correct typographic text size as well as the semantic element corresponding to the level (`h1` for `1` for example).

- Required: No
- Default: `2`
4 changes: 2 additions & 2 deletions packages/components/src/heading/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import type { ForwardedRef } from 'react';
*/
import { contextConnect, WordPressComponentProps } from '../ui/context';
import { View } from '../view';
import { useHeading, HeadingProps } from './hook';
import { useHeading } from './hook';
import type { HeadingProps } from './types';

function UnconnectedHeading(
props: WordPressComponentProps< HeadingProps, 'h1' >,
Expand All @@ -22,7 +23,6 @@ function UnconnectedHeading(
/**
* `Heading` renders headings and titles using the library's typography system.
*
* @example
* ```jsx
* import { __experimentalHeading as Heading } from "@wordpress/components";
*
Expand Down
43 changes: 1 addition & 42 deletions packages/components/src/heading/hook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,51 +2,10 @@
* Internal dependencies
*/
import { useContextSystem, WordPressComponentProps } from '../ui/context';
import type { Props as TextProps } from '../text/types';
import { useText } from '../text';
import { getHeadingFontSize } from '../ui/utils/font-size';
import { CONFIG, COLORS } from '../utils';

export type HeadingSize =
| 1
| 2
| 3
| 4
| 5
| 6
| '1'
| '2'
| '3'
| '4'
| '5'
| '6';

export interface HeadingProps extends Omit< TextProps, 'size' > {
/**
* `Heading` will typically render the sizes `1`, `2`, `3`, `4`, `5`, or `6`, which map to `h1`-`h6`.
*
* @default 2
*
* @example
* ```jsx
* import { __experimentalHeading as Heading } from `@wordpress/components`
*
* function Example() {
* return (
* <div>
* <Heading level="1">Code is Poetry</Heading>
* <Heading level="2">Code is Poetry</Heading>
* <Heading level="3">Code is Poetry</Heading>
* <Heading level="4">Code is Poetry</Heading>
* <Heading level="5">Code is Poetry</Heading>
* <Heading level="6">Code is Poetry</Heading>
* </div>
* );
* }
* ```
*/
level: HeadingSize;
}
import type { HeadingProps } from './types';

export function useHeading(
props: WordPressComponentProps< HeadingProps, 'h1' >
Expand Down
6 changes: 5 additions & 1 deletion packages/components/src/heading/stories/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ const meta: ComponentMeta< typeof Heading > = {
letterSpacing: { control: { type: 'text' } },
lineHeight: { control: { type: 'text' } },
optimizeReadabilityFor: { control: { type: 'color' } },
variant: { control: { type: 'radio' }, options: [ 'muted' ] },
variant: {
control: { type: 'radio' },
options: [ 'undefined', 'muted' ],
mapping: { undefined, muted: 'muted' },
},
weight: { control: { type: 'text' } },
},
parameters: {
Expand Down
67 changes: 0 additions & 67 deletions packages/components/src/heading/test/index.js

This file was deleted.

68 changes: 68 additions & 0 deletions packages/components/src/heading/test/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/**
* External dependencies
*/
import { render, screen } from '@testing-library/react';

/**
* Internal dependencies
*/
import { Heading } from '../';

describe( 'props', () => {
test( 'should render correctly', () => {
render( <Heading>Code is Poetry</Heading> );
expect( screen.getByRole( 'heading' ) ).toMatchSnapshot();
} );

test( 'should render level as a number', () => {
render( <Heading>Code is Poetry</Heading> );
render( <Heading level={ 4 }>Code is Poetry</Heading> );
expect(
screen.getByRole( 'heading', { level: 4 } )
).toMatchStyleDiffSnapshot(
screen.getByRole( 'heading', { level: 2 } )
);
} );

test( 'should render level as a string', () => {
render( <Heading>Code is Poetry</Heading> );
render( <Heading level="4">Code is Poetry</Heading> );
expect(
screen.getByRole( 'heading', { level: 4 } )
).toMatchStyleDiffSnapshot(
screen.getByRole( 'heading', { level: 2 } )
);
} );

test( 'should allow as prop', () => {
render(
<Heading level="1" as="span">
Code is Poetry
</Heading>
);
expect( screen.getByRole( 'heading' ).tagName ).toBe( 'SPAN' );
} );

test( 'should render a11y props when not using a semantic element', () => {
render(
<Heading level="3" as="div">
Code is Poetry
</Heading>
);
expect(
screen.getByRole( 'heading', { level: 3 } )
).toBeInTheDocument();
} );

test( 'should not render a11y props when using a semantic element', () => {
render(
<Heading level="1" as="h4">
Code is Poetry
</Heading>
);
expect( screen.getByRole( 'heading' ) ).not.toHaveAttribute( 'role' );
expect( screen.getByRole( 'heading' ) ).not.toHaveAttribute(
'aria-level'
);
} );
} );
29 changes: 29 additions & 0 deletions packages/components/src/heading/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* Internal dependencies
*/
import type { Props as TextProps } from '../text/types';

export type HeadingSize =
| 1
| 2
| 3
| 4
| 5
| 6
| '1'
| '2'
| '3'
| '4'
| '5'
| '6';

export type HeadingProps = Omit< TextProps, 'size' > & {
/**
* Passing any of the heading levels to `level` will both render the correct
* typographic text size as well as the semantic element corresponding to
* the level (`h1` for `1` for example).
*
* @default 2
*/
level?: HeadingSize;
};

0 comments on commit 443e8cb

Please sign in to comment.