Skip to content

Commit a913d84

Browse files
Mohammad JavedMohammad Javed
Mohammad Javed
authored and
Mohammad Javed
committed
core(improvement): Implemented tailwind variants slot to handle classes
1 parent 7044762 commit a913d84

File tree

9 files changed

+79
-154
lines changed

9 files changed

+79
-154
lines changed

projects/core/src/lib/accordion.ts

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,15 @@ import { computed, Directive, input } from '@angular/core';
22
import { NgpAccordion, NgpAccordionTrigger, NgpAccordionItem, NgpAccordionContent } from 'ng-primitives/accordion';
33
import { tv } from 'tailwind-variants';
44

5-
export const accordionItemVariants = tv({
6-
base: 'border-b border-border last:border-b-0'
5+
const accordionVariants = tv({
6+
slots: {
7+
itemVariant: 'border-b border-border last:border-b-0',
8+
triggerVariant: 'ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 flex flex-1 items-start justify-between gap-4 rounded-md py-4 text-left text-sm font-medium transition-all hover:underline focus-visible:ring-4 focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 [&[data-open]>[uiAccordionTriggerIcon]]:rotate-180',
9+
contentVariant: 'data-[closed]:animate-accordion-up data-[open]:animate-accordion-down overflow-hidden text-sm'
10+
}
711
});
812

9-
export const accordionTriggerVariants = tv({
10-
base: 'ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 flex flex-1 items-start justify-between gap-4 rounded-md py-4 text-left text-sm font-medium transition-all hover:underline focus-visible:ring-4 focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 [&[data-open]>[uiAccordionTriggerIcon]]:rotate-180'
11-
});
12-
13-
export const accordionContentVariants = tv({
14-
base: 'data-[closed]:animate-accordion-up data-[open]:animate-accordion-down overflow-hidden text-sm'
15-
});
13+
const { itemVariant, triggerVariant, contentVariant } = accordionVariants();
1614

1715
@Directive({
1816
selector: '[uiAccordion]',
@@ -45,10 +43,8 @@ export class UiAccordion {
4543
hostDirectives: [NgpAccordionTrigger]
4644
})
4745
export class UiAccordionTrigger {
48-
4946
inputClass = input<string>('', { alias: 'class' });
50-
51-
computedClass = computed(() => accordionTriggerVariants({ class: this.inputClass() }));
47+
computedClass = computed(() => triggerVariant({ class: this.inputClass() }));
5248

5349
}
5450

@@ -66,11 +62,8 @@ export class UiAccordionTrigger {
6662
],
6763
})
6864
export class UiAccordionItem {
69-
7065
inputClass = input<string>('', { alias: 'class' });
71-
72-
computedClass = computed(() => accordionItemVariants({ class: this.inputClass() }));
73-
66+
computedClass = computed(() => itemVariant({ class: this.inputClass() }));
7467
}
7568

7669

@@ -83,9 +76,6 @@ export class UiAccordionItem {
8376
hostDirectives: [NgpAccordionContent]
8477
})
8578
export class UiAccordionContent {
86-
8779
inputClass = input<string>('', { alias: 'class' });
88-
89-
computedClass = computed(() => accordionContentVariants({ class: this.inputClass() }));
90-
80+
computedClass = computed(() => contentVariant({ class: this.inputClass() }));
9181
}

projects/core/src/lib/alert.ts

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
import { computed, Directive, input } from '@angular/core';
22
import { tv, VariantProps } from 'tailwind-variants';
33

4-
export const alertVariants = tv({
5-
base: 'relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>[uiAlertIcon]]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>[uiAlertIcon]]:gap-x-3 gap-y-0.5 items-start [&>[uiAlertIcon]]:size-4 [&>[uiAlertIcon]]:translate-y-0.5 [&>[uiAlertIcon]]:text-current',
4+
const alertVariants = tv({
5+
slots: {
6+
base: 'relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>[uiAlertIcon]]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>[uiAlertIcon]]:gap-x-3 gap-y-0.5 items-start [&>[uiAlertIcon]]:size-4 [&>[uiAlertIcon]]:translate-y-0.5 [&>[uiAlertIcon]]:text-current',
7+
titleVariant: 'col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight',
8+
descriptionVariant: 'col-start-2 grid justify-items-start gap-1 text-sm [&_p]:leading-relaxed'
9+
},
610
variants: {
711
variant: {
812
default: "bg-background text-foreground border-border",
@@ -11,16 +15,10 @@ export const alertVariants = tv({
1115
},
1216
defaultVariants: {
1317
variant: 'default'
14-
},
15-
});
16-
17-
export const alertTitleVariants = tv({
18-
base: 'col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight'
18+
}
1919
});
2020

21-
export const alertDescriptionVariants = tv({
22-
base: 'col-start-2 grid justify-items-start gap-1 text-sm [&_p]:leading-relaxed'
23-
});
21+
const { base, titleVariant, descriptionVariant } = alertVariants();
2422

2523
type AlertVariants = VariantProps<typeof alertVariants>;
2624

@@ -31,13 +29,10 @@ type AlertVariants = VariantProps<typeof alertVariants>;
3129
'[class]': 'computedClass()'
3230
}
3331
})
34-
3532
export class UiAlert {
3633
inputClass = input<string>('', { alias: 'class' });
37-
3834
variant = input<AlertVariants['variant']>('default');
39-
40-
computedClass = computed(() => alertVariants({ variant: this.variant(), class: this.inputClass() }));
35+
computedClass = computed(() => base({ variant: this.variant(), class: this.inputClass() }));
4136
}
4237

4338
@Directive({
@@ -48,9 +43,8 @@ export class UiAlert {
4843
}
4944
})
5045
export class UiAlertTitle {
51-
5246
inputClass = input<string>('', { alias: 'class' });
53-
computedClass = computed(() => alertTitleVariants({ class: this.inputClass() }));
47+
computedClass = computed(() => titleVariant({ class: this.inputClass() }));
5448
}
5549

5650
@Directive({
@@ -61,7 +55,6 @@ export class UiAlertTitle {
6155
}
6256
})
6357
export class UiAlertDescription {
64-
6558
inputClass = input<string>('', { alias: 'class' });
66-
computedClass = computed(() => alertDescriptionVariants({ class: this.inputClass() }));
59+
computedClass = computed(() => descriptionVariant({ class: this.inputClass() }));
6760
}

projects/core/src/lib/avatar.ts

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,15 @@ import { computed, Directive, input, numberAttribute } from '@angular/core';
33
import { NgpAvatar, NgpAvatarFallback, NgpAvatarImage } from "ng-primitives/avatar";
44
import { tv } from "tailwind-variants";
55

6-
export const avatarVariants = tv({
7-
base: 'relative flex w-12 h-12 shrink-0 overflow-hidden rounded-full'
6+
const avatarVariants = tv({
7+
slots: {
8+
base: 'relative flex w-12 h-12 shrink-0 overflow-hidden rounded-full',
9+
imageVariant: 'aspect-square size-full',
10+
fallbackVariant: 'bg-muted flex size-full items-center justify-center rounded-full'
11+
}
812
});
913

10-
export const avatarImageVariants = tv({
11-
base: 'aspect-square size-full'
12-
});
13-
export const avatarFallbackVariants = tv({
14-
base: 'bg-muted flex size-full items-center justify-center rounded-full'
15-
});
14+
const { base, imageVariant, fallbackVariant } = avatarVariants();
1615

1716
@Directive({
1817
selector: '[uiAvatar]',
@@ -24,7 +23,7 @@ export const avatarFallbackVariants = tv({
2423
})
2524
export class UiAvatar {
2625
inputClass = input<string>('', { alias: 'class' });
27-
computedClass = computed(() => avatarVariants({ class: this.inputClass() }));
26+
computedClass = computed(() => base({ class: this.inputClass() }));
2827
}
2928

3029
@Directive({
@@ -37,7 +36,7 @@ export class UiAvatar {
3736
})
3837
export class UiAvatarImage {
3938
inputClass = input<string>('', { alias: 'class' });
40-
computedClass = computed(() => avatarImageVariants({ class: this.inputClass() }));
39+
computedClass = computed(() => imageVariant({ class: this.inputClass() }));
4140
}
4241

4342
@Directive({
@@ -53,7 +52,7 @@ export class UiAvatarImage {
5352
})
5453
export class UiAvatarFallback {
5554
inputClass = input<string>('', { alias: 'class' });
56-
computedClass = computed(() => avatarFallbackVariants({ class: this.inputClass() }));
55+
computedClass = computed(() => fallbackVariant({ class: this.inputClass() }));
5756
readonly delay = input<number, NumberInput>(0, {
5857
alias: 'uiAvatarFallbackDelay',
5958
transform: numberAttribute,

projects/core/src/lib/button.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { VariantProps } from 'tailwind-variants';
33
import { NgpButton } from "ng-primitives/button";
44
import { tv } from 'tailwind-variants';
55

6-
export const buttonVariants = tv({
6+
const buttonVariants = tv({
77
base: "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 data-[focus-visible]:ring-4 data-[focus-visible]:outline-1 aria-invalid:focus-visible:ring-0 cursor-pointer",
88
variants: {
99
variant: {

projects/core/src/lib/dialog.ts

Lines changed: 17 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,19 @@ import { computed, Directive, input } from "@angular/core";
22
import { tv } from "tailwind-variants";
33
import { NgpDialog, NgpDialogDescription, NgpDialogOverlay, NgpDialogTitle, NgpDialogTrigger } from "ng-primitives/dialog";
44

5-
const dialogOverlayVariants = tv({
6-
base: 'data-[enter]:animate-in data-[exit]:animate-out data-[exit]:fade-out-0 data-[enter]:fade-in-0 fixed inset-0 z-50 bg-black/50'
7-
});
8-
95
const dialogVariants = tv({
10-
base: 'bg-background data-[enter]:animate-in data-[exit]:animate-out data-[exit]:fade-out-0 data-[enter]:fade-in-0 data-[exit]:zoom-out-95 data-[enter]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border border-border p-6 shadow-lg sm:max-w-lg'
11-
});
12-
13-
const dialogHeaderVariants = tv({
14-
base: 'flex gap-2 justify-between items-center sm:text-left'
15-
});
16-
17-
const dialogFooterVariants = tv({
18-
base: 'flex flex-col-reverse gap-2 sm:flex-row sm:justify-end'
6+
slots: {
7+
base: 'bg-background data-[enter]:animate-in data-[exit]:animate-out data-[exit]:fade-out-0 data-[enter]:fade-in-0 data-[exit]:zoom-out-95 data-[enter]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border border-border p-6 shadow-lg sm:max-w-lg',
8+
overlayVariant: 'data-[enter]:animate-in data-[exit]:animate-out data-[exit]:fade-out-0 data-[enter]:fade-in-0 fixed inset-0 z-50 bg-black/50',
9+
headerVarinat: 'flex gap-2 justify-between items-center sm:text-left',
10+
footerVariant: 'flex flex-col-reverse gap-2 sm:flex-row sm:justify-end',
11+
titleVariant: 'text-lg leading-none font-semibold',
12+
descriptionVariant: 'text-muted-foreground text-sm',
13+
triggerVariant: ''
14+
}
1915
});
2016

21-
const dialogTitleVariants = tv({
22-
base: 'text-lg leading-none font-semibold'
23-
});
24-
25-
const dialogDescriptionVariants = tv({
26-
base: 'text-muted-foreground text-sm'
27-
});
28-
29-
const dialogPlainVariants = tv({
30-
base: ''
31-
})
17+
const { base, overlayVariant, headerVarinat, footerVariant, titleVariant, descriptionVariant, triggerVariant } = dialogVariants();
3218

3319
@Directive({
3420
selector: '[uiDialog]',
@@ -40,7 +26,7 @@ const dialogPlainVariants = tv({
4026
})
4127
export class UiDialog {
4228
inputClass = input<string>('', { alias: 'class' });
43-
computedClass = computed(() => dialogVariants({ class: this.inputClass() }));
29+
computedClass = computed(() => base({ class: this.inputClass() }));
4430
}
4531

4632
@Directive({
@@ -53,7 +39,7 @@ export class UiDialog {
5339
})
5440
export class UiDialogHeader {
5541
inputClass = input<string>('', { alias: 'class' });
56-
computedClass = computed(() => dialogHeaderVariants({ class: this.inputClass() }));
42+
computedClass = computed(() => headerVarinat({ class: this.inputClass() }));
5743
}
5844

5945
@Directive({
@@ -66,7 +52,7 @@ export class UiDialogHeader {
6652
})
6753
export class UiDialogTitle {
6854
inputClass = input<string>('', { alias: 'class' });
69-
computedClass = computed(() => dialogTitleVariants({ class: this.inputClass() }));
55+
computedClass = computed(() => titleVariant({ class: this.inputClass() }));
7056
}
7157

7258
@Directive({
@@ -79,7 +65,7 @@ export class UiDialogTitle {
7965
})
8066
export class UiDialogDescription {
8167
inputClass = input<string>('', { alias: 'class' });
82-
computedClass = computed(() => dialogDescriptionVariants({ class: this.inputClass() }));
68+
computedClass = computed(() => descriptionVariant({ class: this.inputClass() }));
8369
}
8470

8571
@Directive({
@@ -92,7 +78,7 @@ export class UiDialogDescription {
9278
})
9379
export class UiDialogFooter {
9480
inputClass = input<string>('', { alias: 'class' });
95-
computedClass = computed(() => dialogFooterVariants({ class: this.inputClass() }));
81+
computedClass = computed(() => footerVariant({ class: this.inputClass() }));
9682
}
9783

9884
@Directive({
@@ -105,7 +91,7 @@ export class UiDialogFooter {
10591
})
10692
export class UiDialogTrigger {
10793
inputClass = input<string>('', { alias: 'class' });
108-
computedClass = computed(() => dialogPlainVariants({ class: this.inputClass() }));
94+
computedClass = computed(() => triggerVariant({ class: this.inputClass() }));
10995
}
11096

11197
@Directive({
@@ -118,5 +104,5 @@ export class UiDialogTrigger {
118104
})
119105
export class UiDialogOverlay {
120106
inputClass = input<string>('', { alias: 'class' });
121-
computedClass = computed(() => dialogOverlayVariants({ class: this.inputClass() }));
107+
computedClass = computed(() => overlayVariant({ class: this.inputClass() }));
122108
}

0 commit comments

Comments
 (0)