Remove the components prop in favor of the native children prop to prevent unnecessary re-renders which are breaking component animations

This commit is contained in:
Daniel Dudzic 2024-12-17 11:50:32 +01:00
parent 51613c3020
commit f32f30ef0a
No known key found for this signature in database
GPG key ID: 31B40D33E3465483
13 changed files with 271 additions and 371 deletions

View file

@ -9,25 +9,19 @@ import {
} from './SettingsBlockElements';
const SettingsAccordion = ( { title, description, children, ...props } ) => (
<SettingsBlock
{ ...props }
className="ppcp-r-settings-block__accordion"
components={ [
() => (
<Accordion
title={ title }
description={ description }
Header={ Header }
TitleWrapper={ TitleWrapper }
Title={ Title }
Action={ Action }
Description={ Description }
>
{ children }
</Accordion>
),
] }
/>
<SettingsBlock { ...props } className="ppcp-r-settings-block__accordion">
<Accordion
title={ title }
description={ description }
Header={ Header }
TitleWrapper={ TitleWrapper }
Title={ Title }
Action={ Action }
Description={ Description }
>
{ children }
</Accordion>
</SettingsBlock>
);
export default SettingsAccordion;

View file

@ -3,32 +3,24 @@ import SettingsBlock from './SettingsBlock';
import { Header, Title, Action, Description } from './SettingsBlockElements';
const ButtonSettingsBlock = ( { title, description, ...props } ) => (
<SettingsBlock
{ ...props }
className="ppcp-r-settings-block__button"
components={ [
() => (
<>
<Header>
<Title>{ title }</Title>
<Description>{ description }</Description>
</Header>
<Action>
<Button
variant={ props.actionProps?.buttonType }
onClick={
props.actionProps?.callback
? () => props.actionProps.callback()
: undefined
}
>
{ props.actionProps.value }
</Button>
</Action>
</>
),
] }
/>
<SettingsBlock { ...props } className="ppcp-r-settings-block__button">
<Header>
<Title>{ title }</Title>
<Description>{ description }</Description>
</Header>
<Action>
<Button
variant={ props.actionProps?.buttonType }
onClick={
props.actionProps?.callback
? () => props.actionProps.callback()
: undefined
}
>
{ props.actionProps.value }
</Button>
</Action>
</SettingsBlock>
);
export default ButtonSettingsBlock;

View file

@ -11,56 +11,42 @@ const FeatureSettingsBlock = ( { title, description, ...props } ) => {
}
return (
<>
<span className="ppcp-r-feature-item__notes">
{ notes.map( ( note, index ) => (
<span key={ index }>{ note }</span>
) ) }
</span>
</>
<span className="ppcp-r-feature-item__notes">
{ notes.map( ( note, index ) => (
<span key={ index }>{ note }</span>
) ) }
</span>
);
};
return (
<SettingsBlock
{ ...props }
className="ppcp-r-settings-block__feature"
components={ [
() => (
<>
<Header>
<Title>
{ title }
{ props.actionProps?.featureStatus && (
<TitleBadge
{ ...props.actionProps?.badge }
/>
) }
</Title>
<Description className="ppcp-r-settings-block__feature__description">
{ description }
{ printNotes() }
</Description>
</Header>
<Action>
<div className="ppcp-r-feature-item__buttons">
{ props.actionProps?.buttons.map(
( button ) => (
<Button
href={ button.url }
key={ button.text }
variant={ button.type }
>
{ button.text }
</Button>
)
) }
</div>
</Action>
</>
),
] }
/>
<SettingsBlock { ...props } className="ppcp-r-settings-block__feature">
<Header>
<Title>
{ title }
{ props.actionProps?.featureStatus && (
<TitleBadge { ...props.actionProps?.badge } />
) }
</Title>
<Description className="ppcp-r-settings-block__feature__description">
{ description }
{ printNotes() }
</Description>
</Header>
<Action>
<div className="ppcp-r-feature-item__buttons">
{ props.actionProps?.buttons.map( ( button ) => (
<Button
href={ button.url }
key={ button.text }
variant={ button.type }
>
{ button.text }
</Button>
) ) }
</div>
</Action>
</SettingsBlock>
);
};

View file

@ -42,28 +42,20 @@ const InputSettingsBlock = ( {
order = DEFAULT_ELEMENT_ORDER,
...props
} ) => (
<SettingsBlock
{ ...props }
className="ppcp-r-settings-block__input"
components={ [
() => (
<>
{ order.map( ( elementKey ) => {
const RenderElement = ELEMENT_RENDERERS[ elementKey ];
return RenderElement ? (
<RenderElement
key={ elementKey }
title={ title }
description={ description }
supplementaryLabel={ supplementaryLabel }
actionProps={ props.actionProps }
/>
) : null;
} ) }
</>
),
] }
/>
<SettingsBlock { ...props } className="ppcp-r-settings-block__input">
{ order.map( ( elementKey ) => {
const RenderElement = ELEMENT_RENDERERS[ elementKey ];
return RenderElement ? (
<RenderElement
key={ elementKey }
title={ title }
description={ description }
supplementaryLabel={ supplementaryLabel }
actionProps={ props.actionProps }
/>
) : null;
} ) }
</SettingsBlock>
);
export default InputSettingsBlock;

View file

@ -16,25 +16,18 @@ const PaymentMethodsBlock = ( { paymentMethods, className = '' } ) => {
return (
<SettingsBlock
className={ `ppcp-r-settings-block__payment-methods ${ className }` }
components={ [
() => (
<>
{ paymentMethods.map( ( paymentMethod ) => (
<PaymentMethodItemBlock
key={ paymentMethod.id }
{ ...paymentMethod }
isSelected={
selectedMethod === paymentMethod.id
}
onSelect={ ( checked ) =>
handleSelect( paymentMethod.id, checked )
}
/>
) ) }
</>
),
] }
/>
>
{ paymentMethods.map( ( paymentMethod ) => (
<PaymentMethodItemBlock
key={ paymentMethod.id }
{ ...paymentMethod }
isSelected={ selectedMethod === paymentMethod.id }
onSelect={ ( checked ) =>
handleSelect( paymentMethod.id, checked )
}
/>
) ) }
</SettingsBlock>
);
};

View file

@ -11,37 +11,32 @@ const RadioSettingsBlock = ( {
<SettingsBlock
{ ...props }
className="ppcp-r-settings-block__radio ppcp-r-settings-block--expert-rdb"
components={ [
() => (
<>
<Header>
<Title>{ title }</Title>
<Description>{ description }</Description>
</Header>
{ options.map( ( option ) => (
<PayPalRdbWithContent
key={ option.id }
id={ option.id }
name={ props.actionProps?.name }
value={ option.value }
currentValue={ props.actionProps?.currentValue }
handleRdbState={ ( newValue ) =>
props.actionProps?.callback(
props.actionProps?.key,
newValue
)
}
label={ option.label }
description={ option.description }
toggleAdditionalContent={ true }
>
{ option.additionalContent }
</PayPalRdbWithContent>
) ) }
</>
),
] }
/>
>
<Header>
<Title>{ title }</Title>
<Description>{ description }</Description>
</Header>
{ options.map( ( option ) => (
<PayPalRdbWithContent
key={ option.id }
id={ option.id }
name={ props.actionProps?.name }
value={ option.value }
currentValue={ props.actionProps?.currentValue }
handleRdbState={ ( newValue ) =>
props.actionProps?.callback(
props.actionProps?.key,
newValue
)
}
label={ option.label }
description={ option.description }
toggleAdditionalContent={ true }
>
{ option.additionalContent }
</PayPalRdbWithContent>
) ) }
</SettingsBlock>
);
export default RadioSettingsBlock;

View file

@ -35,27 +35,19 @@ const SelectSettingsBlock = ( {
order = DEFAULT_ELEMENT_ORDER,
...props
} ) => (
<SettingsBlock
{ ...props }
className="ppcp-r-settings-block__select"
components={ [
() => (
<>
{ order.map( ( elementKey ) => {
const RenderElement = ELEMENT_RENDERERS[ elementKey ];
return RenderElement ? (
<RenderElement
key={ elementKey }
title={ title }
description={ description }
actionProps={ props.actionProps }
/>
) : null;
} ) }
</>
),
] }
/>
<SettingsBlock { ...props } className="ppcp-r-settings-block__select">
{ order.map( ( elementKey ) => {
const RenderElement = ELEMENT_RENDERERS[ elementKey ];
return RenderElement ? (
<RenderElement
key={ elementKey }
title={ title }
description={ description }
actionProps={ props.actionProps }
/>
) : null;
} ) }
</SettingsBlock>
);
export default SelectSettingsBlock;

View file

@ -1,16 +1,9 @@
const SettingsBlock = ( { className, components = [], children } ) => {
const SettingsBlock = ( { className, children } ) => {
const blockClassName = [ 'ppcp-r-settings-block', className ].filter(
Boolean
);
return (
<div className={ blockClassName.join( ' ' ) }>
{ children ||
components.map( ( Component, index ) => (
<Component key={ index } />
) ) }
</div>
);
return <div className={ blockClassName.join( ' ' ) }>{ children }</div>;
};
export default SettingsBlock;

View file

@ -3,35 +3,25 @@ import SettingsBlock from './SettingsBlock';
import { Header, Title, Action, Description } from './SettingsBlockElements';
const ToggleSettingsBlock = ( { title, description, ...props } ) => (
<SettingsBlock
{ ...props }
className="ppcp-r-settings-block__toggle"
components={ [
() => (
<Action>
<ToggleControl
className="ppcp-r-settings-block__toggle-control"
__nextHasNoMarginBottom={ true }
checked={ props.actionProps?.value }
onChange={ ( newValue ) =>
props.actionProps?.callback(
props.actionProps?.key,
newValue
)
}
/>
</Action>
),
() => (
<Header>
{ title && <Title>{ title }</Title> }
{ description && (
<Description>{ description }</Description>
) }
</Header>
),
] }
/>
<SettingsBlock { ...props } className="ppcp-r-settings-block__toggle">
<Action>
<ToggleControl
className="ppcp-r-settings-block__toggle-control"
__nextHasNoMarginBottom={ true }
checked={ props.actionProps?.value }
onChange={ ( newValue ) =>
props.actionProps?.callback(
props.actionProps?.key,
newValue
)
}
/>
</Action>
<Header>
{ title && <Title>{ title }</Title> }
{ description && <Description>{ description }</Description> }
</Header>
</SettingsBlock>
);
export default ToggleSettingsBlock;