diff --git a/src/app/features/config/color-input/color-input.component.html b/src/app/features/config/color-input/color-input.component.html new file mode 100644 index 0000000000..13740fec7d --- /dev/null +++ b/src/app/features/config/color-input/color-input.component.html @@ -0,0 +1,11 @@ + + {{ to.label }} + + diff --git a/src/app/features/config/color-input/color-input.component.scss b/src/app/features/config/color-input/color-input.component.scss new file mode 100644 index 0000000000..c7acb4bf6e --- /dev/null +++ b/src/app/features/config/color-input/color-input.component.scss @@ -0,0 +1,3 @@ +mat-form-field { + width: 100%; +} diff --git a/src/app/features/config/color-input/color-input.component.ts b/src/app/features/config/color-input/color-input.component.ts new file mode 100644 index 0000000000..054e113ead --- /dev/null +++ b/src/app/features/config/color-input/color-input.component.ts @@ -0,0 +1,32 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { ReactiveFormsModule } from '@angular/forms'; +import { MatFormField, MatInput, MatLabel } from '@angular/material/input'; +import { FieldType, FormlyModule } from '@ngx-formly/core'; +import { IS_FIREFOX } from '../../../util/is-firefox'; +import { IS_MOBILE } from '../../../util/is-mobile'; + +/** + * This component deliberately avoids Formly's field type abstractions for the + * Material UI components because the form field wrapper implementation uses + * a focus monitoring service that is counterproductive for certain native + * color input controls. + */ +@Component({ + selector: 'color-input', + templateUrl: './color-input.component.html', + styleUrls: ['./color-input.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, + imports: [FormlyModule, MatFormField, MatInput, MatLabel, ReactiveFormsModule], +}) +export class ColorInputComponent extends FieldType { + onFocus(event: FocusEvent): void { + if (!IS_FIREFOX || IS_MOBILE) return; + // Desktop Firefox oddly fires another focus event when the native color + // input closes rather than a blur event, so determine whether a value + // change has occurred and force a blur to have it persisted + const input = event.target as HTMLInputElement; + if (input.value !== this.formControl.value) { + input.blur(); + } + } +} diff --git a/src/app/features/project/project-form-cfg.const.ts b/src/app/features/project/project-form-cfg.const.ts index 0879ae3e3e..9bc0933c38 100644 --- a/src/app/features/project/project-form-cfg.const.ts +++ b/src/app/features/project/project-form-cfg.const.ts @@ -57,10 +57,9 @@ export const CREATE_PROJECT_BASIC_CONFIG_FORM_CONFIG: ConfigFormSection }, { key: 'theme.primary' as any, - type: 'input', + type: 'color', templateOptions: { label: T.F.PROJECT.FORM_THEME.L_THEME_COLOR, - type: 'color', }, }, { diff --git a/src/app/features/tag/tag-form-cfg.const.ts b/src/app/features/tag/tag-form-cfg.const.ts index 5f4b29a230..01078b469a 100644 --- a/src/app/features/tag/tag-form-cfg.const.ts +++ b/src/app/features/tag/tag-form-cfg.const.ts @@ -24,10 +24,9 @@ export const BASIC_TAG_CONFIG_FORM_CONFIG: ConfigFormSection = { }, { key: 'color', - type: 'input', + type: 'color', templateOptions: { label: T.F.TAG.FORM_BASIC.L_COLOR, - type: 'color', }, }, ], diff --git a/src/app/features/work-context/work-context.const.ts b/src/app/features/work-context/work-context.const.ts index c13d51b28c..a82d76b3c3 100644 --- a/src/app/features/work-context/work-context.const.ts +++ b/src/app/features/work-context/work-context.const.ts @@ -65,26 +65,23 @@ export const WORK_CONTEXT_THEME_CONFIG_FORM_CONFIG: ConfigFormSection