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