From efdb03f23e6fa5a37f208b0e1a4a08bed14b5566 Mon Sep 17 00:00:00 2001 From: sdarbinyan Date: Wed, 15 Jul 2026 03:40:56 +0400 Subject: [PATCH] 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. --- .../ui/empty-state/empty-state.component.html | 12 +++++ .../ui/empty-state/empty-state.component.scss | 44 +++++++++++++++++++ .../ui/empty-state/empty-state.component.ts | 13 ++++++ 3 files changed, 69 insertions(+) create mode 100644 src/app/shared/ui/empty-state/empty-state.component.html create mode 100644 src/app/shared/ui/empty-state/empty-state.component.scss create mode 100644 src/app/shared/ui/empty-state/empty-state.component.ts diff --git a/src/app/shared/ui/empty-state/empty-state.component.html b/src/app/shared/ui/empty-state/empty-state.component.html new file mode 100644 index 0000000..e8ed0c4 --- /dev/null +++ b/src/app/shared/ui/empty-state/empty-state.component.html @@ -0,0 +1,12 @@ +
+
+ +
+

{{ title() }}

+ @if (description()) { +

{{ description() }}

+ } +
+ +
+
diff --git a/src/app/shared/ui/empty-state/empty-state.component.scss b/src/app/shared/ui/empty-state/empty-state.component.scss new file mode 100644 index 0000000..d5d7b5b --- /dev/null +++ b/src/app/shared/ui/empty-state/empty-state.component.scss @@ -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; + } +} diff --git a/src/app/shared/ui/empty-state/empty-state.component.ts b/src/app/shared/ui/empty-state/empty-state.component.ts new file mode 100644 index 0000000..dc7eb02 --- /dev/null +++ b/src/app/shared/ui/empty-state/empty-state.component.ts @@ -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(); + readonly description = input(null); +}