Make WordPress Core

Opened 2 months ago

Last modified 3 weeks ago

#62131 new defect (bug)

WP Intreractivity API calculated classes aren't added

Reported by: mishaml's profile mishaml Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 6.5
Component: Interactivity API Keywords: needs-patch
Focuses: Cc:

Description

Hi! I'm using tailwind in the project on WordPress with Interactivity API. When I'm using simple classes using data-wp-class directives, everything works good, classes are added.

    data-wp-class--top-auto="context.isEditCard"

At the same time calculated classes with same directive aren't added to the element. I've checked whether with backslashing of classes will work, but it any way the class wasn't added.

     data-wp-class--bottom-[-24rem]="context.isEditCard"

Change History (9)

#1 @jonsurrell
2 months ago

Will you describe the desired result? Please include the expected class names and what you're seeing. The context is also important, is this used in a block?

I just did a quick test and this seemed to work correctly:

<div data-wp-context='{"isEditCard": true}'>
	<div data-wp-class--top-auto="context.isEditCard"></div>
	<div data-wp-class--bottom-[-24rem]="context.isEditCard"></div>
</div>

Processed result:

<div data-wp-context="{&quot;isEditCard&quot;: true}">
	<div class="top-auto" data-wp-class--top-auto="context.isEditCard"></div>
	<div class="bottom-[-24rem]" data-wp-class--bottom-[-24rem]="context.isEditCard"></div>
</div>

Checking the elements via DOM APIs el.classList.contains('top-auto') and el.classList.contains('bottom-[-24rem]') return true where expected.

Last edited 2 months ago by jonsurrell (previous) (diff)

#2 @mishaml
2 months ago

If by default you have isEditCard equals false, and dynamically set isEditCard:true for example by click on button than the class doesn't added. As well if by default isEditCard:true, and dynamically remove set to false, the class doesn't removed from the element

#3 @jonsurrell
2 months ago

Confirmed, with a store and HTML like the following, the top-auto class toggles correctly, while the bottom-[-24rem] does not.

import * as I from '@wordpress/interactivity';

store( 'namespace', {
	handleTest() {
		const prev = I.getContext().val;
		I.getContext().val = !prev;
		console.log(
			'prev %o // next %o // updated %o',
			prev,
			!prev,
			I.getContext().val,
		);
	},
})
<div data-wp-interactive="namespace" data-wp-context='{"val": true}'>
	<div data-wp-class--top-auto="context.val"></div>
	<div data-wp-class--bottom-[-24rem]="context.val"></div>
	<button type="button" data-wp-on--click="handleTest">toggle val</button>
</div>

#4 @jonsurrell
2 months ago

I believe this is caused by a mismatch between server and client parsing, where the server (via the HTML API) can correctly parse these attributes but the client relies on a more restrictive RegExp:

// Regular expression for directive parsing.
const directiveParser = new RegExp(
	`^data-${ p }-` + // ${p} must be a prefix string, like 'wp'.
		// Match alphanumeric characters including hyphen-separated
		// segments. It excludes underscore intentionally to prevent confusion.
		// E.g., "custom-directive".
		'([a-z0-9]+(?:-[a-z0-9]+)*)' +
		// (Optional) Match '--' followed by any alphanumeric charachters. It
		// excludes underscore intentionally to prevent confusion, but it can
		// contain multiple hyphens. E.g., "--custom-prefix--with-more-info".
		'(?:--([a-z0-9_-]+))?$',
	'i' // Case insensitive.
);

#6 @jonsurrell
2 months ago

  • Version changed from 6.6.2 to 6.5

#7 @jonsurrell
6 weeks ago

KSES would also filter these kinds of class directives: #61501.

#8 @jonsurrell
3 weeks ago

Conversation has continued on the PR, in particular https://github.com/WordPress/gutenberg/pull/65803#issuecomment-2468475673.

I'd invite @mishaml and anyone interested to participate there if you have feedback.

#9 @jonsurrell
3 weeks ago

This seems unlikely to be supported, but @luisherranz shared some ideas for supporting an advanced class syntax to allow arbitrary classes in this comment.

Last edited 3 weeks ago by jonsurrell (previous) (diff)
Note: See TracTickets for help on using tickets.