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

AlignmentMatrixControl: refactor to TypeScript #46162

Merged
merged 31 commits into from
Dec 6, 2022
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
b50cbee
remove from exclude list in tsconfig.json
chad1008 Nov 28, 2022
50b7b8c
rename files
chad1008 Nov 28, 2022
927dd12
add types.ts file
chad1008 Nov 28, 2022
ed54021
define types in utils.tsx
chad1008 Nov 28, 2022
a67acdc
add types to icon.tsx
chad1008 Nov 29, 2022
3d9bba6
add initial types to cell.tsx
chad1008 Nov 29, 2022
4ba5863
type main component props
chad1008 Nov 29, 2022
7a46879
type remainder of index.tsx, establish the AlignmentMatrixControlValu…
chad1008 Nov 29, 2022
abfcd64
Clean up type errors in cell.tsx
chad1008 Nov 30, 2022
91032be
fix undefined declaration on useBaseID
chad1008 Nov 30, 2022
4d0ee46
remove type props provided by WordPressComponentProps
chad1008 Nov 30, 2022
5f4a4aa
fix issues around AlignmentMatrixControlValue
chad1008 Nov 30, 2022
581b4de
fix types in styles files
chad1008 Nov 30, 2022
b1d4655
clean up type declarations
chad1008 Nov 30, 2022
42bbe67
fix width prop typing in styles file
chad1008 Nov 30, 2022
577f890
add types to test
chad1008 Nov 30, 2022
ded92be
type stories
chad1008 Nov 30, 2022
c5f4006
match README to types.ts
chad1008 Nov 30, 2022
0cc5543
remove todo
chad1008 Nov 30, 2022
704529d
remove `iconProps` abstraction, and exclude the `size` prop from `Root`
chad1008 Nov 30, 2022
c04514c
add named import and JSDoc example
chad1008 Dec 1, 2022
bef43fa
mark subcomponent props with default values as optional
chad1008 Dec 1, 2022
ed6c44d
fix typo
chad1008 Dec 1, 2022
585e404
clean up argTypes
chad1008 Dec 1, 2022
1a6746a
update CHANGELOG
chad1008 Dec 1, 2022
bec2095
remove uneeded type guard
chad1008 Dec 5, 2022
bebe60e
add missing JSDoc @default tags
chad1008 Dec 5, 2022
6b04a27
add named export to AlignmentMatrixControlIcon
chad1008 Dec 5, 2022
1398c9a
simplify `onChange` in component example
chad1008 Dec 5, 2022
3f54beb
remove unhelpful references to implementation details
chad1008 Dec 5, 2022
609b859
Merge branch 'trunk' into refactor/AlignmentMatrixControl-typescript
chad1008 Dec 6, 2022
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 @@ -36,6 +36,7 @@
- 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)).
- `Dashicon`: Convert to TypeScript ([#45924](https://github.com/WordPress/gutenberg/pull/45924)).
- `AlignmentMatrixControl`: Convert to TypeScript ([#46162](https://github.com/WordPress/gutenberg/pull/46162)).

### Documentation

Expand Down
14 changes: 7 additions & 7 deletions packages/components/src/alignment-matrix-control/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ The component accepts the following props:

### className

The class that will be added to the classes of the wrapper <Composite/> component.

The class that will be added to the classes of the underlying `grid` widget.
- Type: `string`
- Required: No

Expand All @@ -44,7 +43,7 @@ Unique ID for the component.

### label

Accessible label. If provided, sets the `aria-label` attribute of the underlying <Composite/> component.
Accessible label. If provided, sets the `aria-label` attribute of the underlying `grid` widget.

- Type: `string`
- Required: No
Expand All @@ -54,26 +53,27 @@ Accessible label. If provided, sets the `aria-label` attribute of the underlying

If provided, sets the default alignment value.

- Type: `string`
- Type: `AlignmentMatrixControlValue`
chad1008 marked this conversation as resolved.
Show resolved Hide resolved
- Required: No
- Default: `center center`

### value

The current alignment value.
- Type: `string`

- Type: `AlignmentMatrixControlValue`
- Required: No

### onChange

A function that receives the updated alignment value.

- Type: `( nextValue: string ) => void`
- Type: `( newValue: AlignmentMatrixControlValue ) => void`
- Required: No

### width

If provided, sets the width of the wrapper <Composite/> component.
If provided, sets the width of the control.

- Type: `number`
- Required: No
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,14 @@ import {
Cell as CellView,
Point,
} from './styles/alignment-matrix-control-styles';
import type { AlignmentMatrixControlCellProps } from './types';
import type { WordPressComponentProps } from '../ui/context';

export default function Cell( { isActive = false, value, ...props } ) {
export default function Cell( {
isActive = false,
value,
...props
}: WordPressComponentProps< AlignmentMatrixControlCellProps, 'span', false > ) {
const tooltipText = ALIGNMENT_LABEL[ value ];

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,19 @@ import {
Cell,
Point,
} from './styles/alignment-matrix-control-icon-styles';
import type { AlignmentMatrixControlIconProps } from './types';
chad1008 marked this conversation as resolved.
Show resolved Hide resolved
import type { WordPressComponentProps } from '../ui/context';

const BASE_SIZE = 24;

export default function AlignmentMatrixControlIcon( {
function AlignmentMatrixControlIcon( {
className,
disablePointerEvents = true,
size = BASE_SIZE,
style = {},
value = 'center',
...props
} ) {
}: WordPressComponentProps< AlignmentMatrixControlIconProps, 'div', false > ) {
const alignIndex = getAlignmentIndex( value );
const scale = ( size / BASE_SIZE ).toFixed( 2 );

Expand All @@ -42,7 +44,6 @@ export default function AlignmentMatrixControlIcon( {
className={ classes }
disablePointerEvents={ disablePointerEvents }
role="presentation"
size={ size }
chad1008 marked this conversation as resolved.
Show resolved Hide resolved
style={ styles }
>
{ ALIGNMENTS.map( ( align, index ) => {
Expand All @@ -57,3 +58,5 @@ export default function AlignmentMatrixControlIcon( {
</Root>
);
}

export default AlignmentMatrixControlIcon;
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,15 @@ import { Composite, CompositeGroup, useCompositeState } from '../composite';
import { Root, Row } from './styles/alignment-matrix-control-styles';
import AlignmentMatrixControlIcon from './icon';
import { GRID, getItemId } from './utils';
import type { WordPressComponentProps } from '../ui/context';
import type {
AlignmentMatrixControlProps,
AlignmentMatrixControlValue,
} from './types';

const noop = () => {};

function useBaseId( id ) {
function useBaseId( id?: string ) {
const instanceId = useInstanceId(
AlignmentMatrixControl,
'alignment-matrix-control'
Expand All @@ -30,7 +35,27 @@ function useBaseId( id ) {
return id || instanceId;
}

export default function AlignmentMatrixControl( {
/**
*
* AlignmentMatrixControl components enable adjustments to horizontal and vertical alignments for UI.
*
* ```jsx
* import { __experimentalAlignmentMatrixControl as AlignmentMatrixControl } from '@wordpress/components';
* import { useState } from '@wordpress/element';
*
* const Example = () => {
* const [ alignment, setAlignment ] = useState( 'center center' );
*
* return (
* <AlignmentMatrixControl
* value={ alignment }
* onChange={ setAlignment }
* />
* );
* };
* ```
*/
export function AlignmentMatrixControl( {
className,
id,
label = __( 'Alignment Matrix Control' ),
Expand All @@ -39,7 +64,7 @@ export default function AlignmentMatrixControl( {
onChange = noop,
width = 92,
...props
} ) {
}: WordPressComponentProps< AlignmentMatrixControlProps, 'div', false > ) {
const [ immutableDefaultValue ] = useState( value ?? defaultValue );
const baseId = useBaseId( id );
const initialCurrentId = getItemId( baseId, immutableDefaultValue );
Expand All @@ -50,7 +75,7 @@ export default function AlignmentMatrixControl( {
rtl: isRTL(),
} );

const handleOnChange = ( nextValue ) => {
const handleOnChange = ( nextValue: AlignmentMatrixControlValue ) => {
onChange( nextValue );
};

Expand Down Expand Up @@ -107,3 +132,5 @@ export default function AlignmentMatrixControl( {
}

AlignmentMatrixControl.Icon = AlignmentMatrixControlIcon;

export default AlignmentMatrixControl;
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/**
* External dependencies
*/
import type { ComponentMeta, ComponentStory } from '@storybook/react';

/**
* WordPress dependencies
*/
Expand All @@ -7,31 +12,34 @@ import { Icon } from '@wordpress/icons';
/**
* Internal dependencies
*/
import AlignmentMatrixControl from '../';
import { ALIGNMENTS } from '../utils';
import AlignmentMatrixControl from '..';
import { HStack } from '../../h-stack';
import type { AlignmentMatrixControlProps } from '../types';

export default {
const meta: ComponentMeta< typeof AlignmentMatrixControl > = {
title: 'Components (Experimental)/AlignmentMatrixControl',
component: AlignmentMatrixControl,
subcomponents: {
'AlignmentMatrixControl.Icon': AlignmentMatrixControl.Icon,
},
argTypes: {
defaultValue: { options: ALIGNMENTS },
onChange: { action: 'onChange', control: { type: null } },
label: { control: { type: 'text' } },
width: { control: { type: 'number' } },
value: { control: { type: null } },
},
parameters: {
controls: { expanded: true },
docs: { source: { state: 'open' } },
},
};
export default meta;

const Template = ( { defaultValue, onChange, ...props } ) => {
const [ value, setValue ] = useState();
const Template: ComponentStory< typeof AlignmentMatrixControl > = ( {
defaultValue,
onChange,
...props
} ) => {
const [ value, setValue ] =
useState< AlignmentMatrixControlProps[ 'value' ] >();

// Convenience handler for Canvas view so changes are reflected
useEffect( () => {
Expand All @@ -43,7 +51,7 @@ const Template = ( { defaultValue, onChange, ...props } ) => {
{ ...props }
onChange={ ( ...changeArgs ) => {
setValue( ...changeArgs );
onChange( ...changeArgs );
onChange?.( ...changeArgs );
} }
value={ value }
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ import {
pointBase,
Cell as CellBase,
} from './alignment-matrix-control-styles';
import type {
AlignmentMatrixControlIconProps,
AlignmentMatrixControlCellProps,
} from '../types';

const rootSize = () => {
const padding = 1.5;
Expand All @@ -25,9 +29,11 @@ const rootSize = () => {
} );
};

const rootPointerEvents = ( { disablePointerEvents } ) => {
const rootPointerEvents = ( {
disablePointerEvents,
}: Pick< AlignmentMatrixControlIconProps, 'disablePointerEvents' > ) => {
return css( {
pointerEvents: disablePointerEvents ? 'none' : null,
pointerEvents: disablePointerEvents ? 'none' : undefined,
} );
};

Expand All @@ -46,7 +52,9 @@ export const Root = styled.div`
${ rootPointerEvents };
`;

const pointActive = ( { isActive } ) => {
const pointActive = ( {
isActive,
}: Pick< AlignmentMatrixControlCellProps, 'isActive' > ) => {
const boxShadow = isActive ? `0 0 0 1px currentColor` : null;

return css`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ import { css } from '@emotion/react';
* Internal dependencies
*/
import { COLORS, reduceMotion } from '../../utils';
import type {
AlignmentMatrixControlProps,
AlignmentMatrixControlCellProps,
} from '../types';

export const rootBase = () => {
return css`
Expand All @@ -27,7 +31,9 @@ const rootSize = ( { size = 92 } ) => {
`;
};

export const Root = styled.div`
export const Root = styled.div< {
size: AlignmentMatrixControlProps[ 'width' ];
} >`
${ rootBase };

border: 1px solid transparent;
Expand All @@ -43,7 +49,9 @@ export const Row = styled.div`
grid-template-columns: repeat( 3, 1fr );
`;

const pointActive = ( { isActive } ) => {
const pointActive = ( {
isActive,
}: Pick< AlignmentMatrixControlCellProps, 'isActive' > ) => {
const boxShadow = isActive ? `0 0 0 2px ${ COLORS.gray[ 900 ] }` : null;
const pointColor = isActive ? COLORS.gray[ 900 ] : COLORS.gray[ 400 ];
const pointColorHover = isActive ? COLORS.gray[ 900 ] : COLORS.ui.theme;
Expand All @@ -58,7 +66,9 @@ const pointActive = ( { isActive } ) => {
`;
};

export const pointBase = ( props ) => {
export const pointBase = (
props: Pick< AlignmentMatrixControlCellProps, 'isActive' >
) => {
return css`
background: currentColor;
box-sizing: border-box;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import { act, render, screen, within } from '@testing-library/react';
/**
* Internal dependencies
*/
import AlignmentMatrixControl from '../';
import AlignmentMatrixControl from '..';

const getControl = () => {
return screen.getByRole( 'grid' );
};

const getCell = ( name ) => {
const getCell = ( name: string ) => {
return within( getControl() ).getByRole( 'gridcell', { name } );
};

Expand Down
54 changes: 54 additions & 0 deletions packages/components/src/alignment-matrix-control/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
export type AlignmentMatrixControlValue =
| 'top left'
| 'top center'
| 'top right'
| 'center left'
| 'center'
| 'center center'
| 'center right'
| 'bottom left'
| 'bottom center'
| 'bottom right';

export type AlignmentMatrixControlProps = {
/**
* Accessible label. If provided, sets the `aria-label` attribute of the
* underlying `grid` widget.
*
* @default 'Alignment Matrix Control'
*/
label?: string;
/**
* If provided, sets the default alignment value.
*
* @default 'center center'
*/
defaultValue?: AlignmentMatrixControlValue;
chad1008 marked this conversation as resolved.
Show resolved Hide resolved
/**
* The current alignment value.
*/
value?: AlignmentMatrixControlValue;
/**
* A function that receives the updated alignment value.
*/
onChange?: ( newValue: AlignmentMatrixControlValue ) => void;
/**
* If provided, sets the width of the control.
*
* @default 92
*/
width?: number;
chad1008 marked this conversation as resolved.
Show resolved Hide resolved
};

export type AlignmentMatrixControlIconProps = Pick<
AlignmentMatrixControlProps,
'value'
> & {
disablePointerEvents?: boolean;
size?: number;
};

export type AlignmentMatrixControlCellProps = {
isActive?: boolean;
value: NonNullable< AlignmentMatrixControlProps[ 'value' ] >;
};
Loading