sveltejs / svelte

web development for the rest of us
https://svelte.dev
MIT License
80.1k stars 4.26k forks source link

Type safe --style-props #13463

Open fcrozatier opened 1 month ago

fcrozatier commented 1 month ago

Describe the bug

--style-props are a convenient way to pass CSS variables to a component, and type-safety would make it even better (auto-completion + useful format checking for things like sizes typed as ${number}rem etc.)

We can declare these properties in a $props() type annotation, which already enables auto-completion. But the props are not picked-up by the tooling and ts will complain even though they are passed in.

// Component.svelte
<script lang="ts">
  let {}: { '--size': `${number}rem` } = $props();
</script>

<div>hey</div>

<style>
  div {
    padding: var(--size, 0);
  }
</style>
Capture d’écran 2024-10-01 à 16 25 33

A "workaround" is to spread an object containing the property but now TS is happy but it doesn't work

Capture d’écran 2024-10-01 à 16 29 19

Reproduction

https://svelte-5-preview.vercel.app/#H4sIAAAAAAAAE52QzU7DMBCEX2WxKqWV4hQ4umkkxCPAjSDVSbatVf_JdoJC5HdHSUoL9MZtPbP-djQD2QuJnrC3gWiukDDyZC1JSejt-PAdyoAkJd60rh6V3NdO2ACS68O2JMGXpCh1GYSyxgV4NsoajTrA3hkFSba-KNkMSzalztczZfyp8ztK4fUFaqOs5EJ7qNoAIsCHcScPlBalzq9cSr34xG1JHhyqkhT59cIvnPBw5Nb237TGoNfJTL2BwpBl2QDJDE8YJI8OVQIx_uGTlCjTiL3AhrDgWozppbnL3n_6kxhgiAx-htgtBt2qCl10qHYQYQsL64z1y9VNiY3oiiP2-XocJsWHXuLEbkQHwziMo7eS9wyElkIjraSpT5vZq3h9OjjT6obWRhrHoO65PpuWN43QBwYdd8s5YQr3q8mNU5jzuduG3uMXl60IR2cCAAA=

Logs

No response

System Info

irrelevant

Severity

annoyance

david-plugge commented 1 month ago

That is actually a cool idea. Maybe its possible to use css for declaring variables?

/* or some special thing like :global(...) */
:root {
  /* name - default value */
  --size:        3em;
}

Just throwing in my thoughts^^

fcrozatier commented 1 month ago

Sure they're declared in CSS I'm just talking about the DX and type-safety here

Maybe the best way to go about it would be that the tooling enforces the types based on the @property syntax descriptor

eg. declaring a CSS variable this way

<style>
@property --size {
    syntax: "<percentage>";
    inherits: true;
    initial-value: 100%;
  }
</style>

should enforce a "${number}%" type on the --size --style-prop

<-- valid -->
<Component --size="50%"></Component>

<-- invalid -->
<Component --size="50"></Component>
david-plugge commented 1 month ago

Yeah that is basicly what im talking about. I would prefer the css variable declaration in my css section, the script part doesnt care about that.