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:
parent
a811009a06
commit
db737f2190
|
@ -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.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 }
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 }
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: update
|
||||
|
||||
Make product form header and actions responsive for smaller viewports
|
Loading…
Reference in New Issue