Skip to content

Commit

Permalink
Polish ResizableBox and convert it to TypeScript. (#35062)
Browse files Browse the repository at this point in the history
* Polish ResizableBox and convert it to TypeScript.

* Address review feedback. Props to @sarayourfriend.

* Revise JSDocs.
  • Loading branch information
ZebulanStanphill committed Oct 13, 2021
1 parent 0afabe4 commit bbae8c9
Show file tree
Hide file tree
Showing 7 changed files with 225 additions and 161 deletions.
114 changes: 0 additions & 114 deletions packages/components/src/resizable-box/index.js

This file was deleted.

128 changes: 128 additions & 0 deletions packages/components/src/resizable-box/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/**
* WordPress dependencies
*/
import { forwardRef } from '@wordpress/element';

/**
* External dependencies
*/
import classnames from 'classnames';
import { Resizable } from 're-resizable';
import type { ResizableProps } from 're-resizable';
// eslint-disable-next-line no-restricted-imports
import type { ReactNode, Ref } from 'react';

/**
* Internal dependencies
*/
import ResizeTooltip from './resize-tooltip';

const HANDLE_CLASS_NAME = 'components-resizable-box__handle';
const SIDE_HANDLE_CLASS_NAME = 'components-resizable-box__side-handle';
const CORNER_HANDLE_CLASS_NAME = 'components-resizable-box__corner-handle';

const HANDLE_CLASSES = {
top: classnames(
HANDLE_CLASS_NAME,
SIDE_HANDLE_CLASS_NAME,
'components-resizable-box__handle-top'
),
right: classnames(
HANDLE_CLASS_NAME,
SIDE_HANDLE_CLASS_NAME,
'components-resizable-box__handle-right'
),
bottom: classnames(
HANDLE_CLASS_NAME,
SIDE_HANDLE_CLASS_NAME,
'components-resizable-box__handle-bottom'
),
left: classnames(
HANDLE_CLASS_NAME,
SIDE_HANDLE_CLASS_NAME,
'components-resizable-box__handle-left'
),
topLeft: classnames(
HANDLE_CLASS_NAME,
CORNER_HANDLE_CLASS_NAME,
'components-resizable-box__handle-top',
'components-resizable-box__handle-left'
),
topRight: classnames(
HANDLE_CLASS_NAME,
CORNER_HANDLE_CLASS_NAME,
'components-resizable-box__handle-top',
'components-resizable-box__handle-right'
),
bottomRight: classnames(
HANDLE_CLASS_NAME,
CORNER_HANDLE_CLASS_NAME,
'components-resizable-box__handle-bottom',
'components-resizable-box__handle-right'
),
bottomLeft: classnames(
HANDLE_CLASS_NAME,
CORNER_HANDLE_CLASS_NAME,
'components-resizable-box__handle-bottom',
'components-resizable-box__handle-left'
),
};

// Removes the inline styles in the drag handles.
const HANDLE_STYLES_OVERRIDES = {
width: undefined,
height: undefined,
top: undefined,
right: undefined,
bottom: undefined,
left: undefined,
};
const HANDLE_STYLES = {
top: HANDLE_STYLES_OVERRIDES,
right: HANDLE_STYLES_OVERRIDES,
bottom: HANDLE_STYLES_OVERRIDES,
left: HANDLE_STYLES_OVERRIDES,
topLeft: HANDLE_STYLES_OVERRIDES,
topRight: HANDLE_STYLES_OVERRIDES,
bottomRight: HANDLE_STYLES_OVERRIDES,
bottomLeft: HANDLE_STYLES_OVERRIDES,
};

type ResizableBoxProps = ResizableProps & {
className: string;
children: ReactNode;
showHandle: boolean;
__experimentalShowTooltip: boolean;
__experimentalTooltipProps: Parameters< typeof ResizeTooltip >[ 0 ];
};

function ResizableBox(
{
className,
children,
showHandle = true,
__experimentalShowTooltip: showTooltip = false,
__experimentalTooltipProps: tooltipProps = {},
...props
}: ResizableBoxProps,
ref: Ref< Resizable >
): JSX.Element {
return (
<Resizable
className={ classnames(
'components-resizable-box__container',
showHandle && 'has-show-handle',
className
) }
handleClasses={ HANDLE_CLASSES }
handleStyles={ HANDLE_STYLES }
ref={ ref }
{ ...props }
>
{ children }
{ showTooltip && <ResizeTooltip { ...tooltipProps } /> }
</Resizable>
);
}

export default forwardRef( ResizableBox );
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,29 @@ import classnames from 'classnames';
* WordPress dependencies
*/
import { forwardRef } from '@wordpress/element';
// eslint-disable-next-line no-restricted-imports
import type { Ref } from 'react';

/**
* Internal dependencies
*/
import Label from './label';
import { useResizeLabel, POSITIONS } from './utils';
import { useResizeLabel, Axis, Position, POSITIONS } from './utils';
import { Root } from './styles/resize-tooltip.styles';

type ResizeTooltipProps = React.ComponentProps< typeof Root > & {
'aria-hidden'?: boolean;
axis?: Axis;
className?: string;
fadeTimeout?: number;
isVisible?: boolean;
labelRef?: Ref< HTMLDivElement >;
onResize?: Parameters< typeof useResizeLabel >[ 0 ][ 'onResize' ];
position?: Position;
showPx?: boolean;
zIndex?: number;
};

function ResizeTooltip(
{
axis,
Expand All @@ -28,9 +43,9 @@ function ResizeTooltip(
showPx = true,
zIndex = 1000,
...props
},
ref
) {
}: ResizeTooltipProps,
ref: Ref< HTMLDivElement >
): JSX.Element | null {
const { label, resizeListener } = useResizeLabel( {
axis,
fadeTimeout,
Expand All @@ -48,8 +63,6 @@ function ResizeTooltip(
{ resizeListener }
<Label
aria-hidden={ props[ 'aria-hidden' ] }
fadeTimeout={ fadeTimeout }
isVisible={ isVisible }
label={ label }
position={ position }
ref={ labelRef }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
/**
* External dependencies
*/
// eslint-disable-next-line no-restricted-imports
import type { Ref } from 'react';

/**
* WordPress dependencies
*/
Expand All @@ -7,7 +13,7 @@ import { isRTL } from '@wordpress/i18n';
/**
* Internal dependencies
*/
import { POSITIONS } from './utils';
import { Position, POSITIONS } from './utils';
import {
TooltipWrapper,
Tooltip,
Expand All @@ -17,19 +23,28 @@ import {
const CORNER_OFFSET = 4;
const CURSOR_OFFSET_TOP = CORNER_OFFSET * 2.5;

type LabelProps = React.DetailedHTMLProps<
React.HTMLAttributes< HTMLDivElement >,
HTMLDivElement
> & {
label?: string;
position: Position;
zIndex: number;
};

function Label(
{ label, position = POSITIONS.corner, zIndex = 1000, ...props },
ref
) {
{ label, position = POSITIONS.corner, zIndex = 1000, ...props }: LabelProps,
ref: Ref< HTMLDivElement >
): JSX.Element | null {
const showLabel = !! label;

const isBottom = position === POSITIONS.bottom;
const isCorner = position === POSITIONS.corner;

if ( ! showLabel ) return null;

let style = {
opacity: showLabel ? 1 : null,
let style: React.CSSProperties = {
opacity: showLabel ? 1 : undefined,
zIndex,
};

Expand All @@ -54,16 +69,15 @@ function Label(
...style,
position: 'absolute',
top: CORNER_OFFSET,
right: isRTL() ? null : CORNER_OFFSET,
left: isRTL() ? CORNER_OFFSET : null,
right: isRTL() ? undefined : CORNER_OFFSET,
left: isRTL() ? CORNER_OFFSET : undefined,
};
}

return (
<TooltipWrapper
aria-hidden="true"
className="components-resizable-tooltip__tooltip-wrapper"
isActive={ showLabel }
ref={ ref }
style={ style }
{ ...props }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export const Tooltip = styled.div`

export const LabelText = styled( Text )`
&&& {
color: white;
color: ${ COLORS.ui.textDark };
display: block;
font-size: 13px;
line-height: 1.4;
Expand Down
Loading

0 comments on commit bbae8c9

Please sign in to comment.