Skip to content

Commit

Permalink
CustomSelectControlV2: tweak item inline padding based on size (WordP…
Browse files Browse the repository at this point in the history
…ress#62850)

* Use context to forward size down to the option item

* Apply different paddings based on item size, matching the select button

* Use shared variables

* CHANGELOG

* Extract size calculations outside of styled element function

---

Co-authored-by: ciampo <[email protected]>
Co-authored-by: tyxla <[email protected]>
  • Loading branch information
3 people authored Jul 2, 2024
1 parent 6a5e8df commit b67f00f
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 60 deletions.
1 change: 1 addition & 0 deletions packages/components/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
- `CustomSelectControlV2`: prevent keyboard event propagation in legacy wrapper. ([#62907](https://github.com/WordPress/gutenberg/pull/62907))
- `CustomSelectControlV2`: fix item styles ([#62825](https://github.com/WordPress/gutenberg/pull/62825))
- `CustomSelectControlV2`: add root element wrapper. ([#62803](https://github.com/WordPress/gutenberg/pull/62803))
- `CustomSelectControlV2`: tweak item inline padding based on size ([#62850](https://github.com/WordPress/gutenberg/pull/62850)).
- `CustomSelectControlV2`: fix popover styles. ([#62821](https://github.com/WordPress/gutenberg/pull/62821))
- `CustomSelectControlV2`: fix trigger text alignment in RTL languages ([#62869](https://github.com/WordPress/gutenberg/pull/62869)).
- `CustomSelectControlV2`: allow wrapping item hint to new line ([#62848](https://github.com/WordPress/gutenberg/pull/62848)).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ function _CustomSelect(
[ isLegacy ]
);

const contextValue = useMemo( () => ( { store, size } ), [ store, size ] );

return (
// Where should `restProps` be forwarded to?
<div className={ className }>
Expand Down Expand Up @@ -134,7 +136,7 @@ function _CustomSelect(
slide={ false }
onKeyDown={ onSelectPopoverKeyDown }
>
<CustomSelectContext.Provider value={ { store } }>
<CustomSelectContext.Provider value={ contextValue }>
{ children }
</CustomSelectContext.Provider>
</Styled.SelectPopover>
Expand Down
6 changes: 5 additions & 1 deletion packages/components/src/custom-select-control-v2/item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ export function CustomSelectItem( {
}: WordPressComponentProps< CustomSelectItemProps, 'div', false > ) {
const customSelectContext = useContext( CustomSelectContext );
return (
<Styled.SelectItem store={ customSelectContext?.store } { ...props }>
<Styled.SelectItem
store={ customSelectContext?.store }
size={ customSelectContext?.size ?? 'default' }
{ ...props }
>
{ children ?? props.value }
<Styled.SelectedItemCheck>
<Icon icon={ check } />
Expand Down
148 changes: 92 additions & 56 deletions packages/components/src/custom-select-control-v2/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,59 @@ import { space } from '../utils/space';
import { chevronIconSize } from '../select-control/styles/select-control-styles';
import type { CustomSelectButtonSize } from './types';

const ITEM_PADDING = space( 2 );
const INLINE_PADDING = {
compact: 8, // space(2)
small: 8, // space(2)
default: 16, // space(4)
};

const getSelectSize = (
size: NonNullable< CustomSelectButtonSize[ 'size' ] >,
heightProperty: 'minHeight' | 'height'
) => {
const sizes = {
compact: {
[ heightProperty ]: 32,
paddingInlineStart: INLINE_PADDING.compact,
paddingInlineEnd: INLINE_PADDING.compact + chevronIconSize,
},
default: {
[ heightProperty ]: 40,
paddingInlineStart: INLINE_PADDING.default,
paddingInlineEnd: INLINE_PADDING.default + chevronIconSize,
},
small: {
[ heightProperty ]: 24,
paddingInlineStart: INLINE_PADDING.small,
paddingInlineEnd: INLINE_PADDING.small + chevronIconSize,
},
};

return sizes[ size ] || sizes.default;
};

const getSelectItemSize = (
size: NonNullable< CustomSelectButtonSize[ 'size' ] >
) => {
// Used to visually align the checkmark with the chevron
const checkmarkCorrection = 6;
const sizes = {
compact: {
paddingInlineStart: INLINE_PADDING.compact,
paddingInlineEnd: INLINE_PADDING.compact - checkmarkCorrection,
},
default: {
paddingInlineStart: INLINE_PADDING.default,
paddingInlineEnd: INLINE_PADDING.default - checkmarkCorrection,
},
small: {
paddingInlineStart: INLINE_PADDING.small,
paddingInlineEnd: INLINE_PADDING.small - checkmarkCorrection,
},
};

return sizes[ size ] || sizes.default;
};

export const SelectLabel = styled( Ariakit.SelectLabel )`
font-size: 11px;
Expand All @@ -26,38 +78,14 @@ export const SelectLabel = styled( Ariakit.SelectLabel )`
export const Select = styled( Ariakit.Select, {
// Do not forward `hasCustomRenderProp` to the underlying Ariakit.Select component
shouldForwardProp: ( prop ) => prop !== 'hasCustomRenderProp',
} )( ( {
size,
hasCustomRenderProp,
}: {
size: NonNullable< CustomSelectButtonSize[ 'size' ] >;
hasCustomRenderProp: boolean;
} ) => {
const heightProperty = hasCustomRenderProp ? 'minHeight' : 'height';

const getSize = () => {
const sizes = {
compact: {
[ heightProperty ]: 32,
paddingInlineStart: 8,
paddingInlineEnd: 8 + chevronIconSize,
},
default: {
[ heightProperty ]: 40,
paddingInlineStart: 16,
paddingInlineEnd: 16 + chevronIconSize,
},
small: {
[ heightProperty ]: 24,
paddingInlineStart: 8,
paddingInlineEnd: 8 + chevronIconSize,
},
};

return sizes[ size ] || sizes.default;
};

return css`
} )(
( {
size,
hasCustomRenderProp,
}: {
size: NonNullable< CustomSelectButtonSize[ 'size' ] >;
hasCustomRenderProp: boolean;
} ) => css`
display: block;
background-color: ${ COLORS.theme.background };
border: none;
Expand All @@ -73,10 +101,10 @@ export const Select = styled( Ariakit.Select, {
outline: none; // handled by InputBase component
}
${ getSize() }
${ getSelectSize( size, hasCustomRenderProp ? 'minHeight' : 'height' ) }
${ ! hasCustomRenderProp && truncateStyles }
`;
} );
`
);

export const SelectPopover = styled( Ariakit.SelectPopover )`
display: flex;
Expand All @@ -101,31 +129,39 @@ export const SelectPopover = styled( Ariakit.SelectPopover )`
}
`;

export const SelectItem = styled( Ariakit.SelectItem )`
cursor: default;
display: flex;
align-items: center;
justify-content: space-between;
padding: ${ ITEM_PADDING };
font-size: ${ CONFIG.fontSize };
// TODO: reassess line-height for non-legacy v2
line-height: 28px;
scroll-margin: ${ space( 1 ) };
user-select: none;
&[aria-disabled='true'] {
cursor: not-allowed;
}
export const SelectItem = styled( Ariakit.SelectItem )(
( {
size,
}: {
size: NonNullable< CustomSelectButtonSize[ 'size' ] >;
} ) => css`
cursor: default;
display: flex;
align-items: center;
justify-content: space-between;
font-size: ${ CONFIG.fontSize };
// TODO: reassess line-height for non-legacy v2
line-height: 28px;
padding-block: ${ space( 2 ) };
scroll-margin: ${ space( 1 ) };
user-select: none;
&[data-active-item] {
background-color: ${ COLORS.theme.gray[ 300 ] };
}
`;
&[aria-disabled='true'] {
cursor: not-allowed;
}
&[data-active-item] {
background-color: ${ COLORS.theme.gray[ 300 ] };
}
${ getSelectItemSize( size ) }
`
);

export const SelectedItemCheck = styled( Ariakit.SelectItemCheck )`
display: flex;
align-items: center;
margin-inline-start: ${ ITEM_PADDING };
margin-inline-start: ${ space( 2 ) };
font-size: 24px; // Size of checkmark icon
`;

Expand Down
6 changes: 4 additions & 2 deletions packages/components/src/custom-select-control-v2/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ export type CustomSelectStore = {
store: Ariakit.SelectStore;
};

export type CustomSelectContext = CustomSelectStore | undefined;

type CustomSelectSize< Size = 'compact' | 'default' > = {
/**
* The size of the control.
Expand All @@ -27,6 +25,10 @@ export type CustomSelectButtonSize = CustomSelectSize<
'compact' | 'default' | 'small'
>;

export type CustomSelectContext =
| ( CustomSelectStore & CustomSelectButtonSize )
| undefined;

export type CustomSelectButtonProps = {
/**
* An optional default value for the control when used in uncontrolled mode.
Expand Down

0 comments on commit b67f00f

Please sign in to comment.