Elderjs / elderjs

Elder.js is an opinionated static site generator and web framework for Svelte built with SEO in mind.

Home Page:https://elderguide.com/tech/elderjs/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Cannot apply style props to client components

eight04 opened this issue · comments

commented

Here is the repro:
https://github.com/eight04/node-test/tree/elderjs-style-prop

Svelte allows you to pass css custom property to components via --prop=value syntax:
https://svelte.dev/docs#template-syntax-component-directives---style-props

However it doesn't work with client components:

<script>
import Test from '../../components/Test.svelte';
</script>

<Test --color="red" text="test1"/>

<Test --color="red" hydrate-client={{text: "test2"}} />

<Test hydrate-client={{"--color": "red", text: "test3"}} />

Result in:
image

I guess it's just syntax sugar that will be compiled into styled dummy div at compile time. Elderjs replaces the entire client component with something else when compiling hence the directive doesn't work. Passing it as a real component prop does not work either since it's not a real prop but template syntax.

@eight04 You nailed one of the drawbacks with partial hydration and this is related to #237.

Basically each component is an island so we can't fully support all of Svelte's functionality out of the box... but you can get what you are trying to achieve by wrapping sub components in a hydrated component.

Open to a PR for this if you'd like to add and document this.

The concern here is expanding scope of trying to match Svelte's offerings and adding more complexity to the preprocessing stage when our business case doesn't need this functionality. (we just hydrate a sub component)

Basically it is a decision against complexity and maintenance burden. Would be a nice to have though.

commented

I think it is possible to make Elderjs support style props.

Since elderjs adds a component wrapper

<!-- rendered HTML -->
<div class="test-component" id="testXXX">
  ... prerendered component ...
</div>

It can apply style props to this wrapper:

<!-- rendered HTML -->
<div class="text-component" id="testXXX" style:--color="red">
  ... prerendered component ...
</div>

This won't work when hydrate-options={{"loading": "none"}} because there is no wrapper. In this case, we can just produce a valid svelte component:

<!-- source -->
<Test --color="red" hydrate-client={{text: "test2"}} hydrate-options={{"loading": "none"}}/>
<!-- after preprocess -->
<Test --color="red" {...{text: "test2"}} />