Skip to content

Commit be518d4

Browse files
authored
Merge pull request #1 from luminacn/luminacn-v1.3
Luminacn v1.3
2 parents b87a02a + fc39f7e commit be518d4

80 files changed

Lines changed: 1463 additions & 731 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { Directive, input, computed, output, signal } from '@angular/core';
2+
import { cn } from '../../../lib/cn';
3+
import { alertVariants } from './alert.variants';
4+
import { LuminaAlertVariant } from './alert.types';
5+
6+
@Directive({
7+
selector: '[lmAlert]',
8+
standalone: true,
9+
exportAs: 'lmAlert',
10+
host: {
11+
'[class]': 'computedClass()',
12+
'[class.hidden]': 'closed()',
13+
role: 'alert',
14+
},
15+
})
16+
export class LuminaAlertDirective {
17+
// Shorthand: <div lmAlert="destructive">
18+
variant = input<LuminaAlertVariant, LuminaAlertVariant | ''>('default', {
19+
alias: 'lmAlert',
20+
transform: (v) => (v === '' ? 'default' : v),
21+
});
22+
protected closed = signal(false);
23+
onClose = output<void>();
24+
25+
close() {
26+
this.closed.set(true);
27+
this.onClose.emit(); // Notify the parent
28+
}
29+
30+
userClass = input('', { alias: 'class' });
31+
32+
computedClass = computed(() =>
33+
cn(alertVariants({ variant: this.variant() as LuminaAlertVariant }), this.userClass()),
34+
);
35+
}
36+
37+
@Directive({
38+
selector: '[lmAlertTitle]',
39+
standalone: true,
40+
host: {
41+
'[class]': 'computedClass()',
42+
},
43+
})
44+
export class LuminaAlertTitleDirective {
45+
userClass = input('', { alias: 'class' });
46+
computedClass = computed(() =>
47+
cn('mb-1 font-medium leading-none tracking-tight', this.userClass()),
48+
);
49+
}
50+
51+
@Directive({
52+
selector: '[lmAlertDescription]',
53+
standalone: true,
54+
host: {
55+
'[class]': 'computedClass()',
56+
},
57+
})
58+
export class LuminaAlertDescriptionDirective {
59+
userClass = input('', { alias: 'class' });
60+
computedClass = computed(() => cn('text-sm [&_p]:leading-relaxed', this.userClass()));
61+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export type LuminaAlertVariant = 'default' | 'destructive' | 'success' | 'warning';
2+
3+
export interface LuminaAlertProps {
4+
variant?: LuminaAlertVariant;
5+
class?: string;
6+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { cva } from '../../../lib/cva';
2+
import { LuminaAlertVariant } from './alert.types';
3+
4+
export const alertVariants = cva(
5+
'relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4',
6+
{
7+
variants: {
8+
variant: {
9+
default: 'bg-background text-foreground [&>svg]:text-foreground',
10+
destructive:
11+
'border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive',
12+
success:
13+
'border-emerald-500/50 text-emerald-600 dark:text-emerald-400 [&>svg]:text-emerald-600 dark:[&>svg]:text-emerald-400',
14+
warning:
15+
'border-amber-500/50 text-amber-600 dark:text-amber-400 [&>svg]:text-amber-600 dark:[&>svg]:text-amber-400',
16+
} as Record<LuminaAlertVariant, string>,
17+
},
18+
defaultVariants: {
19+
variant: 'default',
20+
},
21+
},
22+
);
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"name": "alert",
3+
"destination": "ui/alert",
4+
"primaryExport": "LuminaAlertDirective",
5+
"files": [
6+
"alert.variants.ts.template",
7+
"alert.types.ts.template",
8+
"alert.directive.ts.template"
9+
]
10+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { Component, input, computed } from '@angular/core';
2+
import { cn } from '../../../lib/cn';
3+
import { avatarVariants } from './avatar.variants';
4+
import { LmAvatarSize, LmAvatarShape } from './avatar.types';
5+
6+
@Component({
7+
selector: 'lm-avatar',
8+
standalone: true,
9+
template: `<ng-content />`,
10+
host: {
11+
'[class]': 'computedClass()',
12+
},
13+
})
14+
export class LuminaAvatarComponent {
15+
size = input<LmAvatarSize>('md');
16+
shape = input<LmAvatarShape>('circle');
17+
userClass = input('', { alias: 'class' });
18+
19+
computedClass = computed(() =>
20+
cn(
21+
avatarVariants({
22+
size: this.size(),
23+
shape: this.shape(),
24+
}),
25+
this.userClass(),
26+
),
27+
);
28+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { Directive, input, signal, computed } from '@angular/core';
2+
import { cn } from '../../../lib/cn';
3+
4+
@Directive({
5+
selector: 'img[lmAvatarImage]',
6+
standalone: true,
7+
host: {
8+
'[class]': 'classes()',
9+
'(error)': 'onError()',
10+
},
11+
})
12+
export class LuminaAvatarImageDirective {
13+
// If the image fails, we hide it so the fallback behind it shows up
14+
hasError = signal(false);
15+
16+
classes = computed(() =>
17+
cn('aspect-square h-full w-full object-cover', this.hasError() ? 'hidden' : 'block'),
18+
);
19+
20+
onError() {
21+
this.hasError.set(true);
22+
}
23+
}
24+
25+
@Directive({
26+
selector: '[lmAvatarFallback]',
27+
standalone: true,
28+
host: {
29+
'[class]': 'classes()',
30+
},
31+
})
32+
export class LuminaAvatarFallbackDirective {
33+
userClass = input('', { alias: 'class' });
34+
35+
classes = computed(() =>
36+
cn(
37+
'flex h-full w-full items-center justify-center rounded-full bg-muted text-sm font-medium',
38+
this.userClass(),
39+
),
40+
);
41+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"name": "avatar",
3+
"destination": "ui/avatar",
4+
"primaryExport": "LuminaAvatarComponent",
5+
"files": [
6+
"avatar.component.ts.template",
7+
"avatar.variants.ts.template",
8+
"avatar.types.ts.template",
9+
"avatar.directive.ts.template"
10+
]
11+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export type LmAvatarSize = 'sm' | 'md' | 'lg' | 'xl';
2+
export type LmAvatarShape = 'circle' | 'square' | 'rounded';
3+
4+
export interface LmAvatarProps {
5+
size?: LmAvatarSize;
6+
shape?: LmAvatarShape;
7+
class?: string;
8+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { cva } from '../../../lib/cva';
2+
3+
export const avatarVariants = cva('relative flex shrink-0 overflow-hidden rounded-full', {
4+
variants: {
5+
size: {
6+
sm: 'h-8 w-8',
7+
md: 'h-10 w-10', // Default
8+
lg: 'h-12 w-12',
9+
xl: 'h-16 w-16',
10+
},
11+
shape: {
12+
circle: 'rounded-full',
13+
square: 'rounded-none',
14+
rounded: 'rounded-md',
15+
},
16+
},
17+
defaultVariants: {
18+
size: 'md',
19+
shape: 'circle',
20+
},
21+
});

src/packages/registry/badge/badge.component.ts.template

Lines changed: 0 additions & 27 deletions
This file was deleted.

0 commit comments

Comments
 (0)