diff --git a/webapp/src/app/about/about.component.ts b/webapp/src/app/about/about.component.ts
index 34a3de53..98934696 100644
--- a/webapp/src/app/about/about.component.ts
+++ b/webapp/src/app/about/about.component.ts
@@ -5,13 +5,13 @@ import { lastValueFrom } from 'rxjs';
import { AvatarComponent } from 'app/ui/avatar/avatar.component';
import { AvatarImageComponent } from 'app/ui/avatar/avatar-image.component';
import { AvatarFallbackComponent } from 'app/ui/avatar/avatar-fallback.component';
-import { ButtonComponent } from 'app/ui/button/button.component';
+import { ButtonDirective } from 'app/ui/button/button.component';
import { GitHub } from 'app/@types/github';
@Component({
selector: 'app-about',
standalone: true,
- imports: [AvatarComponent, AvatarImageComponent, AvatarFallbackComponent, ButtonComponent],
+ imports: [AvatarComponent, AvatarImageComponent, AvatarFallbackComponent, ButtonDirective],
templateUrl: './about.component.html'
})
export class AboutComponent {
diff --git a/webapp/src/app/app.component.html b/webapp/src/app/app.component.html
index d71dcc41..a8d62862 100644
--- a/webapp/src/app/app.component.html
+++ b/webapp/src/app/app.component.html
@@ -2,11 +2,22 @@
}
-
-
+
diff --git a/webapp/src/app/app.component.ts b/webapp/src/app/app.component.ts
index eb7377c8..92d460f0 100644
--- a/webapp/src/app/app.component.ts
+++ b/webapp/src/app/app.component.ts
@@ -1,18 +1,20 @@
import { Component, isDevMode } from '@angular/core';
import { AngularQueryDevtools } from '@tanstack/angular-query-devtools-experimental';
import { RouterLink, RouterLinkActive, RouterOutlet } from '@angular/router';
-import { LucideAngularModule, Hammer } from 'lucide-angular';
+import { LucideAngularModule, Hammer, Sparkles } from 'lucide-angular';
import { ThemeSwitcherComponent } from 'app/core/theme/theme-switcher.component';
+import { ButtonDirective } from './ui/button/button.component';
@Component({
selector: 'app-root',
standalone: true,
- imports: [RouterOutlet, LucideAngularModule, ThemeSwitcherComponent, RouterLink, RouterLinkActive, AngularQueryDevtools],
+ imports: [RouterOutlet, LucideAngularModule, ThemeSwitcherComponent, RouterLink, RouterLinkActive, AngularQueryDevtools, ButtonDirective],
templateUrl: './app.component.html',
styles: []
})
export class AppComponent {
protected Hammer = Hammer;
+ protected Sparkles = Sparkles;
title = 'Hephaestus';
diff --git a/webapp/src/app/core/theme/theme-switcher.component.html b/webapp/src/app/core/theme/theme-switcher.component.html
index 95c8ccb0..4689d435 100644
--- a/webapp/src/app/core/theme/theme-switcher.component.html
+++ b/webapp/src/app/core/theme/theme-switcher.component.html
@@ -1,5 +1,5 @@
-
+
+
diff --git a/webapp/src/app/core/theme/theme-switcher.component.ts b/webapp/src/app/core/theme/theme-switcher.component.ts
index fc7722fc..0723a77c 100644
--- a/webapp/src/app/core/theme/theme-switcher.component.ts
+++ b/webapp/src/app/core/theme/theme-switcher.component.ts
@@ -1,13 +1,13 @@
import { Component, inject } from '@angular/core';
import { LucideAngularModule, Sun, Moon } from 'lucide-angular';
-import { ButtonComponent } from 'app/ui/button/button.component';
+import { ButtonDirective } from 'app/ui/button/button.component';
import { AppTheme, ThemeSwitcherService } from './theme-switcher.service';
import { animate, state, style, transition, trigger } from '@angular/animations';
@Component({
selector: 'app-theme-switcher',
standalone: true,
- imports: [ButtonComponent, LucideAngularModule],
+ imports: [ButtonDirective, LucideAngularModule],
templateUrl: './theme-switcher.component.html',
animations: [
trigger('iconTrigger', [
diff --git a/webapp/src/app/ui/button/button.component.ts b/webapp/src/app/ui/button/button.component.ts
index 49fe0a90..17354582 100644
--- a/webapp/src/app/ui/button/button.component.ts
+++ b/webapp/src/app/ui/button/button.component.ts
@@ -1,4 +1,4 @@
-import { Component, computed, input, output } from '@angular/core';
+import { Directive, computed, input } from '@angular/core';
import type { ClassValue } from 'clsx';
import { VariantProps } from 'class-variance-authority';
import { cn } from 'app/utils';
@@ -34,18 +34,17 @@ export { args, argTypes };
interface ButtonVariants extends VariantProps {}
-@Component({
- selector: 'app-button',
+@Directive({
+ selector: '[appButton]',
standalone: true,
- templateUrl: './button.component.html'
+ host: {
+ '[class]': 'computedClass()'
+ }
})
-export class ButtonComponent {
+export class ButtonDirective {
class = input('');
variant = input('default');
size = input('default');
- disabled = input(false);
-
- onClick = output();
computedClass = computed(() => cn(buttonVariants({ variant: this.variant(), size: this.size() }), this.class()));
}
diff --git a/webapp/src/app/ui/button/button.stories.ts b/webapp/src/app/ui/button/button.stories.ts
index afa30147..7ce63177 100644
--- a/webapp/src/app/ui/button/button.stories.ts
+++ b/webapp/src/app/ui/button/button.stories.ts
@@ -1,12 +1,17 @@
import { argsToTemplate, moduleMetadata, type Meta, type StoryObj } from '@storybook/angular';
-import { ButtonComponent, args, argTypes } from './button.component';
+import { ButtonDirective, args, argTypes } from './button.component';
import { LucideAngularModule, ChevronRight, Mail, Loader2 } from 'lucide-angular';
-import { within, userEvent, expect, fn } from '@storybook/test';
+import { fn } from '@storybook/test';
+
+type CustomArgs = {
+ disabled: boolean;
+ onClick: () => void;
+};
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories
-const meta: Meta = {
+const meta: Meta = {
title: 'UI/Button',
- component: ButtonComponent,
+ component: ButtonDirective,
tags: ['autodocs'],
args: {
...args,
@@ -25,18 +30,13 @@ const meta: Meta = {
};
export default meta;
-type Story = StoryObj;
+type Story = StoryObj;
// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args
export const Primary: Story = {
- play: async ({ args, canvasElement }) => {
- const canvas = within(canvasElement);
- await userEvent.click(canvas.getByText('Primary'));
- await expect(args.onClick).toHaveBeenCalled();
- },
render: (args) => ({
props: args,
- template: `Primary`
+ template: ``
})
};
@@ -48,7 +48,7 @@ export const Secondary: Story = {
render: (args) => ({
props: args,
- template: `Secondary`
+ template: ``
})
};
@@ -60,7 +60,7 @@ export const Destructive: Story = {
render: (args) => ({
props: args,
- template: `Destructive`
+ template: ``
})
};
@@ -72,7 +72,7 @@ export const Outline: Story = {
render: (args) => ({
props: args,
- template: `Outline`
+ template: ``
})
};
@@ -84,7 +84,7 @@ export const Ghost: Story = {
render: (args) => ({
props: args,
- template: `Ghost`
+ template: ``
})
};
@@ -96,7 +96,7 @@ export const Link: Story = {
render: (args) => ({
props: args,
- template: `Link`
+ template: ``
})
};
@@ -111,7 +111,7 @@ export const Icon: Story = {
variant: 'outline',
size: 'icon'
},
- template: ``
+ template: ``
})
};
@@ -126,7 +126,7 @@ export const WithIcon: Story = {
variant: 'default',
size: 'default'
},
- template: `Login with Email`
+ template: ``
})
};
@@ -142,6 +142,6 @@ export const Loading: Story = {
size: 'default',
disabled: true
},
- template: `Please wait`
+ template: ``
})
};
diff --git a/webapp/src/app/ui/input/input.stories.ts b/webapp/src/app/ui/input/input.stories.ts
index 8e5dafd1..8bff6fa4 100644
--- a/webapp/src/app/ui/input/input.stories.ts
+++ b/webapp/src/app/ui/input/input.stories.ts
@@ -1,6 +1,6 @@
import { argsToTemplate, moduleMetadata, type Meta, type StoryObj } from '@storybook/angular';
import { action } from '@storybook/addon-actions';
-import { ButtonComponent } from '@app/ui/button/button.component';
+import { ButtonDirective } from '@app/ui/button/button.component';
import { LabelComponent } from '@app/ui/label/label.component';
import { InputComponent, args, argTypes } from './input.component';
@@ -25,7 +25,7 @@ const meta: Meta = {
},
decorators: [
moduleMetadata({
- imports: [ButtonComponent, LabelComponent]
+ imports: [ButtonDirective, LabelComponent]
})
]
};
@@ -74,7 +74,7 @@ export const WithButton: Story = {
template: `
`
})