ionic-team / stencil

A toolchain for building scalable, enterprise-ready component systems on top of TypeScript and Web Component standards. Stencil components can be distributed natively to React, Angular, Vue, and traditional web developers from a single, framework-agnostic codebase.
https://stenciljs.com
Other
12.49k stars 783 forks source link

Feature Request : @Props OR component inheritance #2844

Open xe4me opened 3 years ago

xe4me commented 3 years ago

Hi Thank you for your wonderful job, we are one of your biggest supporters, here in Australia :) I'm writing to get help or perhaps if possible get this feature natively. We're developing a design system with Stencil , however ,since StencilJS doesn't support component inheritance, we're finding it very limiting when it comes to reusing our internal code base.

Use Case : Create a bunch of icon components that each represent one icon element, but they all share similar props :

Component 1 :

    <my-icon-arrow-left size="small" color="primary">

Component 2 :

    <my-icon-arrow-right size="small" color="primary">

Each of above component accepts a series of similar props, like color, size, shape and passes all those props to an internal component which has the SCSS file which does the actual magic .

Each of above components would look like below


@Component({
  tag: 'icon-arrow-left',
  shadow: true,
})
export class IconArrowLeft {

  @Prop() size: SvgSizeProp;

  @Prop() color: SvgColourProp;

  @Prop() bgColor: SvgBgColorProp;

  @Prop() shape: SvgShapeProp;

  @Prop() elevation: SvgElevationProp;

  @Prop() customColor: string;

  @Prop() customSize: string;

  @Prop() variant: SvgVariantProp;

  render() {
    return (
      <svg-icon
        size={this.size}
        color={this.color}
        bg-color={this.bgColor}
        shape={this.shape}
        elevation={this.elevation}
        custom-color={this.customColor}
        custom-size={this.customSize}
        variant={this.variant}
        path={
          <g stroke="none">
            <path d="M44.003282"></path>
          </g>
        }
      />
    );
  }
}

This pattern has been heavily used in React Material design, https://material-ui.com/components/material-icons/

We have hundreds of these icons and we have to repeat these props inside every single one of them. Is there any way we could avoid this ?

Ideally, it would be nice if there was a @Props() allProps decorator which would contain all the props.

With Props, we could do something like this :

@Component({
  tag: 'icon-arrow-left',
  shadow: true,
})
export class IconArrowLeft {
  @Props() allProps:

  render() {
    return (
      <svg-icon
        {...this.allProps} <<<<<<<<====== HERE 
        path={
          <g stroke="none">
            <path d="M44.003282,63.9997333"></path>
          </g>
        }
      />
    );
  }
}

Or at least allow us to use inheritance to achieve something like this :

export class IconArrowLeft extend IconProps {

  render() {
    return (
      <svg-icon
        size={this.size}
        color={this.color}
        bg-color={this.bgColor}
        shape={this.shape}
        elevation={this.elevation}
        custom-color={this.customColor}
        custom-size={this.customSize}
        variant={this.variant} 
        path={
          <g stroke="none">
            <path d="M44.003282,63.9997333"></path>
          </g>
        }
      />
    );
  }
}

We look forward to hearing from you.

Cheers

granfar commented 3 years ago

We WOULD LOVE THIS KIND OF FEATURE AS WELL!

miladwooliesx commented 3 years ago

Hey guys :) Any updates on this ?

johnjenkins commented 3 years ago

I will be submitting a PR which should solve this issue :) - just as soon as my source maps branch gets merged as source maps would be helpful. (Mentioned as per the contributing guide)

miladwooliesx commented 3 years ago

@johnjenkins that would be amazing. Any updates ?

johnjenkins commented 3 years ago

Yep, nearly there. Just writing tests

johnjenkins commented 3 years ago

Ok, if anyone get a chance, I'd urge you to take a look and try it out :)

centigrade-julian-lang commented 2 years ago

Component inheritance is really a foundational feature IMHO. Also there are several already-closed issues to this exact topic (starting from 2017, nearly 5 years ago). Will this have a chance to arrive in stencil or is it considered as "won't fix"?