2

In a large project we decided to create a button component. We added Input for most of the things that we needed and at the end it summed to 20 Inputs.

  @Input() body: string;
  @Input() chevron: "right" | "left" | "none" = "none";
  @Input() chevronDown: "right" | "left" | "none" = "none";
  @Input() padding: "small" | "normal" = "normal";
  @Input() shade: "dark" | "light" = "dark";
  @Input() active: boolean = false;
  @Input() color: "primary" | "transparent" | "danger" | "warning" | "secondary" | "success" = "primary";
  @Input() buttonType: "button" | "menu" | "reset" | "submit" = "button";
  @Input() disabled: boolean = false;
  @Input() icon: "plus" | "three-dots" | "x" | "chevron-down" | "chevron-up" | "pen" | "grid" | "funnel";
  @Input() helper: string;
  @Input() fontSize: "x-small" | "small" | "normal" = "normal";
  @Input() textAlign: "left" | "center" | "right" = "left";
  @Input() spinner: "left" | "right" | "none" = "none";
  @Input() disableWhenSpin: boolean = true;
  @Input() fontWeight: number = 400;
  @Input() width: "full" | "normal" = "normal";
  @Input() hiddenAfter: "md" | "none" = "none";
  @Input() hiddenBefore: "md" | "none" = "none";
  @Input() checkbox = false;
  @Input() checked = false;

And we added icons inside template and conditionally rendered them with inputs. But mostly we don't give inputs conditionally:

  <app-button body="Cancel"
                    padding="small"
                    color="transparent"
                    (onClick)="cancelEmitter.emit()"></app-button>

So event we don't give inputs conditionally (like color insead of [color]) is it bad to add this much input and html to component. And also is Angular removes unnessecary html and js logic according to inputs, if it is the case this should not be a problem too?

  • It's looks no good :)) May be better use a Input with json config or create directives? – V.Tur Oct 03 '20 at 14:23
  • Using a single *config* is usually a bad idea. There is nothing wrong with having such structure. There are, however, [many ways](https://stackoverflow.com/questions/47743281/refactoring-angular-components-from-many-inputs-outputs-to-a-single-config-objec) you can refactor your code, if you want. Also you can remove @Input decorators if you have: `@Component({ inputs: ['body', 'active', ...], ...})` – Aleksey Solovey Oct 03 '20 at 14:34
  • Giving the consumer options is always a good concept. But even better is to keep view as simple as possible and provide functions to alter behaviors. Here's an article that explains this concept https://dev.to/jwp/stop-using-classes-for-everthting-3pb1 – JWP Oct 03 '20 at 14:40

1 Answers1

1

From Code Quality point of view, It is slightly bad to have such a large number of inputs. The main argument in support of this is - when you will write such a button a define , lets say 9 inputs (I dont think you have to really define all at once), It will make the code unobtrusively convoluted and not only hard to read but also difficult to maintain.

Then, What Can We Do ?

Define core properties as inputs and make a config input to pass rest of properties is config object in it. define this config type using interface.

Or

We can divide the inputs into closely related configOption.

This will achieve both Encapsulation as well as Code Maintainability. Below code can be taken as a hint.

  <app-button body="Cancel" optionConfig="opCfg" styleConfig="styCfg" (onClick)="cancelEmitter.emit()"></app-button>

Or

If applicable, identify the core attributes to set as Inputs and remove the rest. Like OP suggested, if most cases don't require so much customization, don't burden everyone with the options and have the few instances who do require the customization build on top of a smaller component or build their own.

abhay tripathi
  • 3,547
  • 4
  • 20
  • 25