diff --git a/src/app/shared/ui/card/card.component.html b/src/app/shared/ui/card/card.component.html new file mode 100644 index 0000000..40b3726 --- /dev/null +++ b/src/app/shared/ui/card/card.component.html @@ -0,0 +1 @@ + diff --git a/src/app/shared/ui/card/card.component.scss b/src/app/shared/ui/card/card.component.scss new file mode 100644 index 0000000..0f94cdd --- /dev/null +++ b/src/app/shared/ui/card/card.component.scss @@ -0,0 +1,47 @@ +:host { + display: block; + background: var(--bg-primary, #fff); + border-radius: var(--radius-lg, 10px); + box-shadow: var(--shadow-sm, 0 1px 2px rgba(0, 0, 0, 0.06)); + transition: box-shadow var(--transition-fast, 120ms ease), + border-color var(--transition-fast, 120ms ease); +} + +:host.app-card--bordered { + border: 1px solid var(--border-color, #e4e4e7); +} + +:host.app-card--interactive { + cursor: pointer; + + &:hover { + box-shadow: var(--shadow-md, 0 4px 12px rgba(0, 0, 0, 0.08)); + } + + &:focus-visible { + outline: 2px solid var(--primary-color, #2f6e5d); + outline-offset: 2px; + } +} + +:host.app-card--pad-none { + padding: 0; +} + +:host.app-card--pad-sm { + padding: var(--space-sm, 0.5rem); +} + +:host.app-card--pad-md { + padding: var(--space-md, 1rem); +} + +:host.app-card--pad-lg { + padding: var(--space-lg, 1.5rem); +} + +@media (prefers-reduced-motion: reduce) { + :host { + transition: none; + } +} diff --git a/src/app/shared/ui/card/card.component.ts b/src/app/shared/ui/card/card.component.ts new file mode 100644 index 0000000..6bb63f1 --- /dev/null +++ b/src/app/shared/ui/card/card.component.ts @@ -0,0 +1,24 @@ +import { ChangeDetectionStrategy, Component, input } from '@angular/core'; + +export type CardPadding = 'none' | 'sm' | 'md' | 'lg'; + +@Component({ + selector: 'app-card', + standalone: true, + templateUrl: './card.component.html', + styleUrl: './card.component.scss', + changeDetection: ChangeDetectionStrategy.OnPush, + host: { + '[class.app-card--bordered]': 'bordered()', + '[class.app-card--interactive]': 'interactive()', + '[class.app-card--pad-none]': "padding() === 'none'", + '[class.app-card--pad-sm]': "padding() === 'sm'", + '[class.app-card--pad-md]': "padding() === 'md'", + '[class.app-card--pad-lg]': "padding() === 'lg'" + } +}) +export class CardComponent { + readonly padding = input('md'); + readonly bordered = input(true); + readonly interactive = input(false); +}