carbon-design-system / carbon-components-angular

An Angular implementation of the Carbon Design System for IBM.
https://angular.carbondesignsystem.com
Apache License 2.0
531 stars 300 forks source link

[proposal/discussion]: form generator service + component #282

Open cal-smith opened 5 years ago

cal-smith commented 5 years ago

Carbon Design System has pretty complete form guidance, and Angular has excellent form handling, and our form components keep improving.

So, it follows that we could provide a complete solution for generating forms, based on the Carbon principals and Angular's reactive forms module.

At a high level:

<ibm-form [controls]="formControls" (submit)="onSubmit()" (clear)="onClear()"></ibm-form>
constructor(private formGen: FormGenerator) {}

public formControls = this.formGen.group({
  firstName: {value: "", component: "input", validators: [ Validators.required ] },
  lastName: {value: "", component: "input", validators: [ Validators.required ]  },
  address: this.formGen.group({
    street: {value: "", component: "input" },
    city: {value: "", component: "input", asyncValidators: [ validateCity ] },
    province: {value: "", component: "dropdown" },
    postalCode: {value: "", component: "input" }
  }),
});

Where FormGenerator would wrap (or potentially extend) FormBuilder ...

class FormGenerator {
  public group(controlConfig: ControlConfig) { // return value TBD
    // ...
  }
}

And the ControlConfig interface would resemble:

interface ControlConfig {
  [key: string]: Control
}

type FromComponent = "input" | "select" | "dropdown" | "radio" | "checkbox" | "password"; // and more

interface Control {
  value: any;
  component: FormComponent | Class; // Union with class iff we can use https://angular.io/api/common/NgComponentOutlet
  validators: Array<ValidatorFn>;
  asyncValidators: Array<AsyncValidatorFn>;
  // + others
}

There's still a few open questions, and implementation details to sort out, but this should represent the consumers view of the component/service.

esuau commented 5 years ago

It means all the existing input components have to be modified to support Reactive Forms first…

cal-smith commented 5 years ago

By and large they already do! Generally, if it supports ngModel it supports usage in Reactive Forms ... most of the base inputs are just directives, and IIRC checkbox/toggle/dropdown/combobox/select all support ngModel

I'm sure there may be some additional hooks Reactive Forms want access to, but the base functionality should be there

cal-smith commented 4 years ago

https://www.carbondesignsystem.com/patterns/forms-pattern we have some slightly better defined form specs now, so we should be able to take another run at this pattern