600,
+ 'is-button': !! onClick,
} ) }
style={ {
color: textColor,
@@ -206,53 +218,125 @@ function StyleBook( { isSelected, onSelect } ) {
} }
>
{ resizeObserver }
-
- { ( tab ) => (
-
- ) }
-
+ ) }
+
+ ) : (
+
+ ) }
);
}
+const StyleBookBody = ( {
+ category,
+ examples,
+ isSelected,
+ onClick,
+ onSelect,
+ settings,
+ sizes,
+ title,
+} ) => {
+ const [ isFocused, setIsFocused ] = useState( false );
+
+ // The presence of an `onClick` prop indicates that the Style Book is being used as a button.
+ // In this case, add additional props to the iframe to make it behave like a button.
+ const buttonModeProps = {
+ role: 'button',
+ onFocus: () => setIsFocused( true ),
+ onBlur: () => setIsFocused( false ),
+ onKeyDown: ( event ) => {
+ if ( event.defaultPrevented ) {
+ return;
+ }
+ const { keyCode } = event;
+ if ( onClick && ( keyCode === ENTER || keyCode === SPACE ) ) {
+ event.preventDefault();
+ onClick( event );
+ }
+ },
+ onClick: ( event ) => {
+ if ( event.defaultPrevented ) {
+ return;
+ }
+ if ( onClick ) {
+ event.preventDefault();
+ onClick( event );
+ }
+ },
+ readonly: true,
+ };
+
+ const buttonModeStyles = onClick
+ ? 'body { cursor: pointer; } body * { pointer-events: none; }'
+ : '';
+
+ return (
+
+ );
+};
+
const Examples = memo(
( { className, examples, category, label, isSelected, onSelect } ) => {
const composite = useCompositeState( { orientation: 'vertical' } );
@@ -263,7 +347,9 @@ const Examples = memo(
aria-label={ label }
>
{ examples
- .filter( ( example ) => example.category === category )
+ .filter( ( example ) =>
+ category ? example.category === category : true
+ )
.map( ( example ) => (
{
- onSelect( example.name );
+ onSelect?.( example.name );
} }
/>
) ) }
diff --git a/packages/edit-site/src/components/style-book/style.scss b/packages/edit-site/src/components/style-book/style.scss
index 6dcc1fec328abc..0ddefb055a8d8d 100644
--- a/packages/edit-site/src/components/style-book/style.scss
+++ b/packages/edit-site/src/components/style-book/style.scss
@@ -1,3 +1,22 @@
+.edit-site-style-book {
+ // Ensure the style book fills the available vertical space.
+ // This is useful when the style book is used to fill a frame.
+ height: 100%;
+ &.is-button {
+ border-radius: $radius-block-ui * 4;
+ }
+}
+
+.edit-site-style-book__iframe {
+ &.is-button {
+ border-radius: $radius-block-ui * 4;
+ }
+ &.is-focused {
+ outline: calc(2 * var(--wp-admin-border-width-focus)) solid var(--wp-admin-theme-color);
+ outline-offset: calc(-2 * var(--wp-admin-border-width-focus));
+ }
+}
+
.edit-site-style-book__tab-panel {
.components-tab-panel__tabs {
background: $white;