Skip to content

Commit

Permalink
AlignmentMatrixControl: refactor to TypeScript (WordPress#46162)
Browse files Browse the repository at this point in the history
Co-authored-by: Lena Morita <[email protected]>
  • Loading branch information
2 people authored and mpkelly committed Dec 7, 2022
1 parent aa31f74 commit ac19df6
Show file tree
Hide file tree
Showing 12 changed files with 173 additions and 47 deletions.
1 change: 1 addition & 0 deletions packages/components/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
- `useBaseField`: Convert to TypeScript ([#45712](https://github.com/WordPress/gutenberg/pull/45712)).
- `Dashicon`: Convert to TypeScript ([#45924](https://github.com/WordPress/gutenberg/pull/45924)).
- `PaletteEdit`: add follow up changelog for #45681 and tests [#46095](https://github.com/WordPress/gutenberg/pull/46095).
- `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`
- 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';
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 }
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;
/**
* 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;
};

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

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

0 comments on commit ac19df6

Please sign in to comment.