mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 10:21:52 +00:00
feat: add input color (#2257)
* feat: add input color * patterns will always be there --------- Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
This commit is contained in:
committed by
Aiden McClelland
parent
833c1f22a3
commit
e0ee89bdd9
22
frontend/package-lock.json
generated
22
frontend/package-lock.json
generated
@@ -19,6 +19,8 @@
|
||||
"@angular/router": "^14.1.0",
|
||||
"@angular/service-worker": "^14.2.2",
|
||||
"@ionic/angular": "^6.1.15",
|
||||
"@maskito/angular": "^0.10.0",
|
||||
"@maskito/core": "^0.10.0",
|
||||
"@materia-ui/ngx-monaco-editor": "^6.0.0",
|
||||
"@ng-web-apis/common": "^2.0.0",
|
||||
"@ng-web-apis/mutation-observer": "^2.0.0",
|
||||
@@ -3498,6 +3500,26 @@
|
||||
"integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@maskito/angular": {
|
||||
"version": "0.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@maskito/angular/-/angular-0.10.0.tgz",
|
||||
"integrity": "sha512-RpwN4zj//IV1Lnm1kkDlxej7XuhSlkr3VfkG+dAkl7gJsqdnLnrSFesnId564vwI6oxXZHEGzSpujXdQwje7Kg==",
|
||||
"dependencies": {
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/common": ">=12.0.0",
|
||||
"@angular/core": ">=12.0.0",
|
||||
"@angular/forms": ">=12.0.0",
|
||||
"@maskito/core": "^0.10.0",
|
||||
"rxjs": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@maskito/core": {
|
||||
"version": "0.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@maskito/core/-/core-0.10.0.tgz",
|
||||
"integrity": "sha512-ChCGFiA5uIOVetctbFaWjv1EDj4WdHW2cWtOFuqGbTB4+NcIn//ubccjuTEV41Pb/gR4pyO0Fkv2RRzV+cLOmA=="
|
||||
},
|
||||
"node_modules/@materia-ui/ngx-monaco-editor": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@materia-ui/ngx-monaco-editor/-/ngx-monaco-editor-6.0.0.tgz",
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
"@angular/router": "^14.1.0",
|
||||
"@angular/service-worker": "^14.2.2",
|
||||
"@ionic/angular": "^6.1.15",
|
||||
"@maskito/angular": "^0.10.0",
|
||||
"@maskito/core": "^0.10.0",
|
||||
"@materia-ui/ngx-monaco-editor": "^6.0.0",
|
||||
"@ng-web-apis/common": "^2.0.0",
|
||||
"@ng-web-apis/mutation-observer": "^2.0.0",
|
||||
|
||||
@@ -6,6 +6,10 @@ export abstract class Control<Spec extends ValueSpec, Value> {
|
||||
private readonly control: FormControlComponent<Spec, Value> =
|
||||
inject(FormControlComponent)
|
||||
|
||||
get invalid(): boolean {
|
||||
return this.control.touched && this.control.invalid
|
||||
}
|
||||
|
||||
get spec(): Spec {
|
||||
return this.control.spec
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
<tui-input
|
||||
[maskito]="mask"
|
||||
[tuiTextfieldCustomContent]="color"
|
||||
[tuiTextfieldCleaner]="false"
|
||||
[tuiHintContent]="spec.description"
|
||||
[pseudoInvalid]="invalid"
|
||||
[(ngModel)]="value"
|
||||
(focusedChange)="onFocus($event)"
|
||||
>
|
||||
{{ spec.name }}
|
||||
<span *ngIf="spec.required">*</span>
|
||||
</tui-input>
|
||||
<ng-template #color>
|
||||
<div class="wrapper" [style.color]="value">
|
||||
<input
|
||||
type="color"
|
||||
class="color"
|
||||
tabindex="-1"
|
||||
[(ngModel)]="value"
|
||||
(click.stop)="(0)"
|
||||
/>
|
||||
<tui-svg
|
||||
src="tuiIconPaintLarge"
|
||||
tuiWrapper
|
||||
appearance="icon"
|
||||
class="icon"
|
||||
></tui-svg>
|
||||
</div>
|
||||
</ng-template>
|
||||
@@ -0,0 +1,33 @@
|
||||
@import '@taiga-ui/core/styles/taiga-ui-local';
|
||||
|
||||
.wrapper {
|
||||
position: relative;
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
pointer-events: auto;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
height: 0.3rem;
|
||||
width: 1.4rem;
|
||||
bottom: 0.125rem;
|
||||
background: currentColor;
|
||||
border-radius: 0.125rem;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
.color {
|
||||
@include fullsize();
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.icon {
|
||||
@include fullsize();
|
||||
pointer-events: none;
|
||||
|
||||
input:hover + & {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { Component } from '@angular/core'
|
||||
import { ValueSpecColor } from 'start-sdk/lib/config/configTypes'
|
||||
import { Control } from '../control'
|
||||
import { MaskitoOptions } from '@maskito/core'
|
||||
|
||||
@Component({
|
||||
selector: 'form-color',
|
||||
templateUrl: './form-color.component.html',
|
||||
styleUrls: ['./form-color.component.scss'],
|
||||
})
|
||||
export class FormColorComponent extends Control<ValueSpecColor, string> {
|
||||
readonly mask: MaskitoOptions = {
|
||||
mask: ['#', ...Array(6).fill(/[0-9a-f]/i)],
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,12 @@
|
||||
<ng-container [ngSwitch]="spec.type">
|
||||
<form-text *ngSwitchCase="'text'"></form-text>
|
||||
<form-color *ngSwitchCase="'color'"></form-color>
|
||||
<form-file *ngSwitchCase="'file'"></form-file>
|
||||
<form-multiselect *ngSwitchCase="'multiselect'"></form-multiselect>
|
||||
<form-number *ngSwitchCase="'number'"></form-number>
|
||||
<form-select *ngSwitchCase="'select'"></form-select>
|
||||
<form-text *ngSwitchCase="'text'"></form-text>
|
||||
<form-textarea *ngSwitchCase="'textarea'"></form-textarea>
|
||||
<form-toggle *ngSwitchCase="'toggle'"></form-toggle>
|
||||
<form-select *ngSwitchCase="'select'"></form-select>
|
||||
<form-multiselect *ngSwitchCase="'multiselect'"></form-multiselect>
|
||||
<form-file *ngSwitchCase="'file'"></form-file>
|
||||
</ng-container>
|
||||
<tui-error [error]="order | tuiFieldError | async"></tui-error>
|
||||
<ng-template *ngIf="spec.warning" #warning let-completeWith="completeWith">
|
||||
|
||||
@@ -39,7 +39,7 @@ interface ValidatorsPatternError {
|
||||
pattern: ({ requiredPattern }: ValidatorsPatternError) =>
|
||||
control.spec.patterns.find(
|
||||
({ regex }) => String(regex) === String(requiredPattern),
|
||||
)?.description || 'Invalid pattern',
|
||||
)?.description || 'Invalid format',
|
||||
}),
|
||||
},
|
||||
],
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<tui-input-files
|
||||
[pseudoInvalid]="true"
|
||||
[pseudoInvalid]="invalid"
|
||||
[(ngModel)]="value"
|
||||
(focusedChange)="onFocus($event)"
|
||||
>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<tui-multi-select
|
||||
[tuiHintContent]="spec.description"
|
||||
[pseudoInvalid]="invalid"
|
||||
[editable]="false"
|
||||
[disabledItemHandler]="disabledItemHandler"
|
||||
[(ngModel)]="selected"
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
<tui-input-number
|
||||
[tuiHintContent]="spec.description"
|
||||
[tuiTextfieldPostfix]="spec.units || ''"
|
||||
[pseudoInvalid]="invalid"
|
||||
[precision]="Infinity"
|
||||
[decimal]="spec.integer ? 'never' : 'not-zero'"
|
||||
[min]="spec.min ?? -Infinity"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<tui-select
|
||||
[tuiHintContent]="spec.description"
|
||||
[tuiTextfieldCleaner]="!spec.required"
|
||||
[pseudoInvalid]="invalid"
|
||||
[(ngModel)]="selected"
|
||||
(focusedChange)="onFocus($event)"
|
||||
>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<tui-input
|
||||
[tuiTextfieldCustomContent]="spec.masked ? toggle : ''"
|
||||
[tuiHintContent]="spec.description"
|
||||
[pseudoInvalid]="invalid"
|
||||
[(ngModel)]="value"
|
||||
(focusedChange)="onFocus($event)"
|
||||
>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<tui-text-area
|
||||
[tuiHintContent]="spec.description"
|
||||
[pseudoInvalid]="invalid"
|
||||
[expandable]="true"
|
||||
[rows]="6"
|
||||
[maxLength]="spec.maxLength"
|
||||
|
||||
@@ -9,8 +9,10 @@ import {
|
||||
TuiHintModule,
|
||||
TuiLinkModule,
|
||||
TuiModeModule,
|
||||
TuiSvgModule,
|
||||
TuiTextfieldControllerModule,
|
||||
TuiTooltipModule,
|
||||
TuiWrapperModule,
|
||||
} from '@taiga-ui/core'
|
||||
import {
|
||||
TuiElasticContainerModule,
|
||||
@@ -40,6 +42,8 @@ import { FormArrayComponent } from './form-array/form-array.component'
|
||||
import { FormControlComponent } from './form-control/form-control.component'
|
||||
import { MustachePipe } from './mustache.pipe'
|
||||
import { ControlDirective } from './control.directive'
|
||||
import { FormColorComponent } from './form-color/form-color.component'
|
||||
import { MaskitoModule } from '@maskito/angular'
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@@ -66,10 +70,14 @@ import { ControlDirective } from './control.directive'
|
||||
TuiFieldErrorPipeModule,
|
||||
TuiValueChangesModule,
|
||||
TuiElasticContainerModule,
|
||||
MaskitoModule,
|
||||
TuiSvgModule,
|
||||
TuiWrapperModule,
|
||||
],
|
||||
declarations: [
|
||||
FormGroupComponent,
|
||||
FormControlComponent,
|
||||
FormColorComponent,
|
||||
FormTextComponent,
|
||||
FormToggleComponent,
|
||||
FormTextareaComponent,
|
||||
|
||||
@@ -766,6 +766,14 @@ export module Mock {
|
||||
},
|
||||
},
|
||||
},
|
||||
background: {
|
||||
name: 'Background',
|
||||
type: 'color',
|
||||
description: 'Background color for the service',
|
||||
warning: null,
|
||||
required: false,
|
||||
default: '#000000',
|
||||
},
|
||||
advanced: {
|
||||
name: 'Advanced',
|
||||
type: 'object',
|
||||
|
||||
@@ -28,6 +28,7 @@ import {
|
||||
unionSelectKey,
|
||||
ValueSpecTextarea,
|
||||
unionValueKey,
|
||||
ValueSpecColor,
|
||||
} from 'start-sdk/lib/config/configTypes'
|
||||
const Mustache = require('mustache')
|
||||
|
||||
@@ -123,6 +124,13 @@ export class FormService {
|
||||
value = spec.default || null
|
||||
}
|
||||
return this.formBuilder.control(value, numberValidators(spec))
|
||||
case 'color':
|
||||
if (currentValue !== undefined) {
|
||||
value = currentValue
|
||||
} else {
|
||||
value = spec.default || null
|
||||
}
|
||||
return this.formBuilder.control(value, colorValidators(spec))
|
||||
case 'object':
|
||||
return this.getFormGroup(spec.spec, [], currentValue)
|
||||
case 'list':
|
||||
@@ -198,6 +206,16 @@ function textareaValidators(spec: ValueSpecTextarea): ValidatorFn[] {
|
||||
return validators
|
||||
}
|
||||
|
||||
function colorValidators({ required }: ValueSpecColor): ValidatorFn[] {
|
||||
const validators: ValidatorFn[] = [Validators.pattern(/^#[0-9a-f]{6}$/i)]
|
||||
|
||||
if (required) {
|
||||
validators.push(Validators.required)
|
||||
}
|
||||
|
||||
return validators
|
||||
}
|
||||
|
||||
function numberValidators(
|
||||
spec: ValueSpecNumber | ListValueSpecNumber,
|
||||
): ValidatorFn[] {
|
||||
|
||||
Reference in New Issue
Block a user