diff --git a/angular.json b/angular.json index 39ba2d35..c8a4b710 100644 --- a/angular.json +++ b/angular.json @@ -44,6 +44,12 @@ "src/assets" ], "styles": [ + "node_modules/@fontsource/jost/400.css", + "node_modules/@fontsource/jost/400-italic.css", + "node_modules/@fontsource/jost/500.css", + "node_modules/@fontsource/jost/500-italic.css", + "node_modules/@fontsource/ubuntu-mono/400.css", + "node_modules/@fontsource/ubuntu-mono/400-italic.css", "src/styles.scss" ], "stylePreprocessorOptions": { @@ -118,6 +124,12 @@ "src/assets" ], "styles": [ + "node_modules/@fontsource/jost/400.css", + "node_modules/@fontsource/jost/400-italic.css", + "node_modules/@fontsource/jost/500.css", + "node_modules/@fontsource/jost/500-italic.css", + "node_modules/@fontsource/ubuntu-mono/400.css", + "node_modules/@fontsource/ubuntu-mono/400-italic.css", "src/styles.scss" ], "stylePreprocessorOptions": { diff --git a/package-lock.json b/package-lock.json index 8a5524cb..163d4094 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "@angular/platform-browser-dynamic": "~13.2.5", "@angular/router": "~13.2.5", "@fontsource/jost": "^4.5.4", + "@fontsource/ubuntu-mono": "^4.5.4", "@sentry/angular": "^6.18.2", "ng-particles": "^2.40.2", "rxjs": "~7.5.0", @@ -2631,6 +2632,11 @@ "resolved": "https://registry.npmjs.org/@fontsource/jost/-/jost-4.5.4.tgz", "integrity": "sha512-KHTF84XsoO3MUxHjdUqwF7jsHbqyZAafceFngKURUfx2MdN795ilQ7noNW2gu7qlv2N1fwGJnAUhCTUGelkLwQ==" }, + "node_modules/@fontsource/ubuntu-mono": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/@fontsource/ubuntu-mono/-/ubuntu-mono-4.5.4.tgz", + "integrity": "sha512-zJL8ImnfNWrAzmjaWlxnYtAT54j2kxZm2sUtx/UQ6JPEypeaC51iQ3HAZOa8h8TzF0ZuJmxxlAsI+mHdvT+rkg==" + }, "node_modules/@gar/promisify": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", @@ -15362,6 +15368,11 @@ "resolved": "https://registry.npmjs.org/@fontsource/jost/-/jost-4.5.4.tgz", "integrity": "sha512-KHTF84XsoO3MUxHjdUqwF7jsHbqyZAafceFngKURUfx2MdN795ilQ7noNW2gu7qlv2N1fwGJnAUhCTUGelkLwQ==" }, + "@fontsource/ubuntu-mono": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/@fontsource/ubuntu-mono/-/ubuntu-mono-4.5.4.tgz", + "integrity": "sha512-zJL8ImnfNWrAzmjaWlxnYtAT54j2kxZm2sUtx/UQ6JPEypeaC51iQ3HAZOa8h8TzF0ZuJmxxlAsI+mHdvT+rkg==" + }, "@gar/promisify": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", diff --git a/package.json b/package.json index cb773f4b..4c086212 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "@angular/platform-browser-dynamic": "~13.2.5", "@angular/router": "~13.2.5", "@fontsource/jost": "^4.5.4", + "@fontsource/ubuntu-mono": "^4.5.4", "@sentry/angular": "^6.18.2", "ng-particles": "^2.40.2", "rxjs": "~7.5.0", diff --git a/src/app/base-components/base-components.component.html b/src/app/base-components/base-components.component.html index c2b20396..e4fce684 100644 --- a/src/app/base-components/base-components.component.html +++ b/src/app/base-components/base-components.component.html @@ -98,5 +98,60 @@

Buttons - Text only

Info disabled +
+

Textinput

+ + + + + + + + + + + + +
- diff --git a/src/app/base-components/base-components.component.ts b/src/app/base-components/base-components.component.ts index ec2fc41d..3adfe97c 100644 --- a/src/app/base-components/base-components.component.ts +++ b/src/app/base-components/base-components.component.ts @@ -1,4 +1,5 @@ -import { Component } from '@angular/core'; +import {Component} from '@angular/core'; +import {FormControl, Validators} from "@angular/forms"; @Component({ selector: 'app-base-components', @@ -7,9 +8,22 @@ import { Component } from '@angular/core'; }) export class BaseComponentsComponent { - constructor() { } + control: FormControl = new FormControl({value: 0, disabled: true}, [Validators.required]); + controlWithValidator: FormControl = new FormControl(0, [Validators.required]); pressedAlert(name: string) { alert(name + " was pressed!"); } + + changedText(event: any) { + console.log(event) + alert("Text changed! Text: " + event.target.value); + } + + getValidatorHintText() { + if (this.controlWithValidator.errors?.['required']) { + return "Value is required"; + } + return ""; + } } diff --git a/src/app/base-components/base-components.module.ts b/src/app/base-components/base-components.module.ts index 5f0daab6..65298937 100644 --- a/src/app/base-components/base-components.module.ts +++ b/src/app/base-components/base-components.module.ts @@ -6,18 +6,22 @@ import { BaseComponentsComponent } from './base-components.component'; import {ButtonModule} from "../../core/components/buttons/button/button.module"; import {ButtonOutlineModule} from "../../core/components/buttons/button-outline/button-outline.module"; import {ButtonTextModule} from "../../core/components/buttons/button-text/button-text.module"; +import {TextInputModule} from "../../core/components/inputs/text-input/text-input.module"; +import {ReactiveFormsModule} from "@angular/forms"; @NgModule({ declarations: [ BaseComponentsComponent ], - imports: [ - CommonModule, - BaseComponentsRoutingModule, - ButtonModule, - ButtonOutlineModule, - ButtonTextModule - ] + imports: [ + CommonModule, + BaseComponentsRoutingModule, + ButtonModule, + ButtonOutlineModule, + ButtonTextModule, + TextInputModule, + ReactiveFormsModule + ] }) export class BaseComponentsModule { } diff --git a/src/core/components/inputs/text-input/text-input.component.html b/src/core/components/inputs/text-input/text-input.component.html new file mode 100644 index 00000000..a3f0e798 --- /dev/null +++ b/src/core/components/inputs/text-input/text-input.component.html @@ -0,0 +1,12 @@ + + +{{hintText}} + diff --git a/src/core/components/inputs/text-input/text-input.component.scss b/src/core/components/inputs/text-input/text-input.component.scss new file mode 100644 index 00000000..aa03a37a --- /dev/null +++ b/src/core/components/inputs/text-input/text-input.component.scss @@ -0,0 +1,70 @@ +@import "src/global-styles/_theme-colors.scss"; + +$flavors: ( + primary: $primary-default, + success: $success-default, + warning: $warning-default, + danger: $danger-default, + info: $info-default, +); + +:host { + vertical-align: top; + display: inline-block; +} + +label { + font-weight: 500; + color: $light-font; +} + +input { + width: 100%; + margin-top: 2px; + margin-bottom: 1px; + + background-color: $input-background; + color: $light-font; + font-family: inherit; + font-size: inherit; + + padding: 8px 16px 8px 16px; + border: 2px solid transparent; + border-radius: 8px; + outline: none; + + &::placeholder { + color: $placeholder-font + } + + &:disabled::placeholder { + color: $disabled-placeholder-font + } + + @each $name, $color in $flavors { + &.#{$name} { + + @if $name == "danger" + or $name == "warning" + or $name == "success" + or $name == "info" { + border: 2px solid $color; + } @else { + &:focus { + border: 2px solid $color; + } + } + } + } +} + +small { + font-size: 16px; + display: block; + color: $grey-font; + @each $name, $color in $flavors { + &.#{$name} { + color: $color; + } + } +} diff --git a/src/core/components/inputs/text-input/text-input.component.spec.ts b/src/core/components/inputs/text-input/text-input.component.spec.ts new file mode 100644 index 00000000..f895776f --- /dev/null +++ b/src/core/components/inputs/text-input/text-input.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TextInputComponent } from './text-input.component'; + +describe('TextInputComponent', () => { + let component: TextInputComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ TextInputComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(TextInputComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/core/components/inputs/text-input/text-input.component.ts b/src/core/components/inputs/text-input/text-input.component.ts new file mode 100644 index 00000000..10b47f16 --- /dev/null +++ b/src/core/components/inputs/text-input/text-input.component.ts @@ -0,0 +1,96 @@ +import {Component, EventEmitter, Input, Output, ViewChild} from '@angular/core'; +import {ControlValueAccessor, NG_VALUE_ACCESSOR} from "@angular/forms"; +import {ɵgetDOM as getDOM} from '@angular/common'; + +export type Flavor = 'primary' | 'success' | 'warning' | 'danger' | 'info'; + +/** + * We must check whether the agent is Android because composition events + * behave differently between iOS and Android. + */ +function isAndroid(): boolean { + const userAgent = getDOM() ? getDOM().getUserAgent() : ''; + return /android (\d+)/.test(userAgent.toLowerCase()); +} + +@Component({ + selector: 'design-text-input', + templateUrl: './text-input.component.html', + styleUrls: ['./text-input.component.scss'], + providers: [ + { + provide: NG_VALUE_ACCESSOR, + multi: true, + useExisting: TextInputComponent + } + ] +}) +export class TextInputComponent implements ControlValueAccessor { + + public disabled = false; + @Input() placeholder: string = ""; + @Input() hintText: string = ""; + @Input() label: string = ""; + @Input() hintColored: boolean = false; + @Input() public flavor: Flavor = 'primary'; + @ViewChild(HTMLInputElement) private input?: HTMLInputElement; + + // eslint-disable-next-line @angular-eslint/no-output-on-prefix + @Output() public onEnter = new EventEmitter(); + onChanged: ((_: any) => void) | null = null; + onTouched: (() => void) | null = null; + composing: boolean = false; + + private readonly compositionMode: boolean | null; + + constructor() { + if (this.compositionMode === null) { + this.compositionMode = !isAndroid(); + } + } + + writeValue(obj: any): void { + if(this.input) { + this.input.value = obj + } + } + + registerOnChange(fn: (_: any) => void): void { + this.onChanged = fn; + } + + registerOnTouched(fn: () => void): void { + this.onTouched = fn; + } + + setDisabledState(isDisabled: boolean) { + this.disabled = isDisabled; + } + + getLabelColor() { + if (this.hintColored && !this.disabled && this.flavor != "primary") { + return this.flavor; + } else { + return ""; + } + } + + onInput(target: EventTarget | null) { + if (!this.compositionMode || (this.compositionMode && !this.composing)) { + // @ts-ignore + this.onChanged?.(target.value) + } + } + + compositionStart() { + this.composing = true; + } + + compositionEnd(target: EventTarget | null) { + this.composing = false; + if (this.compositionMode) { + // @ts-ignore + this.onChanged?.(target.value); + } + } +} diff --git a/src/core/components/inputs/text-input/text-input.module.ts b/src/core/components/inputs/text-input/text-input.module.ts new file mode 100644 index 00000000..6ba804e1 --- /dev/null +++ b/src/core/components/inputs/text-input/text-input.module.ts @@ -0,0 +1,18 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { TextInputComponent } from './text-input.component'; + + + +@NgModule({ + declarations: [ + TextInputComponent + ], + imports: [ + CommonModule + ], + exports: [ + TextInputComponent + ] +}) +export class TextInputModule { } diff --git a/src/global-styles/_variables.scss b/src/global-styles/_variables.scss index 55fd1eff..88412ffd 100644 --- a/src/global-styles/_variables.scss +++ b/src/global-styles/_variables.scss @@ -18,7 +18,6 @@ $window-input-background: #1a1a1a; $task-manager-chart-back: rgba(12, 12, 12, 0.7); $task-manager-chart-border: #8c8c8c; $start-menu-background: rgba(0, 0, 0, 0.719); - // FONTS // -$default-font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; +$default-font: Jost, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; diff --git a/src/styles.scss b/src/styles.scss index 82bfe68c..f1bb3ff5 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -1,23 +1,28 @@ /* You can add global styles to this file, and also import other style files */ -@import url("https://fonts.googleapis.com/css?family=Ubuntu+Mono"); @import "variables"; @import "controls"; @import "context-menu"; -@import "@fontsource/jost"; app-root { width: 100%; height: 100%; } +* { + box-sizing: border-box; +} + body, html { width: 100%; height: 100%; margin: 0; - overflow: hidden; font-size: 20px; - font-family: "Jost", Roboto, "Open Sans", sans-serif; + overflow: hidden; background-color: #000; color: #fff; } + +button, input, select, textarea, span, div, a, p, small { + font-family: $default-font; +}