@memberjunction/ng-ui-components 6.1.0-edge.2 → 6.1.0-edge.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"card-grid.component.js","sourceRoot":"","sources":["../../../src/lib/card-grid/card-grid.component.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n Directive,\n Input,\n Output,\n EventEmitter,\n TemplateRef,\n ContentChild,\n HostListener,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n inject,\n OnInit,\n OnDestroy,\n OnChanges,\n SimpleChanges\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { BehaviorSubject, Subscription } from 'rxjs';\n\nlet nextCardId = 0;\n\n/**\n * Directive to provide a custom template for the Card Title.\n */\n@Directive({\n selector: '[mjCardTitle]',\n standalone: true,\n})\nexport class MJCardTitleDirective {\n constructor(public templateRef: TemplateRef<unknown>) {}\n}\n\n/**\n * Directive to provide custom action controls in the Card Header.\n */\n@Directive({\n selector: '[mjCardActions]',\n standalone: true,\n})\nexport class MJCardActionsDirective {\n constructor(public templateRef: TemplateRef<unknown>) {}\n}\n\n/**\n * Directive to provide custom tools/badges in the Card Header.\n */\n@Directive({\n selector: '[mjCardTools]',\n standalone: true,\n})\nexport class MJCardToolsDirective {\n constructor(public templateRef: TemplateRef<unknown>) {}\n}\n\n/**\n * Directive to provide a custom template for the Card Footer.\n */\n@Directive({\n selector: '[mjCardFooter]',\n standalone: true,\n})\nexport class MJCardFooterDirective {\n constructor(public templateRef: TemplateRef<unknown>) {}\n}\n\nconst CARD_GRID_CSS = `\n:host {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n min-width: 0;\n box-sizing: border-box;\n}\n\n.mj-card-grid {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n align-items: stretch;\n gap: var(--mj-card-grid-gap, var(--mj-space-4, 16px));\n width: 100%;\n position: relative;\n box-sizing: border-box;\n transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.mj-card-grid--has-maximized {\n grid-template-columns: 1fr !important;\n}\n\n@media (max-width: 640px) {\n .mj-card-grid {\n grid-template-columns: 1fr !important;\n }\n}\n\nmj-card {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-width: 0;\n width: 100%;\n box-sizing: border-box;\n}\n\n.mj-card {\n display: flex;\n flex-direction: column;\n flex: 1 1 100%;\n height: 100%;\n min-height: 290px;\n background: var(--mj-bg-surface-card, var(--mj-bg-surface, #141f33));\n border: 1px solid var(--mj-border-default, #2a3852);\n border-radius: var(--mj-radius-xl, 16px);\n box-shadow: var(--mj-shadow-sm, 0 1px 3px rgba(0, 0, 0, 0.08));\n padding: var(--mj-space-4, 16px) var(--mj-space-5, 20px);\n box-sizing: border-box;\n transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;\n position: relative;\n min-width: 0;\n}\n\n.mj-card:hover {\n border-color: color-mix(in srgb, var(--mj-brand-primary, #38bdf8) 40%, var(--mj-border-default, #2a3852));\n}\n\n.mj-card--maximized {\n grid-column: 1 / -1;\n width: 100%;\n min-height: 480px;\n box-shadow: var(--mj-shadow-lg, 0 10px 25px rgba(0, 0, 0, 0.25));\n border-color: var(--mj-brand-primary, #38bdf8);\n z-index: 10;\n}\n\n.mj-card--hidden {\n display: none !important;\n}\n\n.mj-card__header {\n display: flex;\n flex-direction: row;\n align-items: flex-start;\n justify-content: space-between;\n gap: var(--mj-space-3, 12px);\n margin-bottom: var(--mj-space-3, 12px);\n min-height: 28px;\n width: 100%;\n}\n\n.mj-card__title-group {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n flex: 1 1 auto;\n}\n\n.mj-card__title-row {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: var(--mj-space-2, 8px);\n min-width: 0;\n}\n\n.mj-card__icon {\n color: var(--mj-brand-primary, #38bdf8);\n font-size: 14px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.mj-card__title {\n font-size: 14px;\n font-weight: 700;\n color: var(--mj-text-primary, #ffffff);\n letter-spacing: -0.01em;\n margin: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.mj-card__subtitle {\n font-size: 11.5px;\n font-weight: 500;\n color: var(--mj-text-muted, #94a3b8);\n margin: 0;\n padding-left: 22px;\n}\n\n.mj-card__actions {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: var(--mj-space-2, 8px);\n flex-shrink: 0;\n margin-left: auto;\n}\n\n.mj-card__toggle-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border-radius: var(--mj-radius-sm, 6px);\n background: transparent;\n border: 1px solid transparent;\n color: var(--mj-text-muted, #94a3b8);\n cursor: pointer;\n padding: 0;\n font-size: 12px;\n transition: all 0.15s ease;\n}\n\n.mj-card__toggle-btn:hover {\n color: var(--mj-text-primary, #ffffff);\n background: var(--mj-bg-surface-sunken, rgba(255, 255, 255, 0.06));\n border-color: var(--mj-border-default, #2a3852);\n}\n\n.mj-card__toggle-btn:focus-visible {\n outline: 2px solid var(--mj-brand-primary, #38bdf8);\n outline-offset: 1px;\n}\n\n.mj-card__body {\n flex: 1 1 auto;\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n min-width: 0;\n}\n\n.mj-card__footer {\n margin-top: auto;\n padding-top: var(--mj-space-3, 12px);\n border-top: 1px solid var(--mj-border-default, #2a3852);\n}\n`;\n\n/**\n * Responsive Card Grid container that manages responsive layout and card maximization state.\n */\n@Component({\n selector: 'mj-card-grid',\n standalone: true,\n imports: [CommonModule],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CARD_GRID_CSS],\n template: `\n <div class=\"mj-card-grid\"\n [class.mj-card-grid--has-maximized]=\"!!MaximizedCardId\"\n [style.--mj-card-grid-columns]=\"Columns\"\n [style.--mj-card-grid-gap]=\"Gap\">\n <ng-content></ng-content>\n </div>\n `,\n})\nexport class MJCardGridComponent implements OnChanges {\n private cdr = inject(ChangeDetectorRef);\n\n /** Stream of the currently maximized card ID across all children. */\n public readonly maximizedCard$ = new BehaviorSubject<string | null>(null);\n\n /** Number of columns for standard layout (defaults to 2). */\n @Input() Columns: number | string = 2;\n\n /** CSS gap between cards (defaults to var(--mj-space-4)). */\n @Input() Gap = 'var(--mj-space-4, 16px)';\n\n /** Currently maximized card ID. When set, only this card is shown full-width. */\n @Input() MaximizedCardId: string | null = null;\n\n /** Emits when the maximized card ID changes (two-way binding support). */\n @Output() MaximizedCardIdChange = new EventEmitter<string | null>();\n\n /** Emits the card ID when a card is maximized. */\n @Output() CardMaximized = new EventEmitter<string>();\n\n /** Emits when the maximized card is restored back to the grid view. */\n @Output() CardRestored = new EventEmitter<void>();\n\n public ngOnChanges(changes: SimpleChanges): void {\n if (changes['MaximizedCardId'] && !changes['MaximizedCardId'].firstChange) {\n this.maximizedCard$.next(this.MaximizedCardId);\n }\n }\n\n /** Pressing Escape restores the grid view if a card is maximized. */\n @HostListener('window:keydown.escape')\n public OnEscape(): void {\n if (this.MaximizedCardId) {\n this.Restore();\n }\n }\n\n public MaximizeCard(cardId: string): void {\n this.MaximizedCardId = cardId;\n this.maximizedCard$.next(cardId);\n this.MaximizedCardIdChange.emit(cardId);\n this.CardMaximized.emit(cardId);\n this.cdr.markForCheck();\n }\n\n public Restore(): void {\n if (!this.MaximizedCardId) return;\n this.MaximizedCardId = null;\n this.maximizedCard$.next(null);\n this.MaximizedCardIdChange.emit(null);\n this.CardRestored.emit();\n this.cdr.markForCheck();\n }\n\n public IsCardMaximized(cardId: string): boolean {\n return this.MaximizedCardId === cardId;\n }\n\n public IsCardHidden(cardId: string): boolean {\n return !!this.MaximizedCardId && this.MaximizedCardId !== cardId;\n }\n}\n\n/**\n * Modular card component with header title, icon, actions, and maximize/restore capability.\n */\n@Component({\n selector: 'mj-card',\n standalone: true,\n imports: [CommonModule],\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [CARD_GRID_CSS],\n template: `\n <div class=\"mj-card\"\n [class.mj-card--maximized]=\"IsMaximized\"\n [class.mj-card--hidden]=\"IsHidden\"\n role=\"region\"\n [attr.aria-label]=\"Title || 'Card'\">\n \n <!-- Card Header -->\n @if (ShowHeader) {\n <div class=\"mj-card__header\">\n <div class=\"mj-card__title-group\">\n <div class=\"mj-card__title-row\">\n @if (Icon) {\n <span class=\"mj-card__icon\" aria-hidden=\"true\">\n <i [class]=\"Icon\"></i>\n </span>\n }\n @if (TitleTemplate) {\n <ng-container [ngTemplateOutlet]=\"TitleTemplate.templateRef\"></ng-container>\n } @else if (Title) {\n <h3 class=\"mj-card__title\">{{ Title }}</h3>\n }\n </div>\n @if (Subtitle) {\n <span class=\"mj-card__subtitle\">{{ Subtitle }}</span>\n }\n </div>\n\n <div class=\"mj-card__actions\">\n @if (ToolsTemplate) {\n <ng-container [ngTemplateOutlet]=\"ToolsTemplate.templateRef\"></ng-container>\n }\n @if (ActionsTemplate) {\n <ng-container [ngTemplateOutlet]=\"ActionsTemplate.templateRef\"></ng-container>\n }\n @if (AllowMaximize) {\n <button type=\"button\"\n class=\"mj-card__toggle-btn\"\n [title]=\"IsMaximized ? RestoreTooltip : MaximizeTooltip\"\n [attr.aria-label]=\"IsMaximized ? RestoreTooltip : MaximizeTooltip\"\n (click)=\"ToggleMaximize($event)\">\n @if (IsMaximized) {\n <i class=\"fa-solid fa-compress\" aria-hidden=\"true\"></i>\n } @else {\n <i class=\"fa-solid fa-expand\" aria-hidden=\"true\"></i>\n }\n </button>\n }\n </div>\n </div>\n }\n\n <!-- Card Body -->\n <div class=\"mj-card__body\">\n <ng-content></ng-content>\n </div>\n\n <!-- Card Footer -->\n @if (FooterTemplate) {\n <div class=\"mj-card__footer\">\n <ng-container [ngTemplateOutlet]=\"FooterTemplate.templateRef\"></ng-container>\n </div>\n }\n </div>\n `,\n})\nexport class MJCardComponent implements OnInit, OnDestroy {\n private grid = inject(MJCardGridComponent, { optional: true });\n private cdr = inject(ChangeDetectorRef);\n private sub?: Subscription;\n\n @Input() CardId = `mj-card-${++nextCardId}`;\n @Input() Title?: string;\n @Input() Subtitle?: string;\n @Input() Icon?: string;\n @Input() AllowMaximize = true;\n @Input() MaximizeTooltip = 'Expand card';\n @Input() RestoreTooltip = 'Restore view';\n @Input() ShowHeader = true;\n\n @Output() Maximize = new EventEmitter<void>();\n @Output() Restore = new EventEmitter<void>();\n\n @ContentChild(MJCardTitleDirective) TitleTemplate?: MJCardTitleDirective;\n @ContentChild(MJCardActionsDirective) ActionsTemplate?: MJCardActionsDirective;\n @ContentChild(MJCardToolsDirective) ToolsTemplate?: MJCardToolsDirective;\n @ContentChild(MJCardFooterDirective) FooterTemplate?: MJCardFooterDirective;\n\n public get IsMaximized(): boolean {\n if (this.grid) {\n return this.grid.IsCardMaximized(this.CardId);\n }\n return false;\n }\n\n public get IsHidden(): boolean {\n if (this.grid) {\n return this.grid.IsCardHidden(this.CardId);\n }\n return false;\n }\n\n public ngOnInit(): void {\n if (!this.CardId) {\n this.CardId = `mj-card-${++nextCardId}`;\n }\n if (this.grid) {\n this.sub = this.grid.maximizedCard$.subscribe(() => {\n this.cdr.markForCheck();\n });\n }\n }\n\n public ngOnDestroy(): void {\n this.sub?.unsubscribe();\n }\n\n public ToggleMaximize(event?: MouseEvent): void {\n if (event) {\n event.stopPropagation();\n }\n if (this.IsMaximized) {\n this.grid?.Restore();\n this.Restore.emit();\n } else {\n this.grid?.MaximizeCard(this.CardId);\n this.Maximize.emit();\n }\n this.cdr.markForCheck();\n }\n}\n"]}
@@ -0,0 +1,177 @@
1
+ // Card Grid & Expandable Card styling using MJ Design Tokens
2
+
3
+ :host {
4
+ display: flex;
5
+ flex-direction: column;
6
+ width: 100%;
7
+ height: 100%;
8
+ min-width: 0;
9
+ }
10
+
11
+ .mj-card-grid {
12
+ display: grid;
13
+ grid-template-columns: repeat(2, minmax(0, 1fr));
14
+ align-items: stretch;
15
+ gap: var(--mj-card-grid-gap, var(--mj-space-4, 16px));
16
+ width: 100%;
17
+ position: relative;
18
+ box-sizing: border-box;
19
+ transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
20
+
21
+ &.mj-card-grid--has-maximized {
22
+ grid-template-columns: 1fr !important;
23
+ }
24
+
25
+ @media (max-width: 640px) {
26
+ grid-template-columns: 1fr !important;
27
+ }
28
+ }
29
+
30
+ // Host element for mj-card
31
+ mj-card {
32
+ display: flex;
33
+ flex-direction: column;
34
+ height: 100%;
35
+ min-width: 0;
36
+ width: 100%;
37
+ box-sizing: border-box;
38
+ }
39
+
40
+ .mj-card {
41
+ display: flex;
42
+ flex-direction: column;
43
+ flex: 1 1 100%;
44
+ height: 100%;
45
+ min-height: 290px;
46
+ background: var(--mj-bg-surface-card, var(--mj-bg-surface, #141f33));
47
+ border: 1px solid var(--mj-border-default, #2a3852);
48
+ border-radius: var(--mj-radius-xl, 16px);
49
+ box-shadow: var(--mj-shadow-sm, 0 1px 3px rgba(0, 0, 0, 0.08));
50
+ padding: var(--mj-space-4, 16px) var(--mj-space-5, 20px);
51
+ box-sizing: border-box;
52
+ transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
53
+ position: relative;
54
+ min-width: 0;
55
+
56
+ &:hover {
57
+ border-color: color-mix(in srgb, var(--mj-brand-primary, #38bdf8) 40%, var(--mj-border-default, #2a3852));
58
+ }
59
+
60
+ &.mj-card--maximized {
61
+ grid-column: 1 / -1;
62
+ width: 100%;
63
+ min-height: 480px;
64
+ box-shadow: var(--mj-shadow-lg, 0 10px 25px rgba(0, 0, 0, 0.25));
65
+ border-color: var(--mj-brand-primary, #38bdf8);
66
+ z-index: 10;
67
+ }
68
+
69
+ &.mj-card--hidden {
70
+ display: none !important;
71
+ }
72
+
73
+ &__header {
74
+ display: flex !important;
75
+ flex-direction: row !important;
76
+ align-items: flex-start !important;
77
+ justify-content: space-between !important;
78
+ gap: var(--mj-space-3, 12px) !important;
79
+ margin-bottom: var(--mj-space-3, 12px) !important;
80
+ min-height: 28px !important;
81
+ width: 100% !important;
82
+ }
83
+
84
+ &__title-group {
85
+ display: flex !important;
86
+ flex-direction: column !important;
87
+ gap: 2px !important;
88
+ min-width: 0 !important;
89
+ flex: 1 1 auto !important;
90
+ }
91
+
92
+ &__title-row {
93
+ display: flex !important;
94
+ flex-direction: row !important;
95
+ align-items: center !important;
96
+ gap: var(--mj-space-2, 8px) !important;
97
+ min-width: 0 !important;
98
+ }
99
+
100
+ &__icon {
101
+ color: var(--mj-brand-primary, #38bdf8);
102
+ font-size: 14px;
103
+ display: inline-flex;
104
+ align-items: center;
105
+ justify-content: center;
106
+ flex-shrink: 0;
107
+ }
108
+
109
+ &__title {
110
+ font-size: 14px;
111
+ font-weight: 700;
112
+ color: var(--mj-text-primary, #ffffff);
113
+ letter-spacing: -0.01em;
114
+ margin: 0;
115
+ white-space: nowrap;
116
+ overflow: hidden;
117
+ text-overflow: ellipsis;
118
+ }
119
+
120
+ &__subtitle {
121
+ font-size: 11.5px;
122
+ font-weight: 500;
123
+ color: var(--mj-text-muted, #94a3b8);
124
+ margin: 0;
125
+ padding-left: 22px;
126
+ }
127
+
128
+ &__actions {
129
+ display: flex !important;
130
+ flex-direction: row !important;
131
+ align-items: center !important;
132
+ gap: var(--mj-space-2, 8px) !important;
133
+ flex-shrink: 0 !important;
134
+ margin-left: auto !important;
135
+ }
136
+
137
+ &__toggle-btn {
138
+ display: inline-flex;
139
+ align-items: center;
140
+ justify-content: center;
141
+ width: 28px;
142
+ height: 28px;
143
+ border-radius: var(--mj-radius-sm, 6px);
144
+ background: transparent;
145
+ border: 1px solid transparent;
146
+ color: var(--mj-text-muted, #94a3b8);
147
+ cursor: pointer;
148
+ padding: 0;
149
+ font-size: 12px;
150
+ transition: all 0.15s ease;
151
+
152
+ &:hover {
153
+ color: var(--mj-text-primary, #ffffff);
154
+ background: var(--mj-bg-surface-sunken, rgba(255, 255, 255, 0.06));
155
+ border-color: var(--mj-border-default, #2a3852);
156
+ }
157
+
158
+ &:focus-visible {
159
+ outline: 2px solid var(--mj-brand-primary, #38bdf8);
160
+ outline-offset: 1px;
161
+ }
162
+ }
163
+
164
+ &__body {
165
+ flex: 1 1 auto;
166
+ display: flex;
167
+ flex-direction: column;
168
+ justify-content: space-between;
169
+ min-width: 0;
170
+ }
171
+
172
+ &__footer {
173
+ margin-top: auto;
174
+ padding-top: var(--mj-space-3, 12px);
175
+ border-top: 1px solid var(--mj-border-default, #2a3852);
176
+ }
177
+ }
@@ -12,7 +12,7 @@ import * as i0 from "@angular/core";
12
12
  */
13
13
  export type MJEmptyStateVariant = 'empty' | 'no-results' | 'success' | 'warning' | 'error';
14
14
  /** Density of an `<mj-empty-state>` — controls padding and icon size. */
15
- export type MJEmptyStateSize = 'compact' | 'default' | 'large';
15
+ export type MJEmptyStateSize = 'inline' | 'compact' | 'default' | 'large';
16
16
  /**
17
17
  * mj-empty-state — Canonical centered empty/no-results/error placeholder.
18
18
  *
@@ -89,6 +89,7 @@ export declare class MJEmptyStateComponent {
89
89
  Role: string | null;
90
90
  /** Emitted when the built-in CTA button is clicked. */
91
91
  Action: EventEmitter<MouseEvent>;
92
+ get IsInline(): boolean;
92
93
  get IsCompact(): boolean;
93
94
  get IsLarge(): boolean;
94
95
  get IsNoResults(): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"empty-state.component.d.ts","sourceRoot":"","sources":["../../../src/lib/empty-state/empty-state.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,YAAY,EAA8B,MAAM,eAAe,CAAC;;AAGpF;;;;;;;;;GASG;AACH,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAE3F,yEAAyE;AACzE,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAE/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,qBA6Ga,qBAAqB;IAChC;;;;OAIG;IACM,IAAI,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEpC,kDAAkD;IACzC,KAAK,EAAE,MAAM,CAAM;IAE5B,4CAA4C;IACnC,OAAO,EAAE,MAAM,CAAM;IAE9B,8DAA8D;IACrD,UAAU,EAAE,MAAM,CAAM;IAEjC,8DAA8D;IACrD,UAAU,EAAE,MAAM,CAAM;IAEjC,oEAAoE;IAC3D,aAAa,EAAE,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,MAAM,CAAa;IAEjF,mFAAmF;IAC1E,OAAO,EAAE,mBAAmB,CAAW;IAEhD,uEAAuE;IAC9D,IAAI,EAAE,gBAAgB,CAAa;IAE5C;;;;;;;;OAQG;IACM,IAAI,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEpC,uDAAuD;IAC7C,MAAM,2BAAkC;IAElD,IACI,SAAS,IAAI,OAAO,CAAoC;IAE5D,IACI,OAAO,IAAI,OAAO,CAAkC;IAExD,IACI,WAAW,IAAI,OAAO,CAA0C;IAEpE,IACI,SAAS,IAAI,OAAO,CAAuC;IAE/D,IACI,SAAS,IAAI,OAAO,CAAuC;IAE/D,IACI,OAAO,IAAI,OAAO,CAAqC;IAE3D;;;OAGG;IACH,IACI,QAAQ,IAAI,MAAM,GAAG,IAAI,CAK5B;IAED;;;OAGG;IACH,IAAI,YAAY,IAAI,MAAM,CAKzB;IAED,kDAAkD;IAClD,MAAM,CAAC,qBAAqB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM;IAelE,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;yCApGtB,qBAAqB;2CAArB,qBAAqB;CAuGjC"}
1
+ {"version":3,"file":"empty-state.component.d.ts","sourceRoot":"","sources":["../../../src/lib/empty-state/empty-state.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,YAAY,EAA8B,MAAM,eAAe,CAAC;;AAGpF;;;;;;;;;GASG;AACH,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAE3F,yEAAyE;AACzE,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAE1E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,qBA0Ha,qBAAqB;IAChC;;;;OAIG;IACM,IAAI,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEpC,kDAAkD;IACzC,KAAK,EAAE,MAAM,CAAM;IAE5B,4CAA4C;IACnC,OAAO,EAAE,MAAM,CAAM;IAE9B,8DAA8D;IACrD,UAAU,EAAE,MAAM,CAAM;IAEjC,8DAA8D;IACrD,UAAU,EAAE,MAAM,CAAM;IAEjC,oEAAoE;IAC3D,aAAa,EAAE,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,MAAM,CAAa;IAEjF,mFAAmF;IAC1E,OAAO,EAAE,mBAAmB,CAAW;IAEhD,uEAAuE;IAC9D,IAAI,EAAE,gBAAgB,CAAa;IAE5C;;;;;;;;OAQG;IACM,IAAI,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEpC,uDAAuD;IAC7C,MAAM,2BAAkC;IAElD,IACI,QAAQ,IAAI,OAAO,CAAmC;IAE1D,IACI,SAAS,IAAI,OAAO,CAAoC;IAE5D,IACI,OAAO,IAAI,OAAO,CAAkC;IAExD,IACI,WAAW,IAAI,OAAO,CAA0C;IAEpE,IACI,SAAS,IAAI,OAAO,CAAuC;IAE/D,IACI,SAAS,IAAI,OAAO,CAAuC;IAE/D,IACI,OAAO,IAAI,OAAO,CAAqC;IAE3D;;;OAGG;IACH,IACI,QAAQ,IAAI,MAAM,GAAG,IAAI,CAK5B;IAED;;;OAGG;IACH,IAAI,YAAY,IAAI,MAAM,CAKzB;IAED,kDAAkD;IAClD,MAAM,CAAC,qBAAqB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM;IAelE,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;yCAvGtB,qBAAqB;2CAArB,qBAAqB;CA0GjC"}
@@ -124,6 +124,7 @@ export class MJEmptyStateComponent {
124
124
  Role = null;
125
125
  /** Emitted when the built-in CTA button is clicked. */
126
126
  Action = new EventEmitter();
127
+ get IsInline() { return this.Size === 'inline'; }
127
128
  get IsCompact() { return this.Size === 'compact'; }
128
129
  get IsLarge() { return this.Size === 'large'; }
129
130
  get IsNoResults() { return this.Variant === 'no-results'; }
@@ -169,9 +170,9 @@ export class MJEmptyStateComponent {
169
170
  this.Action.emit(event);
170
171
  }
171
172
  static ɵfac = function MJEmptyStateComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || MJEmptyStateComponent)(); };
172
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MJEmptyStateComponent, selectors: [["mj-empty-state"]], hostVars: 13, hostBindings: function MJEmptyStateComponent_HostBindings(rf, ctx) { if (rf & 2) {
173
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MJEmptyStateComponent, selectors: [["mj-empty-state"]], hostVars: 15, hostBindings: function MJEmptyStateComponent_HostBindings(rf, ctx) { if (rf & 2) {
173
174
  i0.ɵɵattribute("role", ctx.HostRole);
174
- i0.ɵɵclassProp("mj-empty-state--compact", ctx.IsCompact)("mj-empty-state--large", ctx.IsLarge)("mj-empty-state--no-results", ctx.IsNoResults)("mj-empty-state--success", ctx.IsSuccess)("mj-empty-state--warning", ctx.IsWarning)("mj-empty-state--error", ctx.IsError);
175
+ i0.ɵɵclassProp("mj-empty-state--inline", ctx.IsInline)("mj-empty-state--compact", ctx.IsCompact)("mj-empty-state--large", ctx.IsLarge)("mj-empty-state--no-results", ctx.IsNoResults)("mj-empty-state--success", ctx.IsSuccess)("mj-empty-state--warning", ctx.IsWarning)("mj-empty-state--error", ctx.IsError);
175
176
  } }, inputs: { Icon: "Icon", Title: "Title", Message: "Message", ActionText: "ActionText", ActionIcon: "ActionIcon", ActionVariant: "ActionVariant", Variant: "Variant", Size: "Size", Role: "Role" }, outputs: { Action: "Action" }, ngContentSelectors: _c1, decls: 7, vars: 4, consts: [["aria-hidden", "true", 3, "class"], [1, "mj-empty-state__title"], [1, "mj-empty-state__message"], [1, "mj-empty-state__actions"], ["type", "button", "mjButton", "", 3, "variant"], ["aria-hidden", "true"], ["type", "button", "mjButton", "", 3, "click", "variant"]], template: function MJEmptyStateComponent_Template(rf, ctx) { if (rf & 1) {
176
177
  i0.ɵɵprojectionDef(_c0);
177
178
  i0.ɵɵconditionalCreate(0, MJEmptyStateComponent_Conditional_0_Template, 1, 3, "i", 0);
@@ -190,7 +191,7 @@ export class MJEmptyStateComponent {
190
191
  i0.ɵɵconditional(ctx.Message ? 2 : -1);
191
192
  i0.ɵɵadvance(3);
192
193
  i0.ɵɵconditional(ctx.ActionText ? 5 : -1);
193
- } }, dependencies: [MJButtonDirective], styles: ["[_nghost-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n text-align: center;\n padding: var(--mj-space-12);\n color: var(--mj-text-secondary);\n }\n\n .mj-empty-state__icon[_ngcontent-%COMP%] {\n font-size: 3rem;\n line-height: 1;\n margin-bottom: var(--mj-space-4);\n color: var(--mj-text-disabled);\n }\n\n .mj-empty-state__title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: var(--mj-text-lg);\n font-weight: 600;\n color: var(--mj-text-primary);\n }\n\n .mj-empty-state__message[_ngcontent-%COMP%] {\n margin: var(--mj-space-2) 0 0;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-muted);\n max-width: 420px;\n }\n\n .mj-empty-state__actions[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n gap: var(--mj-space-2);\n margin-top: var(--mj-space-6);\n }\n \n\n\n .mj-empty-state__actions[_ngcontent-%COMP%]:empty {\n display: none;\n }\n\n \n\n .mj-empty-state--compact[_nghost-%COMP%] {\n padding: var(--mj-space-8);\n }\n .mj-empty-state--compact[_nghost-%COMP%] .mj-empty-state__icon[_ngcontent-%COMP%] {\n font-size: 2rem;\n margin-bottom: var(--mj-space-3);\n }\n\n .mj-empty-state--large[_nghost-%COMP%] {\n padding: var(--mj-space-16) var(--mj-space-10);\n }\n .mj-empty-state--large[_nghost-%COMP%] .mj-empty-state__icon[_ngcontent-%COMP%] {\n font-size: 4rem;\n }\n\n \n\n .mj-empty-state--no-results[_nghost-%COMP%] .mj-empty-state__icon[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n }\n .mj-empty-state--success[_nghost-%COMP%] .mj-empty-state__icon[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n }\n .mj-empty-state--warning[_nghost-%COMP%] .mj-empty-state__icon[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n }\n .mj-empty-state--error[_nghost-%COMP%] .mj-empty-state__icon[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n }"] });
194
+ } }, dependencies: [MJButtonDirective], styles: ["[_nghost-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n text-align: center;\n padding: var(--mj-space-12);\n color: var(--mj-text-secondary);\n }\n\n .mj-empty-state__icon[_ngcontent-%COMP%] {\n font-size: 3rem;\n line-height: 1;\n margin-bottom: var(--mj-space-4);\n color: var(--mj-text-disabled);\n }\n\n .mj-empty-state__title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: var(--mj-text-lg);\n font-weight: 600;\n color: var(--mj-text-primary);\n }\n\n .mj-empty-state__message[_ngcontent-%COMP%] {\n margin: var(--mj-space-2) 0 0;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-muted);\n max-width: 420px;\n }\n\n .mj-empty-state__actions[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n gap: var(--mj-space-2);\n margin-top: var(--mj-space-6);\n }\n \n\n\n .mj-empty-state__actions[_ngcontent-%COMP%]:empty {\n display: none;\n }\n\n \n\n .mj-empty-state--inline[_nghost-%COMP%] {\n padding: 8px 12px;\n justify-content: flex-start;\n }\n .mj-empty-state--inline[_nghost-%COMP%] .mj-empty-state__icon[_ngcontent-%COMP%] {\n font-size: 1.25rem;\n margin-bottom: 4px;\n }\n .mj-empty-state--inline[_nghost-%COMP%] .mj-empty-state__title[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n font-weight: 500;\n }\n\n .mj-empty-state--compact[_nghost-%COMP%] {\n padding: var(--mj-space-8);\n }\n .mj-empty-state--compact[_nghost-%COMP%] .mj-empty-state__icon[_ngcontent-%COMP%] {\n font-size: 2rem;\n margin-bottom: var(--mj-space-3);\n }\n\n .mj-empty-state--large[_nghost-%COMP%] {\n padding: var(--mj-space-16) var(--mj-space-10);\n }\n .mj-empty-state--large[_nghost-%COMP%] .mj-empty-state__icon[_ngcontent-%COMP%] {\n font-size: 4rem;\n }\n\n \n\n .mj-empty-state--no-results[_nghost-%COMP%] .mj-empty-state__icon[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n }\n .mj-empty-state--success[_nghost-%COMP%] .mj-empty-state__icon[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n }\n .mj-empty-state--warning[_nghost-%COMP%] .mj-empty-state__icon[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n }\n .mj-empty-state--error[_nghost-%COMP%] .mj-empty-state__icon[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n }"] });
194
195
  }
195
196
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJEmptyStateComponent, [{
196
197
  type: Component,
@@ -221,7 +222,7 @@ export class MJEmptyStateComponent {
221
222
  }
222
223
  <ng-content select="[actions]"></ng-content>
223
224
  </div>
224
- `, styles: ["\n :host {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n text-align: center;\n padding: var(--mj-space-12);\n color: var(--mj-text-secondary);\n }\n\n .mj-empty-state__icon {\n font-size: 3rem;\n line-height: 1;\n margin-bottom: var(--mj-space-4);\n color: var(--mj-text-disabled);\n }\n\n .mj-empty-state__title {\n margin: 0;\n font-size: var(--mj-text-lg);\n font-weight: 600;\n color: var(--mj-text-primary);\n }\n\n .mj-empty-state__message {\n margin: var(--mj-space-2) 0 0;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-muted);\n max-width: 420px;\n }\n\n .mj-empty-state__actions {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n gap: var(--mj-space-2);\n margin-top: var(--mj-space-6);\n }\n /* Collapse the actions row entirely when no CTA is rendered (modern browsers\n treat an element containing only Angular's @if comment-anchors as :empty). */\n .mj-empty-state__actions:empty {\n display: none;\n }\n\n /* \u2500\u2500 Sizes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n :host(.mj-empty-state--compact) {\n padding: var(--mj-space-8);\n }\n :host(.mj-empty-state--compact) .mj-empty-state__icon {\n font-size: 2rem;\n margin-bottom: var(--mj-space-3);\n }\n\n :host(.mj-empty-state--large) {\n padding: var(--mj-space-16) var(--mj-space-10);\n }\n :host(.mj-empty-state--large) .mj-empty-state__icon {\n font-size: 4rem;\n }\n\n /* \u2500\u2500 Variants (icon tone) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n :host(.mj-empty-state--no-results) .mj-empty-state__icon {\n color: var(--mj-text-muted);\n }\n :host(.mj-empty-state--success) .mj-empty-state__icon {\n color: var(--mj-status-success);\n }\n :host(.mj-empty-state--warning) .mj-empty-state__icon {\n color: var(--mj-status-warning);\n }\n :host(.mj-empty-state--error) .mj-empty-state__icon {\n color: var(--mj-status-error);\n }\n "] }]
225
+ `, styles: ["\n :host {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n text-align: center;\n padding: var(--mj-space-12);\n color: var(--mj-text-secondary);\n }\n\n .mj-empty-state__icon {\n font-size: 3rem;\n line-height: 1;\n margin-bottom: var(--mj-space-4);\n color: var(--mj-text-disabled);\n }\n\n .mj-empty-state__title {\n margin: 0;\n font-size: var(--mj-text-lg);\n font-weight: 600;\n color: var(--mj-text-primary);\n }\n\n .mj-empty-state__message {\n margin: var(--mj-space-2) 0 0;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-muted);\n max-width: 420px;\n }\n\n .mj-empty-state__actions {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n gap: var(--mj-space-2);\n margin-top: var(--mj-space-6);\n }\n /* Collapse the actions row entirely when no CTA is rendered (modern browsers\n treat an element containing only Angular's @if comment-anchors as :empty). */\n .mj-empty-state__actions:empty {\n display: none;\n }\n\n /* \u2500\u2500 Sizes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n :host(.mj-empty-state--inline) {\n padding: 8px 12px;\n justify-content: flex-start;\n }\n :host(.mj-empty-state--inline) .mj-empty-state__icon {\n font-size: 1.25rem;\n margin-bottom: 4px;\n }\n :host(.mj-empty-state--inline) .mj-empty-state__title {\n font-size: var(--mj-text-sm);\n font-weight: 500;\n }\n\n :host(.mj-empty-state--compact) {\n padding: var(--mj-space-8);\n }\n :host(.mj-empty-state--compact) .mj-empty-state__icon {\n font-size: 2rem;\n margin-bottom: var(--mj-space-3);\n }\n\n :host(.mj-empty-state--large) {\n padding: var(--mj-space-16) var(--mj-space-10);\n }\n :host(.mj-empty-state--large) .mj-empty-state__icon {\n font-size: 4rem;\n }\n\n /* \u2500\u2500 Variants (icon tone) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n :host(.mj-empty-state--no-results) .mj-empty-state__icon {\n color: var(--mj-text-muted);\n }\n :host(.mj-empty-state--success) .mj-empty-state__icon {\n color: var(--mj-status-success);\n }\n :host(.mj-empty-state--warning) .mj-empty-state__icon {\n color: var(--mj-status-warning);\n }\n :host(.mj-empty-state--error) .mj-empty-state__icon {\n color: var(--mj-status-error);\n }\n "] }]
225
226
  }], null, { Icon: [{
226
227
  type: Input
227
228
  }], Title: [{
@@ -242,6 +243,9 @@ export class MJEmptyStateComponent {
242
243
  type: Input
243
244
  }], Action: [{
244
245
  type: Output
246
+ }], IsInline: [{
247
+ type: HostBinding,
248
+ args: ['class.mj-empty-state--inline']
245
249
  }], IsCompact: [{
246
250
  type: HostBinding,
247
251
  args: ['class.mj-empty-state--compact']
@@ -264,5 +268,5 @@ export class MJEmptyStateComponent {
264
268
  type: HostBinding,
265
269
  args: ['attr.role']
266
270
  }] }); })();
267
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJEmptyStateComponent, { className: "MJEmptyStateComponent", filePath: "lib/empty-state/empty-state.component.ts", lineNumber: 171 }); })();
271
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJEmptyStateComponent, { className: "MJEmptyStateComponent", filePath: "lib/empty-state/empty-state.component.ts", lineNumber: 184 }); })();
268
272
  //# sourceMappingURL=empty-state.component.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"empty-state.component.js","sourceRoot":"","sources":["../../../src/lib/empty-state/empty-state.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, EventEmitter, HostBinding, Input, Output } from '@angular/core';\nimport { MJButtonDirective } from '../button/button.directive';\n\n/**\n * Visual intent of an `<mj-empty-state>`. Drives the default icon and the icon's\n * color treatment so callers don't restate either for the common cases.\n *\n * - `empty` — nothing exists yet (default). Neutral/disabled icon tone.\n * - `no-results` — a search/filter matched nothing. Muted icon tone, magnifier default.\n * - `success` — a positive \"all clear\" empty (e.g. \"No Errors Found\"). Success icon tone, check default.\n * - `warning` — a non-error blocking condition (disabled/misconfigured feature). Warning icon tone.\n * - `error` — a load/operation failed. Error icon tone, triangle default.\n */\nexport type MJEmptyStateVariant = 'empty' | 'no-results' | 'success' | 'warning' | 'error';\n\n/** Density of an `<mj-empty-state>` — controls padding and icon size. */\nexport type MJEmptyStateSize = 'compact' | 'default' | 'large';\n\n/**\n * mj-empty-state — Canonical centered empty/no-results/error placeholder.\n *\n * Replaces the ~213 inline empty-state `<div>`s that pages were each hand-rolling\n * (icon + title + message, optionally a CTA), e.g.:\n * ```html\n * <div class=\"empty-state\">\n * <i class=\"fa-solid fa-inbox\"></i>\n * <h3>No Permissions Found</h3>\n * <p>Try adjusting your filters or refresh the data.</p>\n * <button mjButton variant=\"primary\" (click)=\"refreshData()\">Refresh</button>\n * </div>\n * ```\n *\n * Usage:\n * ```html\n * <!-- Simplest: nothing-here placeholder -->\n * <mj-empty-state Title=\"No runs found\" Message=\"No runs match the selected filters.\" />\n *\n * <!-- Search/filter produced nothing -->\n * <mj-empty-state Variant=\"no-results\" Title=\"No icons found\" Message=\"Try a different search term.\" />\n *\n * <!-- Load failed, retry CTA -->\n * <mj-empty-state Variant=\"error\" Title=\"Couldn't load permissions\" [Message]=\"error\"\n * ActionText=\"Try Again\" ActionIcon=\"fa-solid fa-rotate-right\" (Action)=\"loadData()\" />\n *\n * <!-- Invitation to create the first record -->\n * <mj-empty-state Icon=\"fa-solid fa-key\" Title=\"No API keys yet\"\n * Message=\"Generate a key to start calling the API.\"\n * ActionText=\"Generate Your First Key\" ActionIcon=\"fa-solid fa-plus\"\n * (Action)=\"requestCreate()\" />\n *\n * <!-- Multiple / bespoke CTAs: project them into the [actions] slot -->\n * <mj-empty-state Title=\"No pinned items yet\" Message=\"Pin dashboards for quick access.\">\n * <button mjButton variant=\"primary\" (click)=\"addPin()\">Add your first pin</button>\n * <button mjButton variant=\"flat\" (click)=\"dismiss()\">Don't show again</button>\n * </mj-empty-state>\n * ```\n *\n * For dynamic messages (e.g. \"No keys matching X\" vs \"No keys yet\"), compute the\n * string in the parent and bind it to `[Message]`, or project richer body content\n * as default `<ng-content>` (rendered between the message and the actions).\n */\n@Component({\n selector: 'mj-empty-state',\n standalone: true,\n imports: [MJButtonDirective],\n template: `\n @if (ResolvedIcon) {\n <i class=\"mj-empty-state__icon {{ ResolvedIcon }}\" aria-hidden=\"true\"></i>\n }\n @if (Title) {\n <h3 class=\"mj-empty-state__title\">{{ Title }}</h3>\n }\n @if (Message) {\n <p class=\"mj-empty-state__message\">{{ Message }}</p>\n }\n\n <!-- Optional richer body content (feature lists, dynamic text, links) -->\n <ng-content></ng-content>\n\n <!-- Actions: the built-in single CTA and/or projected [actions] buttons.\n Hidden via :empty when neither is present. -->\n <div class=\"mj-empty-state__actions\">\n @if (ActionText) {\n <button type=\"button\" mjButton [variant]=\"ActionVariant\" (click)=\"OnAction($event)\">\n @if (ActionIcon) {\n <i class=\"{{ ActionIcon }}\" aria-hidden=\"true\"></i>\n }\n {{ ActionText }}\n </button>\n }\n <ng-content select=\"[actions]\"></ng-content>\n </div>\n `,\n styles: [`\n :host {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n text-align: center;\n padding: var(--mj-space-12);\n color: var(--mj-text-secondary);\n }\n\n .mj-empty-state__icon {\n font-size: 3rem;\n line-height: 1;\n margin-bottom: var(--mj-space-4);\n color: var(--mj-text-disabled);\n }\n\n .mj-empty-state__title {\n margin: 0;\n font-size: var(--mj-text-lg);\n font-weight: 600;\n color: var(--mj-text-primary);\n }\n\n .mj-empty-state__message {\n margin: var(--mj-space-2) 0 0;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-muted);\n max-width: 420px;\n }\n\n .mj-empty-state__actions {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n gap: var(--mj-space-2);\n margin-top: var(--mj-space-6);\n }\n /* Collapse the actions row entirely when no CTA is rendered (modern browsers\n treat an element containing only Angular's @if comment-anchors as :empty). */\n .mj-empty-state__actions:empty {\n display: none;\n }\n\n /* ── Sizes ────────────────────────────────────────────────── */\n :host(.mj-empty-state--compact) {\n padding: var(--mj-space-8);\n }\n :host(.mj-empty-state--compact) .mj-empty-state__icon {\n font-size: 2rem;\n margin-bottom: var(--mj-space-3);\n }\n\n :host(.mj-empty-state--large) {\n padding: var(--mj-space-16) var(--mj-space-10);\n }\n :host(.mj-empty-state--large) .mj-empty-state__icon {\n font-size: 4rem;\n }\n\n /* ── Variants (icon tone) ─────────────────────────────────── */\n :host(.mj-empty-state--no-results) .mj-empty-state__icon {\n color: var(--mj-text-muted);\n }\n :host(.mj-empty-state--success) .mj-empty-state__icon {\n color: var(--mj-status-success);\n }\n :host(.mj-empty-state--warning) .mj-empty-state__icon {\n color: var(--mj-status-warning);\n }\n :host(.mj-empty-state--error) .mj-empty-state__icon {\n color: var(--mj-status-error);\n }\n `]\n})\nexport class MJEmptyStateComponent {\n /**\n * Font Awesome icon class string (e.g. \"fa-solid fa-key\"). When omitted, a\n * sensible default is chosen from `Variant`. Pass an empty string AND no\n * variant default applies — set this explicitly to \"\" to render no icon.\n */\n @Input() Icon: string | null = null;\n\n /** Bold heading line (e.g. \"No API keys yet\"). */\n @Input() Title: string = '';\n\n /** Supporting/help text below the title. */\n @Input() Message: string = '';\n\n /** When set, renders a primary CTA button with this label. */\n @Input() ActionText: string = '';\n\n /** Optional Font Awesome icon shown inside the CTA button. */\n @Input() ActionIcon: string = '';\n\n /** mjButton variant for the built-in CTA. Defaults to 'primary'. */\n @Input() ActionVariant: 'primary' | 'secondary' | 'outline' | 'flat' = 'primary';\n\n /** Visual intent — drives the default icon and icon color. Defaults to 'empty'. */\n @Input() Variant: MJEmptyStateVariant = 'empty';\n\n /** Density — controls padding and icon size. Defaults to 'default'. */\n @Input() Size: MJEmptyStateSize = 'default';\n\n /**\n * ARIA live-region role on the host. When unset, it defaults from `Variant`:\n * `error` → `'alert'` (assertive), everything else → `'status'` (polite). This\n * makes a dynamically-appearing empty state announce itself to screen readers —\n * the title + message are read together via the role's implicit\n * `aria-live`/`aria-atomic`. (Empty states present at page load are not\n * announced, per the live-region spec, so static placeholders stay quiet.)\n * Pass an explicit role to override, or `''` to opt out of the live region.\n */\n @Input() Role: string | null = null;\n\n /** Emitted when the built-in CTA button is clicked. */\n @Output() Action = new EventEmitter<MouseEvent>();\n\n @HostBinding('class.mj-empty-state--compact')\n get IsCompact(): boolean { return this.Size === 'compact'; }\n\n @HostBinding('class.mj-empty-state--large')\n get IsLarge(): boolean { return this.Size === 'large'; }\n\n @HostBinding('class.mj-empty-state--no-results')\n get IsNoResults(): boolean { return this.Variant === 'no-results'; }\n\n @HostBinding('class.mj-empty-state--success')\n get IsSuccess(): boolean { return this.Variant === 'success'; }\n\n @HostBinding('class.mj-empty-state--warning')\n get IsWarning(): boolean { return this.Variant === 'warning'; }\n\n @HostBinding('class.mj-empty-state--error')\n get IsError(): boolean { return this.Variant === 'error'; }\n\n /**\n * Live-region role applied to the host. Explicit `Role` wins (`''` ⇒ no role);\n * otherwise an error state is an assertive `alert`, everything else a polite `status`.\n */\n @HostBinding('attr.role')\n get HostRole(): string | null {\n if (this.Role != null) {\n return this.Role || null;\n }\n return this.Variant === 'error' ? 'alert' : 'status';\n }\n\n /**\n * Icon actually rendered: the explicit `Icon` when provided (including \"\"\n * to suppress the icon), otherwise the per-variant default.\n */\n get ResolvedIcon(): string {\n if (this.Icon != null) {\n return this.Icon;\n }\n return MJEmptyStateComponent.DefaultIconForVariant(this.Variant);\n }\n\n /** Default Font Awesome icon for each variant. */\n static DefaultIconForVariant(variant: MJEmptyStateVariant): string {\n switch (variant) {\n case 'no-results':\n return 'fa-solid fa-magnifying-glass';\n case 'success':\n return 'fa-solid fa-circle-check';\n case 'warning':\n case 'error':\n return 'fa-solid fa-triangle-exclamation';\n case 'empty':\n default:\n return 'fa-solid fa-inbox';\n }\n }\n\n OnAction(event: MouseEvent): void {\n this.Action.emit(event);\n }\n}\n"]}
1
+ {"version":3,"file":"empty-state.component.js","sourceRoot":"","sources":["../../../src/lib/empty-state/empty-state.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACpF,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;;;;;IAkEzD,uBAA0E;;;IAAvE,cAAA,+DAA+C,CAAA;;;IAGlD,6BAAkC;IAAA,YAAW;IAAA,iBAAK;;;IAAhB,cAAW;IAAX,kCAAW;;;IAG7C,4BAAmC;IAAA,YAAa;IAAA,iBAAI;;;IAAjB,cAAa;IAAb,oCAAa;;;IAY1C,uBAAmD;;;IAAhD,gCAAwB;;;;IAF/B,iCAAoF;IAA3B,+LAAS,uBAAgB,KAAC;IACjF,mGAAkB;IAGlB,YACF;IAAA,iBAAS;;;IALsB,8CAAyB;IACtD,cAEC;IAFD,4CAEC;IACD,cACF;IADE,kDACF;;AAtER;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AA2HH,MAAM,OAAO,qBAAqB;IAChC;;;;OAIG;IACM,IAAI,GAAkB,IAAI,CAAC;IAEpC,kDAAkD;IACzC,KAAK,GAAW,EAAE,CAAC;IAE5B,4CAA4C;IACnC,OAAO,GAAW,EAAE,CAAC;IAE9B,8DAA8D;IACrD,UAAU,GAAW,EAAE,CAAC;IAEjC,8DAA8D;IACrD,UAAU,GAAW,EAAE,CAAC;IAEjC,oEAAoE;IAC3D,aAAa,GAAiD,SAAS,CAAC;IAEjF,mFAAmF;IAC1E,OAAO,GAAwB,OAAO,CAAC;IAEhD,uEAAuE;IAC9D,IAAI,GAAqB,SAAS,CAAC;IAE5C;;;;;;;;OAQG;IACM,IAAI,GAAkB,IAAI,CAAC;IAEpC,uDAAuD;IAC7C,MAAM,GAAG,IAAI,YAAY,EAAc,CAAC;IAElD,IACI,QAAQ,KAAc,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC;IAE1D,IACI,SAAS,KAAc,OAAO,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC;IAE5D,IACI,OAAO,KAAc,OAAO,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC;IAExD,IACI,WAAW,KAAc,OAAO,IAAI,CAAC,OAAO,KAAK,YAAY,CAAC,CAAC,CAAC;IAEpE,IACI,SAAS,KAAc,OAAO,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC;IAE/D,IACI,SAAS,KAAc,OAAO,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC;IAE/D,IACI,OAAO,KAAc,OAAO,IAAI,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC;IAE3D;;;OAGG;IACH,IACI,QAAQ;QACV,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC;YACtB,OAAO,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC;QAC3B,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC;IACvD,CAAC;IAED;;;OAGG;IACH,IAAI,YAAY;QACd,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC;YACtB,OAAO,IAAI,CAAC,IAAI,CAAC;QACnB,CAAC;QACD,OAAO,qBAAqB,CAAC,qBAAqB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACnE,CAAC;IAED,kDAAkD;IAClD,MAAM,CAAC,qBAAqB,CAAC,OAA4B;QACvD,QAAQ,OAAO,EAAE,CAAC;YAChB,KAAK,YAAY;gBACf,OAAO,8BAA8B,CAAC;YACxC,KAAK,SAAS;gBACZ,OAAO,0BAA0B,CAAC;YACpC,KAAK,SAAS,CAAC;YACf,KAAK,OAAO;gBACV,OAAO,kCAAkC,CAAC;YAC5C,KAAK,OAAO,CAAC;YACb;gBACE,OAAO,mBAAmB,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,QAAQ,CAAC,KAAiB;QACxB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;+GAzGU,qBAAqB;6DAArB,qBAAqB;;YAArB,sDAAqB,0CAAA,sCAAA,+CAAA,0CAAA,0CAAA,sCAAA;;;YArH9B,qFAAoB;YAGpB,sFAAa;YAGb,qFAAe;YAKf,kBAAyB;YAIzB,8BAAqC;YACnC,0FAAkB;YAQlB,qBAA4C;YAC9C,iBAAM;;YAzBN,2CAEC;YACD,cAEC;YAFD,oCAEC;YACD,cAEC;YAFD,sCAEC;YAQC,eAOC;YAPD,yCAOC;4BAzBK,iBAAiB;;iFAuHhB,qBAAqB;cA1HjC,SAAS;2BACE,gBAAgB,cACd,IAAI,WACP,CAAC,iBAAiB,CAAC,YAClB;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BT;;kBAiGA,KAAK;;kBAGL,KAAK;;kBAGL,KAAK;;kBAGL,KAAK;;kBAGL,KAAK;;kBAGL,KAAK;;kBAGL,KAAK;;kBAGL,KAAK;;kBAWL,KAAK;;kBAGL,MAAM;;kBAEN,WAAW;mBAAC,8BAA8B;;kBAG1C,WAAW;mBAAC,+BAA+B;;kBAG3C,WAAW;mBAAC,6BAA6B;;kBAGzC,WAAW;mBAAC,kCAAkC;;kBAG9C,WAAW;mBAAC,+BAA+B;;kBAG3C,WAAW;mBAAC,+BAA+B;;kBAG3C,WAAW;mBAAC,6BAA6B;;kBAOzC,WAAW;mBAAC,WAAW;;kFApEb,qBAAqB","sourcesContent":["import { Component, EventEmitter, HostBinding, Input, Output } from '@angular/core';\nimport { MJButtonDirective } from '../button/button.directive';\n\n/**\n * Visual intent of an `<mj-empty-state>`. Drives the default icon and the icon's\n * color treatment so callers don't restate either for the common cases.\n *\n * - `empty` — nothing exists yet (default). Neutral/disabled icon tone.\n * - `no-results` — a search/filter matched nothing. Muted icon tone, magnifier default.\n * - `success` — a positive \"all clear\" empty (e.g. \"No Errors Found\"). Success icon tone, check default.\n * - `warning` — a non-error blocking condition (disabled/misconfigured feature). Warning icon tone.\n * - `error` — a load/operation failed. Error icon tone, triangle default.\n */\nexport type MJEmptyStateVariant = 'empty' | 'no-results' | 'success' | 'warning' | 'error';\n\n/** Density of an `<mj-empty-state>` — controls padding and icon size. */\nexport type MJEmptyStateSize = 'inline' | 'compact' | 'default' | 'large';\n\n/**\n * mj-empty-state — Canonical centered empty/no-results/error placeholder.\n *\n * Replaces the ~213 inline empty-state `<div>`s that pages were each hand-rolling\n * (icon + title + message, optionally a CTA), e.g.:\n * ```html\n * <div class=\"empty-state\">\n * <i class=\"fa-solid fa-inbox\"></i>\n * <h3>No Permissions Found</h3>\n * <p>Try adjusting your filters or refresh the data.</p>\n * <button mjButton variant=\"primary\" (click)=\"refreshData()\">Refresh</button>\n * </div>\n * ```\n *\n * Usage:\n * ```html\n * <!-- Simplest: nothing-here placeholder -->\n * <mj-empty-state Title=\"No runs found\" Message=\"No runs match the selected filters.\" />\n *\n * <!-- Search/filter produced nothing -->\n * <mj-empty-state Variant=\"no-results\" Title=\"No icons found\" Message=\"Try a different search term.\" />\n *\n * <!-- Load failed, retry CTA -->\n * <mj-empty-state Variant=\"error\" Title=\"Couldn't load permissions\" [Message]=\"error\"\n * ActionText=\"Try Again\" ActionIcon=\"fa-solid fa-rotate-right\" (Action)=\"loadData()\" />\n *\n * <!-- Invitation to create the first record -->\n * <mj-empty-state Icon=\"fa-solid fa-key\" Title=\"No API keys yet\"\n * Message=\"Generate a key to start calling the API.\"\n * ActionText=\"Generate Your First Key\" ActionIcon=\"fa-solid fa-plus\"\n * (Action)=\"requestCreate()\" />\n *\n * <!-- Multiple / bespoke CTAs: project them into the [actions] slot -->\n * <mj-empty-state Title=\"No pinned items yet\" Message=\"Pin dashboards for quick access.\">\n * <button mjButton variant=\"primary\" (click)=\"addPin()\">Add your first pin</button>\n * <button mjButton variant=\"flat\" (click)=\"dismiss()\">Don't show again</button>\n * </mj-empty-state>\n * ```\n *\n * For dynamic messages (e.g. \"No keys matching X\" vs \"No keys yet\"), compute the\n * string in the parent and bind it to `[Message]`, or project richer body content\n * as default `<ng-content>` (rendered between the message and the actions).\n */\n@Component({\n selector: 'mj-empty-state',\n standalone: true,\n imports: [MJButtonDirective],\n template: `\n @if (ResolvedIcon) {\n <i class=\"mj-empty-state__icon {{ ResolvedIcon }}\" aria-hidden=\"true\"></i>\n }\n @if (Title) {\n <h3 class=\"mj-empty-state__title\">{{ Title }}</h3>\n }\n @if (Message) {\n <p class=\"mj-empty-state__message\">{{ Message }}</p>\n }\n\n <!-- Optional richer body content (feature lists, dynamic text, links) -->\n <ng-content></ng-content>\n\n <!-- Actions: the built-in single CTA and/or projected [actions] buttons.\n Hidden via :empty when neither is present. -->\n <div class=\"mj-empty-state__actions\">\n @if (ActionText) {\n <button type=\"button\" mjButton [variant]=\"ActionVariant\" (click)=\"OnAction($event)\">\n @if (ActionIcon) {\n <i class=\"{{ ActionIcon }}\" aria-hidden=\"true\"></i>\n }\n {{ ActionText }}\n </button>\n }\n <ng-content select=\"[actions]\"></ng-content>\n </div>\n `,\n styles: [`\n :host {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n text-align: center;\n padding: var(--mj-space-12);\n color: var(--mj-text-secondary);\n }\n\n .mj-empty-state__icon {\n font-size: 3rem;\n line-height: 1;\n margin-bottom: var(--mj-space-4);\n color: var(--mj-text-disabled);\n }\n\n .mj-empty-state__title {\n margin: 0;\n font-size: var(--mj-text-lg);\n font-weight: 600;\n color: var(--mj-text-primary);\n }\n\n .mj-empty-state__message {\n margin: var(--mj-space-2) 0 0;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-muted);\n max-width: 420px;\n }\n\n .mj-empty-state__actions {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n gap: var(--mj-space-2);\n margin-top: var(--mj-space-6);\n }\n /* Collapse the actions row entirely when no CTA is rendered (modern browsers\n treat an element containing only Angular's @if comment-anchors as :empty). */\n .mj-empty-state__actions:empty {\n display: none;\n }\n\n /* ── Sizes ────────────────────────────────────────────────── */\n :host(.mj-empty-state--inline) {\n padding: 8px 12px;\n justify-content: flex-start;\n }\n :host(.mj-empty-state--inline) .mj-empty-state__icon {\n font-size: 1.25rem;\n margin-bottom: 4px;\n }\n :host(.mj-empty-state--inline) .mj-empty-state__title {\n font-size: var(--mj-text-sm);\n font-weight: 500;\n }\n\n :host(.mj-empty-state--compact) {\n padding: var(--mj-space-8);\n }\n :host(.mj-empty-state--compact) .mj-empty-state__icon {\n font-size: 2rem;\n margin-bottom: var(--mj-space-3);\n }\n\n :host(.mj-empty-state--large) {\n padding: var(--mj-space-16) var(--mj-space-10);\n }\n :host(.mj-empty-state--large) .mj-empty-state__icon {\n font-size: 4rem;\n }\n\n /* ── Variants (icon tone) ─────────────────────────────────── */\n :host(.mj-empty-state--no-results) .mj-empty-state__icon {\n color: var(--mj-text-muted);\n }\n :host(.mj-empty-state--success) .mj-empty-state__icon {\n color: var(--mj-status-success);\n }\n :host(.mj-empty-state--warning) .mj-empty-state__icon {\n color: var(--mj-status-warning);\n }\n :host(.mj-empty-state--error) .mj-empty-state__icon {\n color: var(--mj-status-error);\n }\n `]\n})\nexport class MJEmptyStateComponent {\n /**\n * Font Awesome icon class string (e.g. \"fa-solid fa-key\"). When omitted, a\n * sensible default is chosen from `Variant`. Pass an empty string AND no\n * variant default applies — set this explicitly to \"\" to render no icon.\n */\n @Input() Icon: string | null = null;\n\n /** Bold heading line (e.g. \"No API keys yet\"). */\n @Input() Title: string = '';\n\n /** Supporting/help text below the title. */\n @Input() Message: string = '';\n\n /** When set, renders a primary CTA button with this label. */\n @Input() ActionText: string = '';\n\n /** Optional Font Awesome icon shown inside the CTA button. */\n @Input() ActionIcon: string = '';\n\n /** mjButton variant for the built-in CTA. Defaults to 'primary'. */\n @Input() ActionVariant: 'primary' | 'secondary' | 'outline' | 'flat' = 'primary';\n\n /** Visual intent — drives the default icon and icon color. Defaults to 'empty'. */\n @Input() Variant: MJEmptyStateVariant = 'empty';\n\n /** Density — controls padding and icon size. Defaults to 'default'. */\n @Input() Size: MJEmptyStateSize = 'default';\n\n /**\n * ARIA live-region role on the host. When unset, it defaults from `Variant`:\n * `error` → `'alert'` (assertive), everything else → `'status'` (polite). This\n * makes a dynamically-appearing empty state announce itself to screen readers —\n * the title + message are read together via the role's implicit\n * `aria-live`/`aria-atomic`. (Empty states present at page load are not\n * announced, per the live-region spec, so static placeholders stay quiet.)\n * Pass an explicit role to override, or `''` to opt out of the live region.\n */\n @Input() Role: string | null = null;\n\n /** Emitted when the built-in CTA button is clicked. */\n @Output() Action = new EventEmitter<MouseEvent>();\n\n @HostBinding('class.mj-empty-state--inline')\n get IsInline(): boolean { return this.Size === 'inline'; }\n\n @HostBinding('class.mj-empty-state--compact')\n get IsCompact(): boolean { return this.Size === 'compact'; }\n\n @HostBinding('class.mj-empty-state--large')\n get IsLarge(): boolean { return this.Size === 'large'; }\n\n @HostBinding('class.mj-empty-state--no-results')\n get IsNoResults(): boolean { return this.Variant === 'no-results'; }\n\n @HostBinding('class.mj-empty-state--success')\n get IsSuccess(): boolean { return this.Variant === 'success'; }\n\n @HostBinding('class.mj-empty-state--warning')\n get IsWarning(): boolean { return this.Variant === 'warning'; }\n\n @HostBinding('class.mj-empty-state--error')\n get IsError(): boolean { return this.Variant === 'error'; }\n\n /**\n * Live-region role applied to the host. Explicit `Role` wins (`''` ⇒ no role);\n * otherwise an error state is an assertive `alert`, everything else a polite `status`.\n */\n @HostBinding('attr.role')\n get HostRole(): string | null {\n if (this.Role != null) {\n return this.Role || null;\n }\n return this.Variant === 'error' ? 'alert' : 'status';\n }\n\n /**\n * Icon actually rendered: the explicit `Icon` when provided (including \"\"\n * to suppress the icon), otherwise the per-variant default.\n */\n get ResolvedIcon(): string {\n if (this.Icon != null) {\n return this.Icon;\n }\n return MJEmptyStateComponent.DefaultIconForVariant(this.Variant);\n }\n\n /** Default Font Awesome icon for each variant. */\n static DefaultIconForVariant(variant: MJEmptyStateVariant): string {\n switch (variant) {\n case 'no-results':\n return 'fa-solid fa-magnifying-glass';\n case 'success':\n return 'fa-solid fa-circle-check';\n case 'warning':\n case 'error':\n return 'fa-solid fa-triangle-exclamation';\n case 'empty':\n default:\n return 'fa-solid fa-inbox';\n }\n }\n\n OnAction(event: MouseEvent): void {\n this.Action.emit(event);\n }\n}\n"]}
@@ -41,4 +41,5 @@ export * from './lib/left-nav/left-nav-content.component';
41
41
  export * from './lib/page-header-interior/page-header-interior.component';
42
42
  export * from './lib/page-body-interior/page-body-interior.component';
43
43
  export * from './lib/empty-state/empty-state.component';
44
+ export * from './lib/card-grid/card-grid.component';
44
45
  //# sourceMappingURL=public-api.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"public-api.d.ts","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAGA,cAAc,+BAA+B,CAAC;AAC9C,cAAc,qCAAqC,CAAC;AACpD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+CAA+C,CAAC;AAC9D,cAAc,6CAA6C,CAAC;AAC5D,cAAc,mCAAmC,CAAC;AAClD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6CAA6C,CAAC;AAC5D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,+BAA+B,CAAC;AAC9C,cAAc,uCAAuC,CAAC;AACtD,cAAc,mCAAmC,CAAC;AAClD,cAAc,qCAAqC,CAAC;AACpD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,yCAAyC,CAAC;AACxD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,mCAAmC,CAAC;AAClD,cAAc,yCAAyC,CAAC;AACxD,cAAc,yCAAyC,CAAC;AACxD,cAAc,qCAAqC,CAAC;AACpD,cAAc,uCAAuC,CAAC;AACtD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,+CAA+C,CAAC;AAC9D,cAAc,yCAAyC,CAAC;AACxD,cAAc,yCAAyC,CAAC;AACxD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,iCAAiC,CAAC;AAChD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,2CAA2C,CAAC;AAC1D,cAAc,0CAA0C,CAAC;AACzD,cAAc,oDAAoD,CAAC;AACnE,cAAc,+CAA+C,CAAC;AAC9D,cAAc,8CAA8C,CAAC;AAC7D,cAAc,yCAAyC,CAAC;AACxD,cAAc,mCAAmC,CAAC;AAClD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,2DAA2D,CAAC;AAC1E,cAAc,uDAAuD,CAAC;AACtE,cAAc,yCAAyC,CAAC"}
1
+ {"version":3,"file":"public-api.d.ts","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAGA,cAAc,+BAA+B,CAAC;AAC9C,cAAc,qCAAqC,CAAC;AACpD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+CAA+C,CAAC;AAC9D,cAAc,6CAA6C,CAAC;AAC5D,cAAc,mCAAmC,CAAC;AAClD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6CAA6C,CAAC;AAC5D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,+BAA+B,CAAC;AAC9C,cAAc,uCAAuC,CAAC;AACtD,cAAc,mCAAmC,CAAC;AAClD,cAAc,qCAAqC,CAAC;AACpD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,yCAAyC,CAAC;AACxD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,mCAAmC,CAAC;AAClD,cAAc,yCAAyC,CAAC;AACxD,cAAc,yCAAyC,CAAC;AACxD,cAAc,qCAAqC,CAAC;AACpD,cAAc,uCAAuC,CAAC;AACtD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,+CAA+C,CAAC;AAC9D,cAAc,yCAAyC,CAAC;AACxD,cAAc,yCAAyC,CAAC;AACxD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,iCAAiC,CAAC;AAChD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,2CAA2C,CAAC;AAC1D,cAAc,0CAA0C,CAAC;AACzD,cAAc,oDAAoD,CAAC;AACnE,cAAc,+CAA+C,CAAC;AAC9D,cAAc,8CAA8C,CAAC;AAC7D,cAAc,yCAAyC,CAAC;AACxD,cAAc,mCAAmC,CAAC;AAClD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,2DAA2D,CAAC;AAC1E,cAAc,uDAAuD,CAAC;AACtE,cAAc,yCAAyC,CAAC;AACxD,cAAc,qCAAqC,CAAC"}
@@ -43,4 +43,5 @@ export * from './lib/left-nav/left-nav-content.component';
43
43
  export * from './lib/page-header-interior/page-header-interior.component';
44
44
  export * from './lib/page-body-interior/page-body-interior.component';
45
45
  export * from './lib/empty-state/empty-state.component';
46
+ export * from './lib/card-grid/card-grid.component';
46
47
  //# sourceMappingURL=public-api.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"public-api.js","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,+DAA+D;AAE/D,cAAc,+BAA+B,CAAC;AAC9C,cAAc,qCAAqC,CAAC;AACpD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+CAA+C,CAAC;AAC9D,cAAc,6CAA6C,CAAC;AAC5D,cAAc,mCAAmC,CAAC;AAClD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6CAA6C,CAAC;AAC5D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,+BAA+B,CAAC;AAC9C,cAAc,uCAAuC,CAAC;AACtD,cAAc,mCAAmC,CAAC;AAClD,cAAc,qCAAqC,CAAC;AACpD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,yCAAyC,CAAC;AACxD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,mCAAmC,CAAC;AAClD,cAAc,yCAAyC,CAAC;AACxD,cAAc,yCAAyC,CAAC;AACxD,cAAc,qCAAqC,CAAC;AACpD,cAAc,uCAAuC,CAAC;AACtD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,+CAA+C,CAAC;AAC9D,cAAc,yCAAyC,CAAC;AACxD,cAAc,yCAAyC,CAAC;AACxD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,iCAAiC,CAAC;AAChD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,2CAA2C,CAAC;AAC1D,cAAc,0CAA0C,CAAC;AACzD,cAAc,oDAAoD,CAAC;AACnE,cAAc,+CAA+C,CAAC;AAC9D,cAAc,8CAA8C,CAAC;AAC7D,cAAc,yCAAyC,CAAC;AACxD,cAAc,mCAAmC,CAAC;AAClD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,2DAA2D,CAAC;AAC1E,cAAc,uDAAuD,CAAC;AACtE,cAAc,yCAAyC,CAAC","sourcesContent":["// @memberjunction/ng-ui-components\n// Reusable standalone Angular UI components for MemberJunction\n\nexport * from './lib/button/button.directive';\nexport * from './lib/clickable/clickable.directive';\nexport * from './lib/dialog/dialog.component';\nexport * from './lib/dialog/dialog.service';\nexport * from './lib/confirm-dialog/confirm-dialog.component';\nexport * from './lib/confirm-dialog/confirm-dialog.service';\nexport * from './lib/dropdown/dropdown.component';\nexport * from './lib/switch/switch.component';\nexport * from './lib/numeric-input/numeric-input.component';\nexport * from './lib/progress-bar/progress-bar.component';\nexport * from './lib/calendar/calendar-utils';\nexport * from './lib/datepicker/datepicker.component';\nexport * from './lib/splitter/splitter.component';\nexport * from './lib/accordion/accordion.component';\nexport * from './lib/alert/alert.component';\nexport * from './lib/window/window.component';\nexport * from './lib/slide-panel/slide-panel.component';\nexport * from './lib/bottom-sheet/bottom-sheet.component';\nexport * from './lib/combobox/combobox.component';\nexport * from './lib/page-header/page-header.component';\nexport * from './lib/page-layout/page-layout.component';\nexport * from './lib/page-body/page-body.component';\nexport * from './lib/stat-badge/stat-badge.component';\nexport * from './lib/refresh-button/refresh-button.component';\nexport * from './lib/filter-popover/filter-popover.component';\nexport * from './lib/page-search/page-search.component';\nexport * from './lib/filter-chip/filter-chip.component';\nexport * from './lib/filter-field/filter-field.component';\nexport * from './lib/filter-panel/filter-panel.component';\nexport * from './lib/tab-nav/tab-nav.component';\nexport * from './lib/tabs/tab-list.directive';\nexport * from './lib/tabs/tab-chrome-guard';\nexport * from './lib/workspace-tabs/workspace-tabs.types';\nexport * from './lib/workspace-tabs/workspace-tab-store';\nexport * from './lib/workspace-tabs/workspace-tab-strip.component';\nexport * from './lib/workspace-tabs/workspace-card.component';\nexport * from './lib/workspace-tabs/workspace-tip.directive';\nexport * from './lib/view-toggle/view-toggle.component';\nexport * from './lib/left-nav/left-nav.component';\nexport * from './lib/left-nav/left-nav-content.component';\nexport * from './lib/page-header-interior/page-header-interior.component';\nexport * from './lib/page-body-interior/page-body-interior.component';\nexport * from './lib/empty-state/empty-state.component';\n"]}
1
+ {"version":3,"file":"public-api.js","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,+DAA+D;AAE/D,cAAc,+BAA+B,CAAC;AAC9C,cAAc,qCAAqC,CAAC;AACpD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+CAA+C,CAAC;AAC9D,cAAc,6CAA6C,CAAC;AAC5D,cAAc,mCAAmC,CAAC;AAClD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6CAA6C,CAAC;AAC5D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,+BAA+B,CAAC;AAC9C,cAAc,uCAAuC,CAAC;AACtD,cAAc,mCAAmC,CAAC;AAClD,cAAc,qCAAqC,CAAC;AACpD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,yCAAyC,CAAC;AACxD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,mCAAmC,CAAC;AAClD,cAAc,yCAAyC,CAAC;AACxD,cAAc,yCAAyC,CAAC;AACxD,cAAc,qCAAqC,CAAC;AACpD,cAAc,uCAAuC,CAAC;AACtD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,+CAA+C,CAAC;AAC9D,cAAc,yCAAyC,CAAC;AACxD,cAAc,yCAAyC,CAAC;AACxD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,iCAAiC,CAAC;AAChD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,2CAA2C,CAAC;AAC1D,cAAc,0CAA0C,CAAC;AACzD,cAAc,oDAAoD,CAAC;AACnE,cAAc,+CAA+C,CAAC;AAC9D,cAAc,8CAA8C,CAAC;AAC7D,cAAc,yCAAyC,CAAC;AACxD,cAAc,mCAAmC,CAAC;AAClD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,2DAA2D,CAAC;AAC1E,cAAc,uDAAuD,CAAC;AACtE,cAAc,yCAAyC,CAAC;AACxD,cAAc,qCAAqC,CAAC","sourcesContent":["// @memberjunction/ng-ui-components\n// Reusable standalone Angular UI components for MemberJunction\n\nexport * from './lib/button/button.directive';\nexport * from './lib/clickable/clickable.directive';\nexport * from './lib/dialog/dialog.component';\nexport * from './lib/dialog/dialog.service';\nexport * from './lib/confirm-dialog/confirm-dialog.component';\nexport * from './lib/confirm-dialog/confirm-dialog.service';\nexport * from './lib/dropdown/dropdown.component';\nexport * from './lib/switch/switch.component';\nexport * from './lib/numeric-input/numeric-input.component';\nexport * from './lib/progress-bar/progress-bar.component';\nexport * from './lib/calendar/calendar-utils';\nexport * from './lib/datepicker/datepicker.component';\nexport * from './lib/splitter/splitter.component';\nexport * from './lib/accordion/accordion.component';\nexport * from './lib/alert/alert.component';\nexport * from './lib/window/window.component';\nexport * from './lib/slide-panel/slide-panel.component';\nexport * from './lib/bottom-sheet/bottom-sheet.component';\nexport * from './lib/combobox/combobox.component';\nexport * from './lib/page-header/page-header.component';\nexport * from './lib/page-layout/page-layout.component';\nexport * from './lib/page-body/page-body.component';\nexport * from './lib/stat-badge/stat-badge.component';\nexport * from './lib/refresh-button/refresh-button.component';\nexport * from './lib/filter-popover/filter-popover.component';\nexport * from './lib/page-search/page-search.component';\nexport * from './lib/filter-chip/filter-chip.component';\nexport * from './lib/filter-field/filter-field.component';\nexport * from './lib/filter-panel/filter-panel.component';\nexport * from './lib/tab-nav/tab-nav.component';\nexport * from './lib/tabs/tab-list.directive';\nexport * from './lib/tabs/tab-chrome-guard';\nexport * from './lib/workspace-tabs/workspace-tabs.types';\nexport * from './lib/workspace-tabs/workspace-tab-store';\nexport * from './lib/workspace-tabs/workspace-tab-strip.component';\nexport * from './lib/workspace-tabs/workspace-card.component';\nexport * from './lib/workspace-tabs/workspace-tip.directive';\nexport * from './lib/view-toggle/view-toggle.component';\nexport * from './lib/left-nav/left-nav.component';\nexport * from './lib/left-nav/left-nav-content.component';\nexport * from './lib/page-header-interior/page-header-interior.component';\nexport * from './lib/page-body-interior/page-body-interior.component';\nexport * from './lib/empty-state/empty-state.component';\nexport * from './lib/card-grid/card-grid.component';\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/ng-ui-components",
3
- "version": "6.1.0-edge.2",
3
+ "version": "6.1.0-edge.3",
4
4
  "description": "MemberJunction: Angular UI Components - reusable standalone components replacing Kendo UI dependencies.",
5
5
  "main": "./dist/public-api.js",
6
6
  "typings": "./dist/public-api.d.ts",
@@ -12,11 +12,11 @@
12
12
  "Angular"
13
13
  ],
14
14
  "author": "",
15
- "license": "ISC",
15
+ "license": "BUSL-1.1",
16
16
  "devDependencies": {
17
17
  "@angular/compiler": "21.1.3",
18
18
  "@angular/compiler-cli": "21.1.3",
19
- "@memberjunction/ng-test-utils": "6.1.0-edge.2",
19
+ "@memberjunction/ng-test-utils": "6.1.0-edge.3",
20
20
  "vitest": "^4.0.18"
21
21
  },
22
22
  "peerDependencies": {
@@ -40,7 +40,7 @@
40
40
  "test": "vitest run",
41
41
  "test:types": "tsc --noEmit -p tsconfig.spec.json",
42
42
  "build": "npm run clean && ngc && npm run copy-assets",
43
- "copy-assets": "cpy src/lib/button/button.scss dist/lib/button --flat && cpy src/lib/dialog/dialog.scss dist/lib/dialog --flat && cpy src/lib/dropdown/dropdown.scss dist/lib/dropdown --flat && cpy src/lib/combobox/combobox.scss dist/lib/combobox --flat && cpy src/lib/input/input.scss dist/lib/input --flat && cpy src/lib/input/input-switch-progress.scss dist/lib/input --flat && cpy src/lib/datepicker/datepicker.scss dist/lib/datepicker --flat && cpy src/lib/splitter/splitter.scss dist/lib/splitter --flat && cpy src/lib/accordion/accordion.scss dist/lib/accordion --flat && cpy src/lib/window/window.scss dist/lib/window --flat && cpy src/lib/input/chip.scss dist/lib/input --flat && cpy src/lib/tabs/tabs.scss dist/lib/tabs --flat",
43
+ "copy-assets": "cpy src/lib/button/button.scss dist/lib/button --flat && cpy src/lib/dialog/dialog.scss dist/lib/dialog --flat && cpy src/lib/dropdown/dropdown.scss dist/lib/dropdown --flat && cpy src/lib/combobox/combobox.scss dist/lib/combobox --flat && cpy src/lib/input/input.scss dist/lib/input --flat && cpy src/lib/input/input-switch-progress.scss dist/lib/input --flat && cpy src/lib/datepicker/datepicker.scss dist/lib/datepicker --flat && cpy src/lib/splitter/splitter.scss dist/lib/splitter --flat && cpy src/lib/accordion/accordion.scss dist/lib/accordion --flat && cpy src/lib/window/window.scss dist/lib/window --flat && cpy src/lib/input/chip.scss dist/lib/input --flat && cpy src/lib/tabs/tabs.scss dist/lib/tabs --flat && cpy src/lib/card-grid/card-grid.scss dist/lib/card-grid --flat",
44
44
  "clean": "rimraf dist",
45
45
  "test:watch": "vitest"
46
46
  }