Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

feat: html / css components #6159

Open
3 tasks done
johnjenkins opened this issue Feb 16, 2025 · 3 comments
Open
3 tasks done

feat: html / css components #6159

johnjenkins opened this issue Feb 16, 2025 · 3 comments
Labels
Feature: Want this? Upvote it! This PR or Issue may be a great consideration for a future idea.

Comments

@johnjenkins
Copy link
Contributor

johnjenkins commented Feb 16, 2025

Prerequisites

Describe the Feature Request

CSS Web components or HTML web components are increasingly popular.

Stencil could provide some quality of life for devs; allowing them to integrate this pattern into the Stencil build chain.

Describe the Use Case

Some components within a design system, just don’t require any js runtime at all.

A ‘my-card’ or for example, could just be hook for some css. A ‘my-button’ could just be a styling wrapper around a ‘button’.

It’s quite possible to augment Stencil’s ‘components.d.ts’ with plain types, a la

declare global {
  interface HTMLElementTagNameMap {
    "my-card": HTMLElement & { props: { variant: "primary" | "secondary" } };
  }
}

But I don’t think this would pass into framework wrapper outputs for autocomplete, documentation etc etc.

Describe Preferred Solution

Something like

@Component({
  tag: 'my-card',
  styleUrl: 'my-card.css',
}) 
export class Card {
  /** The variant of the card. @default "primary" */
  @Prop() variant: "primary" | "secondary" = "primary";
}

Would add 'my-card' to all the docs / types outputs including the prop jsdocs.

Any styles could automatically be added to the global.css - it could even automatically add styles within something like

@scope (my-card) {
  ...
  [primary] { ... }
  [secondary] { ... }
}

I realise omitting shadow: true and scoped: true to mean 'no js runtime / css only' would be a breaking change, so we can discuss alternatives ( e.g. cssOnly: true etc)

Describe Alternatives

Todo

Related Code

No response

Additional Information

No response

@ionitron-bot ionitron-bot bot added the triage label Feb 16, 2025
@christian-bromann
Copy link
Member

A ‘my-card’ or for example, could just be hook for some css. A ‘my-button’ could just be a styling wrapper around a ‘button’.

Would the usage be like this then:

<my-card variant="primary">
  <button>...</button>
</my-card>

?

@christian-bromann christian-bromann added Feature: Want this? Upvote it! This PR or Issue may be a great consideration for a future idea. and removed triage labels Feb 18, 2025
@johnjenkins
Copy link
Contributor Author

johnjenkins commented Feb 18, 2025

Would the usage be like this then:

<my-card variant="primary">
 <button>...</button>
</my-card>```

Essentially, although there's 2 different examples mentioned.

A general styled block:

<my-card variant="primary">
  <!-- anything -->
</my-card>

(^ perhaps the component jsdoc could add more information about available elements / nested classes supported)

And a more prescriptive block which only supports a couple of nested elements:

<my-button variant="primary">
  <button>A button</button>
  <!-- or -->
  <a>a link</a>
</my-button>

(^ css would only target a or button and again, perhaps the component jsdoc could add more information about available elements / nested classes supported)

Thinking more on it, perhaps a full ts class in this situation is too misleading and it should just be a more ergonomic way to include the types / js docs in final outputs

@christian-bromann
Copy link
Member

christian-bromann commented Feb 18, 2025

First off, just learned about the @scope css feature, thanks for that!

Would functional components be an alternative? For Example:

@Component({ styleUrl: 'my-card.css' })
export const MyCard = ({ variant }: { variant: "primary" | "secondary" }, children) => <>
  <!-- anything -->
  {children}
</>;

This assumes:

  • We enhance the current FC implementation to acknowledge the @Component annotation
  • We may have to turn FC into a scoped component to have a host element we can register the scope to
  • FC annotated with @Component only supports styleUrl, maybe we can call it @FunctionalComponent

It seems like more work but makes sense from the semantic POV, thoughts?

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
Feature: Want this? Upvote it! This PR or Issue may be a great consideration for a future idea.
Projects
None yet
Development

No branches or pull requests

2 participants