Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Form Input: Don't use flex-direction: row-reverse for checkbox field #64232

Merged
merged 11 commits into from
Sep 12, 2024
115 changes: 114 additions & 1 deletion packages/block-library/src/form-input/deprecated.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import removeAccents from 'remove-accents';
*/
import {
RichText,
useBlockProps,
__experimentalGetBorderClassesAndStyles as getBorderClassesAndStyles,
__experimentalGetColorClassesAndStyles as getColorClassesAndStyles,
} from '@wordpress/block-editor';
Expand All @@ -26,6 +27,118 @@ const getNameFromLabelV1 = ( content ) => {
);
};

const v2 = {
attributes: {
type: {
type: 'string',
default: 'text',
},
name: {
type: 'string',
},
label: {
type: 'string',
default: 'Label',
selector: '.wp-block-form-input__label-content',
source: 'html',
__experimentalRole: 'content',
},
inlineLabel: {
type: 'boolean',
default: false,
},
required: {
type: 'boolean',
default: false,
selector: '.wp-block-form-input__input',
source: 'attribute',
attribute: 'required',
},
placeholder: {
type: 'string',
selector: '.wp-block-form-input__input',
source: 'attribute',
attribute: 'placeholder',
__experimentalRole: 'content',
},
value: {
type: 'string',
default: '',
selector: 'input',
source: 'attribute',
attribute: 'value',
},
visibilityPermissions: {
type: 'string',
default: 'all',
},
},
supports: {
anchor: true,
reusable: false,
spacing: {
margin: [ 'top', 'bottom' ],
},
__experimentalBorder: {
radius: true,
__experimentalSkipSerialization: true,
__experimentalDefaultControls: {
radius: true,
},
},
},
save( { attributes } ) {
const { type, name, label, inlineLabel, required, placeholder, value } =
attributes;

const borderProps = getBorderClassesAndStyles( attributes );
const colorProps = getColorClassesAndStyles( attributes );

const inputStyle = {
...borderProps.style,
...colorProps.style,
};

const inputClasses = clsx(
'wp-block-form-input__input',
colorProps.className,
borderProps.className
);
const TagName = type === 'textarea' ? 'textarea' : 'input';

const blockProps = useBlockProps.save();

if ( 'hidden' === type ) {
return <input type={ type } name={ name } value={ value } />;
}

return (
<div { ...blockProps }>
{ /* eslint-disable jsx-a11y/label-has-associated-control */ }
<label
className={ clsx( 'wp-block-form-input__label', {
'is-label-inline': inlineLabel,
} ) }
>
<span className="wp-block-form-input__label-content">
<RichText.Content value={ label } />
</span>
<TagName
className={ inputClasses }
type={ 'textarea' === type ? undefined : type }
name={ name || getNameFromLabelV1( label ) }
required={ required }
aria-required={ required }
placeholder={ placeholder || undefined }
style={ inputStyle }
/>
</label>
{ /* eslint-enable jsx-a11y/label-has-associated-control */ }
</div>
);
},
};

// Version without wrapper div in saved markup
// See: https://github.com/WordPress/gutenberg/pull/56507
const v1 = {
Expand Down Expand Up @@ -137,6 +250,6 @@ const v1 = {
},
};

const deprecated = [ v1 ];
const deprecated = [ v2, v1 ];

export default deprecated;
28 changes: 17 additions & 11 deletions packages/block-library/src/form-input/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ function InputFieldBlock( { attributes, setAttributes, className } ) {
ref.current.focus();
}

// Note: radio inputs aren't implemented yet.
const isCheckboxOrRadio = type === 'checkbox' || type === 'radio';

const controls = (
<>
{ 'hidden' !== type && (
Expand Down Expand Up @@ -81,6 +84,18 @@ function InputFieldBlock( { attributes, setAttributes, className } ) {
</>
);

const content = (
<RichText
tagName="span"
className="wp-block-form-input__label-content"
value={ label }
onChange={ ( newLabel ) => setAttributes( { label: newLabel } ) }
aria-label={ label ? __( 'Label' ) : __( 'Empty label' ) }
data-empty={ ! label }
placeholder={ __( 'Type the label for this input' ) }
/>
);

if ( 'hidden' === type ) {
return (
<>
Expand Down Expand Up @@ -111,17 +126,7 @@ function InputFieldBlock( { attributes, setAttributes, className } ) {
'is-label-inline': inlineLabel || 'checkbox' === type,
} ) }
>
<RichText
tagName="span"
className="wp-block-form-input__label-content"
value={ label }
onChange={ ( newLabel ) =>
setAttributes( { label: newLabel } )
}
aria-label={ label ? __( 'Label' ) : __( 'Empty label' ) }
data-empty={ label ? false : true }
placeholder={ __( 'Type the label for this input' ) }
/>
{ ! isCheckboxOrRadio && content }
<TagName
type={ 'textarea' === type ? undefined : type }
className={ clsx(
Expand All @@ -147,6 +152,7 @@ function InputFieldBlock( { attributes, setAttributes, className } ) {
...colorProps.style,
} }
/>
{ isCheckboxOrRadio && content }
</span>
</div>
);
Expand Down
16 changes: 13 additions & 3 deletions packages/block-library/src/form-input/save.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ export default function save( { attributes } ) {

const blockProps = useBlockProps.save();

// Note: radio inputs aren't implemented yet.
const isCheckboxOrRadio = type === 'checkbox' || type === 'radio';

if ( 'hidden' === type ) {
return <input type={ type } name={ name } value={ value } />;
}
Expand All @@ -67,9 +70,11 @@ export default function save( { attributes } ) {
'is-label-inline': inlineLabel,
} ) }
>
<span className="wp-block-form-input__label-content">
<RichText.Content value={ label } />
</span>
{ ! isCheckboxOrRadio && (
<span className="wp-block-form-input__label-content">
<RichText.Content value={ label } />
</span>
) }
<TagName
className={ inputClasses }
type={ 'textarea' === type ? undefined : type }
Expand All @@ -79,6 +84,11 @@ export default function save( { attributes } ) {
placeholder={ placeholder || undefined }
style={ inputStyle }
/>
{ isCheckboxOrRadio && (
<span className="wp-block-form-input__label-content">
<RichText.Content value={ label } />
</span>
) }
</label>
{ /* eslint-enable jsx-a11y/label-has-associated-control */ }
</div>
Expand Down
17 changes: 9 additions & 8 deletions packages/block-library/src/form-input/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,17 @@
}
}

/*
Small tweak to left-align the checkbox.
Even though `:has` is not currently supported in Firefox, this is a small tweak
and does not affect the functionality of the block or the user's experience.
There will be a minor inconsistency between browsers. However, it's more important to provide
a better experience for 80+% of users, until Firefox catches up and supports `:has`.
*/
&:has(input[type="checkbox"]) {
flex-direction: row;
width: fit-content;
/* stylelint-disable-next-line declaration-property-value-allowed-list -- This should be refactored to not use the row-reverse value. */

.wp-block-form-input__label-content {
margin: 0;
}
}

&:has(.wp-block-form-input__label-content + input[type="checkbox"]) {
/* stylelint-disable-next-line declaration-property-value-allowed-list -- This style is required for old markup. */
flex-direction: row-reverse;
}
}
Expand Down
17 changes: 17 additions & 0 deletions test/integration/fixtures/blocks/core__form-input.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
<!-- wp:form-input -->
<div class="wp-block-form-input"><label class="wp-block-form-input__label"><span class="wp-block-form-input__label-content">Label</span><input class="wp-block-form-input__input" type="text" name="label" aria-required="false"/></label></div>
<!-- /wp:form-input -->

<!-- wp:form-input {"type":"email"} -->
<div class="wp-block-form-input"><label class="wp-block-form-input__label"><span class="wp-block-form-input__label-content">Label</span><input class="wp-block-form-input__input" type="email" name="label" aria-required="false"/></label></div>
<!-- /wp:form-input -->

<!-- wp:form-input {"type":"number"} -->
<div class="wp-block-form-input"><label class="wp-block-form-input__label"><span class="wp-block-form-input__label-content">Label</span><input class="wp-block-form-input__input" type="number" name="label" aria-required="false"/></label></div>
<!-- /wp:form-input -->

<!-- wp:form-input {"type":"tel"} -->
<div class="wp-block-form-input"><label class="wp-block-form-input__label"><span class="wp-block-form-input__label-content">Label</span><input class="wp-block-form-input__input" type="tel" name="label" aria-required="false"/></label></div>
<!-- /wp:form-input -->

<!-- wp:form-input {"type":"url"} -->
<div class="wp-block-form-input"><label class="wp-block-form-input__label"><span class="wp-block-form-input__label-content">Label</span><input class="wp-block-form-input__input" type="url" name="label" aria-required="false"/></label></div>
<!-- /wp:form-input -->

52 changes: 52 additions & 0 deletions test/integration/fixtures/blocks/core__form-input.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,57 @@
"visibilityPermissions": "all"
},
"innerBlocks": []
},
{
"name": "core/form-input",
"isValid": true,
"attributes": {
"type": "email",
"label": "Label",
"inlineLabel": false,
"required": false,
"value": "",
"visibilityPermissions": "all"
},
"innerBlocks": []
},
{
"name": "core/form-input",
"isValid": true,
"attributes": {
"type": "number",
"label": "Label",
"inlineLabel": false,
"required": false,
"value": "",
"visibilityPermissions": "all"
},
"innerBlocks": []
},
{
"name": "core/form-input",
"isValid": true,
"attributes": {
"type": "tel",
"label": "Label",
"inlineLabel": false,
"required": false,
"value": "",
"visibilityPermissions": "all"
},
"innerBlocks": []
},
{
"name": "core/form-input",
"isValid": true,
"attributes": {
"type": "url",
"label": "Label",
"inlineLabel": false,
"required": false,
"value": "",
"visibilityPermissions": "all"
},
"innerBlocks": []
}
]
Loading
Loading