webstudio-is / webstudio

Open source website builder and Webflow alternative. Webstudio is an advanced visual builder that connects to any headless CMS, supports all CSS properties, and can be hosted anywhere, including with us.
https://webstudio.is
GNU Affero General Public License v3.0
5.07k stars 589 forks source link

Reimplement style info computing for style panel #1536

Closed TrySound closed 2 days ago

TrySound commented 1 year ago

Since initial implementation style info computing became very complex. We need new version based considering all new requirements and data structures

Here are all sources of styles we have now

istarkov commented 1 year ago

The other thing we need to iterate/find ancestor node with specific styles

image

And we need computedStyle for inherit keyword. Use case - detect current node real style if inherit is set, needed in cases like show Position.

Both needs recursion or top/down algorithm of building current style.

istarkov commented 1 year ago

I think this is already too hard to read, we need some model like DOM.

node.parentNode
node.style
getComputedStyle(node)

Ability to use model with minimal knowledge of all that internal atoms. Without relying on React hooks.

kof commented 1 year ago

@istarkov be careful with "like DOM" DOM is slow partially because of the model.

istarkov commented 1 year ago

I don't mind if it will be not the full model but only parent iterator or getStyle(instanceId) call. As of now to do anything with styling you need to know all the internals we use. That's bad.

istarkov commented 1 year ago

I also think that tests we have should be rewritten in readable format. For now they are fully unreadable. It will be much better to understand what style shoud element have if our test input would be jsx like (we can use own jsx)

const blablaStyleSource = { width: 20px };
const blubluStyleSource = { height: 20px }

<div 
  style={{a: 1}} 
  style:break300={{ width: 10px, inheritedProp: blabla }} 
  style:break700={{ width: 10px, inheritedProp: blabla }} 
  styleSources={['local', blablaStyleSource, blublu]}
>
<selected style={} styleSources={['local']} selectedStyleSourceIndex={2} />
</div>

let screenWidth = 360px;
expect (calc(selected, screenWidth).style.local).tobe(xxx);
expect (calc(selected, screenWidth).style.value).tobe(xxx);
expect (calc(selected, screenWidth).parent.style.local).tobe(xxx);

or without jsx

div({ style: { }, styleSources: {}], [
  selected({ style, styleSources: {} })
]))

Looking at such tests at least the tree model is understandable, and I as a human can calc final result

kof commented 1 year ago

DOM model I meant meaning the children referencing parents and stuff like that. There are better ways to do this.

TrySound commented 1 year ago

Jax doesn't work for us because component names have pascal case and require such components to be in scope.

But yeah, if we use it for tests and embed template all would be easier.