From 37e4e72203c99f56b1c1691a56878613e5e4e38c Mon Sep 17 00:00:00 2001 From: im3dabasia Date: Mon, 30 Dec 2024 16:33:03 +0530 Subject: [PATCH 1/5] feat: Improve developer experience for presets --- packages/components/src/box-control/index.tsx | 9 +++++++++ packages/components/src/box-control/types.ts | 4 +++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/components/src/box-control/index.tsx b/packages/components/src/box-control/index.tsx index d4d4b03f893036..e38d5ac51ae5a2 100644 --- a/packages/components/src/box-control/index.tsx +++ b/packages/components/src/box-control/index.tsx @@ -4,6 +4,7 @@ import { useInstanceId } from '@wordpress/compose'; import { useState } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; +import warning from '@wordpress/warning'; /** * Internal dependencies @@ -166,6 +167,14 @@ function BoxControl( { } ); const sidesToRender = getAllowedSides( sides ); + if ( ( presets && ! presetKey ) || ( ! presets && presetKey ) ) { + warning( + presets + ? '`presetKey` is required when `presets` is defined.' + : '`presets` is required when `presetKey` is defined.' + ); + } + return ( & * If you provide a list of presets, you must provide a preset key to use. * The format of preset selected values is going to be `var:preset|${ presetKey }|${ presetSlug }` */ - presetKey?: string; + presetKey?: BoxControlProps[ 'presets' ] extends undefined + ? never + : string; }; export type BoxControlInputControlProps = UnitControlPassthroughProps & { From e760c72404f1c13e9d6feb06d4d9bdccd28c84c0 Mon Sep 17 00:00:00 2001 From: im3dabasia Date: Mon, 20 Jan 2025 22:18:27 +0530 Subject: [PATCH 2/5] fix: change Warning error message --- packages/components/src/box-control/index.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/components/src/box-control/index.tsx b/packages/components/src/box-control/index.tsx index e38d5ac51ae5a2..c5bf28a13de3ad 100644 --- a/packages/components/src/box-control/index.tsx +++ b/packages/components/src/box-control/index.tsx @@ -168,10 +168,10 @@ function BoxControl( { const sidesToRender = getAllowedSides( sides ); if ( ( presets && ! presetKey ) || ( ! presets && presetKey ) ) { + const definedProp = presets ? 'presets' : 'presetKey'; + const missingProp = presets ? 'presetKey' : 'presets'; warning( - presets - ? '`presetKey` is required when `presets` is defined.' - : '`presets` is required when `presetKey` is defined.' + `wp.components.BoxControl: the '${ missingProp }' prop is required when the '${ definedProp }' prop is defined.` ); } From 0b0c2e476b0e32255f6d415ddb6040ed35b148ab Mon Sep 17 00:00:00 2001 From: im3dabasia Date: Wed, 22 Jan 2025 20:57:09 +0530 Subject: [PATCH 3/5] fix: Enforce runtime check for presets, and presetKey --- .../components/src/box-control/test/index.tsx | 11 +++++- packages/components/src/box-control/types.ts | 39 ++++++++++++------- 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/packages/components/src/box-control/test/index.tsx b/packages/components/src/box-control/test/index.tsx index 185a18b258951f..a7d17b0289e92c 100644 --- a/packages/components/src/box-control/test/index.tsx +++ b/packages/components/src/box-control/test/index.tsx @@ -15,8 +15,15 @@ import { useState } from '@wordpress/element'; import BoxControl from '..'; import type { BoxControlProps, BoxControlValue } from '../types'; +// Since `BoxControlProps` is a the result of type unions, we need to use +// a distributive version of the standard `Omit` utility. +// See https://stackoverflow.com/a/57103940 +type DistributiveOmit< T, K extends keyof any > = T extends any + ? Omit< T, K > + : never; + const ControlledBoxControl = ( - extraProps: Omit< BoxControlProps, 'onChange' > + extraProps: DistributiveOmit< BoxControlProps, 'onChange' > ) => { const [ state, setState ] = useState< BoxControlValue >(); @@ -33,7 +40,7 @@ const ControlledBoxControl = ( const UncontrolledBoxControl = ( { onChange = () => {}, ...props -}: Omit< BoxControlProps, 'onChange' > & { +}: DistributiveOmit< BoxControlProps, 'onChange' > & { onChange?: BoxControlProps[ 'onChange' ]; } ) => ; diff --git a/packages/components/src/box-control/types.ts b/packages/components/src/box-control/types.ts index d0a353024c5fda..8c763f6ccb4d7c 100644 --- a/packages/components/src/box-control/types.ts +++ b/packages/components/src/box-control/types.ts @@ -100,19 +100,32 @@ export type BoxControlProps = Pick< UnitControlProps, 'units' > & * @default false */ __next40pxDefaultSize?: boolean; - /** - * Available presets to pick from. - */ - presets?: Preset[]; - /** - * The key of the preset to apply. - * If you provide a list of presets, you must provide a preset key to use. - * The format of preset selected values is going to be `var:preset|${ presetKey }|${ presetSlug }` - */ - presetKey?: BoxControlProps[ 'presets' ] extends undefined - ? never - : string; - }; + } & ( + | { + /** + * Available presets to pick from. + */ + presets?: never; + /** + * The key of the preset to apply. + * If you provide a list of presets, you must provide a preset key to use. + * The format of preset selected values is going to be `var:preset|${ presetKey }|${ presetSlug }` + */ + presetKey?: never; + } + | { + /** + * Available presets to pick from. + */ + presets: Preset[]; + /** + * The key of the preset to apply. + * If you provide a list of presets, you must provide a preset key to use. + * The format of preset selected values is going to be `var:preset|${ presetKey }|${ presetSlug }` + */ + presetKey: string; + } + ); export type BoxControlInputControlProps = UnitControlPassthroughProps & { onChange?: ( nextValues: BoxControlValue ) => void; From bb3d6eb2ac8211c5eac19af3999c2623fe88f6ca Mon Sep 17 00:00:00 2001 From: im3dabasia Date: Wed, 22 Jan 2025 21:24:23 +0530 Subject: [PATCH 4/5] doc: Add log for runtime check --- packages/components/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index db1778ee625b18..6c47514798534c 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -23,6 +23,7 @@ - `Text`: Fix text contrast for dark mode ([#68349](https://github.com/WordPress/gutenberg/pull/68349)). - `Heading`: Revert text contrast fix for dark mode with optimizeReadabilityFor ([#68472](https://github.com/WordPress/gutenberg/pull/68472)). - `Text`: Revert text contrast fix for dark mode with optimizeReadabilityFor ([#68472](https://github.com/WordPress/gutenberg/pull/68472)). +- `BoxControl`: Add runtime check for presets and presetKey ([#68385](https://github.com/WordPress/gutenberg/pull/68385)). ### Deprecations From c7d110a071531e0ba8412bac3cb09f5c910addb3 Mon Sep 17 00:00:00 2001 From: im3dabasia Date: Wed, 22 Jan 2025 21:38:45 +0530 Subject: [PATCH 5/5] doc: Add in unreleased section --- packages/components/CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index 6c47514798534c..6adec34a18b786 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Internal + +- `BoxControl`: Add runtime check for presets and presetKey ([#68385](https://github.com/WordPress/gutenberg/pull/68385)). + ## 29.2.0 (2025-01-15) ### Internal @@ -23,7 +27,6 @@ - `Text`: Fix text contrast for dark mode ([#68349](https://github.com/WordPress/gutenberg/pull/68349)). - `Heading`: Revert text contrast fix for dark mode with optimizeReadabilityFor ([#68472](https://github.com/WordPress/gutenberg/pull/68472)). - `Text`: Revert text contrast fix for dark mode with optimizeReadabilityFor ([#68472](https://github.com/WordPress/gutenberg/pull/68472)). -- `BoxControl`: Add runtime check for presets and presetKey ([#68385](https://github.com/WordPress/gutenberg/pull/68385)). ### Deprecations