Adjust Settings Popup Position
This commit is contained in:
1 parent
010771b22a
commit
898df6a318
9 files changed
+64
-19
No files matched your search
@@ -1,7 +1,7 @@
|
|||||||
# AefComponentTest Docker 이미지 빌드 및 추출 스크립트
|
# AefComponentTest Docker 이미지 빌드 및 추출 스크립트
|
||||||
|
|
||||||
$IMAGE_NAME = "aef-component-test"
|
$IMAGE_NAME = "aef-component-test"
|
||||||
$TAG = "0.0.2"
|
$TAG = "0.0.3"
|
||||||
$OUTPUT_FILE = "aef-component-test.tar"
|
$OUTPUT_FILE = "aef-component-test.tar"
|
||||||
|
|
||||||
Write-Host "--- Docker 이미지 빌드 시작: ${IMAGE_NAME}:${TAG} ---" -ForegroundColor Cyan
|
Write-Host "--- Docker 이미지 빌드 시작: ${IMAGE_NAME}:${TAG} ---" -ForegroundColor Cyan
|
||||||
|
|||||||
+2
-2
@@ -2,7 +2,7 @@
|
|||||||
<router-outlet />
|
<router-outlet />
|
||||||
|
|
||||||
<div id="global-popup-root" class="popup-outlet">
|
<div id="global-popup-root" class="popup-outlet">
|
||||||
@for (popup of popupService.activePopups(); track popup) {
|
@for (popup of popupService.activePopups(); track popup.component) {
|
||||||
<ng-container *ngComponentOutlet="popup" />
|
<ng-container *ngComponentOutlet="popup.component; inputs: popup.inputs" />
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
@@ -1,5 +1,11 @@
|
|||||||
<div class="popup-backdrop" (click)="onClose()">
|
<div class="popup-backdrop" [class.center]="isCenter" (click)="onClose()">
|
||||||
<div class="popup-container" (click)="$event.stopPropagation()">
|
<div class="popup-container"
|
||||||
|
[class.custom-pos]="!isCenter"
|
||||||
|
[style.top]="customStyle.top"
|
||||||
|
[style.left]="customStyle.left"
|
||||||
|
[style.right]="customStyle.right"
|
||||||
|
[style.bottom]="customStyle.bottom"
|
||||||
|
(click)="$event.stopPropagation()">
|
||||||
<header class="popup-header">
|
<header class="popup-header">
|
||||||
<div class="header-left">
|
<div class="header-left">
|
||||||
<ng-content select="[header-left]"></ng-content>
|
<ng-content select="[header-left]"></ng-content>
|
||||||
|
|||||||
@@ -6,10 +6,13 @@
|
|||||||
position: fixed;
|
position: fixed;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
display: flex;
|
z-index: 100;
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
&.center {
|
||||||
z-index: 100; /* .popup-outlet 내부에서의 상대적 순서 */
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.popup-container {
|
.popup-container {
|
||||||
@@ -26,6 +29,10 @@
|
|||||||
|
|
||||||
border: oklch(0 0 0 / 20%) 2px solid;
|
border: oklch(0 0 0 / 20%) 2px solid;
|
||||||
gap: 15px;
|
gap: 15px;
|
||||||
|
|
||||||
|
&.custom-pos {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes popup-enter {
|
@keyframes popup-enter {
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
import { Component, output } from '@angular/core';
|
import { Component, input, output } from '@angular/core';
|
||||||
|
|
||||||
|
export type PopupPosition = {
|
||||||
|
top?: string;
|
||||||
|
left?: string;
|
||||||
|
right?: string;
|
||||||
|
bottom?: string;
|
||||||
|
};
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-popup',
|
selector: 'app-popup',
|
||||||
@@ -7,6 +14,12 @@ import { Component, output } from '@angular/core';
|
|||||||
styleUrl: './popup.scss',
|
styleUrl: './popup.scss',
|
||||||
})
|
})
|
||||||
export class PopupComponent {
|
export class PopupComponent {
|
||||||
|
/**
|
||||||
|
* 팝업의 위치 (기본값은 'center')
|
||||||
|
* 'center' 또는 { top, left, right, bottom } 객체를 받습니다.
|
||||||
|
*/
|
||||||
|
position = input<PopupPosition | 'center'>('center');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 팝업 닫기 요청 (배경 클릭 또는 닫기 버튼)
|
* 팝업 닫기 요청 (배경 클릭 또는 닫기 버튼)
|
||||||
*/
|
*/
|
||||||
@@ -15,4 +28,13 @@ export class PopupComponent {
|
|||||||
onClose() {
|
onClose() {
|
||||||
this.closeRequest.emit();
|
this.closeRequest.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get isCenter() {
|
||||||
|
return this.position() === 'center';
|
||||||
|
}
|
||||||
|
|
||||||
|
get customStyle() {
|
||||||
|
const pos = this.position();
|
||||||
|
return pos === 'center' ? {} : pos;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -15,6 +15,6 @@ export class HeaderMenu {
|
|||||||
|
|
||||||
onSettingsClick() {
|
onSettingsClick() {
|
||||||
console.log('HeaderMenu: Settings clicked');
|
console.log('HeaderMenu: Settings clicked');
|
||||||
this.popupService.open(SettingsPopup);
|
this.popupService.open(SettingsPopup, { position: { top: '82px', right: '18px' } });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<app-popup (closeRequest)="close()">
|
<app-popup (closeRequest)="close()" [position]="position()">
|
||||||
<div header-left class="profile-section">
|
<div header-left class="profile-section">
|
||||||
<img ngSrc="/guest_profile.png" alt="profile" class="avatar" width="24" height="24">
|
<img ngSrc="/guest_profile.png" alt="profile" class="avatar" width="24" height="24">
|
||||||
<span>{{ userName }}</span>
|
<span>{{ userName }}</span>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Component, inject } from '@angular/core';
|
import { Component, inject, input } from '@angular/core';
|
||||||
import { PopupComponent } from '../../components/popup/popup';
|
import { PopupComponent, PopupPosition } from '../../components/popup/popup';
|
||||||
import { Dropdown, DropdownOption } from '../../components/dropdown/dropdown';
|
import { Dropdown, DropdownOption } from '../../components/dropdown/dropdown';
|
||||||
import { Switch } from '../../components/switch/switch';
|
import { Switch } from '../../components/switch/switch';
|
||||||
import { NgOptimizedImage } from '@angular/common';
|
import { NgOptimizedImage } from '@angular/common';
|
||||||
@@ -15,6 +15,11 @@ import { PopupService } from '../../services/popup.service';
|
|||||||
export class SettingsPopup {
|
export class SettingsPopup {
|
||||||
private popupService = inject(PopupService);
|
private popupService = inject(PopupService);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 팝업의 위치 (기본값은 'center')
|
||||||
|
*/
|
||||||
|
position = input<PopupPosition | 'center'>('center');
|
||||||
|
|
||||||
languages: DropdownOption[] = [
|
languages: DropdownOption[] = [
|
||||||
{ label: 'English', value: 'EN' },
|
{ label: 'English', value: 'EN' },
|
||||||
{ label: '한국어', value: 'KR' },
|
{ label: '한국어', value: 'KR' },
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
import { Injectable, signal, Type } from '@angular/core';
|
import { Injectable, signal, Type } from '@angular/core';
|
||||||
|
|
||||||
|
export interface PopupInstance {
|
||||||
|
component: Type<any>;
|
||||||
|
inputs?: Record<string, any>;
|
||||||
|
}
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
})
|
})
|
||||||
@@ -7,15 +12,15 @@ export class PopupService {
|
|||||||
/**
|
/**
|
||||||
* 현재 활성화된 팝업 컴포넌트들의 리스트 (Signal)
|
* 현재 활성화된 팝업 컴포넌트들의 리스트 (Signal)
|
||||||
*/
|
*/
|
||||||
activePopups = signal<Type<any>[]>([]);
|
activePopups = signal<PopupInstance[]>([]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 팝업을 엽니다. 이미 열려있는 동일한 컴포넌트가 있다면 중복해서 열지 않습니다.
|
* 팝업을 엽니다. 이미 열려있는 동일한 컴포넌트가 있다면 중복해서 열지 않습니다.
|
||||||
*/
|
*/
|
||||||
open<T>(component: Type<T>) {
|
open<T>(component: Type<T>, inputs?: Record<string, any>) {
|
||||||
this.activePopups.update((popups) => {
|
this.activePopups.update((popups) => {
|
||||||
if (popups.includes(component)) return popups;
|
if (popups.some((p) => p.component === component)) return popups;
|
||||||
return [...popups, component];
|
return [...popups, { component, inputs }];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,7 +28,7 @@ export class PopupService {
|
|||||||
* 특정 컴포넌트를 닫습니다.
|
* 특정 컴포넌트를 닫습니다.
|
||||||
*/
|
*/
|
||||||
close(component: Type<any>) {
|
close(component: Type<any>) {
|
||||||
this.activePopups.update((popups) => popups.filter((p) => p !== component));
|
this.activePopups.update((popups) => popups.filter((p) => p.component !== component));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in new issue
Block a user