diff --git a/README.md b/README.md index ac0fef9..0c45d6d 100644 --- a/README.md +++ b/README.md @@ -82,15 +82,20 @@ breakpoints. The components included in this project are: - **InputComponent**: A generic input field that can be used for text, email, - password, etc. + password, etc. **InputDropdownOptionComponent**: An option element for the + dropdown list input field. - **InputCheckboxComponent**: A checkbox input field. +- **InputChipComponent**: A chip element for the chips list input field. +- **InputChipsComponent**: A chips list input field. - **InputDatepickerComponent**: A datepicker input field. -- **InputDropdownComponent**: A dropdown input field. -- **InputRadioModule**: A radio input options field. +- **InputDropdownComponent**: A dropdown list input field. +- **InputDropdownOptionGroupComponent**: An option group element for the + dropdown list input field. +- **InputRadioComponent**: A radio input options field. +- **InputRadioOptionComponent**: An option element for the radio input field. - **InputTextareaComponent**: A textarea input field. - **InputTimepickerComponent**: A timepicker input field. - **InputToggleComponent**: A toggle input field. -- More to come... Each component is designed to be easily customized and extended to meet your specific needs. They are built using Angular Material and Angular CDK, ensuring @@ -145,9 +150,14 @@ application where used: + import { + InputComponent, + InputCheckboxComponent, ++ InputChipComponent, ++ InputChipsComponent, + InputDatepickerComponent, + InputDropdownComponent, -+ InputRadioModule, ++ InputDropdownOptionComponent, ++ InputDropdownOptionGroupComponent, ++ InputRadioComponent, ++ InputRadioOptionComponent, + InputTextareaComponent, + InputTimepickerComponent, + InputToggleComponent, @@ -158,34 +168,58 @@ application where used: ... imports: [ + InputComponent, ++ InputCheckboxComponent, ++ InputChipComponent, ++ InputChipsComponent, ++ InputDatepickerComponent, ++ InputDropdownComponent, ++ InputDropdownOptionComponent, ++ InputDropdownOptionGroupComponent, ++ InputRadioComponent, ++ InputRadioOptionComponent, ++ InputTextareaComponent, ++ InputTimepickerComponent, ++ InputToggleComponent, ... ], }) ... -// Or import to component +// Or import to a standalone component @Component({ ... imports: [ + InputComponent, ++ InputCheckboxComponent, ++ InputChipComponent, ++ InputChipsComponent, ++ InputDatepickerComponent, ++ InputDropdownComponent, ++ InputDropdownOptionComponent, ++ InputDropdownOptionGroupComponent, ++ InputRadioComponent, ++ InputRadioOptionComponent, ++ InputTextareaComponent, ++ InputTimepickerComponent, ++ InputToggleComponent, ... ], }) ... -// Then use in template +// Then use in template, simplified example form below: +
-+ -+ -+ -+ -+ -+ -+ -+ -+ ... ++ ++ ++ ++ ++ ++ ++ ++ ++ + ``` diff --git a/package-lock.json b/package-lock.json index c45f195..1b72b25 100644 --- a/package-lock.json +++ b/package-lock.json @@ -42,6 +42,7 @@ "ng-packagr": "^19.1.2", "npm-check-updates": "^17.1.11", "prettier": "^3.4.1", + "tslib": "^2.3.0", "typescript": "~5.7.2" }, "engines": { @@ -66,7 +67,6 @@ "@types/luxon": "^3.4.2", "luxon": "^3.5.0", "rxjs": "~7.8.0", - "tslib": "^2.3.0", "zone.js": "~0.15.0" } }, diff --git a/package.json b/package.json index d841153..6e3b08c 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,6 @@ "@types/luxon": "^3.4.2", "luxon": "^3.5.0", "rxjs": "~7.8.0", - "tslib": "^2.3.0", "zone.js": "~0.15.0" }, "devDependencies": { @@ -75,6 +74,7 @@ "ng-packagr": "^19.1.2", "npm-check-updates": "^17.1.11", "prettier": "^3.4.1", + "tslib": "^2.3.0", "typescript": "~5.7.2" }, "contributors": [ diff --git a/prettier.config.js b/prettier.config.js index 2735ad2..82d6156 100644 --- a/prettier.config.js +++ b/prettier.config.js @@ -1,5 +1,5 @@ /** Prettier configuration and options. */ -const prettierConfig = { +var prettierConfig = { $schema: 'https://json.schemastore.org/prettierrc', plugins: ['@trivago/prettier-plugin-sort-imports'], importOrderParserPlugins: ['typescript', 'decorators-legacy'], diff --git a/src/app/form/form-group-example.ts b/src/app/form/form-group-example.ts index bee9379..6dda8a8 100644 --- a/src/app/form/form-group-example.ts +++ b/src/app/form/form-group-example.ts @@ -2,18 +2,21 @@ import { DateTime } from 'luxon'; import { FormControl, FormGroup, Validators } from '@angular/forms'; -import { RadioOption } from '../public/types'; +import { Option } from '../public/types'; import { CustomValidators } from '../public/utilities/custom-validators'; export interface FormGroupExample { checkboxOptional: FormControl; checkboxRequired: FormControl; + chips: FormControl; count: FormControl; date: FormControl; description: FormControl; + dropdown: FormControl; + dropdownMultiple: FormControl | null>; email: FormControl; name: FormControl; - optionsRadio: FormControl; + optionsRadio: FormControl; password: FormControl; time: FormControl; toggleOptional: FormControl; @@ -42,6 +45,10 @@ export const formGroupExample = new FormGroup({ checkboxRequired: new FormControl(null, [ Validators.required, ]), + chips: new FormControl(null, [ + Validators.required, + Validators.maxLength(3), + ]), count: new FormControl(null, [ Validators.min(validation.count.min), Validators.max(validation.count.max), @@ -55,12 +62,19 @@ export const formGroupExample = new FormGroup({ Validators.required, Validators.maxLength(validation.description.maxLength), ]), + dropdown: new FormControl(null, [ + Validators.required, + ]), + dropdownMultiple: new FormControl | null>( + null, + [Validators.required, Validators.maxLength(2)], + ), email: new FormControl(null, [ Validators.email, Validators.required, ]), name: new FormControl(null, [Validators.required]), - optionsRadio: new FormControl(null, [ + optionsRadio: new FormControl(null, [ Validators.required, ]), password: new FormControl(null, [ diff --git a/src/app/form/form.component.html b/src/app/form/form.component.html index 5b03cbc..e34dd09 100644 --- a/src/app/form/form.component.html +++ b/src/app/form/form.component.html @@ -74,6 +74,64 @@ placeholder="Enter or select a time" hint="A time between 8 AM and 8 PM CST." > + + + @for (option of dropdownOptions; track option) { + {{ + option.label + }} + } + + @for (option of groupedDropdownOptions; track option) { + {{ + option.label + }} + } + + Disabled Option + + + + @for (option of dropdownOptions; track option) { + {{ + option.label + }} + } + + @for (option of groupedDropdownOptions; track option) { + {{ + option.label + }} + } + + Disabled Option + + + + @for (chip of chips; track chip) { + {{ chip }} + } + pro-input, > pro-input-checkbox, + > pro-input-chips, > pro-input-datepicker, + > pro-input-dropdown, > pro-input-radio, - > pro-input-timepicker, > pro-input-textarea, - > pro-input-toggle { + > pro-input-timepicker, + > pro-input-toggle, + > pro-loading-input { flex: 0 0 100%; margin: 0 0 calc($margin * 2) 0; max-width: 100%; diff --git a/src/app/form/form.component.ts b/src/app/form/form.component.ts index ff47ff0..31c4ed4 100644 --- a/src/app/form/form.component.ts +++ b/src/app/form/form.component.ts @@ -9,12 +9,20 @@ import { MatSnackBar } from '@angular/material/snack-bar'; import { FormDirective } from '../public/form.directive'; import { InputCheckboxComponent } from '../public/input-checkbox/input-checkbox.component'; import { InputDatepickerComponent } from '../public/input-datepicker/input-datepicker.component'; -import { InputRadioModule } from '../public/input-radio/input-radio.module'; +import { InputDropdownOptionGroupComponent } from '../public/input-dropdown/input-dropdown-option-group.component'; +import { InputDropdownOptionComponent } from '../public/input-dropdown/input-dropdown-option.component'; +import { InputRadioComponent } from '../public/input-radio/input-radio.component'; import { InputTextareaComponent } from '../public/input-textarea/input-textarea.component'; import { InputTimepickerComponent } from '../public/input-timepicker/input-timepicker.component'; import { InputToggleComponent } from '../public/input-toggle/input-toggle.component'; import { InputComponent } from '../public/input/input.component'; -import { RadioOption } from '../public/types'; +import { + InputChipComponent, + InputChipsComponent, + InputDropdownComponent, + InputRadioOptionComponent, +} from '../public/public'; +import { Option } from '../public/types'; import { FormGroupExample, formGroupExample, @@ -27,9 +35,15 @@ import { imports: [ CommonModule, InputCheckboxComponent, + InputChipComponent, + InputChipsComponent, InputComponent, InputDatepickerComponent, - InputRadioModule, + InputDropdownComponent, + InputDropdownOptionComponent, + InputDropdownOptionGroupComponent, + InputRadioComponent, + InputRadioOptionComponent, InputTextareaComponent, InputTimepickerComponent, InputToggleComponent, @@ -50,6 +64,9 @@ export class FormComponent extends FormDirective { } protected override readonly formGroup = formGroupExample; + protected readonly chips = chips; + protected readonly dropdownOptions = dropdownOptions; + protected readonly groupedDropdownOptions = groupedDropdownOptions; protected readonly radioOptions = radioOptions; protected readonly thirtyDaysFromNow: DateTime; protected readonly today: DateTime; @@ -60,9 +77,15 @@ export class FormComponent extends FormDirective { this.formGroup.setValue({ checkboxOptional: false, checkboxRequired: true, + chips: [this.chips[0], this.chips[1]], count: 45, date: this.today.plus({ weeks: 1 }), description: 'Lorem ipsum dolor sit amet.', + dropdown: this.dropdownOptions[0].value, + dropdownMultiple: [ + this.dropdownOptions[0].value, + this.dropdownOptions[1].value, + ], email: 'test@test.com', name: 'John Doe', optionsRadio: this.radioOptions[0].value, @@ -82,14 +105,18 @@ export class FormComponent extends FormDirective { if (this.formGroup.invalid) { this.highlightInvalidControls(); this.scrollToFirstInvalidControl(); - this.snackBar.open('Form invalid!', 'Dismiss', { - duration: 3000, - }); + this.snackBar.open( + 'Form invalid! Please fix the displayed errors and try again.', + 'Dismiss', + { + duration: 3000, + }, + ); return; } - this.snackBar.open('Form submitted!', 'Dismiss', { + this.snackBar.open('Form valid! Submitted successfully.', 'Dismiss', { duration: 3000, }); this.formGroup.reset(); @@ -105,7 +132,30 @@ export class FormComponent extends FormDirective { } } -const radioOptions: RadioOption[] = [ +const chips: readonly string[] = [ + 'Chip 1', + 'Chip 2', + 'Chip 3', + 'Chip 4', + 'Chip 5', + 'Chip 6', + 'Chip 7', + 'Chip 8', +]; + +const dropdownOptions: readonly Option[] = [ + { label: 'Option 1', value: 'One' }, + { label: 'Option 2', value: '2' }, + { label: 'Option 3', value: 3 }, +]; + +const groupedDropdownOptions: readonly Option[] = [ + { label: 'Option 4', value: 'Four' }, + { label: 'Option 5', value: '5' }, + { label: 'Option 6', value: 6 }, +]; + +const radioOptions: readonly Option[] = [ { label: 'Option 1', value: 1 }, { label: 'Option 2', value: '2' }, { label: 'Option 3', value: 3 }, diff --git a/src/app/layout/footer.component.html b/src/app/layout/footer.component.html index 2ffb88d..39f7683 100644 --- a/src/app/layout/footer.component.html +++ b/src/app/layout/footer.component.html @@ -1,8 +1,6 @@