diff --git a/packages/blocks/src/types.ts b/packages/blocks/src/types.ts index aad6663dbdb7cb..4d4f4633839220 100644 --- a/packages/blocks/src/types.ts +++ b/packages/blocks/src/types.ts @@ -840,8 +840,17 @@ export interface TypographyProps { export interface SpacingProps { /** * Enable block gap control. + * + * The object form declares the sides the control applies to, and the gap + * value to fall back to when neither the theme nor the user has set one. */ - blockGap: boolean | AxialDirection[]; + blockGap: + | boolean + | AxialDirection[] + | { + __experimentalDefault?: string; + sides?: AxialDirection[]; + }; /** * Enable margin control UI for all or specified element directions. diff --git a/packages/components/src/icon/index.tsx b/packages/components/src/icon/index.tsx index 73ee33d8258853..e54c95e249d69b 100644 --- a/packages/components/src/icon/index.tsx +++ b/packages/components/src/icon/index.tsx @@ -25,6 +25,13 @@ export type IconType = | ( ( props: { size?: number } ) => React.JSX.Element ) | React.JSX.Element; +/* The sizing props forwarded to an icon element that is not an `SVG` or a `Dashicon`. */ +type SizeProps = { + size?: number; + width?: number | string; + height?: number | string; +}; + type AdditionalProps< T > = T extends ComponentType< infer U > ? U : T extends DashiconIconKey @@ -103,9 +110,8 @@ function Icon( { return ; } - if ( isValidElement( icon ) ) { + if ( isValidElement< SizeProps >( icon ) ) { return cloneElement( icon, { - // @ts-expect-error `size` is forwarded but is not in the icon component overloads. size, width: size, height: size, diff --git a/packages/components/src/input-control/utils.ts b/packages/components/src/input-control/utils.ts index 71e477d978ea5f..b95e698b0cf54c 100644 --- a/packages/components/src/input-control/utils.ts +++ b/packages/components/src/input-control/utils.ts @@ -60,8 +60,7 @@ export function useDragCursor( if ( isDragging ) { document.documentElement.style.cursor = dragCursor; } else { - // @ts-expect-error `cursor` is typed as `string`, but `null` clears it. - document.documentElement.style.cursor = null; + document.documentElement.style.removeProperty( 'cursor' ); } }, [ isDragging, dragCursor ] ); diff --git a/packages/dataviews/src/components/dataviews-view-config/properties-section.tsx b/packages/dataviews/src/components/dataviews-view-config/properties-section.tsx index c74ec9f4e630eb..d6cc19eb6f7797 100644 --- a/packages/dataviews/src/components/dataviews-view-config/properties-section.tsx +++ b/packages/dataviews/src/components/dataviews-view-config/properties-section.tsx @@ -80,7 +80,7 @@ export function PropertiesSection( { }, ].filter( ( { field } ) => isDefined( field ) ) as Array< { field: NormalizedField< any >; - isVisibleFlag: string; + isVisibleFlag: 'showTitle' | 'showMedia' | 'showDescription'; } >; const visibleFieldIds = view.fields ?? []; const visibleRegularFieldsCount = regularFields.filter( ( f ) => @@ -88,9 +88,7 @@ export function PropertiesSection( { ).length; const visibleLockedFields = lockedFields.filter( - ( { isVisibleFlag } ) => - // @ts-expect-error A string key cannot index `View`. - view[ isVisibleFlag ] ?? true + ( { isVisibleFlag } ) => view[ isVisibleFlag ] ?? true ); // If only one field (locked or regular) is visible, prevent it from being hidden @@ -112,7 +110,6 @@ export function PropertiesSection( { > { lockedFields.map( ( { field, isVisibleFlag } ) => { - // @ts-expect-error A string key cannot index `View`. const isVisible = view[ isVisibleFlag ] ?? true; const fieldToRender = isSingleVisibleLockedField && isVisible diff --git a/packages/global-styles-engine/src/core/render.tsx b/packages/global-styles-engine/src/core/render.tsx index e3f693418b02f1..8127000561206c 100644 --- a/packages/global-styles-engine/src/core/render.tsx +++ b/packages/global-styles-engine/src/core/render.tsx @@ -1921,9 +1921,12 @@ export const getBlockSelectors = ( const hasLayoutSupport = !! blockType?.supports?.layout || !! blockType?.supports?.__experimentalLayout; + const blockGapSupport = blockType?.supports?.spacing?.blockGap; const fallbackGapValue = - // @ts-expect-error `blockGap` support is typed as `boolean | AxialDirection[]`. - blockType?.supports?.spacing?.blockGap?.__experimentalDefault; + typeof blockGapSupport === 'object' && + ! Array.isArray( blockGapSupport ) + ? blockGapSupport.__experimentalDefault + : undefined; const blockStyleVariations = getBlockStyles( name ); const styleVariationSelectors: Record< string, string > = {}; diff --git a/packages/global-styles-engine/src/utils/background.ts b/packages/global-styles-engine/src/utils/background.ts index 41efe615b0b05d..fa7eb09c6c92fe 100644 --- a/packages/global-styles-engine/src/utils/background.ts +++ b/packages/global-styles-engine/src/utils/background.ts @@ -8,11 +8,29 @@ export const BACKGROUND_BLOCK_DEFAULT_VALUES = { backgroundPosition: '50% 50%', // used only when backgroundSize is 'contain'. }; +/** + * Whether a background image resolves to a URL, as opposed to a reference or an + * unresolved value. + * + * @param backgroundImage The background image value. + * + * @return Whether the value carries a URL. + */ +function hasImageUrl( + backgroundImage: BackgroundStyle[ 'backgroundImage' ] +): backgroundImage is { url: string } { + return ( + typeof backgroundImage === 'object' && + backgroundImage !== null && + 'url' in backgroundImage && + !! backgroundImage.url + ); +} + export function setBackgroundStyleDefaults( backgroundStyle: BackgroundStyle ) { if ( ! backgroundStyle || - // @ts-expect-error `backgroundImage` is a union whose other members have no `url`. - ! backgroundStyle?.backgroundImage?.url + ! hasImageUrl( backgroundStyle.backgroundImage ) ) { return; }