diff --git a/packages/block-editor/src/hooks/border.scss b/packages/block-editor/src/hooks/border.scss index 0aab500b550764..c86c046309d886 100644 --- a/packages/block-editor/src/hooks/border.scss +++ b/packages/block-editor/src/hooks/border.scss @@ -3,51 +3,3 @@ grid-column: span 1; } } - -.block-editor__border-box-control__popover, -.block-editor__border-box-control__popover-top, -.block-editor__border-box-control__popover-right, -.block-editor__border-box-control__popover-bottom, -.block-editor__border-box-control__popover-left { - .components-popover__content { - width: 282px; - } -} - -$split-border-control-offset: 55px; - -@include break-medium() { - .block-editor__border-box-control__popover, - .block-editor__border-box-control__popover-left { - .components-popover__content { - margin-right: #{ $grid-unit-50 + $grid-unit-15 } !important; - } - } - - .block-editor__border-box-control__popover-top, - .block-editor__border-box-control__popover-bottom { - .components-popover__content { - margin-right: #{ $grid-unit-50 + $grid-unit-15 + $split-border-control-offset } !important; - } - } - - .block-editor__border-box-control__popover-right { - .components-popover__content { - margin-right: #{ $grid-unit-50 + $grid-unit-15 + ( $split-border-control-offset * 2 )} !important; - } - } - - .block-editor__border-box-control__popover, - .block-editor__border-box-control__popover-top, - .block-editor__border-box-control__popover-right, - .block-editor__border-box-control__popover-bottom, - .block-editor__border-box-control__popover-left { - &.is-from-top .components-popover__content { - margin-top: #{ -($grid-unit-50 + $grid-unit-15) } !important; - } - - &.is-from-bottom .components-popover__content { - margin-bottom: #{ -($grid-unit-50 + $grid-unit-15) } !important; - } - } -} diff --git a/packages/components/src/border-box-control/border-box-control-split-controls/component.tsx b/packages/components/src/border-box-control/border-box-control-split-controls/component.tsx index f1e7e26c37f0fa..6bf7925b7203ce 100644 --- a/packages/components/src/border-box-control/border-box-control-split-controls/component.tsx +++ b/packages/components/src/border-box-control/border-box-control-split-controls/component.tsx @@ -25,7 +25,7 @@ const BorderBoxControlSplitControls = ( enableAlpha, enableStyle, onChange, - popoverClassNames, + rightAlignedClassName, value, __experimentalHasMultipleOrigins, __experimentalIsRenderedInSidebar, @@ -50,24 +50,25 @@ const BorderBoxControlSplitControls = ( hideLabelFromVision={ true } label={ __( 'Top border' ) } onChange={ ( newBorder ) => onChange( newBorder, 'top' ) } - popoverContentClassName={ popoverClassNames?.top } value={ value?.top } + __experimentalSide={ 'top' } { ...sharedBorderControlProps } /> onChange( newBorder, 'left' ) } - popoverContentClassName={ popoverClassNames?.left } value={ value?.left } + __experimentalSide={ 'left' } { ...sharedBorderControlProps } /> onChange( newBorder, 'right' ) } - popoverContentClassName={ popoverClassNames?.right } value={ value?.right } + __experimentalSide={ 'right' } { ...sharedBorderControlProps } /> onChange( newBorder, 'bottom' ) } - popoverContentClassName={ popoverClassNames?.bottom } value={ value?.bottom } + __experimentalSide={ 'bottom' } { ...sharedBorderControlProps } /> diff --git a/packages/components/src/border-box-control/border-box-control-split-controls/hook.ts b/packages/components/src/border-box-control/border-box-control-split-controls/hook.ts index d7e018d7580ea0..f46bb415583560 100644 --- a/packages/components/src/border-box-control/border-box-control-split-controls/hook.ts +++ b/packages/components/src/border-box-control/border-box-control-split-controls/hook.ts @@ -30,5 +30,14 @@ export function useBorderBoxControlSplitControls( return cx( styles.CenteredBorderControl, className ); }, [] ); - return { ...otherProps, centeredClassName, className: classes }; + const rightAlignedClassName = useMemo( () => { + return cx( styles.RightBorderControl, className ); + }, [] ); + + return { + ...otherProps, + centeredClassName, + className: classes, + rightAlignedClassName, + }; } diff --git a/packages/components/src/border-box-control/border-box-control/README.md b/packages/components/src/border-box-control/border-box-control/README.md index 67a9426823f0f2..2b0ea5cd3dd214 100644 --- a/packages/components/src/border-box-control/border-box-control/README.md +++ b/packages/components/src/border-box-control/border-box-control/README.md @@ -122,26 +122,6 @@ _Note: The will be `undefined` if a user clears all borders._ - Required: Yes -### `popoverClassNames`: `Object` - -An object defining CSS classnames for all the inner `BorderControl` popover -content. - -Example: -```js -{ - linked: 'linked-border-popover-content', - top: 'top-border-popover-content', - right: 'right-border-popover-content', - bottom: 'bottom-border-popover-content', - left: 'left-border-popover-content', -} -``` - -By default, popovers are displayed relative to the button that initiated the popover. By supplying classnames for each individual popover, it is possible to add styling rules to align the popover positions to an unrelated design element, for example, the sidebar inspector in the block editor. - -- Required: No - ### `value`: `Object` An object representing the current border configuration. @@ -173,6 +153,7 @@ aware of whether the colors prop contains multiple origins. ### `__experimentalIsRenderedInSidebar`: `boolean` This is passed on to the color related sub-components so they may render more -effectively when used within a sidebar. +effectively when used within a sidebar. If `true` this prop will also adjust +border control popover styles for better sidebar display. - Required: No diff --git a/packages/components/src/border-box-control/border-box-control/component.tsx b/packages/components/src/border-box-control/border-box-control/component.tsx index 976fdf90c798b1..d44853c16cd31b 100644 --- a/packages/components/src/border-box-control/border-box-control/component.tsx +++ b/packages/components/src/border-box-control/border-box-control/component.tsx @@ -51,7 +51,6 @@ const BorderBoxControl = ( linkedValue, onLinkedChange, onSplitChange, - popoverClassNames, splitValue, toggleLinked, __experimentalHasMultipleOrigins, @@ -77,7 +76,6 @@ const BorderBoxControl = ( placeholder={ hasMixedBorders ? __( 'Mixed' ) : undefined } - popoverContentClassName={ popoverClassNames?.linked } shouldSanitizeBorder={ false } // This component will handle that. value={ linkedValue } withSlider={ true } @@ -88,6 +86,7 @@ const BorderBoxControl = ( __experimentalIsRenderedInSidebar={ __experimentalIsRenderedInSidebar } + __experimentalSide={ 'all' } /> ) : ( void; - /** - * An object defining CSS classnames for all the inner `BorderControl` - * popover content. - */ - popoverClassNames?: PopoverClassNames; /** * An object representing the current border configuration. * @@ -84,11 +71,6 @@ export type SplitControlsProps = ColorProps & { * changed. */ onChange: ( value: Border | undefined, side: BorderSide ) => void; - /** - * An object defining CSS classnames for the split side `BorderControl`s' - * popover content. - */ - popoverClassNames?: PopoverClassNames; /** * An object representing the current border configuration. It contains * properties for each side, with each side an object reflecting the border diff --git a/packages/components/src/border-control/border-control-dropdown/component.tsx b/packages/components/src/border-control/border-control-dropdown/component.tsx index e7bad227f72edd..175d96edd93843 100644 --- a/packages/components/src/border-control/border-control-dropdown/component.tsx +++ b/packages/components/src/border-control/border-control-dropdown/component.tsx @@ -141,8 +141,7 @@ const BorderControlDropdown = ( onReset, onColorChange, onStyleChange, - popoverClassName, - popoverContentClassName, + popoverProps, popoverControlsClassName, resetButtonClassName, showDropdownHeader, @@ -199,7 +198,6 @@ const BorderControlDropdown = ( ) : undefined } diff --git a/packages/components/src/border-control/border-control-dropdown/hook.ts b/packages/components/src/border-control/border-control-dropdown/hook.ts index 789dd7870cca50..efda7c5bbd56f8 100644 --- a/packages/components/src/border-control/border-control-dropdown/hook.ts +++ b/packages/components/src/border-control/border-control-dropdown/hook.ts @@ -9,6 +9,7 @@ import { useMemo } from '@wordpress/element'; import * as styles from '../styles'; import { parseQuantityAndUnitFromRawValue } from '../../unit-control/utils'; import { useContextSystem, WordPressComponentProps } from '../../ui/context'; +import { useResponsiveValue } from '../../ui/utils/use-responsive-value'; import { useCx } from '../../utils/hooks/use-cx'; import type { DropdownProps } from '../types'; @@ -20,9 +21,10 @@ export function useBorderControlDropdown( border, className, colors, - contentClassName, onChange, previousStyleSelection, + __experimentalIsRenderedInSidebar, + __experimentalSide, ...otherProps } = useContextSystem( props, 'BorderControlDropdown' ); @@ -64,18 +66,26 @@ export function useBorderControlDropdown( return cx( styles.colorIndicatorWrapper( border ) ); }, [ border, cx ] ); + // We only want to apply adjusted popover content styles when on desktop. + const responsiveSide = useResponsiveValue( [ + undefined, + undefined, + __experimentalSide, + ] ); + const popoverClassName = useMemo( () => { - return cx( styles.borderControlPopover, contentClassName ); - }, [ cx, contentClassName ] ); + return cx( + styles.borderControlPopover( + __experimentalIsRenderedInSidebar, + responsiveSide + ) + ); + }, [ cx, __experimentalIsRenderedInSidebar, responsiveSide ] ); const popoverControlsClassName = useMemo( () => { return cx( styles.borderControlPopoverControls ); }, [ cx ] ); - const popoverContentClassName = useMemo( () => { - return cx( styles.borderControlPopoverContent ); - }, [ cx ] ); - const resetButtonClassName = useMemo( () => { return cx( styles.resetButton ); }, [ cx ] ); @@ -90,9 +100,9 @@ export function useBorderControlDropdown( onColorChange, onStyleChange, onReset, - popoverClassName, - popoverContentClassName, + popoverProps: { className: popoverClassName }, popoverControlsClassName, resetButtonClassName, + __experimentalIsRenderedInSidebar, }; } diff --git a/packages/components/src/border-control/border-control/README.md b/packages/components/src/border-control/border-control/README.md index aa8b439d8326bb..8aaab9615cfbf0 100644 --- a/packages/components/src/border-control/border-control/README.md +++ b/packages/components/src/border-control/border-control/README.md @@ -113,13 +113,6 @@ _Note: the value may be `undefined` if a user clears all border properties._ - Required: Yes -### `popoverContentClassName`: `string` - -A custom CSS class name to be assigned to the `BorderControl`'s dropdown -popover content. - -- Required: No - ### `shouldSanitizeBorder`: `boolean` If opted into, sanitizing the border means that if no width or color have been @@ -179,3 +172,9 @@ This is passed on to the color related sub-components so they may render more effectively when used within a sidebar. - Required: No + +### `__experimentalSide`: 'all' | 'left' | 'top' | 'right' | 'bottom'; + +Identifies which side if any this border control will be representing. + +- Required: No diff --git a/packages/components/src/border-control/border-control/component.tsx b/packages/components/src/border-control/border-control/component.tsx index cf170861ea6c85..9717bd95157b37 100644 --- a/packages/components/src/border-control/border-control/component.tsx +++ b/packages/components/src/border-control/border-control/component.tsx @@ -43,7 +43,6 @@ const BorderControl = ( onSliderChange, onWidthChange, placeholder, - popoverContentClassName, previousStyleSelection, showDropdownHeader, sliderClassName, @@ -54,6 +53,7 @@ const BorderControl = ( withSlider, __experimentalHasMultipleOrigins, __experimentalIsRenderedInSidebar, + __experimentalSide, ...otherProps } = useBorderControl( props ); @@ -68,7 +68,6 @@ const BorderControl = ( css` */ ${ UnitControlWrapper } { flex: 1; + height: 36px; ${ rtl( { marginLeft: 0 } )() } } `; @@ -115,11 +116,60 @@ export const colorIndicatorWrapper = ( border?: Border ) => { `; }; -export const borderControlPopover = css` +const sidebarBorderPopoverContentStyles = css` + width: 282px; + margin-bottom: calc( ${ space( 13 ) } * -1 ); +`; + +const borderControlPopoverContent = ( + inSidebar?: boolean, + side?: BorderSides +) => { + if ( ! inSidebar || ! side ) { + return; + } + + /* High specificity below is required to counter Popover component styles */ + switch ( side ) { + case 'top': + case 'bottom': + return css` + &&&& > div { + ${ sidebarBorderPopoverContentStyles } + ${ rtl( { marginRight: space( 26.75 ) } )() } + } + `; + + case 'right': + return css` + &&&& > div { + ${ sidebarBorderPopoverContentStyles } + ${ rtl( { marginRight: space( 40.5 ) } )() } + } + `; + + case 'left': + case 'all': + default: + return css` + &&&& > div { + ${ sidebarBorderPopoverContentStyles } + ${ rtl( { marginRight: space( 13 ) } )() } + } + `; + } +}; + +export const borderControlPopover = ( + inSidebar?: boolean, + side?: BorderSides +) => css` /* Remove padding from content, this will be re-added via inner elements*/ && > div > div { padding: 0; } + /* If rendering within the sidebar adjust width and bottom margin. */ + ${ borderControlPopoverContent( inSidebar, side ) } `; export const borderControlPopoverControls = css` @@ -136,7 +186,6 @@ export const borderControlPopoverControls = css` } `; -export const borderControlPopoverContent = css``; export const borderColorIndicator = css``; export const resetButton = css` diff --git a/packages/components/src/border-control/types.ts b/packages/components/src/border-control/types.ts index 0a5971819d91fb..b784196d99aa60 100644 --- a/packages/components/src/border-control/types.ts +++ b/packages/components/src/border-control/types.ts @@ -8,6 +8,7 @@ export type Border = { style?: CSSProperties[ 'borderStyle' ]; width?: CSSProperties[ 'borderWidth' ]; }; +export type BorderSides = 'all' | 'left' | 'top' | 'right' | 'bottom'; export type Color = { name: string; @@ -80,11 +81,6 @@ export type BorderControlProps = ColorProps & * interaction that selects or clears, border color, style, or width. */ onChange: ( value?: Border ) => void; - /** - * A custom CSS class name to be assigned to the border control's - * dropdown popover content. - */ - popoverContentClassName?: string; /** * If opted into, sanitizing the border means that if no width or color * have been selected, the border style is also cleared and `undefined` @@ -114,6 +110,11 @@ export type BorderControlProps = ColorProps & * `RangeControl` for additional control over a border's width. */ withSlider?: boolean; + /** + * Identifies which side if any this border control will be + * representing. + */ + __experimentalSide?: BorderSides; }; export type DropdownProps = ColorProps & { @@ -150,6 +151,11 @@ export type DropdownProps = ColorProps & { * close button. */ showDropdownHeader?: boolean; + /** + * Identifies which side if any this border control will be + * representing. + */ + __experimentalSide?: BorderSides; }; export type StylePickerProps = LabelProps & { diff --git a/packages/components/src/color-palette/index.js b/packages/components/src/color-palette/index.js index 9e2745fd575747..f590383c5f57fa 100644 --- a/packages/components/src/color-palette/index.js +++ b/packages/components/src/color-palette/index.js @@ -152,17 +152,19 @@ const extractColorNameFromCurrentValue = ( return __( 'Custom' ); }; -export default function ColorPalette( { - clearable = true, - className, - colors, - disableCustomColors = false, - enableAlpha, - onChange, - value, - __experimentalHasMultipleOrigins = false, - __experimentalIsRenderedInSidebar = false, -} ) { +export default function ColorPalette( props ) { + const { + clearable = true, + className, + colors, + disableCustomColors = false, + enableAlpha, + onChange, + value, + __experimentalHasMultipleOrigins = false, + __experimentalIsRenderedInSidebar = false, + } = props; + const clearColor = useCallback( () => onChange( undefined ), [ onChange ] ); const showMultiplePalettes = __experimentalHasMultipleOrigins && colors?.length;