diff --git a/packages/block-editor/src/components/index.js b/packages/block-editor/src/components/index.js index 9b094396d9d8b..c7792608518ac 100644 --- a/packages/block-editor/src/components/index.js +++ b/packages/block-editor/src/components/index.js @@ -32,6 +32,7 @@ export { default as MediaUpload } from './media-upload'; export { default as MediaUploadCheck } from './media-upload/check'; export { default as PanelColorSettings } from './panel-color-settings'; export { default as PlainText } from './plain-text'; +export { default as __experimentalResponsiveBlockControl } from './responsive-block-control'; export { default as RichText, RichTextShortcut, diff --git a/packages/block-editor/src/components/responsive-block-control/README.md b/packages/block-editor/src/components/responsive-block-control/README.md new file mode 100644 index 0000000000000..deabc0bc4af4c --- /dev/null +++ b/packages/block-editor/src/components/responsive-block-control/README.md @@ -0,0 +1,237 @@ +ResponsiveBlockControl +============================= + +`ResponsiveBlockControl` provides a standardised interface for the creation of Block controls that require **different settings per viewport** (ie: "responsive" settings). + +For example, imagine your Block provides a control which affords the ability to change a "padding" value used in the Block display. Consider that whilst this setting may work well on "large" screens, the same value may not work well on smaller screens (it may be too large for example). As a result, you now need to provide a padding control _per viewport/screensize_. + +`ResponsiveBlockControl` provides a standardised component for the creation of such interfaces within Gutenberg. + +Complete control over rendering the controls is provided and the viewport sizes used are entirely customisable. + +Note that `ResponsiveBlockControl` does not handle any persistence of your control values. The control you provide to `ResponsiveBlockControl` as the `renderDefaultControl` prop should take care of this. + +## Usage + +In a block's `edit` implementation, render a `` component passing the required props plus: + +1. a `renderDefaultControl` function which renders an interface control. +2. an boolean state for `isResponsive` (see "Props" below). +3. a handler function for `onIsResponsiveChange` (see "Props" below). + + +By default the default control will be used to render the default (ie: "All") setting _as well as_ the per-viewport responsive settings. + +```jsx +import { registerBlockType } from '@wordpress/blocks'; +import { + InspectorControls, + ResponsiveBlockControl, +} from '@wordpress/block-editor'; + +import { useState } from '@wordpress/element'; + +import { + DimensionControl, +} from '@wordpress/components'; + +registerBlockType( 'my-plugin/my-block', { + // ... + + edit( { attributes, setAttributes } ) { + + const [ isResponsive, setIsResponsive ] = useState( false ); + + // Used for example purposes only + const sizeOptions = [ + { + label: 'Small', + value: 'small', + }, + { + label: 'Medium', + value: 'medium', + }, + { + label: 'Large', + value: 'large', + }, + ]; + + const { paddingSize } = attributes; + + + // Your custom control can be anything you'd like to use. + // You are not restricted to `DimensionControl`s, but this + // makes life easier if dealing with standard CSS values. + // see `packages/components/src/dimension-control/README.md` + const paddingControl = ( labelComponent, viewport ) => { + return ( + + ); + }; + + return ( + <> + + { + setIsResponsive( ! isResponsive ); + } } + /> + +
+ // your Block here +
+ + ); + } +} ); +``` + +## Props + +### `title` +* **Type:** `String` +* **Default:** `undefined` +* **Required:** `true` + +The title of the control group used in the `fieldset`'s `legend` element to label the _entire_ set of controls. + +### `property` +* **Type:** `String` +* **Default:** `undefined` +* **Required:** `true` + +Used to build accessible labels and ARIA roles for the control group. Should represent the layout property which the component controls (eg: `padding`, `margin`...etc). + +### `isResponsive` +* **Type:** `Boolean` +* **Default:** `false` ) +* **Required:** `false` + +Determines whether the component displays the default or responsive controls. Updates the state of the toggle control. See also `onIsResponsiveChange` below. + +### `onIsResponsiveChange` +* **Type:** `Function` +* **Default:** `undefined` +* **Required:** `true` + +A callback function invoked when the component's toggle value is changed between responsive and non-responsive mode. Should be used to update the value of the `isResponsive` prop to reflect the current state of the toggle control. + +### `renderDefaultControl` +* **Type:** `Function` +* **Default:** `undefined` +* **Required:** `true` +* **Args:** + - **labelComponent:** (`Function`) - a rendered `ResponsiveBlockControlLabel` component for your control. + - **viewport:** (`Object`) - an object representing viewport attributes for your control. + +A render function (prop) used to render the control for which you would like to display per viewport settings. + +For example, if you have a `SelectControl` which controls padding size, then pass this component as `renderDefaultControl` and it will be used to render both default and "responsive" controls for "padding". + +The component you return from this function will be used to render the control displayed for the (default) "All" state and (if the `renderResponsiveControls` is not provided) the individual responsive controls when in "responsive" mode. + +It is passed a pre-created, accessible `