feat(design-system): add reusable EmptyState primitive

Standalone, OnPush. title required input (caller supplies translated text),
optional description, icon/actions content-projection slots. Colors via
existing tenant CSS vars with fallbacks.
This commit is contained in:
sdarbinyan
2026-07-15 03:40:56 +04:00
parent 439d3d3c95
commit efdb03f23e
3 changed files with 69 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
<div class="app-empty-state">
<div class="app-empty-state__icon">
<ng-content select="[slot=icon]" />
</div>
<h3 class="app-empty-state__title">{{ title() }}</h3>
@if (description()) {
<p class="app-empty-state__description">{{ description() }}</p>
}
<div class="app-empty-state__actions">
<ng-content select="[slot=actions]" />
</div>
</div>

View File

@@ -0,0 +1,44 @@
.app-empty-state {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
gap: var(--space-sm, 0.5rem);
padding: var(--space-xl, 2rem) var(--space-lg, 1.5rem);
color: var(--text-secondary, #6b7280);
}
.app-empty-state__icon {
display: flex;
align-items: center;
justify-content: center;
color: var(--text-secondary, #6b7280);
&:empty {
display: none;
}
}
.app-empty-state__title {
margin: 0;
font-size: 1.0625rem;
font-weight: 600;
color: var(--text-primary, #1f322d);
}
.app-empty-state__description {
margin: 0;
max-width: 32rem;
font-size: 0.875rem;
}
.app-empty-state__actions {
display: flex;
align-items: center;
gap: var(--space-sm, 0.5rem);
margin-top: var(--space-xs, 0.25rem);
&:empty {
display: none;
}
}

View File

@@ -0,0 +1,13 @@
import { ChangeDetectionStrategy, Component, input } from '@angular/core';
@Component({
selector: 'app-empty-state',
standalone: true,
templateUrl: './empty-state.component.html',
styleUrl: './empty-state.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class EmptyStateComponent {
readonly title = input.required<string>();
readonly description = input<string | null>(null);
}