Add responsiveness to product form header (#35623)

* Update product title in smaller viewports

* Move secondary product actions to menu group on mobile

* Hide settings menu on smaller viewports

* Add changelog entry
This commit is contained in:
Joshua T Flowers 2022-11-24 06:00:20 -08:00 committed by GitHub
parent a811009a06
commit db737f2190
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 124 additions and 53 deletions

View File

@ -8,6 +8,23 @@ $gutenberg-blue-darker: var(--wp-admin-theme-color-darker-20);
justify-content: flex-end;
padding-right: $gap-smaller;
@include breakpoint( '<782px' ) {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
background: $white;
padding: $gap;
border-top: 1px solid $gray-200;
.components-button-group {
width: 100%;
> button {
width: 100%;
}
}
}
> .components-button {
margin-right: $gap-smaller;
}
@ -36,3 +53,9 @@ $gutenberg-blue-darker: var(--wp-admin-theme-color-darker-20);
}
}
}
@include breakpoint( '<782px' ) {
.woocommerce-layout {
margin-bottom: calc(70px + $gap); // Product actions height + gap.
}
}

View File

@ -15,6 +15,11 @@ import { useFormContext } from '@woocommerce/components';
import { Product } from '@woocommerce/data';
import { recordEvent } from '@woocommerce/tracks';
import { navigateTo } from '@woocommerce/navigation';
import { useSelect } from '@wordpress/data';
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore No types for this exist yet.
// eslint-disable-next-line @woocommerce/dependency-group
import { store } from '@wordpress/viewport';
/**
* Internal dependencies
@ -39,6 +44,14 @@ export const ProductFormActions: React.FC = () => {
usePreventLeavingPage( isDirty );
const { isSmallViewport } = useSelect( ( select ) => {
return {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore Types don't appear to be working correctly on this package.
isSmallViewport: select( store ).isViewportMatch( '< medium' ),
};
} );
const getProductDataForTracks = () => {
return {
product_id: values.id,
@ -142,59 +155,63 @@ export const ProductFormActions: React.FC = () => {
};
const isPublished = values.id && values.status === 'publish';
const SecondaryActionsComponent = isSmallViewport ? MenuItem : Button;
const secondaryActions = (
<>
<SecondaryActionsComponent
onClick={ onSaveDraft }
disabled={
! isValidForm ||
( ! isDirty &&
!! values.id &&
values.status !== 'publish' ) ||
isUpdatingDraft ||
isUpdatingPublished ||
isDeleting
}
>
{ ! isDirty && values.id && values.status !== 'publish' && (
<Icon icon={ check } />
) }
{ isUpdatingDraft ? __( 'Saving', 'woocommerce' ) : null }
{ ( isDirty || ! values.id ) &&
! isUpdatingDraft &&
values.status !== 'publish'
? __( 'Save draft', 'woocommerce' )
: null }
{ values.status === 'publish' && ! isUpdatingDraft
? __( 'Switch to draft', 'woocommerce' )
: null }
{ ! isDirty &&
values.id &&
! isUpdatingDraft &&
values.status !== 'publish'
? __( 'Saved', 'woocommerce' )
: null }
</SecondaryActionsComponent>
<SecondaryActionsComponent
onClick={ () =>
recordEvent( 'product_preview_changes', {
new_product_page: true,
...getProductDataForTracks(),
} )
}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore The `href` prop works for both Buttons and MenuItem's.
href={ values.permalink + '?preview=true' }
disabled={ ! isValidForm || ! values.permalink }
target="_blank"
>
{ __( 'Preview', 'woocommerce' ) }
</SecondaryActionsComponent>
</>
);
return (
<WooHeaderItem>
{ () => (
<div className="woocommerce-product-form-actions">
<Button
onClick={ onSaveDraft }
disabled={
! isValidForm ||
( ! isDirty &&
!! values.id &&
values.status !== 'publish' ) ||
isUpdatingDraft ||
isUpdatingPublished ||
isDeleting
}
>
{ ! isDirty &&
values.id &&
values.status !== 'publish' && (
<Icon icon={ check } />
) }
{ isUpdatingDraft
? __( 'Saving', 'woocommerce' )
: null }
{ ( isDirty || ! values.id ) &&
! isUpdatingDraft &&
values.status !== 'publish'
? __( 'Save draft', 'woocommerce' )
: null }
{ values.status === 'publish' && ! isUpdatingDraft
? __( 'Switch to draft', 'woocommerce' )
: null }
{ ! isDirty &&
values.id &&
! isUpdatingDraft &&
values.status !== 'publish'
? __( 'Saved', 'woocommerce' )
: null }
</Button>
<Button
onClick={ () =>
recordEvent( 'product_preview_changes', {
new_product_page: true,
...getProductDataForTracks(),
} )
}
href={ values.permalink + '?preview=true' }
disabled={ ! isValidForm || ! values.permalink }
target="_blank"
>
{ __( 'Preview', 'woocommerce' ) }
</Button>
{ ! isSmallViewport && secondaryActions }
<ButtonGroup className="woocommerce-product-form-actions__publish-button-group">
<Button
onClick={ onPublish }
@ -231,6 +248,7 @@ export const ProductFormActions: React.FC = () => {
{ () => (
<>
<MenuGroup>
{ isSmallViewport && secondaryActions }
<MenuItem
onClick={ onPublishAndDuplicate }
disabled={ ! isValidForm }

View File

@ -1,4 +1,4 @@
.product-settings__panel {
.woocommerce-product-settings__panel {
position: absolute;
top: 100%;
right: 0;
@ -27,3 +27,10 @@
height: 24px;
}
}
@include breakpoint( '<782px' ) {
.woocommerce-product-settings__toggle,
.woocommerce-product-settings__panel {
display: none;
}
}

View File

@ -35,9 +35,10 @@ export const ProductSettings = () => {
icon={ cog }
isPressed={ isOpen }
onClick={ () => setIsOpen( ! isOpen ) }
className="woocommerce-product-settings__toggle"
/>
{ isOpen && (
<Panel className="product-settings__panel">
<Panel className="woocommerce-product-settings__panel">
<PanelHeader label={ __( 'Settings', 'woocommerce' ) }>
<Button
icon={ closeSmall }

View File

@ -0,0 +1,13 @@
.woocommerce-product-title {
display: flex;
align-items: center;
@include breakpoint( '<782px' ) {
flex-direction: column;
align-items: baseline;
.woocommerce-product-breadcrumbs {
font-size: 13px;
}
}
}

View File

@ -19,6 +19,7 @@ import { getProductTitle } from './utils/get-product-title';
import { ProductBreadcrumbs } from './product-breadcrumbs';
import { ProductStatusBadge } from './product-status-badge';
import { WooHeaderPageTitle } from '~/header/utils';
import './product-title.scss';
export const ProductTitle: React.FC = () => {
const { values } = useFormContext< Product >();
@ -46,9 +47,13 @@ export const ProductTitle: React.FC = () => {
return (
<WooHeaderPageTitle>
<ProductBreadcrumbs breadcrumbs={ breadcrumbs } />
{ title }
<ProductStatusBadge />
<span className="woocommerce-product-title">
<ProductBreadcrumbs breadcrumbs={ breadcrumbs } />
<span className="woocommerce-product-title__wrapper">
{ title }
<ProductStatusBadge />
</span>
</span>
</WooHeaderPageTitle>
);
};

View File

@ -0,0 +1,4 @@
Significance: minor
Type: update
Make product form header and actions responsive for smaller viewports