Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Block theme: Add drag handles to resize pattern preview #650

Merged
merged 9 commits into from
Apr 11, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,17 @@
$p->remove_attribute( 'data-wp-context' );
$content = $p->get_updated_html();

$html_id = wp_unique_id( 'pattern-preview-help-' );

?>
<div
<?php echo get_block_wrapper_attributes(); // phpcs:ignore ?>
data-wp-interactive="wporg/patterns/preview"
data-wp-context="<?php echo esc_attr( $encoded_state ); ?>"
data-wp-class--is-mobile-view="state.isWidthNarrow"
data-wp-class--is-dragging="state.isDrag"
data-wp-on-window--mousemove="actions.onDrag"
data-wp-on-window--mouseup="actions.onDragEnd"
>
<section class="wporg-pattern-view-control__controls wp-block-buttons" aria-label="<?php esc_attr_e( 'Preview width', 'wporg-patterns' ); ?>">
<div class="wp-block-button is-style-toggle is-small">
Expand Down Expand Up @@ -66,8 +71,37 @@ class="wp-block-button__link wp-element-button"
</div>
</section>

<?php
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Content from child blocks.
echo $content;
?>
<div class="wporg-pattern-preview__drag-container">
<div class="wporg-pattern-preview__drag-handle">
<button
class="wporg-pattern-view-control__drag-handle is-left"
aria-label="<?php esc_attr( 'Drag to resize', 'wporg-patterns' ); ?>"
aria-describedby="<?php echo esc_attr( $html_id ); ?>-left"
data-direction="left"
data-wp-on--keydown="actions.onLeftKeyDown"
data-wp-on--mousedown="actions.onDragStart"
></button>
</div>
<?php
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Content from child blocks.
echo $content;
?>
<div class="wporg-pattern-preview__drag-handle">
<button
class="wporg-pattern-view-control__drag-handle is-right"
aria-label="<?php esc_attr( 'Drag to resize', 'wporg-patterns' ); ?>"
aria-describedby="<?php echo esc_attr( $html_id ); ?>-right"
data-direction="right"
data-wp-on--keydown="actions.onRightKeyDown"
data-wp-on--mousedown="actions.onDragStart"
></button>
</div>
</div>

<span id="<?php echo esc_attr( $html_id ); ?>-left" hidden>
<?php esc_attr_e( 'Drag or use arrow keys to resize the pattern preview. Left to make larger, right to make smaller.', 'wporg-patterns' ); ?>
</span>
<span id="<?php echo esc_attr( $html_id ); ?>-right" hidden>
<?php esc_attr_e( 'Drag or use arrow keys to resize the pattern preview. Right to make larger, left to make smaller.', 'wporg-patterns' ); ?>
</span>
</div>
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@use "sass:math";

.wp-block-wporg-pattern-view-control {
position: relative;
width: 100%;
Expand All @@ -7,7 +9,7 @@
.wp-block-wporg-pattern-preview {
box-sizing: content-box;
border: none;
width: calc(100% - var(--wp--custom--wporg-pattern-preview--border--width) * 2);
width: auto;
padding: var(--wp--custom--wporg-pattern-preview--border--width);
display: flex;
justify-content: center;
Expand All @@ -24,12 +26,11 @@
margin: 0;
display: block;
border-radius: var(--wp--custom--wporg-pattern-preview--border--radius);
pointer-events: none;
}
}

&.is-mobile-view .wp-block-wporg-pattern-preview__container > iframe {
pointer-events: auto;
&.is-dragging .wp-block-wporg-pattern-preview__container > iframe {
pointer-events: none;
}
}

Expand All @@ -54,3 +55,59 @@
}
}
}

.wporg-pattern-preview__drag-container {
display: flex;
align-items: center;
justify-content: center;
}

.wporg-pattern-view-control__drag-handle {
$height: 52px;
$width: 4px;
height: $height;
width: $width;
box-sizing: content-box;
padding: 0;
z-index: 2;
border: none;
background-color: transparent;
cursor: col-resize;

&::before {
content: "";
display: block;
height: $height;
width: $width;
border-radius: math.div($width, 2);
background: var(--wp--preset--color--charcoal-5);
}

&:hover::before {
background: var(--wp--preset--color--charcoal-4);
}

&:focus {
box-shadow: none;

&::before {
background: var(--wp--preset--color--charcoal-4);
}
}

&:focus-visible::before {
box-shadow: 0 0 0 1.5px var(--wp--custom--link--color--text);
}

&.is-right {
padding-left: 10px;
}

&.is-left {
padding-right: 10px;
}

@media (max-width: 782px) {
display: none;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* WordPress dependencies
*/
import { getContext, getElement, store } from '@wordpress/interactivity';
import { getContext, getElement, store, withScope } from '@wordpress/interactivity';

const { actions, state } = store( 'wporg/patterns/preview', {
state: {
Expand All @@ -23,20 +23,80 @@ const { actions, state } = store( 'wporg/patterns/preview', {
return `scale(${ state.scale })`;
},
get isWidthWide() {
return 1200 === getContext().previewWidth;
return getContext().previewWidth >= 1200;
},
get isWidthMedium() {
return 800 === getContext().previewWidth;
return getContext().previewWidth >= 800 && getContext().previewWidth < 1200;
},
get isWidthNarrow() {
return 400 === getContext().previewWidth;
return getContext().previewWidth < 800;
},
dragPos: 0,
isDrag: false,
throttleTimeout: 0,
prevX: 0,
direction: '',
},
actions: {
updatePreviewWidth( newWidth ) {
const context = getContext();
if ( newWidth > 320 && newWidth < 1400 ) {
context.previewWidth = newWidth;
}
},
onWidthChange() {
const { ref } = getElement();
const context = getContext();
context.previewWidth = parseInt( ref.dataset.width, 10 );
setTimeout(
withScope( () => actions.handleOnResize() ),
0
);
},
onLeftKeyDown( event ) {
const context = getContext();
if ( 'ArrowLeft' === event.code ) {
actions.updatePreviewWidth( context.previewWidth + 20 );
} else if ( 'ArrowRight' === event.code ) {
actions.updatePreviewWidth( context.previewWidth - 20 );
}
},
onRightKeyDown( event ) {
const context = getContext();
if ( 'ArrowRight' === event.code ) {
actions.updatePreviewWidth( context.previewWidth + 20 );
} else if ( 'ArrowLeft' === event.code ) {
actions.updatePreviewWidth( context.previewWidth - 20 );
}
},
onDragStart( event ) {
const { ref } = getElement();
state.isDrag = true;
state.prevX = event.x;
state.direction = ref.dataset.direction;
state.dragPos = getContext().previewWidth;
},
onDrag( event ) {
if ( ! state.isDrag ) {
return;
}

const delta = event.x - state.prevX;
if ( ( delta < 0 && 'left' === state.direction ) || ( delta > 0 && 'right' === state.direction ) ) {
state.dragPos += 2 * Math.abs( delta );
actions.updatePreviewWidth( state.dragPos );
} else {
state.dragPos -= 2 * Math.abs( delta );
actions.updatePreviewWidth( state.dragPos );
}
actions.handleOnResize();

state.prevX = event.x;
},
onDragEnd() {
state.throttleTimeout = 0;
state.isDrag = false;
state.direction = '';
},
*onLoad() {
const { ref } = getElement();
Expand All @@ -50,27 +110,19 @@ const { actions, state } = store( 'wporg/patterns/preview', {
},
updatePreviewHeight() {
const context = getContext();
const { ref } = getElement();

// If this is the "narrow" (mobile) view, it should use a fixed height.
if ( state.isWidthNarrow ) {
context.previewHeight = 600;
return;
}

// Need to "use" previewWidth so that `data-wp-watch` will re-run this action when it changes.
context.previewWidth; // eslint-disable-line no-unused-expressions

const iframeDoc = ref.contentDocument;
const height = iframeDoc.querySelector( '.entry-content' )?.clientHeight;
if ( height ) {
context.previewHeight = height * state.scale;
}
context.previewHeight = 600;
},
handleOnResize() {
const context = getContext();
const { ref } = getElement();
context.pageWidth = ref.querySelector( 'div' )?.clientWidth;

// Back up to the block container, so that this works regardless
// of which element interaction triggered it.
const container = ref.closest( '.wp-block-wporg-pattern-view-control' );
if ( container ) {
const preview = container.querySelector( '.wp-block-wporg-pattern-preview__container' );
context.pageWidth = preview?.clientWidth;
}
},
},
} );
Loading