-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Allow styles to be changed dynamically through editor settings #52767
Conversation
packages/edit-post/src/editor.js
Outdated
: defaultEditorStyles; | ||
}, [ settings, hasThemeStyles ] ); | ||
result.styles = | ||
hasThemeStyles && themeStyles.length |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hasThemeStyles
flag corresponds to a user preferences that is changeable from the preferences modal. That means that any change to the "settings" that is done by updateEditorSettings
call from plugin authors will override any change that this preference might have.
Meaning we might want to avoid doing anything here to the "styles" property and instead move the logic of this preference to within the EditorProvider
component (potentially need to make hasThemeStyles a new setting in editorSettings though).
Maybe there are other options, but it does raise the question about whether "styles" was ever meant to be "editable".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, the styles should be filtered after they are passed down to the EditorProvider
. We can simply move the filtering to Layout
, because that's a component within that provider. I fixed this in 00fde60. I can add an extra e2e test to ensure that this works correctly.
Size Change: +33 B (0%) Total Size: 1.44 MB
ℹ️ View Unchanged
|
I remember trying this approach and that's what I couldn't figure out why it was happening. Here is my crude experiment with it now and it seems to work!: import * as React from 'react'
import {
useEffect,
useState,
} from '@wordpress/element'
import {
store as editorStore,
} from '@wordpress/editor'
import {
useSelect,
useDispatch,
} from '@wordpress/data'
import {
registerPlugin,
} from '@wordpress/plugins'
const useDynamicEditorStyle = (id: string, css: string, early: boolean = false) => {
const getEditorSettings = useSelect((select: any) => {
const {
getEditorSettings,
} = select(editorStore)
return getEditorSettings
}, [])
const {
updateEditorSettings,
} = useDispatch(editorStore) as any
useEffect(() => {
if(!id || !css) {
return
}
const editorSettings = getEditorSettings()
const otherStyles = editorSettings.styles.filter(({id: styleId = ''}) => styleId !== id)
const style = {
id,
css,
isGlobalStyles: true,
}
updateEditorSettings({
...editorSettings,
styles: [
...(early ? [style] : []),
...otherStyles,
...(!early ? [style] : []),
],
})
return () => {
updateEditorSettings({
...editorSettings,
styles: otherStyles,
})
}
}, [id, css, early, getEditorSettings, updateEditorSettings])
return null
}
const RenderDynamicStyles: React.FC = () => {
const [color, setColor] = useState<string>('blue')
useDynamicEditorStyle('test-1', `body { border-left: 10px dashed ${color} !important; }`, true)
useDynamicEditorStyle('test-2', `body { border-right: 10px dashed ${color} !important; }`)
useDynamicEditorStyle('test-3', `body { --spacing-0\.5: 100px; }`) // traverse.js:26 Error while traversing the CSS: Error: undefined:1:19: property missing ':'
useEffect(() => {
const colorChanger = setInterval(() => {
setColor(color => color === 'blue' ? 'green' : 'blue')
}, 5000)
return () => clearInterval(colorChanger)
}, [])
return null
}
registerPlugin('dynamic-style-test', {
render: RenderDynamicStyles,
}) One issue I ran into was that Ideally there would be separate reducer/actions for adding/removing styles so you don't have to manipulate the whole editor settings object. Maybe even a hook? |
@ska-dev-1 Good to hear this works. I will check the escaping. Have you tried double spacing with
Right, but this is the current mechanism we have so I'm not sure if there's more we can do for this release. We could adda filter for the styles array which would still have the flexibility of prepending and appending new styles. But tbh, I'd rather wait with that and see more use cases. |
In any case, this PR would get rid of transformStyles when the iframe is iframed: Iframe: skip scoping styles |
Yes, here's the gist of it: wp.blockEditor.transformStyles([{css: `body { --spacing-0\.5: 1px; }`}], '.test') But it doesn't error with this for example: wp.blockEditor.transformStyles([{css: `.\[--header-height\:theme\(spacing\[1\.5\]\)\] { --header-height: var(--spacing-1\.5); }`}], '.test')
Sounds good. |
I just cherry-picked this PR to the update/packages-RC2 branch to get it included in the next release: cb35dee |
* Filter out patterns that are not allowed in the inserter (#52675) * Remove autofocus and improve placeholder text consistency. (#52634) * Do not navigate to the styles pages unless you're in a random listing page (#52728) * Patterns: Don't override the rootClientID in create menu - only set if undefined (#52713) * Footnotes: store in revisions (#52686) * Fix: Block toolbar obscuring document tools when Top Toolbar is enabled (#52722) * Update toolbar width * Site editor needs specific width * fixes top toolbar width for post editor when not in fullscreen * remove the body rule --------- Co-authored-by: Andrei Draganescu <andrei.draganescu@automattic.com> * Site Editor: Fix site link accessibility issues (#52744) * Add id to pattern inserted notice to stop multiple notices stacking (#52746) * Global Styles: Don't use named arguments for 'sprintf' (#52782) * Footnotes: Use static closures when not using '' (#52781) * removes check for active preview device type to enable the fixed toolbar preference (#52770) * Parser / Site Editor: Ensure autop is not run when freeform block is set to core/html (#52716) * Parse / Site Editor: Ensure autop is not run when freeform block is set to core/html * Switch to equals freeform instead of not equals core/html * Rename core/test-freeform to core/freeform in tests * Adding @SInCE annotation for relevant 6.3 changes. (#52820) * Navigation: Load the raw property on the navigation fallback (#52758) * Navigation: Load the raw property on the navigation fallback * Update lib/compat/wordpress-6.3/navigation-fallback.php Co-authored-by: Dave Smith <getdavemail@gmail.com> * Update lib/compat/wordpress-6.3/navigation-fallback.php Co-authored-by: Dave Smith <getdavemail@gmail.com> * Add a test for these properties * Update phpunit/class-gutenberg-rest-navigation-fallback-controller-test.php Co-authored-by: Dave Smith <getdavemail@gmail.com> * Update phpunit/class-gutenberg-rest-navigation-fallback-controller-test.php Co-authored-by: Dave Smith <getdavemail@gmail.com> * Update phpunit/class-gutenberg-rest-navigation-fallback-controller-test.php Co-authored-by: Dave Smith <getdavemail@gmail.com> * Update phpunit/class-gutenberg-rest-navigation-fallback-controller-test.php Co-authored-by: Dave Smith <getdavemail@gmail.com> * Update phpunit/class-gutenberg-rest-navigation-fallback-controller-test.php Co-authored-by: Dave Smith <getdavemail@gmail.com> * Update phpunit/class-gutenberg-rest-navigation-fallback-controller-test.php Co-authored-by: Dave Smith <getdavemail@gmail.com> * Update phpunit/class-gutenberg-rest-navigation-fallback-controller-test.php Co-authored-by: Dave Smith <getdavemail@gmail.com> * Update phpunit/class-gutenberg-rest-navigation-fallback-controller-test.php Co-authored-by: Dave Smith <getdavemail@gmail.com> * Update phpunit/class-gutenberg-rest-navigation-fallback-controller-test.php Co-authored-by: Dave Smith <getdavemail@gmail.com> * add more comments * add necessary method * Fix php coding standards error --------- Co-authored-by: Dave Smith <getdavemail@gmail.com> Co-authored-by: Jerry Jones <jones.jeremydavid@gmail.com> * Allow styles to be changed dynamically through editor settings (#52767) * ResizableFrame: Fix styling in Firefox (#52700) * ResizableFrame: Fix styling in Firefox * Remove unused class * Patterns: Fix empty general template parts category (#52747) --------- Co-authored-by: Glen Davies <glen.davies@automattic.com> --------- Co-authored-by: Carolina Nymark <myazalea@hotmail.com> Co-authored-by: Andrea Fercia <a.fercia@gmail.com> Co-authored-by: Riad Benguella <benguella@gmail.com> Co-authored-by: Glen Davies <glendaviesnz@users.noreply.github.com> Co-authored-by: Ella <4710635+ellatrix@users.noreply.github.com> Co-authored-by: James Koster <james@jameskoster.co.uk> Co-authored-by: Andrei Draganescu <andrei.draganescu@automattic.com> Co-authored-by: George Mamadashvili <georgemamadashvili@gmail.com> Co-authored-by: Andrei Draganescu <me@andreidraganescu.info> Co-authored-by: Andrew Serong <14988353+andrewserong@users.noreply.github.com> Co-authored-by: Ramon <ramonjd@users.noreply.github.com> Co-authored-by: Ben Dwyer <ben@scruffian.com> Co-authored-by: Dave Smith <getdavemail@gmail.com> Co-authored-by: Jerry Jones <jones.jeremydavid@gmail.com> Co-authored-by: Lena Morita <lena@jaguchi.com> Co-authored-by: Kai Hao <kevin830726@gmail.com> Co-authored-by: Glen Davies <glen.davies@automattic.com>
For some reason, this PR seems to be causing an infinite render loop which crashes the editor on some sites. I'm still trying to find the exact issue, but with this PR reverted, the issue no longer happens. (I found this PR via git bisect) The render loop is related to slot/fill
|
Ah, I think the issue is that the style arrays don't have a stable reference, so they get re-created too frequently. |
What?
Fixes #50091 (comment).
Why?
It should be possible to add content styles dynamically in JS. This should be possible through
wp.data.dispatch( 'core/editor' ).updateEditorSettings
, but it's currently broken: the styles passed through theLayout
component (and all the way down toIframe
are the initialised styles, not the styles from the store, so these components don't react to updates.This PR fixes that and adds an e2e test.
How?
Testing Instructions
There's an e2e test, but you can try using
wp.data.dispatch( 'core/editor' ).updateEditorSettings
(see e2e test).Testing Instructions for Keyboard
Screenshots or screencast