Compare commits
2 Commits
96a81cb5ec
...
e7624ab550
Author | SHA1 | Date | |
---|---|---|---|
|
e7624ab550 | ||
|
1d2c28a370 |
@ -1,3 +1,3 @@
|
||||
<button>
|
||||
<button [attr.data-appearance]="appearance">
|
||||
<ng-content></ng-content>
|
||||
</button>
|
||||
|
@ -6,14 +6,34 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--sk-gap-m);
|
||||
background-color: var(--sk-accent);
|
||||
border: none;
|
||||
border-radius: var(--sk-br-m);
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
&[data-appearance="default"], &[data-appearance="primary"] {
|
||||
background-color: var(--sk-primary);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
&[data-appearance="secondary"] {
|
||||
background-color: var(--sk-secondary);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
&[data-appearance="outline"] {
|
||||
color: #fff;
|
||||
background-color: transparent;
|
||||
box-shadow: 0px 0px 0px 1px rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
&[data-appearance="flat"] {
|
||||
color: #fff;
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,12 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'skirda-button',
|
||||
templateUrl: './button.component.html',
|
||||
styleUrls: ['./button.component.scss']
|
||||
styleUrls: ['./button.component.scss'],
|
||||
})
|
||||
export class ButtonComponent implements OnInit {
|
||||
export class ButtonComponent {
|
||||
@Input() appearance: string = 'default';
|
||||
|
||||
constructor() {}
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,5 +6,5 @@
|
||||
</div>
|
||||
<skirda-text>description</skirda-text>
|
||||
</div>
|
||||
<skirda-icon name="play" size="16" (click)="run(game)" color="var(--sk-accent)"></skirda-icon>
|
||||
<skirda-icon name="play" size="16" (click)="run(game)" color="var(--sk-primary)"></skirda-icon>
|
||||
</div>
|
21
projects/ui/src/lib/popup/popup.component.html
Normal file
21
projects/ui/src/lib/popup/popup.component.html
Normal file
@ -0,0 +1,21 @@
|
||||
<div class="popup-overlay" [ngClass]="{'shown': loaded, 'hiding': hiding}">
|
||||
<div class="popup-window-wrapper">
|
||||
<div class="popup-window">
|
||||
<div class="popup-head">
|
||||
<div class="head-title">Notification</div>
|
||||
<div class="head-close" (click)="cancel.emit()">
|
||||
<skirda-icon name="sign-out" size="18"></skirda-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="popup-body">
|
||||
<ng-template skirdaPopup></ng-template>
|
||||
</div>
|
||||
|
||||
<div class="popup-actions">
|
||||
<skirda-button appearance="flat" (click)="cancel.emit()">Cancel</skirda-button>
|
||||
<skirda-button (click)="confirm.emit()">Confirm</skirda-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
121
projects/ui/src/lib/popup/popup.component.scss
Normal file
121
projects/ui/src/lib/popup/popup.component.scss
Normal file
@ -0,0 +1,121 @@
|
||||
:host {
|
||||
position: absolute;
|
||||
|
||||
@keyframes show {
|
||||
from {
|
||||
translate: 0px 20px;
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
translate: 0px 0px;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes hide {
|
||||
from {
|
||||
translate: 0px 0px;
|
||||
opacity: 1;
|
||||
}
|
||||
to {
|
||||
translate: 0px 20px;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes showOverlay {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes hideOverlay {
|
||||
from {
|
||||
opacity: 1;
|
||||
}
|
||||
to {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.popup-overlay {
|
||||
display: block;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
background-color: rgba(0,0,0,0.5);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
opacity: 0;
|
||||
|
||||
&.shown {
|
||||
animation: showOverlay 0.2s ease 0s 1 forwards;
|
||||
|
||||
.popup-window-wrapper {
|
||||
animation: show 0.3s ease 0.1s 1 forwards;
|
||||
}
|
||||
}
|
||||
&.hiding {
|
||||
animation: hideOverlay 0.3s ease 0s 1 forwards;
|
||||
|
||||
.popup-window-wrapper {
|
||||
animation: hide 0.3s ease 0s 1 forwards;
|
||||
}
|
||||
}
|
||||
|
||||
.popup-window-wrapper {
|
||||
width: 500px;
|
||||
background: linear-gradient(45deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.25));
|
||||
padding: 1px;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
translate: 0px 20px;
|
||||
opacity: 0;
|
||||
|
||||
.popup-window {
|
||||
border-radius: 7px;
|
||||
background-color: #222;
|
||||
|
||||
.popup-head {
|
||||
padding: 1rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||||
|
||||
.head-title {
|
||||
font-size: 1rem;
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
.head-close {
|
||||
width: 1.125rem;
|
||||
height: 1.125rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.popup-body {
|
||||
padding: 2rem;
|
||||
text-align: center;
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
.popup-actions {
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 1rem;
|
||||
gap: 0.25rem;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
23
projects/ui/src/lib/popup/popup.component.spec.ts
Normal file
23
projects/ui/src/lib/popup/popup.component.spec.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { PopupComponent } from './popup.component';
|
||||
|
||||
describe('PopupComponent', () => {
|
||||
let component: PopupComponent;
|
||||
let fixture: ComponentFixture<PopupComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ PopupComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(PopupComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
55
projects/ui/src/lib/popup/popup.component.ts
Normal file
55
projects/ui/src/lib/popup/popup.component.ts
Normal file
@ -0,0 +1,55 @@
|
||||
import {
|
||||
AfterViewInit,
|
||||
Component,
|
||||
EventEmitter,
|
||||
OnInit,
|
||||
Output,
|
||||
TemplateRef,
|
||||
ViewChild,
|
||||
ViewContainerRef,
|
||||
} from '@angular/core';
|
||||
import { PopupDirective } from './popup.directive';
|
||||
|
||||
@Component({
|
||||
selector: 'skirda-popup',
|
||||
templateUrl: './popup.component.html',
|
||||
styleUrls: ['./popup.component.scss'],
|
||||
})
|
||||
export class PopupComponent implements OnInit, AfterViewInit {
|
||||
loaded: boolean = false;
|
||||
hiding: boolean = false;
|
||||
contentQueue?: TemplateRef<any>;
|
||||
|
||||
@Output() cancel: EventEmitter<void> = new EventEmitter();
|
||||
@Output() confirm: EventEmitter<void> = new EventEmitter();
|
||||
|
||||
@ViewChild(PopupDirective) private popupContent!: PopupDirective;
|
||||
|
||||
constructor(private viewContainerRef: ViewContainerRef) {}
|
||||
|
||||
ngOnInit(): void {}
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
if (this.contentQueue) {
|
||||
this.load(this.contentQueue);
|
||||
this.contentQueue = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
load(template?: TemplateRef<any>) {
|
||||
this.loaded = true;
|
||||
|
||||
if (!template) return;
|
||||
if (!this.popupContent) {
|
||||
this.contentQueue = template;
|
||||
return;
|
||||
}
|
||||
|
||||
this.popupContent.viewContainerRef.createEmbeddedView(template);
|
||||
}
|
||||
|
||||
hide() {
|
||||
this.loaded = false;
|
||||
this.hiding = true;
|
||||
}
|
||||
}
|
8
projects/ui/src/lib/popup/popup.directive.spec.ts
Normal file
8
projects/ui/src/lib/popup/popup.directive.spec.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { PopupDirective } from './popup.directive';
|
||||
|
||||
describe('PopupDirective', () => {
|
||||
it('should create an instance', () => {
|
||||
const directive = new PopupDirective();
|
||||
expect(directive).toBeTruthy();
|
||||
});
|
||||
});
|
8
projects/ui/src/lib/popup/popup.directive.ts
Normal file
8
projects/ui/src/lib/popup/popup.directive.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { Directive, ViewContainerRef } from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: '[skirdaPopup]',
|
||||
})
|
||||
export class PopupDirective {
|
||||
constructor(public viewContainerRef: ViewContainerRef) {}
|
||||
}
|
13
projects/ui/src/lib/popup/popup.module.ts
Normal file
13
projects/ui/src/lib/popup/popup.module.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { PopupComponent } from './popup.component';
|
||||
import { PopupDirective } from './popup.directive';
|
||||
import { ButtonModule } from '../button/button.module';
|
||||
import { IconModule } from '../icon/icon.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [PopupComponent, PopupDirective],
|
||||
imports: [CommonModule, ButtonModule, IconModule],
|
||||
exports: [PopupComponent, PopupDirective],
|
||||
})
|
||||
export class PopupModule {}
|
16
projects/ui/src/lib/popup/popup.service.spec.ts
Normal file
16
projects/ui/src/lib/popup/popup.service.spec.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { PopupService } from './popup.service';
|
||||
|
||||
describe('PopupService', () => {
|
||||
let service: PopupService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(PopupService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
49
projects/ui/src/lib/popup/popup.service.ts
Normal file
49
projects/ui/src/lib/popup/popup.service.ts
Normal file
@ -0,0 +1,49 @@
|
||||
import {
|
||||
ComponentRef,
|
||||
EventEmitter,
|
||||
Injectable,
|
||||
Output,
|
||||
TemplateRef,
|
||||
ViewChild,
|
||||
} from '@angular/core';
|
||||
import { first } from 'rxjs';
|
||||
import { PopupComponent } from './popup.component';
|
||||
import { PopupDirective } from './popup.directive';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class PopupService {
|
||||
instance?: PopupComponent;
|
||||
|
||||
constructor() {}
|
||||
|
||||
open(portal: PopupDirective, template?: TemplateRef<any>) {
|
||||
let container = portal.viewContainerRef;
|
||||
|
||||
container.clear();
|
||||
let componentRef = container.createComponent(PopupComponent);
|
||||
|
||||
this.instance = componentRef.instance;
|
||||
|
||||
this.instance.confirm.pipe(first()).subscribe(() => {
|
||||
this.hide(componentRef);
|
||||
});
|
||||
this.instance.cancel.pipe(first()).subscribe(() => {
|
||||
this.hide(componentRef);
|
||||
});
|
||||
|
||||
this.instance.load(template);
|
||||
return this.instance;
|
||||
}
|
||||
|
||||
hide(componentRef: ComponentRef<PopupComponent>) {
|
||||
if (!this.instance) return;
|
||||
|
||||
this.instance.hide();
|
||||
|
||||
setTimeout(() => {
|
||||
componentRef.destroy();
|
||||
}, 300);
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
:host {
|
||||
|
||||
&.filled .sk-tag {
|
||||
background-color: var(--sk-accent);
|
||||
background-color: var(--sk-primary);
|
||||
}
|
||||
|
||||
.sk-tag {
|
||||
|
@ -10,6 +10,7 @@ import { ButtonModule } from './button/button.module';
|
||||
import { TagModule } from './tag/tag.module';
|
||||
import { PipesModule } from './pipes/pipes.module';
|
||||
import { GameModule } from './game/game.module';
|
||||
import { PopupModule } from '../public-api';
|
||||
|
||||
@NgModule({
|
||||
declarations: [],
|
||||
@ -25,6 +26,7 @@ import { GameModule } from './game/game.module';
|
||||
TagModule,
|
||||
PipesModule,
|
||||
GameModule,
|
||||
PopupModule,
|
||||
],
|
||||
exports: [
|
||||
IconModule,
|
||||
@ -34,9 +36,11 @@ import { GameModule } from './game/game.module';
|
||||
TypographyModule,
|
||||
SectionLabelModule,
|
||||
ImageIconModule,
|
||||
ButtonModule,
|
||||
TagModule,
|
||||
PipesModule,
|
||||
GameModule
|
||||
GameModule,
|
||||
PopupModule,
|
||||
],
|
||||
})
|
||||
export class UiModule {}
|
||||
|
@ -13,3 +13,4 @@ export * from './lib/image-icon/image-icon.module';
|
||||
export * from './lib/tag/tag.module';
|
||||
export * from './lib/pipes/pipes.module';
|
||||
export * from './lib/game/game.module';
|
||||
export * from './lib/popup/popup.module';
|
||||
|
@ -4,7 +4,7 @@
|
||||
<skirda-icon name="search" size="16" role="left"></skirda-icon>
|
||||
</skirda-input>
|
||||
<button>
|
||||
<skirda-icon name="menu-panel" color="var(--sk-accent)"></skirda-icon>
|
||||
<skirda-icon name="menu-panel" color="var(--sk-primary)"></skirda-icon>
|
||||
</button>
|
||||
</div>
|
||||
<div class="sk-sections">
|
||||
|
@ -18,6 +18,7 @@
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background-size: cover;
|
||||
position: inherit;
|
||||
}
|
||||
|
||||
.content {
|
||||
|
@ -16,6 +16,7 @@ import { ButtonModule } from 'projects/ui/src/lib/button/button.module';
|
||||
import { TypographyModule } from 'projects/ui/src/lib/typography/typography.module';
|
||||
import { IconModule } from 'projects/ui/src/lib/icon/icon.module';
|
||||
import { DownloadsPageComponent } from './sections/downloads-page/downloads-page.component';
|
||||
import { PopupModule } from 'projects/ui/src/public-api';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
@ -39,6 +40,7 @@ import { DownloadsPageComponent } from './sections/downloads-page/downloads-page
|
||||
TypographyModule,
|
||||
ButtonModule,
|
||||
IconModule,
|
||||
PopupModule,
|
||||
],
|
||||
exports: [
|
||||
MainRootComponent,
|
||||
|
@ -1,3 +1,9 @@
|
||||
<ng-template [skirdaPopup]></ng-template>
|
||||
<ng-template #popupContent>
|
||||
<h1 style="font-size: 72px">😳🕶🤏</h1>
|
||||
<p>Church-key listicle whatever hoodie hexagon pour-over ascot paleo tacos, organic aesthetic tbh meggings raclette.</p>
|
||||
</ng-template>
|
||||
|
||||
<div class="section">
|
||||
<div class="section-head">
|
||||
<div class="head-title">
|
||||
@ -6,6 +12,10 @@
|
||||
<div class="head-subtitle">Game page will be here</div>
|
||||
</div>
|
||||
<div class="section-content">
|
||||
<!-- <skirda-button (click)="openPopup(popupContent)">
|
||||
<skirda-icon name="play" size="16"></skirda-icon>
|
||||
Run game
|
||||
</skirda-button> -->
|
||||
<skirda-button>
|
||||
<skirda-icon name="play" size="16"></skirda-icon>
|
||||
Run game
|
||||
|
@ -1,15 +1,29 @@
|
||||
import { TemplateRef, ViewChild } from '@angular/core';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { PopupDirective } from 'projects/ui/src/lib/popup/popup.directive';
|
||||
import { PopupService } from 'projects/ui/src/lib/popup/popup.service';
|
||||
import { first } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'app-game-page',
|
||||
templateUrl: './game-page.component.html',
|
||||
styleUrls: ['./game-page.component.scss']
|
||||
styleUrls: ['./game-page.component.scss'],
|
||||
})
|
||||
export class GamePageComponent implements OnInit {
|
||||
@ViewChild(PopupDirective, { static: true }) popupPortal!: PopupDirective;
|
||||
|
||||
constructor() { }
|
||||
constructor(private popup: PopupService) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
ngOnInit(): void {}
|
||||
|
||||
openPopup(template: TemplateRef<any>) {
|
||||
let dialog = this.popup.open(this.popupPortal, template);
|
||||
|
||||
dialog.cancel.pipe(first()).subscribe(() => {
|
||||
console.log('cancel clicked');
|
||||
});
|
||||
dialog.confirm.pipe(first()).subscribe(() => {
|
||||
console.log('confirm clicked');
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -20,3 +20,12 @@
|
||||
</form>
|
||||
|
||||
<hr>
|
||||
|
||||
<h3>Dialog</h3>
|
||||
|
||||
<ng-template [skirdaPopup]></ng-template>
|
||||
<ng-template #popupContent>
|
||||
<h3>Warning</h3>
|
||||
<p>Church-key listicle whatever hoodie hexagon pour-over ascot paleo tacos, organic aesthetic tbh meggings raclette.</p>
|
||||
</ng-template>
|
||||
<skirda-button (click)="openPopup(popupContent)">Call popup</skirda-button>
|
||||
|
@ -10,6 +10,11 @@
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
hr {
|
||||
width: 100%;
|
||||
border-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
@ -1,5 +1,8 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
|
||||
import { FormControl, FormGroup } from '@angular/forms';
|
||||
import { PopupDirective } from 'projects/ui/src/lib/popup/popup.directive';
|
||||
import { PopupService } from 'projects/ui/src/lib/popup/popup.service';
|
||||
import { first } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'app-sandbox',
|
||||
@ -13,12 +16,24 @@ export class SandboxComponent implements OnInit {
|
||||
name: new FormControl<string>(''),
|
||||
age: new FormControl<number>(0),
|
||||
});
|
||||
@ViewChild(PopupDirective, { static: true }) popupPortal!: PopupDirective;
|
||||
|
||||
constructor() {}
|
||||
constructor(private popup: PopupService) {}
|
||||
|
||||
ngOnInit(): void {}
|
||||
|
||||
print() {
|
||||
console.log(this.form);
|
||||
}
|
||||
|
||||
openPopup(template: TemplateRef<any>) {
|
||||
let dialog = this.popup.open(this.popupPortal, template);
|
||||
|
||||
dialog.cancel.pipe(first()).subscribe(() => {
|
||||
console.log('cancel clicked');
|
||||
});
|
||||
dialog.confirm.pipe(first()).subscribe(() => {
|
||||
console.log('confirm clicked');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -22,8 +22,9 @@ button, input, textarea {
|
||||
// colors
|
||||
--sk-input: rgba(18,18,18,0.5);
|
||||
--sk-input-focus: rgba(18,18,18,0.9);
|
||||
--sk-accent: #67A69E;
|
||||
--sk-accent-dark: #2A3B39;
|
||||
--sk-primary: #24927a;
|
||||
--sk-secondary: #1b557d;
|
||||
--sk-primary-dark: #2A3B39;
|
||||
|
||||
// border-radius
|
||||
--sk-br-s: 0.25rem;
|
||||
|
Loading…
Reference in New Issue
Block a user