💄 Improve the (broken) UI in the Styling-tab

This commit is contained in:
Philipp Stracker 2025-01-15 19:41:46 +01:00
parent 55d1fd3699
commit 85794e77ce
No known key found for this signature in database
7 changed files with 198 additions and 135 deletions

View file

@ -4,6 +4,7 @@
@import './reusable-components/busy-state'; @import './reusable-components/busy-state';
@import './reusable-components/button'; @import './reusable-components/button';
@import './reusable-components/fields'; @import './reusable-components/fields';
@import './reusable-components/hstack';
@import './reusable-components/navigation'; @import './reusable-components/navigation';
@import './reusable-components/onboarding-header'; @import './reusable-components/onboarding-header';
@import './reusable-components/payment-method-icons'; @import './reusable-components/payment-method-icons';

View file

@ -0,0 +1,20 @@
.components-flex {
display: flex;
-webkit-box-align: stretch;
align-items: stretch;
flex-direction: column;
-webkit-box-pack: center;
justify-content: center;
.components-h-stack {
flex-direction: row;
justify-content: flex-start;
gap: 32px;
}
// Fix layout for checkboxes inside a flex-stack.
.components-checkbox-control >.components-base-control__field > .components-flex {
flex-direction: row;
gap: 12px;
}
}

View file

@ -27,6 +27,16 @@ $width-settings-panel: 422px;
padding-bottom: 24px; padding-bottom: 24px;
margin-bottom: 28px; margin-bottom: 28px;
border-bottom: 1px solid var(--color-separators); border-bottom: 1px solid var(--color-separators);
&:last-child {
padding-bottom: 0;
margin-bottom: 0;
border-bottom-style: none;
}
}
.components-radio-control__option {
min-width: 100px;
} }
} }
@ -65,46 +75,7 @@ $width-settings-panel: 422px;
color: $color-black; color: $color-black;
} }
} }
.components-flex {
gap: 12px;
}
}
&__payment-method-checkboxes {
display: flex;
flex-direction: column;
gap: 24px;
} }
} }
//*/
.ppcp-r {
&__horizontal-control {
.components-flex {
flex-direction: row;
justify-content: flex-start;
gap: 32px;
}
.components-radio-control {
&__option {
gap: 12px;
input {
margin: 0;
}
label {
@include font(13, 20, 400);
color: $color-black;
}
}
input {
margin: 0;
}
}
}
// */
} }

View file

@ -1,107 +1,136 @@
import { CheckboxControl } from '@wordpress/components'; import { CheckboxControl } from '@wordpress/components';
import classNames from 'classnames';
export const PayPalCheckbox = ( props ) => { export const PayPalCheckbox = ( {
let isChecked = null; currentValue,
label,
value,
checked = null,
disabled = null,
changeCallback,
} ) => {
let isChecked = checked;
if ( Array.isArray( props.currentValue ) ) { if ( null === isChecked ) {
isChecked = props.currentValue.includes( props.value ); if ( Array.isArray( currentValue ) ) {
} else { isChecked = currentValue.includes( value );
isChecked = props.currentValue; } else {
isChecked = currentValue;
}
} }
const onChange = ( newState ) => {
let newValue;
if ( ! Array.isArray( currentValue ) ) {
newValue = newState;
} else if ( newState ) {
newValue = [ ...currentValue, value ];
} else {
newValue = currentValue.filter(
( optionValue ) => optionValue !== value
);
}
changeCallback( newValue );
};
return ( return (
<div className="ppcp-r__checkbox"> <div className="ppcp-r__checkbox">
{ /* todo: Can we remove the wrapper div? */ }
<CheckboxControl <CheckboxControl
label={ props?.label ? props.label : '' } label={ label ?? '' }
value={ props.value } value={ value }
checked={ isChecked } checked={ isChecked }
onChange={ ( checked ) => disabled={ disabled }
handleCheckboxState( checked, props ) onChange={ onChange }
}
/> />
</div> </div>
); );
}; };
export const PayPalCheckboxGroup = ( props ) => { export const CheckboxGroup = ( { options, value, onChange } ) => (
const renderCheckboxGroup = () => { <>
return props.value.map( ( checkbox ) => { { options.map( ( checkbox ) => (
return ( <PayPalCheckbox
<PayPalCheckbox key={ checkbox.value }
label={ checkbox.label } label={ checkbox.label }
value={ checkbox.value } value={ checkbox.value }
key={ checkbox.value } checked={ checkbox.checked }
currentValue={ props.currentValue } disabled={ checkbox.disabled }
changeCallback={ props.changeCallback } currentValue={ value }
/> changeCallback={ onChange }
); />
} ); ) ) }
}; </>
);
return <>{ renderCheckboxGroup() }</>; export const PayPalRdb = ( {
}; id,
name,
export const PayPalRdb = ( props ) => { value,
currentValue,
handleRdbState,
} ) => {
return ( return (
<div className="ppcp-r__radio"> <div className="ppcp-r__radio">
{ /* todo: Can we remove the wrapper div? */ }
<input <input
id={ props?.id }
className="ppcp-r__radio-value" className="ppcp-r__radio-value"
type="radio" type="radio"
checked={ props.value === props.currentValue } id={ id }
name={ props.name } checked={ value === currentValue }
value={ props.value } name={ name }
onChange={ () => props.handleRdbState( props.value ) } value={ value }
onChange={ () => handleRdbState( value ) }
/> />
<span className="ppcp-r__radio-presentation"></span> <span className="ppcp-r__radio-presentation"></span>
</div> </div>
); );
}; };
export const PayPalRdbWithContent = ( props ) => { export const PayPalRdbWithContent = ( {
const className = [ 'ppcp-r__radio-wrapper' ]; className,
id,
if ( props?.className ) { name,
className.push( props.className ); label,
} description,
value,
currentValue,
handleRdbState,
toggleAdditionalContent,
children,
} ) => {
const wrapperClasses = classNames( 'ppcp-r__radio-wrapper', className );
return ( return (
<div className="ppcp-r__radio-outer-wrapper"> <div className="ppcp-r__radio-outer-wrapper">
<div className={ className }> <div className={ wrapperClasses }>
<PayPalRdb { ...props } /> <PayPalRdb
id={ id }
name={ name }
value={ value }
currentValue={ currentValue }
handleRdbState={ handleRdbState }
/>
<div className="ppcp-r__radio-content"> <div className="ppcp-r__radio-content">
<label htmlFor={ props?.id }>{ props.label }</label> <label htmlFor={ id }>{ label }</label>
{ props.description && ( { description && (
<p <p
className="ppcp-r__radio-description" className="ppcp-r__radio-description"
dangerouslySetInnerHTML={ { dangerouslySetInnerHTML={ {
__html: props.description, __html: description,
} } } }
/> />
) } ) }
</div> </div>
</div> </div>
{ props?.toggleAdditionalContent && { toggleAdditionalContent && children && value === currentValue && (
props.children && <div className="ppcp-r__radio-content-additional">
props.value === props.currentValue && ( { children }
<div className="ppcp-r__radio-content-additional"> </div>
{ props.children } ) }
</div>
) }
</div> </div>
); );
}; };
export const handleCheckboxState = ( checked, props ) => {
let newValue = null;
if ( ! Array.isArray( props.currentValue ) ) {
newValue = checked;
} else if ( checked ) {
newValue = [ ...props.currentValue, props.value ];
} else {
newValue = props.currentValue.filter(
( value ) => value !== props.value
);
}
props.changeCallback( newValue );
};

View file

@ -0,0 +1,26 @@
/**
* Temporary component, until the experimental HStack block editor component is stable.
*
* @see https://wordpress.github.io/gutenberg/?path=/docs/components-experimental-hstack--docs
* @file
*/
import classNames from 'classnames';
const HStack = ( { className, spacing = 3, children } ) => {
const wrapperClass = classNames(
'components-flex components-h-stack',
className
);
const styles = {
gap: `calc(${ 4 * spacing }px)`,
};
return (
<div className={ wrapperClass } style={ styles }>
{ children }
</div>
);
};
export default HStack;

View file

@ -4,7 +4,8 @@ import { RadioControl, SelectControl } from '@wordpress/components';
// Dummy hook. // Dummy hook.
import { useStylingLocation, useStylingProps } from '../../Tabs/TabStyling'; import { useStylingLocation, useStylingProps } from '../../Tabs/TabStyling';
import { PayPalCheckboxGroup } from '../../../../ReusableComponents/Fields'; import { CheckboxGroup } from '../../../../ReusableComponents/Fields';
import HStack from '../../../../ReusableComponents/HStack';
import LocationSelector from './LocationSelector'; import LocationSelector from './LocationSelector';
import StylingSection from './StylingSection'; import StylingSection from './StylingSection';
@ -30,6 +31,7 @@ const SettingsPanel = () => {
export default SettingsPanel; export default SettingsPanel;
// ----- // -----
const SectionPaymentMethods = ( { location } ) => { const SectionPaymentMethods = ( { location } ) => {
const { paymentMethods, setPaymentMethods, paymentMethodChoices } = const { paymentMethods, setPaymentMethods, paymentMethodChoices } =
useStylingProps( location ); useStylingProps( location );
@ -39,11 +41,13 @@ const SectionPaymentMethods = ( { location } ) => {
title={ __( 'Payment Methods', 'woocommerce-paypal-payments' ) } title={ __( 'Payment Methods', 'woocommerce-paypal-payments' ) }
className="payment-methods" className="payment-methods"
> >
<PayPalCheckboxGroup <HStack spacing={ 6 }>
value={ paymentMethodChoices } <CheckboxGroup
currentValue={ paymentMethods } options={ paymentMethodChoices }
changeCallback={ setPaymentMethods } value={ paymentMethods }
/> onChange={ setPaymentMethods }
/>
</HStack>
</StylingSection> </StylingSection>
); );
}; };
@ -61,12 +65,13 @@ const SectionButtonLayout = ( { location } ) => {
className="button-layout" className="button-layout"
title={ __( 'Button Layout', 'woocommerce-paypal-payments' ) } title={ __( 'Button Layout', 'woocommerce-paypal-payments' ) }
> >
<RadioControl <HStack>
className="ppcp-r__horizontal-control" <RadioControl
options={ layoutChoices } options={ layoutChoices }
selected={ layout } selected={ layout }
onChange={ setLayout } onChange={ setLayout }
/> />
</HStack>
</StylingSection> </StylingSection>
); );
}; };
@ -79,12 +84,13 @@ const SectionButtonShape = ( { location } ) => {
title={ __( 'Shape', 'woocommerce-paypal-payments' ) } title={ __( 'Shape', 'woocommerce-paypal-payments' ) }
className="button-shape" className="button-shape"
> >
<RadioControl <HStack>
className="ppcp-r__horizontal-control" <RadioControl
options={ shapeChoices } options={ shapeChoices }
selected={ shape } selected={ shape }
onChange={ setShape } onChange={ setShape }
/> />
</HStack>
</StylingSection> </StylingSection>
); );
}; };
@ -93,10 +99,11 @@ const SectionButtonLabel = ( { location } ) => {
const { label, setLabel, labelChoices } = useStylingProps( location ); const { label, setLabel, labelChoices } = useStylingProps( location );
return ( return (
<StylingSection> <StylingSection
title={ __( 'Button Label', 'woocommerce-paypal-payments' ) }
className="button-label"
>
<SelectControl <SelectControl
label={ __( 'Button Label', 'woocommerce-paypal-payments' ) }
className="ppcp-r-styling__select"
options={ labelChoices } options={ labelChoices }
value={ label } value={ label }
onChange={ setLabel } onChange={ setLabel }
@ -109,10 +116,11 @@ const SectionButtonColor = ( { location } ) => {
const { color, setColor, colorChoices } = useStylingProps( location ); const { color, setColor, colorChoices } = useStylingProps( location );
return ( return (
<StylingSection> <StylingSection
title={ __( 'Button Color', 'woocommerce-paypal-payments' ) }
className="button-color"
>
<SelectControl <SelectControl
label={ __( 'Button Color', 'woocommerce-paypal-payments' ) }
className=" ppcp-r-styling__select"
options={ colorChoices } options={ colorChoices }
value={ color } value={ color }
onChange={ setColor } onChange={ setColor }
@ -134,11 +142,13 @@ const SectionButtonTagline = ( { location } ) => {
title={ __( 'Tagline', 'woocommerce-paypal-payments' ) } title={ __( 'Tagline', 'woocommerce-paypal-payments' ) }
className="tagline" className="tagline"
> >
<PayPalCheckboxGroup <HStack>
value={ taglineChoices } <CheckboxGroup
currentValue={ tagline } options={ taglineChoices }
changeCallback={ setTagline } value={ tagline }
/> onChange={ setTagline }
/>
</HStack>
</StylingSection> </StylingSection>
); );
}; };

View file

@ -147,6 +147,12 @@ export const STYLING_SHAPES = {
}; };
export const STYLING_PAYMENT_METHODS = { export const STYLING_PAYMENT_METHODS = {
paypal: {
value: '',
label: __( 'PayPal', 'woocommerce-paypal-payments' ),
checked: true,
disabled: true,
},
venmo: { venmo: {
value: 'venmo', value: 'venmo',
label: __( 'Venmo', 'woocommerce-paypal-payments' ), label: __( 'Venmo', 'woocommerce-paypal-payments' ),