Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions projects/packages/forms/changelog/update-forms-from-trunk
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: changed

Forms: Update Form package with latest contact-form changes from trunk
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ const EditTextarea = props => {

return (
<JetpackFieldTextarea
clientId={ props.clientId }
label={ props.attributes.label }
required={ props.attributes.required }
requiredText={ props.attributes.requiredText }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { RichText } from '@wordpress/block-editor';
import { useEffect, useRef } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import classnames from 'classnames';
import { isEmpty, isNil, noop, split, trim } from 'lodash';
import { setFocus } from '../util/focus';
import { useFormWrapper } from '../util/form';
import { useFormStyle, useFormWrapper } from '../util/form';
import JetpackFieldControls from './jetpack-field-controls';
import JetpackFieldLabel from './jetpack-field-label';
import { useJetpackFieldStyles } from './use-jetpack-field-styles';
Expand All @@ -17,6 +18,12 @@ export const JetpackDropdownEdit = ( {
} ) => {
const { id, label, options, required, requiredText, toggleLabel, width } = attributes;
const optionsWrapper = useRef();
const formStyle = useFormStyle( clientId );

const classes = classnames( 'jetpack-field jetpack-field-dropdown', {
'is-selected': isSelected,
'has-placeholder': ! isEmpty( toggleLabel ),
} );

useFormWrapper( { attributes, clientId, name } );

Expand Down Expand Up @@ -100,17 +107,18 @@ export const JetpackDropdownEdit = ( {
const { blockStyle } = useJetpackFieldStyles( attributes );

return (
<div style={ blockStyle }>
<JetpackFieldLabel
required={ required }
requiredText={ requiredText }
label={ label }
attributes={ attributes }
setAttributes={ setAttributes }
isSelected={ isSelected }
/>
<div className="jetpack-field-dropdown">
<div style={ blockStyle } className="jetpack-field-dropdown__toggle">
<div className={ classes } style={ blockStyle }>
<div className="jetpack-field-dropdown__wrapper">
<JetpackFieldLabel
required={ required }
requiredText={ requiredText }
label={ label }
attributes={ attributes }
setAttributes={ setAttributes }
isSelected={ isSelected }
style={ formStyle }
/>
<div className="jetpack-field-dropdown__toggle">
<RichText
value={ toggleLabel }
onChange={ value => {
Expand All @@ -121,25 +129,24 @@ export const JetpackDropdownEdit = ( {
/>
<span className="jetpack-field-dropdown__icon" />
</div>

{ isSelected && (
<div className="jetpack-field-dropdown__popover" ref={ optionsWrapper }>
{ options.map( ( option, index ) => (
<RichText
key={ index }
value={ option }
onChange={ handleChangeOption( index ) }
onSplit={ handleSplitOption( index ) }
onRemove={ handleDeleteOption( index ) }
onReplace={ noop }
placeholder={ __( 'Add option…', 'jetpack-forms' ) }
__unstableDisableFormats
/>
) ) }
</div>
) }
</div>

{ isSelected && (
<div className="jetpack-field-dropdown__popover" ref={ optionsWrapper }>
{ options.map( ( option, index ) => (
<RichText
key={ index }
value={ option }
onChange={ handleChangeOption( index ) }
onSplit={ handleSplitOption( index ) }
onRemove={ handleDeleteOption( index ) }
onReplace={ noop }
placeholder={ __( 'Add option…', 'jetpack-forms' ) }
__unstableDisableFormats
/>
) ) }
</div>
) }
<JetpackFieldControls
id={ id }
required={ required }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,62 +1,87 @@
import { RichText } from '@wordpress/block-editor';
import { useEffect } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import classnames from 'classnames';
import { isNil } from 'lodash';
import { FORM_STYLE } from '../util/form';
import { useJetpackFieldStyles } from './use-jetpack-field-styles';

const JetpackFieldLabel = ( {
setAttributes,
const FieldLabel = ( {
attributes,
className,
label,
labelFieldName,
placeholder,
resetFocus,
required,
requiredText,
attributes,
setAttributes,
} ) => {
useEffect( () => {
if ( isNil( requiredText ) ) {
setAttributes( { requiredText: __( '(required)', 'jetpack-forms' ) } );
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [] );

const { labelStyle } = useJetpackFieldStyles( attributes );

return (
<div className="jetpack-field-label">
<div style={ labelStyle }>
<div className={ classnames( className, 'jetpack-field-label' ) } style={ labelStyle }>
<RichText
tagName="label"
value={ label }
className="jetpack-field-label__input"
onChange={ value => {
resetFocus && resetFocus();
if ( labelFieldName ) {
setAttributes( { [ labelFieldName ]: value } );
return;
}
setAttributes( { label: value } );
} }
placeholder={ placeholder ?? __( 'Add label…', 'jetpack-forms' ) }
withoutInteractiveFormatting
allowedFormats={ [ 'core/bold', 'core/italic' ] }
/>
{ required && (
<RichText
tagName="label"
value={ label }
className="jetpack-field-label__input"
tagName="span"
value={ requiredText }
className="required"
onChange={ value => {
resetFocus && resetFocus();
if ( labelFieldName ) {
setAttributes( { [ labelFieldName ]: value } );
return;
}
setAttributes( { label: value } );
setAttributes( { requiredText: value } );
} }
placeholder={ placeholder ?? __( 'Add label…', 'jetpack-forms' ) }
withoutInteractiveFormatting
allowedFormats={ [ 'core/bold', 'core/italic' ] }
/>
{ required && (
<RichText
tagName="span"
value={ requiredText }
className="required"
onChange={ value => {
setAttributes( { requiredText: value } );
} }
withoutInteractiveFormatting
allowedFormats={ [ 'core/bold', 'core/italic' ] }
/>
) }
</div>
) }
</div>
);
};

const JetpackFieldLabel = props => {
const { setAttributes, requiredText, style } = props;

const classes = classnames( {
'notched-label__label': style === FORM_STYLE.OUTLINED,
'animated-label__label': style === FORM_STYLE.ANIMATED,
'below-label__label': style === FORM_STYLE.BELOW,
} );

useEffect( () => {
if ( isNil( requiredText ) ) {
setAttributes( { requiredText: __( '(required)', 'jetpack-forms' ) } );
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [] );

if ( style === FORM_STYLE.OUTLINED ) {
return (
<div className="notched-label">
<div className="notched-label__leading" />
<div className="notched-label__notch">
<FieldLabel className={ classes } { ...props } />
</div>
<div className="notched-label__trailing" />
</div>
);
}

return <FieldLabel className={ classes } { ...props } />;
};

export default JetpackFieldLabel;
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@ import { Button } from '@wordpress/components';
import { withInstanceId } from '@wordpress/compose';
import { useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import classnames from 'classnames';
import { useFormStyle } from '../util/form';
import JetpackFieldControls from './jetpack-field-controls';
import JetpackFieldLabel from './jetpack-field-label';
import JetpackOption from './jetpack-option';
import { useJetpackFieldStyles } from './use-jetpack-field-styles';

function JetpackFieldMultiple( props ) {
const {
clientId,
id,
type,
instanceId,
Expand All @@ -21,6 +24,12 @@ function JetpackFieldMultiple( props ) {
options,
attributes,
} = props;
const formStyle = useFormStyle( clientId );

const classes = classnames( 'jetpack-field jetpack-field-multiple', {
'is-selected': isSelected,
'has-placeholder': options.length,
} );

const [ inFocus, setInFocus ] = useState( null );

Expand Down Expand Up @@ -60,10 +69,11 @@ function JetpackFieldMultiple( props ) {
const { blockStyle, fieldStyle } = useJetpackFieldStyles( attributes );

return (
<div style={ blockStyle }>
<>
<div
id={ `jetpack-field-multiple-${ instanceId }` }
className="jetpack-field jetpack-field-multiple"
className={ classes }
style={ blockStyle }
>
<JetpackFieldLabel
required={ required }
Expand All @@ -73,6 +83,7 @@ function JetpackFieldMultiple( props ) {
isSelected={ isSelected }
resetFocus={ () => setInFocus( null ) }
attributes={ attributes }
style={ formStyle }
/>
<ol
className="jetpack-field-multiple__list"
Expand Down Expand Up @@ -112,7 +123,7 @@ function JetpackFieldMultiple( props ) {
type={ type }
width={ width }
/>
</div>
</>
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,31 @@
import { TextareaControl, Disabled } from '@wordpress/components';
import { useEffect } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { isNil } from 'lodash';
import classnames from 'classnames';
import { isEmpty, isNil } from 'lodash';
import { useFormStyle } from '../util/form';
import JetpackFieldControls from './jetpack-field-controls';
import JetpackFieldLabel from './jetpack-field-label';
import { useJetpackFieldStyles } from './use-jetpack-field-styles';

export default function JetpackFieldTextarea( props ) {
const {
attributes,
clientId,
id,
isSelected,
required,
requiredText,
label,
setAttributes,
placeholder,
width,
attributes,
} = props;
const formStyle = useFormStyle( clientId );
const { blockStyle, fieldStyle } = useJetpackFieldStyles( attributes );

const classes = classnames( 'jetpack-field jetpack-field-textarea', {
'is-selected': isSelected,
'has-placeholder': ! isEmpty( placeholder ),
} );

useEffect( () => {
if ( isNil( label ) ) {
Expand All @@ -25,27 +34,24 @@ export default function JetpackFieldTextarea( props ) {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [] );

const { blockStyle, fieldStyle } = useJetpackFieldStyles( attributes );

return (
<>
<div style={ blockStyle } className="jetpack-field">
<div className={ classes } style={ blockStyle }>
<JetpackFieldLabel
clientId={ clientId }
required={ required }
requiredText={ requiredText }
label={ label }
setAttributes={ setAttributes }
attributes={ attributes }
style={ formStyle }
/>
<textarea
className="jetpack-field__textarea"
value={ placeholder }
onChange={ e => setAttributes( { placeholder: e.target.value } ) }
style={ fieldStyle }
/>
<Disabled>
<TextareaControl
placeholder={ placeholder }
value={ placeholder }
onChange={ value => setAttributes( { placeholder: value } ) }
title={ __( 'Set the placeholder text', 'jetpack-forms' ) }
style={ fieldStyle }
/>
</Disabled>
</div>

<JetpackFieldControls
Expand Down
Loading