From c1ee5e689910161bd6573af0e5578a66a77de1d1 Mon Sep 17 00:00:00 2001 From: arthur Date: Mon, 16 Oct 2023 14:56:26 +0800 Subject: [PATCH 01/15] Device Switcher: Add range control of zoom --- .../pattern-large-preview.tsx | 3 ++- .../src/device-switcher/device-switcher.scss | 12 ++++++++++ .../src/device-switcher/device-switcher.tsx | 24 ++++++++++++++++--- .../src/device-switcher/toolbar.scss | 2 +- 4 files changed, 36 insertions(+), 5 deletions(-) diff --git a/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-large-preview.tsx b/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-large-preview.tsx index 8c38f039d72016..4460eaa51b42d0 100644 --- a/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-large-preview.tsx +++ b/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-large-preview.tsx @@ -43,7 +43,7 @@ const PatternLargePreview = ( { isNewSite, }: Props ) => { const translate = useTranslate(); - const hasSelectedPattern = header || sections.length || footer; + const hasSelectedPattern = Boolean( header || sections.length || footer ); const frameRef = useRef< HTMLDivElement | null >( null ); const listRef = useRef< HTMLUListElement | null >( null ); const [ viewportHeight, setViewportHeight ] = useState< number | undefined >( 0 ); @@ -154,6 +154,7 @@ const PatternLargePreview = ( { isShowFrameBorder isShowFrameShadow={ false } isFixedViewport={ !! hasSelectedPattern } + isZoomable frameRef={ frameRef } onDeviceChange={ ( device ) => { recordTracksEvent( PATTERN_ASSEMBLER_EVENTS.PREVIEW_DEVICE_CLICK, { device } ); diff --git a/packages/components/src/device-switcher/device-switcher.scss b/packages/components/src/device-switcher/device-switcher.scss index 5a5d28187dadb4..a24af8ca222436 100644 --- a/packages/components/src/device-switcher/device-switcher.scss +++ b/packages/components/src/device-switcher/device-switcher.scss @@ -14,6 +14,18 @@ } } +.device-switcher__header { + display: flex; + align-items: center; + width: 100%; + padding: 0 10px; + box-sizing: border-box; + + &:not(:empty) { + margin-bottom: 13px; + } +} + .device-switcher__container--frame-fixed-viewport { .device-switcher__viewport { position: relative; diff --git a/packages/components/src/device-switcher/device-switcher.tsx b/packages/components/src/device-switcher/device-switcher.tsx index ed96d12f7208bb..63c8018cf20f35 100644 --- a/packages/components/src/device-switcher/device-switcher.tsx +++ b/packages/components/src/device-switcher/device-switcher.tsx @@ -1,4 +1,6 @@ +import { RangeControl } from '@wordpress/components'; import { useResizeObserver } from '@wordpress/compose'; +import { search } from '@wordpress/icons'; import classnames from 'classnames'; import { useState, useEffect, useRef } from 'react'; import { DEVICE_TYPES } from './constants'; @@ -16,6 +18,7 @@ interface Props { isShowFrameShadow?: boolean; isFixedViewport?: boolean; isFullscreen?: boolean; + isZoomable?: boolean; frameRef?: React.MutableRefObject< HTMLDivElement | null >; onDeviceChange?: ( device: Device ) => void; onViewportChange?: ( height?: number ) => void; @@ -33,6 +36,7 @@ const DeviceSwitcher = ( { isShowFrameShadow = true, isFixedViewport, isFullscreen, + isZoomable, frameRef, onDeviceChange, onViewportChange, @@ -43,6 +47,7 @@ const DeviceSwitcher = ( { const viewportElement = frameRef?.current?.parentElement; const viewportWidth = viewportElement?.clientWidth as number; const viewportScale = useViewportScale( device, viewportWidth ); + const [ scale, setScale ] = useState( 1 ); const handleDeviceClick = ( nextDevice: Device ) => { setDevice( nextDevice ); @@ -84,9 +89,22 @@ const DeviceSwitcher = ( { 'device-switcher__container--is-fullscreen': isFullscreen, } ) } > - { isShowDeviceSwitcherToolbar && ( - - ) } +
+ { isShowDeviceSwitcherToolbar && ( + + ) } + { isZoomable && ( + value !== undefined && setScale( value ) } + min={ 0 } + max={ 100 } + /> + ) } +
{ isFixedViewport ? ( { frame } diff --git a/packages/components/src/device-switcher/toolbar.scss b/packages/components/src/device-switcher/toolbar.scss index 7d8cd9a99cafdc..32da3ceada8b3a 100644 --- a/packages/components/src/device-switcher/toolbar.scss +++ b/packages/components/src/device-switcher/toolbar.scss @@ -3,13 +3,13 @@ .device-switcher__toolbar { display: none; + flex: 1; .device-switcher__toolbar-devices { align-items: center; display: flex; height: 58px; gap: 18px; - margin-bottom: 13px; justify-content: center; > button { From 7a2256240a17a0de802b03d95ff01846a5c02487 Mon Sep 17 00:00:00 2001 From: arthur Date: Mon, 16 Oct 2023 15:54:39 +0800 Subject: [PATCH 02/15] Device Switcher: Handle zoom-out --- .../src/device-switcher/device-switcher.scss | 8 +++++++ .../src/device-switcher/device-switcher.tsx | 17 +++++++++----- .../src/device-switcher/use-zoom-out.ts | 22 +++++++++++++++++++ 3 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 packages/components/src/device-switcher/use-zoom-out.ts diff --git a/packages/components/src/device-switcher/device-switcher.scss b/packages/components/src/device-switcher/device-switcher.scss index a24af8ca222436..e5c977a591b1c2 100644 --- a/packages/components/src/device-switcher/device-switcher.scss +++ b/packages/components/src/device-switcher/device-switcher.scss @@ -21,6 +21,10 @@ padding: 0 10px; box-sizing: border-box; + .device-switcher__zoom-out { + width: 156px; + } + &:not(:empty) { margin-bottom: 13px; } @@ -121,4 +125,8 @@ max-height: var(--viewport-height); transition: width 0.2s ease-out, max-width 0.2s ease-out; } + + .device-switcher__container--is-zoomable & { + overflow: auto; + } } diff --git a/packages/components/src/device-switcher/device-switcher.tsx b/packages/components/src/device-switcher/device-switcher.tsx index 63c8018cf20f35..b8050bdae1b209 100644 --- a/packages/components/src/device-switcher/device-switcher.tsx +++ b/packages/components/src/device-switcher/device-switcher.tsx @@ -6,6 +6,7 @@ import { useState, useEffect, useRef } from 'react'; import { DEVICE_TYPES } from './constants'; import FixedViewport, { useViewportScale } from './fixed-viewport'; import DeviceSwitcherToolbar from './toolbar'; +import useZoomOut from './use-zoom-out'; import type { Device } from './types'; import './device-switcher.scss'; @@ -47,7 +48,7 @@ const DeviceSwitcher = ( { const viewportElement = frameRef?.current?.parentElement; const viewportWidth = viewportElement?.clientWidth as number; const viewportScale = useViewportScale( device, viewportWidth ); - const [ scale, setScale ] = useState( 1 ); + const { zoomOutScale, zoomOutStyles, onZoomOutScaleChange } = useZoomOut(); const handleDeviceClick = ( nextDevice: Device ) => { setDevice( nextDevice ); @@ -71,9 +72,11 @@ const DeviceSwitcher = ( { return clearAnimationEndTimer; }, [ width, height, viewportScale, isFixedViewport ] ); + const content = isZoomable ?
{ children }
: children; + const frame = (
- { children } + { content }
); @@ -87,6 +90,7 @@ const DeviceSwitcher = ( { 'device-switcher__container--is-tablet': device === 'tablet', 'device-switcher__container--is-phone': device === 'phone', 'device-switcher__container--is-fullscreen': isFullscreen, + 'device-switcher__container--is-zoomable': isZoomable, } ) } >
@@ -95,12 +99,13 @@ const DeviceSwitcher = ( { ) } { isZoomable && ( value !== undefined && setScale( value ) } - min={ 0 } + __nextHasNoMarginBottom + value={ Math.round( zoomOutScale * 100 ) } + onChange={ ( value ) => value !== undefined && onZoomOutScaleChange( value / 100 ) } + min={ 1 } max={ 100 } /> ) } diff --git a/packages/components/src/device-switcher/use-zoom-out.ts b/packages/components/src/device-switcher/use-zoom-out.ts new file mode 100644 index 00000000000000..b11d5aeddb927f --- /dev/null +++ b/packages/components/src/device-switcher/use-zoom-out.ts @@ -0,0 +1,22 @@ +import { useState } from 'react'; +import type { CSSProperties } from 'react'; + +const useZoomOut = () => { + const [ zoomOutScale, setZoomOutScale ] = useState( 1 ); + + const zoomOutStyles = { + width: '100%', + transform: `scale( ${ zoomOutScale } )`, + transformOrigin: 'top', + } as CSSProperties; + + const onZoomOutScaleChange = ( value: number ) => setZoomOutScale( value ); + + return { + zoomOutScale, + zoomOutStyles, + onZoomOutScaleChange, + }; +}; + +export default useZoomOut; From 41e439e3942fcdfa2e78bf4a306252827c0abd95 Mon Sep 17 00:00:00 2001 From: arthur Date: Mon, 16 Oct 2023 16:38:54 +0800 Subject: [PATCH 03/15] Device Switcher: Adjust styles --- .../src/device-switcher/device-switcher.scss | 26 +++++++++++++++++++ .../src/device-switcher/device-switcher.tsx | 3 +++ 2 files changed, 29 insertions(+) diff --git a/packages/components/src/device-switcher/device-switcher.scss b/packages/components/src/device-switcher/device-switcher.scss index e5c977a591b1c2..148a37aade061d 100644 --- a/packages/components/src/device-switcher/device-switcher.scss +++ b/packages/components/src/device-switcher/device-switcher.scss @@ -22,7 +22,33 @@ box-sizing: border-box; .device-switcher__zoom-out { + --wp-components-color-accent: var(--studio-gray-50, #50575e); width: 156px; + + svg { + width: 21px; + height: 21px; + margin-top: -4px; + fill: var(--studio-gray-50); + } + + .components-range-control__slider + span, + .components-range-control__track { + height: 3px; + } + + .components-range-control__thumb-wrapper { + width: 7px; + height: 7px; + margin-top: 11px; + + > span::before { + width: 11px; + height: 11px; + top: -2px; + left: -2px; + } + } } &:not(:empty) { diff --git a/packages/components/src/device-switcher/device-switcher.tsx b/packages/components/src/device-switcher/device-switcher.tsx index b8050bdae1b209..617162b647e6a1 100644 --- a/packages/components/src/device-switcher/device-switcher.tsx +++ b/packages/components/src/device-switcher/device-switcher.tsx @@ -102,6 +102,9 @@ const DeviceSwitcher = ( { className="device-switcher__zoom-out" beforeIcon={ search } withInputField={ false } + showTooltip={ false } + color="#C3C4C7" + trackColor="#50575E" __nextHasNoMarginBottom value={ Math.round( zoomOutScale * 100 ) } onChange={ ( value ) => value !== undefined && onZoomOutScaleChange( value / 100 ) } From efc2673c4233b6e249816fbba96f80c2f116dab2 Mon Sep 17 00:00:00 2001 From: arthur Date: Wed, 18 Oct 2023 16:21:51 +0800 Subject: [PATCH 04/15] Adjust the zoom-out behavior --- .../src/device-switcher/device-switcher.scss | 4 --- .../src/device-switcher/device-switcher.tsx | 29 ++++++++++--------- .../src/device-switcher/use-zoom-out.ts | 3 ++ 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/packages/components/src/device-switcher/device-switcher.scss b/packages/components/src/device-switcher/device-switcher.scss index 148a37aade061d..5120aa6e1596cf 100644 --- a/packages/components/src/device-switcher/device-switcher.scss +++ b/packages/components/src/device-switcher/device-switcher.scss @@ -151,8 +151,4 @@ max-height: var(--viewport-height); transition: width 0.2s ease-out, max-width 0.2s ease-out; } - - .device-switcher__container--is-zoomable & { - overflow: auto; - } } diff --git a/packages/components/src/device-switcher/device-switcher.tsx b/packages/components/src/device-switcher/device-switcher.tsx index 617162b647e6a1..4d26dbdc1ec8a2 100644 --- a/packages/components/src/device-switcher/device-switcher.tsx +++ b/packages/components/src/device-switcher/device-switcher.tsx @@ -72,14 +72,24 @@ const DeviceSwitcher = ( { return clearAnimationEndTimer; }, [ width, height, viewportScale, isFixedViewport ] ); - const content = isZoomable ?
{ children }
: children; - - const frame = ( + let frame = (
- { content } + { children }
); + if ( isZoomable ) { + frame =
{ frame }
; + } + + if ( isFixedViewport ) { + frame = ( + + { frame } + + ); + } + return (
@@ -108,18 +117,12 @@ const DeviceSwitcher = ( { __nextHasNoMarginBottom value={ Math.round( zoomOutScale * 100 ) } onChange={ ( value ) => value !== undefined && onZoomOutScaleChange( value / 100 ) } - min={ 1 } + min={ 25 } max={ 100 } /> ) }
- { isFixedViewport ? ( - - { frame } - - ) : ( - frame - ) } + { frame } { containerResizeListener }
); diff --git a/packages/components/src/device-switcher/use-zoom-out.ts b/packages/components/src/device-switcher/use-zoom-out.ts index b11d5aeddb927f..6cc3af37e636bf 100644 --- a/packages/components/src/device-switcher/use-zoom-out.ts +++ b/packages/components/src/device-switcher/use-zoom-out.ts @@ -5,7 +5,10 @@ const useZoomOut = () => { const [ zoomOutScale, setZoomOutScale ] = useState( 1 ); const zoomOutStyles = { + display: 'flex', + justifyContent: 'center', width: '100%', + height: `calc( 100% / ${ zoomOutScale } )`, transform: `scale( ${ zoomOutScale } )`, transformOrigin: 'top', } as CSSProperties; From ec37777379bfdc289fe1622fc00df31532d9aae2 Mon Sep 17 00:00:00 2001 From: arthur Date: Wed, 18 Oct 2023 18:16:08 +0800 Subject: [PATCH 05/15] Adjust slider styles --- .../src/device-switcher/device-switcher.scss | 38 +++++++++++++++---- .../src/device-switcher/device-switcher.tsx | 2 - 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/packages/components/src/device-switcher/device-switcher.scss b/packages/components/src/device-switcher/device-switcher.scss index 5120aa6e1596cf..fb920046388307 100644 --- a/packages/components/src/device-switcher/device-switcher.scss +++ b/packages/components/src/device-switcher/device-switcher.scss @@ -22,29 +22,53 @@ box-sizing: border-box; .device-switcher__zoom-out { - --wp-components-color-accent: var(--studio-gray-50, #50575e); + --zoom-out-thumb-size: 8px; + --zoom-out-primary-color: var(--studio-gray-50, #50575e); + --zoom-out-secondary-color: var(--studio-gray-10, #c3c4c7); + --wp-components-color-accent: var(--zoom-out-primary-color); width: 156px; + &:hover { + --zoom-out-primary-color: var(--studio-gray-100, #101517); + } + svg { width: 21px; height: 21px; margin-top: -4px; - fill: var(--studio-gray-50); + fill: var(--zoom-out-primary-color); + stroke: var(--zoom-out-primary-color); + } + + .components-range-control__wrapper:hover { + .components-range-control__thumb-wrapper { + transform: translate(4.5px, -50%) scale(1.5); + } } .components-range-control__slider + span, .components-range-control__track { height: 3px; + background: var(--zoom-out-secondary-color); + } + + .components-range-control__track { + background: var(--zoom-out-primary-color); } .components-range-control__thumb-wrapper { - width: 7px; - height: 7px; - margin-top: 11px; + width: var(--zoom-out-thumb-size); + height: var(--zoom-out-thumb-size); + top: 50%; + transform: translate(4.5px, -50%); + margin-top: 0; + border-color: var(--zoom-out-primary-color); + background: var(--zoom-out-primary-color); + transition: transform 0.15s ease-in-out; > span::before { - width: 11px; - height: 11px; + width: calc(var(--zoom-out-thumb-size) + 4px); + height: calc(var(--zoom-out-thumb-size) + 4px); top: -2px; left: -2px; } diff --git a/packages/components/src/device-switcher/device-switcher.tsx b/packages/components/src/device-switcher/device-switcher.tsx index 4d26dbdc1ec8a2..cb7fb7b80b6cae 100644 --- a/packages/components/src/device-switcher/device-switcher.tsx +++ b/packages/components/src/device-switcher/device-switcher.tsx @@ -112,8 +112,6 @@ const DeviceSwitcher = ( { beforeIcon={ search } withInputField={ false } showTooltip={ false } - color="#C3C4C7" - trackColor="#50575E" __nextHasNoMarginBottom value={ Math.round( zoomOutScale * 100 ) } onChange={ ( value ) => value !== undefined && onZoomOutScaleChange( value / 100 ) } From 8ec6e0b929de5d680c19e840d0e6e4ebdf06dbe7 Mon Sep 17 00:00:00 2001 From: arthur Date: Thu, 19 Oct 2023 13:58:13 +0800 Subject: [PATCH 06/15] Adjust styles --- .../components/src/device-switcher/device-switcher.scss | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/components/src/device-switcher/device-switcher.scss b/packages/components/src/device-switcher/device-switcher.scss index fb920046388307..b74c8e0f49bff6 100644 --- a/packages/components/src/device-switcher/device-switcher.scss +++ b/packages/components/src/device-switcher/device-switcher.scss @@ -21,12 +21,17 @@ padding: 0 10px; box-sizing: border-box; + .device-switcher__toolbar { + margin-bottom: 13px; + } + .device-switcher__zoom-out { --zoom-out-thumb-size: 8px; --zoom-out-primary-color: var(--studio-gray-50, #50575e); --zoom-out-secondary-color: var(--studio-gray-10, #c3c4c7); --wp-components-color-accent: var(--zoom-out-primary-color); width: 156px; + margin-bottom: 13px; &:hover { --zoom-out-primary-color: var(--studio-gray-100, #101517); @@ -74,10 +79,6 @@ } } } - - &:not(:empty) { - margin-bottom: 13px; - } } .device-switcher__container--frame-fixed-viewport { From 98b105abd5df9a30d5e294e50d77f6871e181d95 Mon Sep 17 00:00:00 2001 From: arthur Date: Thu, 19 Oct 2023 15:13:48 +0800 Subject: [PATCH 07/15] Disable zoom-out behavior when there is no selected pattern --- .../pattern-assembler/pattern-large-preview.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-large-preview.tsx b/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-large-preview.tsx index 4460eaa51b42d0..69c6dce31924ef 100644 --- a/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-large-preview.tsx +++ b/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-large-preview.tsx @@ -154,7 +154,7 @@ const PatternLargePreview = ( { isShowFrameBorder isShowFrameShadow={ false } isFixedViewport={ !! hasSelectedPattern } - isZoomable + isZoomable={ hasSelectedPattern } frameRef={ frameRef } onDeviceChange={ ( device ) => { recordTracksEvent( PATTERN_ASSEMBLER_EVENTS.PREVIEW_DEVICE_CLICK, { device } ); From 1c59956aee461827738f3555abfbf5112d9d10cb Mon Sep 17 00:00:00 2001 From: arthur Date: Thu, 19 Oct 2023 15:55:20 +0800 Subject: [PATCH 08/15] Clean up: PatternLayout --- .../pattern-assembler/index.tsx | 1 - .../pattern-assembler/pattern-layout.tsx | 80 --------- .../pattern-assembler/style.scss | 158 ------------------ 3 files changed, 239 deletions(-) delete mode 100644 client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-layout.tsx diff --git a/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/index.tsx b/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/index.tsx index 45573dbd63410b..2a5fb02001024f 100644 --- a/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/index.tsx +++ b/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/index.tsx @@ -627,7 +627,6 @@ const PatternAssembler = ( props: StepProps & NoticesProps ) => { return ( void; - onReplaceHeader?: () => void; - onDeleteHeader?: () => void; - onAddSection: () => void; - onReplaceSection: ( position: number ) => void; - onDeleteSection: ( position: number ) => void; - onMoveUpSection: ( position: number ) => void; - onMoveDownSection: ( position: number ) => void; - onAddFooter?: () => void; - onReplaceFooter?: () => void; - onDeleteFooter?: () => void; - onShuffle: ( type: string, pattern: Pattern, position?: number ) => void; -}; - -const PatternLayout = ( { - sections, - onAddSection, - onReplaceSection, - onDeleteSection, - onMoveUpSection, - onMoveDownSection, - onShuffle, -}: PatternLayoutProps ) => { - const translate = useTranslate(); - - return ( -
- { sections.length > 0 && ( - }> - { ( m: any ) => ( - - { sections.map( ( pattern: Pattern, index ) => { - const { title, category, key } = pattern; - return ( - - - { `${ index + 1 }. ${ category?.label }` } - - onReplaceSection( index ) } - onDelete={ () => onDeleteSection( index ) } - onMoveUp={ () => onMoveUpSection( index ) } - onMoveDown={ () => onMoveDownSection( index ) } - onShuffle={ () => onShuffle( 'sections', pattern, index ) } - disableMoveUp={ index === 0 } - disableMoveDown={ sections?.length === index + 1 } - /> - - ); - } ) } - - ) } - - ) } - -
- ); -}; - -export default PatternLayout; diff --git a/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/style.scss b/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/style.scss index 7c187b4fad0704..a6868eeeb60b84 100644 --- a/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/style.scss +++ b/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/style.scss @@ -79,125 +79,6 @@ $font-family: "SF Pro Text", $sans; } } - /** - * Pattern Layout - */ - .pattern-layout { - display: flex; - flex-direction: column; - height: 100%; - width: 100%; - margin: 0; - - button { - display: flex; - align-items: center; - border: 0; - padding: 0; - font-family: inherit; - color: var(--color-link); - transition: color 0.2s ease-in; - background-color: transparent; - } - - .pattern-layout__list { - list-style: none; - font-family: Inter, sans-serif; - font-style: normal; - font-weight: 500; - font-size: $font-body-small; - color: #101517; - letter-spacing: -0.24px; - user-select: none; - overflow-y: auto; - overflow-x: hidden; - scrollbar-width: none; - // Fix for tooltip position issue - padding-bottom: 25px; - - &::-webkit-scrollbar { - display: none; - } - } - - .pattern-layout__list-item { - position: relative; - display: flex; - align-items: center; - list-style: none; - height: 48px; - line-height: 48px; - border-bottom: 1px solid #eee; - - .pattern-layout__list-item-text { - text-overflow: ellipsis; - overflow: hidden; - max-width: 235px; - white-space: nowrap; - } - - &:hover, - &:focus, - &:focus-within { - button { - color: var(--color-link-dark); - } - - .pattern-layout__list-item-text { - max-width: 154px; - } - - .pattern-action-bar { - animation: slideInShort 0.2s forwards, fadeIn 0.3s forwards; - animation-timing-function: cubic-bezier(0.445, 0.05, 0.55, 0.95); - } - } - - &:last-child { - border-bottom: 0; - } - - &:first-child { - margin-top: auto; - } - } - - .pattern-layout__list-item-button { - width: 100%; - height: 100%; - } - - .pattern-layout__add-button { - flex-shrink: 0; - gap: 16px; - font-family: Inter, sans-serif; - - .pattern-layout__add-button-icon { - display: flex; - align-items: center; - justify-content: center; - width: 24px; - height: 24px; - padding: 5px 6px 6px; - border-radius: 2px; - box-sizing: border-box; - color: var(--studio-white); - background-color: var(--color-link); - transition: background-color 0.2s ease-in; - } - - &:hover, - &:focus, - &:focus-within { - color: var(--color-link-dark); - - .pattern-layout__add-button-icon { - background-color: var(--color-link-dark); - } - } - } - } - /** * Pattern Selector */ @@ -372,42 +253,3 @@ $font-family: "SF Pro Text", $sans; box-shadow: 0 0 0 2px var(--color-primary-light); } } - -.popover.is-right.pattern-layout__add-button-popover { - margin-left: 6px; - outline: none; - - .popover__arrow { - border-right-color: transparent; - - &::before { - border-width: 10px 16px; - border-right-color: var(--studio-black); - } - } - - .popover__inner { - line-height: 20px; - padding: 4px 8px; - border-radius: 4px; - border: 0; - color: #eee; - background-color: var(--studio-black); - } -} - -/** - * Revamp styles - */ -.pattern-assembler.pattern-assembler__sidebar-revamp { - .pattern-layout { - .pattern-layout__list { - // Fix for tooltip position issue - margin: 0 0 -9px; - } - - .pattern-action-bar { - right: 2px; - } - } -} From 36ff2ec87449e358ade28cc72ec424f0df502ecd Mon Sep 17 00:00:00 2001 From: arthur Date: Thu, 19 Oct 2023 21:47:35 +0800 Subject: [PATCH 09/15] Keep the action bar un-scaled and stick to the top of the active pattern --- .../pattern-assembler/pattern-action-bar.scss | 100 ++++++++----- .../pattern-assembler/pattern-action-bar.tsx | 7 +- .../pattern-large-preview.scss | 48 +------ .../pattern-large-preview.tsx | 131 ++++++++++++++---- .../src/device-switcher/device-switcher.tsx | 7 +- .../src/device-switcher/use-zoom-out.ts | 19 ++- 6 files changed, 192 insertions(+), 120 deletions(-) diff --git a/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-action-bar.scss b/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-action-bar.scss index 91a01864b2e74b..0d57b9ca8ba489 100644 --- a/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-action-bar.scss +++ b/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-action-bar.scss @@ -1,54 +1,78 @@ -.pattern-assembler { - .pattern-action-bar { +.pattern-assembler__pattern-action-bar { + display: flex; + align-items: center; + gap: 0; + position: absolute; + top: 0; + left: 0; + height: 40px; + transform: translateY(calc(-100% - 12px)); + padding: 0; + border: 1px solid #1e1e1e; + border-radius: 2px; + box-sizing: border-box; + background-color: #fff; + z-index: 1; + + .pattern-action-bar__block { + flex-direction: column; display: flex; - opacity: 0; align-items: center; - position: absolute; + justify-content: center; + } + + .pattern-action-bar__action { height: 40px; - right: 0; - .pattern-action-bar__block { - flex-direction: column; - display: flex; - align-items: center; - justify-content: center; + &.has-icon { + min-width: 40px; + max-width: 40px; + padding: 0; } - .pattern-action-bar__action { - &.has-icon { - min-width: 40px; - max-width: 40px; - padding: 0; - } + svg { + fill: var(--studio-gray-80); + } + + &:not(:disabled):hover { + color: var(--studio-blue-50); svg { - fill: var(--studio-gray-80); + fill: var(--studio-blue-50); } + } - &:not(:disabled):hover { - color: var(--studio-blue-50); + &--move-up, + &--move-down { + height: 13px; + display: flex; + align-items: center; + } - svg { - fill: var(--studio-blue-50); - } + &--shuffle { + &.has-icon { + flex-direction: row; + gap: 4px; + line-height: 40px; + max-width: none; + padding: 0 12px; } + } + } - &--move-up, - &--move-down { - height: 13px; - display: flex; - align-items: center; - } + > .pattern-action-bar__action:not(:first-child) { + border-left: 1px solid #1e1e1e; + } - &--shuffle { - &.has-icon { - flex-direction: row; - gap: 4px; - line-height: 40px; - max-width: none; - padding: 0 12px; - } - } - } + &::before { + content: ""; + position: absolute; + top: -12px; + left: -12px; + width: 100%; + height: 100%; + padding: 12px 12px 20px 12px; + box-sizing: content-box; + z-index: -1; } } diff --git a/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-action-bar.tsx b/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-action-bar.tsx index ea1162cdaefdbd..05fc42eea44e61 100644 --- a/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-action-bar.tsx +++ b/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-action-bar.tsx @@ -1,6 +1,7 @@ import { Button } from '@wordpress/components'; import { chevronUp, chevronDown, edit, shuffle, trash } from '@wordpress/icons'; import { useTranslate } from 'i18n-calypso'; +import React from 'react'; import { recordTracksEvent } from 'calypso/lib/analytics/tracks'; import { PATTERN_ASSEMBLER_EVENTS } from './events'; import type { Category } from './types'; @@ -12,6 +13,7 @@ type PatternActionBarProps = { onMoveUp?: () => void; onMoveDown?: () => void; onShuffle: () => void; + onMouseLeave?: ( event: React.MouseEvent< HTMLElement > ) => void; disableMoveUp?: boolean; disableMoveDown?: boolean; patternType: string; @@ -25,6 +27,7 @@ const PatternActionBar = ( { onMoveUp, onMoveDown, onShuffle, + onMouseLeave, disableMoveUp, disableMoveDown, patternType, @@ -39,10 +42,12 @@ const PatternActionBar = ( { }; return ( + // eslint-disable-next-line jsx-a11y/interactive-supports-focus
{ onMoveUp && onMoveDown && (
diff --git a/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-large-preview.scss b/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-large-preview.scss index cf63fd13ef461a..43f3af833416bd 100644 --- a/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-large-preview.scss +++ b/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-large-preview.scss @@ -37,45 +37,6 @@ $pattern-large-preview-outer-border-radius: calc(var(--device-switcher-border-radius) - var(--device-switcher-border-width)); position: relative; - .pattern-action-bar { - box-sizing: border-box; - position: absolute; - top: 16px; - left: 16px; - right: unset; - padding: 0; - border: 1px solid #1e1e1e; - border-radius: 2px; - gap: 0; - background-color: #fff; - opacity: 0; - z-index: 1; - // Scale up the action bar in fixed viewport - transform: scale(calc(1 / var(--viewport-scale))); - transform-origin: top left; - - > .pattern-action-bar__action { - position: relative; - min-height: 40px; - min-width: 40px; - padding: 2px; - - &:first-child::after { - content: none; - } - - &::after { - background-color: #1e1e1e; - bottom: 0; - content: ""; - left: 0; - position: absolute; - top: 0; - width: 1px; - } - } - } - &::after { content: ""; position: absolute; @@ -96,16 +57,13 @@ border-bottom-right-radius: $pattern-large-preview-outer-border-radius; } + &--active, &:hover, &:focus, &:focus-within { - .pattern-action-bar { - opacity: 1; - } - &::after { - // Scale up the border of a hovered pattern in fixed viewport - border: calc(2px * (1 / var(--viewport-scale))) solid var(--color-primary-light); + // Scale up the border of a active pattern + border: calc(2px * (1 / var(--viewport-scale) / var(--pattern-large-preview-zoom-out-scale))) solid var(--color-primary-light); } } } diff --git a/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-large-preview.tsx b/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-large-preview.tsx index 69c6dce31924ef..89b723e2770db5 100644 --- a/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-large-preview.tsx +++ b/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-large-preview.tsx @@ -1,9 +1,10 @@ import { PatternRenderer } from '@automattic/block-renderer'; import { DeviceSwitcher } from '@automattic/components'; import { useGlobalStyle } from '@automattic/global-styles'; +import { Popover } from '@wordpress/components'; import classnames from 'classnames'; import { useTranslate } from 'i18n-calypso'; -import { useRef, useEffect, useState, CSSProperties } from 'react'; +import React, { useRef, useEffect, useState, useMemo, CSSProperties } from 'react'; import { PATTERN_ASSEMBLER_EVENTS } from './events'; import PatternActionBar from './pattern-action-bar'; import { encodePatternId } from './utils'; @@ -28,6 +29,8 @@ interface Props { // The pattern renderer element has 1px min height before the pattern is loaded const PATTERN_RENDERER_MIN_HEIGHT = 1; +const LARGE_PREVIEW_OFFSET_TOP = 110; + const PatternLargePreview = ( { header, sections, @@ -51,39 +54,69 @@ const PatternLargePreview = ( { const [ blockGap ] = useGlobalStyle( 'spacing.blockGap' ); const [ backgroundColor ] = useGlobalStyle( 'color.background' ); const [ patternLargePreviewStyle, setPatternLargePreviewStyle ] = useState( { + '--pattern-large-preview-zoom-out-scale': 1, '--pattern-large-preview-background': backgroundColor, } as CSSProperties ); + const [ activeElement, setActiveElement ] = useState< HTMLElement | null >( null ); + + const popoverAnchor = useMemo( () => { + if ( ! activeElement ) { + return undefined; + } + + return { + getBoundingClientRect() { + const { left, top, width, height } = activeElement.getBoundingClientRect(); + + return new window.DOMRect( + left, + // Stick to the top when the partial area of the active element is out of the viewport + Math.max( top, LARGE_PREVIEW_OFFSET_TOP ), + width, + height + ); + }, + }; + }, [ activeElement ] ); + const renderPattern = ( type: string, pattern: Pattern, position = -1 ) => { - const key = type === 'section' ? pattern.key : type; - const handleShuffle = () => onShuffle( type, pattern, position ); - const getActionBarProps = () => { + const isSection = type === 'section'; + const clientId = isSection ? pattern.key : type; + const isActive = activeElement?.dataset?.clientId === clientId; + + const handleMouseEnter = ( event: React.MouseEvent< HTMLElement > ) => { + setActiveElement( event.currentTarget ); + }; + + const handleMouseLeave = ( event: React.MouseEvent< HTMLElement > ) => { + if ( ! frameRef.current?.contains( event.relatedTarget as Node ) ) { + setActiveElement( null ); + } + }; + + const handleDelete = () => { + setActiveElement( null ); if ( type === 'header' ) { - return { onDelete: onDeleteHeader, onShuffle: handleShuffle }; + onDeleteHeader(); } else if ( type === 'footer' ) { - return { onDelete: onDeleteFooter, onShuffle: handleShuffle }; + onDeleteFooter(); + } else { + onDeleteSection( position ); } - - return { - disableMoveUp: position === 0, - disableMoveDown: sections?.length === position + 1, - onDelete: () => onDeleteSection( position ), - onMoveUp: () => onMoveUpSection( position ), - onMoveDown: () => onMoveDownSection( position ), - onShuffle: handleShuffle, - }; }; return (
  • - { viewportHeight && ( + { !! viewportHeight && ( ) } - + { isActive && ( + + onMoveUpSection( position ) : undefined } + onMoveDown={ isSection ? () => onMoveDownSection( position ) : undefined } + onShuffle={ () => onShuffle( type, pattern, position ) } + onDelete={ handleDelete } + onMouseLeave={ handleMouseLeave } + /> + + ) }
  • ); }; @@ -142,11 +193,27 @@ const PatternLargePreview = ( { // Delay updating the styles to make the transition smooth // See https://github.com/Automattic/wp-calypso/pull/74033#issuecomment-1453056703 useEffect( () => { - setPatternLargePreviewStyle( { + setPatternLargePreviewStyle( ( current ) => ( { + ...current, '--pattern-large-preview-background': backgroundColor, - } as CSSProperties ); + } ) ); }, [ blockGap, backgroundColor ] ); + // Unset the hovered element when the mouse is leaving the large preview + useEffect( () => { + const handleMouseLeave = ( event: MouseEvent ) => { + const relatedTarget = event.relatedTarget as HTMLElement | null; + if ( ! relatedTarget?.closest( '.pattern-assembler__pattern-action-bar' ) ) { + setActiveElement( null ); + } + }; + + frameRef.current?.addEventListener( 'mouseleave', handleMouseLeave ); + return () => { + frameRef.current?.removeEventListener( 'mouseleave', handleMouseLeave ); + }; + }, [ frameRef, setActiveElement ] ); + return ( + setPatternLargePreviewStyle( ( current ) => ( { + ...current, + '--pattern-large-preview-zoom-out-scale': value, + } ) ) + } > { hasSelectedPattern ? (
      ; onDeviceChange?: ( device: Device ) => void; onViewportChange?: ( height?: number ) => void; + onZoomOutScaleChange?: ( value: number ) => void; } // Transition animation delay @@ -41,6 +42,7 @@ const DeviceSwitcher = ( { frameRef, onDeviceChange, onViewportChange, + onZoomOutScaleChange, }: Props ) => { const [ device, setDevice ] = useState< Device >( defaultDevice ); const [ containerResizeListener, { width, height } ] = useResizeObserver(); @@ -48,7 +50,8 @@ const DeviceSwitcher = ( { const viewportElement = frameRef?.current?.parentElement; const viewportWidth = viewportElement?.clientWidth as number; const viewportScale = useViewportScale( device, viewportWidth ); - const { zoomOutScale, zoomOutStyles, onZoomOutScaleChange } = useZoomOut(); + const { zoomOutScale, zoomOutStyles, handleZoomOutScaleChange } = + useZoomOut( onZoomOutScaleChange ); const handleDeviceClick = ( nextDevice: Device ) => { setDevice( nextDevice ); @@ -114,7 +117,7 @@ const DeviceSwitcher = ( { showTooltip={ false } __nextHasNoMarginBottom value={ Math.round( zoomOutScale * 100 ) } - onChange={ ( value ) => value !== undefined && onZoomOutScaleChange( value / 100 ) } + onChange={ ( value ) => value !== undefined && handleZoomOutScaleChange( value / 100 ) } min={ 25 } max={ 100 } /> diff --git a/packages/components/src/device-switcher/use-zoom-out.ts b/packages/components/src/device-switcher/use-zoom-out.ts index 6cc3af37e636bf..1f51dee134ae52 100644 --- a/packages/components/src/device-switcher/use-zoom-out.ts +++ b/packages/components/src/device-switcher/use-zoom-out.ts @@ -1,8 +1,10 @@ -import { useState } from 'react'; +import { useState, useEffect } from 'react'; import type { CSSProperties } from 'react'; -const useZoomOut = () => { - const [ zoomOutScale, setZoomOutScale ] = useState( 1 ); +const INITIAL_SCALE = 1; + +const useZoomOut = ( onZoomOutScaleChange?: ( value: number ) => void ) => { + const [ zoomOutScale, setZoomOutScale ] = useState( INITIAL_SCALE ); const zoomOutStyles = { display: 'flex', @@ -13,12 +15,19 @@ const useZoomOut = () => { transformOrigin: 'top', } as CSSProperties; - const onZoomOutScaleChange = ( value: number ) => setZoomOutScale( value ); + const handleZoomOutScaleChange = ( value: number ) => { + setZoomOutScale( value ); + onZoomOutScaleChange?.( value ); + }; + + useEffect( () => { + onZoomOutScaleChange?.( zoomOutScale ); + }, [] ); return { zoomOutScale, zoomOutStyles, - onZoomOutScaleChange, + handleZoomOutScaleChange, }; }; From 8af61d0db7e3103db701bd144846af3b33c49f3b Mon Sep 17 00:00:00 2001 From: arthur Date: Fri, 20 Oct 2023 15:08:02 +0800 Subject: [PATCH 10/15] Centralize viewport components --- .../components/src/device-switcher/device-switcher.scss | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/components/src/device-switcher/device-switcher.scss b/packages/components/src/device-switcher/device-switcher.scss index b74c8e0f49bff6..95fd2ae5ad3155 100644 --- a/packages/components/src/device-switcher/device-switcher.scss +++ b/packages/components/src/device-switcher/device-switcher.scss @@ -30,7 +30,11 @@ --zoom-out-primary-color: var(--studio-gray-50, #50575e); --zoom-out-secondary-color: var(--studio-gray-10, #c3c4c7); --wp-components-color-accent: var(--zoom-out-primary-color); - width: 156px; + + position: absolute; + right: 10px; + width: 15%; + max-width: 156px; margin-bottom: 13px; &:hover { From 966652e320ea6e564a1d62d0d5560372c45ee79b Mon Sep 17 00:00:00 2001 From: arthur Date: Fri, 20 Oct 2023 15:45:43 +0800 Subject: [PATCH 11/15] Adjust action bar position --- .../pattern-assembler/pattern-action-bar.scss | 18 +++++++++-- .../pattern-assembler/pattern-action-bar.tsx | 7 +++- .../pattern-large-preview.tsx | 32 +++++++------------ 3 files changed, 32 insertions(+), 25 deletions(-) diff --git a/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-action-bar.scss b/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-action-bar.scss index 0d57b9ca8ba489..cc572fa77c6068 100644 --- a/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-action-bar.scss +++ b/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-action-bar.scss @@ -3,10 +3,9 @@ align-items: center; gap: 0; position: absolute; - top: 0; - left: 0; + top: 16px; + left: 16px; height: 40px; - transform: translateY(calc(-100% - 12px)); padding: 0; border: 1px solid #1e1e1e; border-radius: 2px; @@ -14,6 +13,14 @@ background-color: #fff; z-index: 1; + &.pattern-assembler__pattern-action-bar--overflow { + transform: translate(-16px, calc(-100% - 16px - 12px)); + + &::before { + display: block; + } + } + .pattern-action-bar__block { flex-direction: column; display: flex; @@ -64,8 +71,13 @@ border-left: 1px solid #1e1e1e; } + /** + * Increase the area of the action bar to keep the element active + * when hovering on the the action bar + */ &::before { content: ""; + display: none; position: absolute; top: -12px; left: -12px; diff --git a/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-action-bar.tsx b/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-action-bar.tsx index 05fc42eea44e61..c84594345d5658 100644 --- a/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-action-bar.tsx +++ b/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-action-bar.tsx @@ -1,5 +1,6 @@ import { Button } from '@wordpress/components'; import { chevronUp, chevronDown, edit, shuffle, trash } from '@wordpress/icons'; +import classnames from 'classnames'; import { useTranslate } from 'i18n-calypso'; import React from 'react'; import { recordTracksEvent } from 'calypso/lib/analytics/tracks'; @@ -19,6 +20,7 @@ type PatternActionBarProps = { patternType: string; category?: Category; source: 'list' | 'large_preview'; + isOverflow?: boolean; }; const PatternActionBar = ( { @@ -33,6 +35,7 @@ const PatternActionBar = ( { patternType, category, source, + isOverflow, }: PatternActionBarProps ) => { const translate = useTranslate(); const eventProps = { @@ -44,7 +47,9 @@ const PatternActionBar = ( { return ( // eslint-disable-next-line jsx-a11y/interactive-supports-focus
      ( null ); const [ viewportHeight, setViewportHeight ] = useState< number | undefined >( 0 ); const [ device, setDevice ] = useState< string >( 'computer' ); - const [ blockGap ] = useGlobalStyle( 'spacing.blockGap' ); + const [ zoomOutScale, setZoomOutScale ] = useState( 1 ); const [ backgroundColor ] = useGlobalStyle( 'color.background' ); - const [ patternLargePreviewStyle, setPatternLargePreviewStyle ] = useState( { - '--pattern-large-preview-zoom-out-scale': 1, - '--pattern-large-preview-background': backgroundColor, - } as CSSProperties ); + const patternLargePreviewStyle = useMemo( + () => ( { + '--pattern-large-preview-zoom-out-scale': zoomOutScale, + '--pattern-large-preview-background': backgroundColor, + } ), + [ zoomOutScale, backgroundColor ] + ); const [ activeElement, setActiveElement ] = useState< HTMLElement | null >( null ); @@ -140,6 +143,7 @@ const PatternLargePreview = ( { patternType={ type } category={ pattern.category } source="large_preview" + isOverflow={ zoomOutScale < 0.75 } disableMoveUp={ position === 0 } disableMoveDown={ sections?.length === position + 1 } onMoveUp={ isSection ? () => onMoveUpSection( position ) : undefined } @@ -190,15 +194,6 @@ const PatternLargePreview = ( { }; }, [ activePosition, header, sections, footer ] ); - // Delay updating the styles to make the transition smooth - // See https://github.com/Automattic/wp-calypso/pull/74033#issuecomment-1453056703 - useEffect( () => { - setPatternLargePreviewStyle( ( current ) => ( { - ...current, - '--pattern-large-preview-background': backgroundColor, - } ) ); - }, [ blockGap, backgroundColor ] ); - // Unset the hovered element when the mouse is leaving the large preview useEffect( () => { const handleMouseLeave = ( event: MouseEvent ) => { @@ -228,12 +223,7 @@ const PatternLargePreview = ( { setDevice( device ); } } onViewportChange={ updateViewportHeight } - onZoomOutScaleChange={ ( value ) => - setPatternLargePreviewStyle( ( current ) => ( { - ...current, - '--pattern-large-preview-zoom-out-scale': value, - } ) ) - } + onZoomOutScaleChange={ setZoomOutScale } > { hasSelectedPattern ? (
        Date: Mon, 23 Oct 2023 15:55:32 +0800 Subject: [PATCH 12/15] Fix types --- .../pattern-assembler/pattern-large-preview.tsx | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-large-preview.tsx b/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-large-preview.tsx index 04373788cbe49a..0a9c19b02bdb16 100644 --- a/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-large-preview.tsx +++ b/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-large-preview.tsx @@ -4,7 +4,7 @@ import { useGlobalStyle } from '@automattic/global-styles'; import { Popover } from '@wordpress/components'; import classnames from 'classnames'; import { useTranslate } from 'i18n-calypso'; -import React, { useRef, useEffect, useState, useMemo } from 'react'; +import React, { useRef, useEffect, useState, useMemo, CSSProperties } from 'react'; import { PATTERN_ASSEMBLER_EVENTS } from './events'; import PatternActionBar from './pattern-action-bar'; import { encodePatternId } from './utils'; @@ -54,10 +54,11 @@ const PatternLargePreview = ( { const [ zoomOutScale, setZoomOutScale ] = useState( 1 ); const [ backgroundColor ] = useGlobalStyle( 'color.background' ); const patternLargePreviewStyle = useMemo( - () => ( { - '--pattern-large-preview-zoom-out-scale': zoomOutScale, - '--pattern-large-preview-background': backgroundColor, - } ), + () => + ( { + '--pattern-large-preview-zoom-out-scale': zoomOutScale, + '--pattern-large-preview-background': backgroundColor, + } ) as CSSProperties, [ zoomOutScale, backgroundColor ] ); From 33b7e4f42beb6c9709c675f9750eee7268e29891 Mon Sep 17 00:00:00 2001 From: arthur Date: Mon, 23 Oct 2023 16:30:06 +0800 Subject: [PATCH 13/15] Fix viewport height --- packages/components/src/device-switcher/device-switcher.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/components/src/device-switcher/device-switcher.tsx b/packages/components/src/device-switcher/device-switcher.tsx index f3d3c02cfb6e5f..6b3db4d5029367 100644 --- a/packages/components/src/device-switcher/device-switcher.tsx +++ b/packages/components/src/device-switcher/device-switcher.tsx @@ -69,7 +69,10 @@ const DeviceSwitcher = ( { // Trigger animation end after the duration timerRef.current = setTimeout( () => { timerRef.current = null; - onViewportChange?.( frameRef?.current?.clientHeight ); + const frameHeight = frameRef?.current?.getBoundingClientRect()?.height; + if ( frameHeight ) { + onViewportChange?.( frameHeight ); + } }, ANIMATION_DURATION ); return clearAnimationEndTimer; From 9628d877633447998628ba68584333c7eb3b0e8a Mon Sep 17 00:00:00 2001 From: arthur Date: Tue, 24 Oct 2023 17:38:25 +0800 Subject: [PATCH 14/15] Add tracks event --- .../steps-repository/pattern-assembler/events.ts | 4 ++-- .../pattern-assembler/pattern-large-preview.tsx | 11 ++++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/events.ts b/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/events.ts index f3b193d44ad7c4..c4d14b99f53c34 100644 --- a/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/events.ts +++ b/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/events.ts @@ -64,6 +64,6 @@ export const PATTERN_ASSEMBLER_EVENTS = { /** * Large Preview */ - LARGE_PREVIEW_ADD_HEADER_BUTTON_CLICK: - 'calypso_signup_pattern_assembler_large_preview_add_header_button_click', + LARGE_PREVIEW_ZOOM_OUT_SCALE_CHANGE: + 'calypso_signup_pattern_assembler_large_preview_zoom_out_scale_change', } as const; diff --git a/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-large-preview.tsx b/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-large-preview.tsx index 0a9c19b02bdb16..a0b6968d155792 100644 --- a/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-large-preview.tsx +++ b/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-large-preview.tsx @@ -164,6 +164,15 @@ const PatternLargePreview = ( { setViewportHeight( height ); }; + const handleZoomOutScale = ( value: number ) => { + setZoomOutScale( value ); + if ( zoomOutScale !== value ) { + recordTracksEvent( PATTERN_ASSEMBLER_EVENTS.LARGE_PREVIEW_ZOOM_OUT_SCALE_CHANGE, { + zoom_out_scale: value, + } ); + } + }; + // Scroll to newly added patterns useEffect( () => { let timerId: number; @@ -224,7 +233,7 @@ const PatternLargePreview = ( { setDevice( device ); } } onViewportChange={ updateViewportHeight } - onZoomOutScaleChange={ setZoomOutScale } + onZoomOutScaleChange={ handleZoomOutScale } > { hasSelectedPattern ? (
          Date: Tue, 24 Oct 2023 18:11:29 +0800 Subject: [PATCH 15/15] Debounce the tracks event --- .../pattern-assembler/pattern-large-preview.tsx | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-large-preview.tsx b/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-large-preview.tsx index a0b6968d155792..d5f18c97cf9b9b 100644 --- a/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-large-preview.tsx +++ b/client/landing/stepper/declarative-flow/internals/steps-repository/pattern-assembler/pattern-large-preview.tsx @@ -5,6 +5,7 @@ import { Popover } from '@wordpress/components'; import classnames from 'classnames'; import { useTranslate } from 'i18n-calypso'; import React, { useRef, useEffect, useState, useMemo, CSSProperties } from 'react'; +import { useDebouncedCallback } from 'use-debounce'; import { PATTERN_ASSEMBLER_EVENTS } from './events'; import PatternActionBar from './pattern-action-bar'; import { encodePatternId } from './utils'; @@ -62,6 +63,12 @@ const PatternLargePreview = ( { [ zoomOutScale, backgroundColor ] ); + const [ debouncedRecordZoomOutScaleChange ] = useDebouncedCallback( ( value: number ) => { + recordTracksEvent( PATTERN_ASSEMBLER_EVENTS.LARGE_PREVIEW_ZOOM_OUT_SCALE_CHANGE, { + zoom_out_scale: value, + } ); + }, 1000 ); + const [ activeElement, setActiveElement ] = useState< HTMLElement | null >( null ); const popoverAnchor = useMemo( () => { @@ -167,9 +174,7 @@ const PatternLargePreview = ( { const handleZoomOutScale = ( value: number ) => { setZoomOutScale( value ); if ( zoomOutScale !== value ) { - recordTracksEvent( PATTERN_ASSEMBLER_EVENTS.LARGE_PREVIEW_ZOOM_OUT_SCALE_CHANGE, { - zoom_out_scale: value, - } ); + debouncedRecordZoomOutScaleChange( value ); } };