diff --git a/packages/block-editor/README.md b/packages/block-editor/README.md index 7c70473430b31..2a25addda9313 100644 --- a/packages/block-editor/README.md +++ b/packages/block-editor/README.md @@ -578,6 +578,10 @@ _Returns_ - `Object`: Typography block support derived CSS classes & styles. +### hasSplitBorders + +Undocumented declaration. + ### HeadingLevelDropdown Dropdown for selecting a heading level (1 through 6) or paragraph (0). @@ -629,6 +633,10 @@ _Related_ - +### isDefinedBorder + +Undocumented declaration. + ### isValueSpacingPreset Checks is given value is a spacing preset. diff --git a/packages/block-editor/src/components/border-box-utils/index.ts b/packages/block-editor/src/components/border-box-utils/index.ts new file mode 100644 index 0000000000000..745b1c4df79a4 --- /dev/null +++ b/packages/block-editor/src/components/border-box-utils/index.ts @@ -0,0 +1,49 @@ +/** + * Internal dependencies + */ +import type { + Border, + AnyBorder, + Borders, + BorderProp, + BorderSide, +} from './types'; + +const sides: BorderSide[] = [ 'top', 'right', 'bottom', 'left' ]; +const borderProps: BorderProp[] = [ 'color', 'style', 'width' ]; + +const isEmptyBorder = ( border?: Border ) => { + if ( ! border ) { + return true; + } + return ! borderProps.some( ( prop ) => border[ prop ] !== undefined ); +}; + +export const isDefinedBorder = ( border: AnyBorder ) => { + // No border, no worries :) + if ( ! border ) { + return false; + } + + // If we have individual borders per side within the border object we + // need to check whether any of those side borders have been set. + if ( hasSplitBorders( border ) ) { + const allSidesEmpty = sides.every( ( side ) => + isEmptyBorder( ( border as Borders )[ side ] ) + ); + + return ! allSidesEmpty; + } + + // If we have a top-level border only, check if that is empty. e.g. + // { color: undefined, style: undefined, width: undefined } + // Border radius can still be set within the border object as it is + // handled separately. + return ! isEmptyBorder( border as Border ); +}; + +export const hasSplitBorders = ( border: AnyBorder = {} ) => { + return Object.keys( border ).some( + ( side ) => sides.indexOf( side as BorderSide ) !== -1 + ); +}; diff --git a/packages/block-editor/src/components/border-box-utils/types.ts b/packages/block-editor/src/components/border-box-utils/types.ts new file mode 100644 index 0000000000000..ec4649225a29f --- /dev/null +++ b/packages/block-editor/src/components/border-box-utils/types.ts @@ -0,0 +1,21 @@ +/** + * External dependencies + */ +import type { CSSProperties } from 'react'; + +export type Border = { + color?: CSSProperties[ 'borderColor' ]; + style?: CSSProperties[ 'borderStyle' ]; + width?: CSSProperties[ 'borderWidth' ]; +}; + +export type Borders = { + top?: Border; + right?: Border; + bottom?: Border; + left?: Border; +}; + +export type AnyBorder = Border | Borders | undefined; +export type BorderProp = keyof Border; +export type BorderSide = keyof Borders; diff --git a/packages/block-editor/src/components/global-styles/border-panel.js b/packages/block-editor/src/components/global-styles/border-panel.js index a20bb15c044c5..a18d4fa66d5b9 100644 --- a/packages/block-editor/src/components/global-styles/border-panel.js +++ b/packages/block-editor/src/components/global-styles/border-panel.js @@ -3,8 +3,6 @@ */ import { __experimentalBorderBoxControl as BorderBoxControl, - __experimentalHasSplitBorders as hasSplitBorders, - __experimentalIsDefinedBorder as isDefinedBorder, __experimentalToolsPanel as ToolsPanel, __experimentalToolsPanelItem as ToolsPanelItem, __experimentalItemGroup as ItemGroup, @@ -22,6 +20,7 @@ import { getValueFromVariable, TOOLSPANEL_DROPDOWNMENU_PROPS } from './utils'; import { setImmutably } from '../../utils/object'; import { useBorderPanelLabel } from '../../hooks/border'; import { ShadowPopover, useShadowPresets } from './shadow-panel-components'; +import { hasSplitBorders, isDefinedBorder } from '../border-box-utils'; export function useHasBorderPanel( settings ) { const controls = Object.values( useHasBorderPanelControls( settings ) ); diff --git a/packages/block-editor/src/components/index.js b/packages/block-editor/src/components/index.js index 2a127feb3df1c..f1ff82c316010 100644 --- a/packages/block-editor/src/components/index.js +++ b/packages/block-editor/src/components/index.js @@ -175,3 +175,5 @@ export { useBlockCommands } from './use-block-commands'; * The following rename hint component can be removed in 6.4. */ export { default as ReusableBlocksRenameHint } from './inserter/reusable-block-rename-hint'; + +export * from './border-box-utils'; diff --git a/packages/block-editor/src/hooks/border.js b/packages/block-editor/src/hooks/border.js index 4ab4c69a41f31..e259fa0fe24d6 100644 --- a/packages/block-editor/src/hooks/border.js +++ b/packages/block-editor/src/hooks/border.js @@ -7,7 +7,6 @@ import clsx from 'clsx'; * WordPress dependencies */ import { hasBlockSupport, getBlockSupport } from '@wordpress/blocks'; -import { __experimentalHasSplitBorders as hasSplitBorders } from '@wordpress/components'; import { Platform, useCallback, useMemo } from '@wordpress/element'; import { addFilter } from '@wordpress/hooks'; import { useSelect } from '@wordpress/data'; @@ -30,6 +29,7 @@ import { } from '../components/global-styles'; import { store as blockEditorStore } from '../store'; import { __ } from '@wordpress/i18n'; +import { hasSplitBorders } from '../components/border-box-utils'; export const BORDER_SUPPORT_KEY = '__experimentalBorder'; export const SHADOW_SUPPORT_KEY = 'shadow'; diff --git a/packages/block-editor/tsconfig.json b/packages/block-editor/tsconfig.json index 192b6f7de7e12..ced74866a77cd 100644 --- a/packages/block-editor/tsconfig.json +++ b/packages/block-editor/tsconfig.json @@ -35,5 +35,8 @@ // NOTE: This package is being progressively typed. You are encouraged to // expand this array with files which can be type-checked. At some point in // the future, this can be simplified to an `includes` of `src/**/*`. - "files": [ "src/components/block-context/index.js", "src/utils/dom.js" ] + "files": [ "src/components/block-context/index.js", "src/utils/dom.js" ], + "include": [ + "src/components/border-box-utils/**/*" + ] } diff --git a/packages/block-library/src/table/edit.js b/packages/block-library/src/table/edit.js index f0c3ece790863..cfa35b926d8f0 100644 --- a/packages/block-library/src/table/edit.js +++ b/packages/block-library/src/table/edit.js @@ -14,6 +14,7 @@ import { BlockIcon, AlignmentControl, useBlockProps, + hasSplitBorders, __experimentalUseColorProps as useColorProps, __experimentalUseBorderProps as useBorderProps, __experimentalGetElementClassName, @@ -26,7 +27,6 @@ import { TextControl, ToggleControl, ToolbarDropdownMenu, - __experimentalHasSplitBorders as hasSplitBorders, } from '@wordpress/components'; import { alignLeft, diff --git a/packages/components/src/index.native.js b/packages/components/src/index.native.js index 7c2866cbe98b1..c7b36fa13310f 100644 --- a/packages/components/src/index.native.js +++ b/packages/components/src/index.native.js @@ -35,6 +35,7 @@ export { export { default as __experimentalStyleProvider } from './style-provider'; export { default as BaseControl } from './base-control'; +// @todo review this RN export export { hasSplitBorders as __experimentalHasSplitBorders } from './border-box-control/utils'; export { default as TextareaControl } from './textarea-control'; export { default as PanelBody } from './panel/body'; diff --git a/packages/components/src/index.ts b/packages/components/src/index.ts index f3643a1499a02..31218ccc342af 100644 --- a/packages/components/src/index.ts +++ b/packages/components/src/index.ts @@ -28,12 +28,7 @@ export { useAutocompleteProps as __unstableUseAutocompleteProps, } from './autocomplete'; export { default as BaseControl, useBaseControlProps } from './base-control'; -export { - BorderBoxControl as __experimentalBorderBoxControl, - hasSplitBorders as __experimentalHasSplitBorders, - isDefinedBorder as __experimentalIsDefinedBorder, - isEmptyBorder as __experimentalIsEmptyBorder, -} from './border-box-control'; +export { BorderBoxControl as __experimentalBorderBoxControl } from './border-box-control'; export { BorderControl as __experimentalBorderControl } from './border-control'; export { default as __experimentalBoxControl, diff --git a/packages/edit-site/src/components/global-styles/screen-block.js b/packages/edit-site/src/components/global-styles/screen-block.js index 2368f7499acbf..08d559937611e 100644 --- a/packages/edit-site/src/components/global-styles/screen-block.js +++ b/packages/edit-site/src/components/global-styles/screen-block.js @@ -2,14 +2,16 @@ * WordPress dependencies */ import { getBlockType } from '@wordpress/blocks'; -import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor'; +import { + privateApis as blockEditorPrivateApis, + hasSplitBorders, +} from '@wordpress/block-editor'; import { useMemo } from '@wordpress/element'; import { useSelect } from '@wordpress/data'; import { store as coreStore } from '@wordpress/core-data'; import { PanelBody, __experimentalVStack as VStack, - __experimentalHasSplitBorders as hasSplitBorders, } from '@wordpress/components'; import { __, sprintf } from '@wordpress/i18n';