Skip to content

Commit

Permalink
add feature request button and change button to directive
Browse files Browse the repository at this point in the history
  • Loading branch information
FelixTJDietrich committed Sep 17, 2024
1 parent b935459 commit 094e54d
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 40 deletions.
4 changes: 2 additions & 2 deletions webapp/src/app/about/about.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
15 changes: 13 additions & 2 deletions webapp/src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,22 @@
<angular-query-devtools />
}
<div class="flex flex-col min-h-dvh">
<header class="container flex items-center justify-between pt-4">
<a class="flex gap-2 items-center hover:text-muted-foreground" routerLink="/">
<header class="container flex items-center justify-between pt-4 gap-2">
<a class="flex gap-2 items-center hover:text-muted-foreground flex-1" routerLink="/">
<lucide-angular [img]="Hammer" class="size-6" />
<span class="text-xl font-semibold">Hephaestus</span>
</a>
<a
appButton
data-canny-link
href="https://hephaestus.canny.io/feature-requests"
class="border-github-upsell-foreground text-github-upsell-foreground hover:text-github-upsell-foreground hover:bg-purple-400/30 flex gap-2"
variant="outline"
size="sm"
>
<lucide-angular [img]="Sparkles" class="size-4" />
Request a feature
</a>
<app-theme-switcher />
</header>
<main class="container flex-grow pt-4 pb-8">
Expand Down
6 changes: 4 additions & 2 deletions webapp/src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -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';

Expand Down
4 changes: 2 additions & 2 deletions webapp/src/app/core/theme/theme-switcher.component.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<app-button (click)="toggleTheme()" variant="outline" size="icon">
<button appButton (click)="toggleTheme()" variant="outline" size="icon">
<div [@iconTrigger]="this.themeSwitcherService.currentTheme() ?? 'dark'">
<lucide-angular [img]="this.themeSwitcherService.currentTheme() === 'dark' ? Sun : Moon" class="size-5" />
</div>
</app-button>
</button>
4 changes: 2 additions & 2 deletions webapp/src/app/core/theme/theme-switcher.component.ts
Original file line number Diff line number Diff line change
@@ -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', [
Expand Down
15 changes: 7 additions & 8 deletions webapp/src/app/ui/button/button.component.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -34,18 +34,17 @@ export { args, argTypes };

interface ButtonVariants extends VariantProps<typeof buttonVariants> {}

@Component({
selector: 'app-button',
@Directive({
selector: '[appButton]',
standalone: true,
templateUrl: './button.component.html'
host: {
'[class]': 'computedClass()'
}
})
export class ButtonComponent {
export class ButtonDirective {
class = input<ClassValue>('');
variant = input<ButtonVariants['variant']>('default');
size = input<ButtonVariants['size']>('default');
disabled = input<boolean>(false);

onClick = output<Event>();

computedClass = computed(() => cn(buttonVariants({ variant: this.variant(), size: this.size() }), this.class()));
}
38 changes: 19 additions & 19 deletions webapp/src/app/ui/button/button.stories.ts
Original file line number Diff line number Diff line change
@@ -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<ButtonComponent> = {
const meta: Meta<CustomArgs> = {
title: 'UI/Button',
component: ButtonComponent,
component: ButtonDirective,
tags: ['autodocs'],
args: {
...args,
Expand All @@ -25,18 +30,13 @@ const meta: Meta<ButtonComponent> = {
};

export default meta;
type Story = StoryObj<ButtonComponent>;
type Story = StoryObj<ButtonDirective>;

// 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: `<app-button ${argsToTemplate(args)}>Primary</app-button>`
template: `<button appButton ${argsToTemplate(args)}>Primary</button>`
})
};

Expand All @@ -48,7 +48,7 @@ export const Secondary: Story = {

render: (args) => ({
props: args,
template: `<app-button ${argsToTemplate(args)}>Secondary</app-button>`
template: `<button appButton ${argsToTemplate(args)}>Secondary</button>`
})
};

Expand All @@ -60,7 +60,7 @@ export const Destructive: Story = {

render: (args) => ({
props: args,
template: `<app-button ${argsToTemplate(args)}>Destructive</app-button>`
template: `<button appButton ${argsToTemplate(args)}>Destructive</button>`
})
};

Expand All @@ -72,7 +72,7 @@ export const Outline: Story = {

render: (args) => ({
props: args,
template: `<app-button ${argsToTemplate(args)}>Outline</app-button>`
template: `<button appButton ${argsToTemplate(args)}>Outline</button>`
})
};

Expand All @@ -84,7 +84,7 @@ export const Ghost: Story = {

render: (args) => ({
props: args,
template: `<app-button ${argsToTemplate(args)}>Ghost</app-button>`
template: `<button appButton ${argsToTemplate(args)}>Ghost</button>`
})
};

Expand All @@ -96,7 +96,7 @@ export const Link: Story = {

render: (args) => ({
props: args,
template: `<app-button ${argsToTemplate(args)}>Link</app-button>`
template: `<button appButton ${argsToTemplate(args)}>Link</button>`
})
};

Expand All @@ -111,7 +111,7 @@ export const Icon: Story = {
variant: 'outline',
size: 'icon'
},
template: `<app-button ${argsToTemplate(args)}><lucide-icon name="chevron-right" class="size-4"/></app-button>`
template: `<button appButton ${argsToTemplate(args)}><lucide-icon name="chevron-right" class="size-4"/></button>`
})
};

Expand All @@ -126,7 +126,7 @@ export const WithIcon: Story = {
variant: 'default',
size: 'default'
},
template: `<app-button ${argsToTemplate(args)}><lucide-icon name="mail" class="mr-2 size-4"/>Login with Email</app-button>`
template: `<button appButton ${argsToTemplate(args)}><lucide-icon name="mail" class="mr-2 size-4"/>Login with Email</button>`
})
};

Expand All @@ -142,6 +142,6 @@ export const Loading: Story = {
size: 'default',
disabled: true
},
template: `<app-button ${argsToTemplate(args)}><lucide-icon name="loader-2" class="mr-2 size-4 animate-spin"/>Please wait</app-button>`
template: `<button appButton ${argsToTemplate(args)}><lucide-icon name="loader-2" class="mr-2 size-4 animate-spin"/>Please wait</button>`
})
};
6 changes: 3 additions & 3 deletions webapp/src/app/ui/input/input.stories.ts
Original file line number Diff line number Diff line change
@@ -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';

Expand All @@ -25,7 +25,7 @@ const meta: Meta<InputComponent> = {
},
decorators: [
moduleMetadata({
imports: [ButtonComponent, LabelComponent]
imports: [ButtonDirective, LabelComponent]
})
]
};
Expand Down Expand Up @@ -74,7 +74,7 @@ export const WithButton: Story = {
template: `
<div class="flex gap-2 flex-row">
<app-input ${argsToTemplate(args)} [size]="args.size" [(value)]="userInput" placeholder="Enter text here" class="grow"/>
<app-button (onClick)="onButtonClick(userInput)" size="${args.size ?? 'default'}" [disabled]="!userInput">Submit</app-button>
<button appButton (onClick)="onButtonClick(userInput)" size="${args.size ?? 'default'}" [disabled]="!userInput">Submit</button>
</div>
`
})
Expand Down

0 comments on commit 094e54d

Please sign in to comment.