Skip to content
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

Why are custom properties not optional? #69

Closed
juice49 opened this issue Nov 28, 2024 · 4 comments
Closed

Why are custom properties not optional? #69

juice49 opened this issue Nov 28, 2024 · 4 comments

Comments

@juice49
Copy link
Contributor

juice49 commented Nov 28, 2024

I was really impressed to learn Mist generates types for CSS custom properties. However, I'm wondering why the resulting style object types are not optional. Especially because—as far as I can tell—Mist can only discover custom properties that have been declared with a default value in a style. Style consumers may not wish to override this default.

CSS input

div[data-component="test"] {
  --color: rebeccapurple;
  outline: 10rem solid var(--color);
}

TypeScript output (--color is not optional)

interface Mist_div_data_component_test extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> {
  'data-component': 'test'
  style?: { '--color': string } & React.CSSProperties
}

Questions

  1. Would the maintainers be receptive to a PR making custom properties optional?
  2. Has there been any consideration around supporting the @property at-rule for discovering custom properties, and perhaps inferring information about them?

Love the work that's been done here ❤️.

@typicode
Copy link
Owner

Hey,

Thanks! :)

  1. It's a mistake, feel free to create a PR
  2. Yes in previous versions, I don't remember why exactly why it wasn't supported in the end. Do you have some use cases/examples that would benefit from it?

@juice49
Copy link
Contributor Author

juice49 commented Nov 28, 2024

Thank you. PR opened! (:

On @property support:

  1. It embraces the spirit of being a standards focused approach.
  2. It eliminates the need to redeclare a custom property that has already been declared using @property.
  3. The syntax descriptor could perhaps be used to enhance the created type (imagine a value that can be 'a' | 'b' being typed that way).

Having said that, it doesn't appear to be permissible to nest @property at-rules. I think this puts a bit of a spanner in the works for discovery, because Mist would not be able to associate the at-rule with an element.

Not permissible

div[data-component="test"] {
  @property --color {
    syntax: "<color>";
    inherits: false;
    initial-value: rebeccapurple;
  }

  outline: 10rem solid var(--color);
}

Permissible, but can no longer be associated with an element

@property --color {
  syntax: "<color>";
  inherits: false;
  initial-value: rebeccapurple;
}

div[data-component="test"] {
  outline: 10rem solid var(--color);
}

Some half baked thoughts:

  1. What if Mist discovered custom properties by observing where they are used (var(--some-property) versus --some-property: 1)?
  2. What if after discovering the usage of a custom property, Mist looked for a matching @property at-rule in order to create a more precise type based on its syntax declaration?
  3. Observation: typing custom properties like this is generally quite a challenging task, because the value could be set on some element outside of where it's declared or used in CSS.

Maybe I'm overthinking it 😅.

typicode pushed a commit that referenced this issue Nov 28, 2024
* fix: make custom properties optional in created types (#69)

* test: add custom property example to tests
@typicode
Copy link
Owner

typicode commented Dec 2, 2024

Thanks for the example! @property is really nice and I think it's possible to take advantage of it with the current way MistCSS works.

Private custom property

@property --color {
  syntax: "<color>";
  inherits: false;
  initial-value: rebeccapurple;
}

div[data-component="test"] {
  outline: 10rem solid var(--color);
}
// TS not allowed
<div data-component="test" style={{ color: ' red' }} />

Public custom property

@property --color {
  syntax: "<color>";
  inherits: false;
  initial-value: rebeccapurple;
}

div[data-component="test"] {
  --color: var(--color); /* Exposed/public custom property */
  outline: 10rem solid var(--color);
}
// TS allowed
<div data-component="test" style={{ color: ' red' }} />

Regarding 3., I agree. I've checked the different possible syntax but most of the time it would translate to string. It would be great if there would be TS types for the syntax values but I'm not aware of one. Maintaining one looks complex/error prone.

@juice49
Copy link
Contributor Author

juice49 commented Dec 3, 2024

Aha! That's a great suggestion, thank you. I'll try adopting this pattern and see how it goes.

Maintaining one looks complex/error prone.

Yeeeeep... I love that Mist embraces the cascade, unlike other approaches that discourage or completely disallow it. However, for typing props, a distinct entry point is necessary.

Appreciate your thoughts on this topic 🙏.

@juice49 juice49 closed this as completed Dec 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants