-
Notifications
You must be signed in to change notification settings - Fork 3
feat: Add Button #23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Add Button #23
Changes from 2 commits
b513312
eda6b3c
c14365d
08ec3f2
6925708
84598a9
631c85b
cf50b59
9dd8a0e
51ec7d5
1a1c7ff
6c2b67b
7b94cc0
3ce3ab1
9866fdb
04f3b95
242f9b2
93ae545
ad0be97
ae8d8f6
cf1eaba
ec0a318
b91e46c
694d272
d6becfc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| <script setup lang="ts"> | ||
| import { computed } from "vue" | ||
| import type { ButtonProps } from "@/types/components/button.types" | ||
| import { ButtonColor, ButtonVariant } from "@/types/components/button.types" | ||
| import SmartLink from "./SmartLink.vue" | ||
|
|
||
| // Props | ||
| const props = withDefaults(defineProps<ButtonProps>(), { | ||
| variant: ButtonVariant.Primary, | ||
| color: ButtonColor.Default, | ||
| type: "button", | ||
| isDisabled: false, | ||
| isOutlined: false, | ||
| isGrey: false, | ||
| linkTarget: "", | ||
| isDownload: false, | ||
| }) | ||
|
|
||
| // Emits | ||
| const emit = defineEmits<{ | ||
| click: [event: MouseEvent] | ||
| }>() | ||
|
|
||
| // Computeds | ||
| const classes = computed(() => [ | ||
| "button", | ||
| props.variant, | ||
| props.color ? `color-${props.color}` : "", | ||
| { "is-outlined": props.isOutlined }, | ||
| { "is-disabled": props.isDisabled }, | ||
| ]) | ||
|
|
||
| // Methods | ||
| function handleClick(event: MouseEvent) { | ||
| if (!props.isDisabled) emit("click", event) | ||
| } | ||
| </script> | ||
|
|
||
| <template> | ||
| <SmartLink | ||
| v-if="to" | ||
| :class="classes" | ||
| :to="to" | ||
| :link-target="linkTarget" | ||
| :is-download="isDownload" | ||
| > | ||
| {{ text }} | ||
| </SmartLink> | ||
|
|
||
| <button | ||
| v-else | ||
| :class="classes" | ||
| :type="type" | ||
| :disabled="isDisabled" | ||
| @click="handleClick" | ||
| > | ||
| {{ text }} | ||
| </button> | ||
| </template> | ||
|
|
||
| <style lang="scss" scoped> | ||
| @import "../styles/default/_button.scss"; | ||
| </style> | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,149 @@ | ||||||
| import Button from "@/lib-components/Button.vue" | ||||||
| import { ButtonColor, ButtonVariant } from "@/types/components/button.types" | ||||||
|
|
||||||
| // Storybook default settings | ||||||
| export default { | ||||||
| title: "Funkhaus / Button", | ||||||
| component: Button, | ||||||
| argTypes: { | ||||||
| text: { control: "text" }, | ||||||
| to: { control: "text" }, | ||||||
| variant: { | ||||||
| control: "select", | ||||||
| options: ["primary", "secondary"], | ||||||
| }, | ||||||
| type: { | ||||||
| control: "select", | ||||||
| options: ["button", "submit", "reset"], | ||||||
| }, | ||||||
| isDisabled: { control: "boolean" }, | ||||||
| isOutlined: { control: "boolean" }, | ||||||
| linkTarget: { control: "text" }, | ||||||
| isDownload: { control: "boolean" }, | ||||||
| click: { action: "clicked" }, | ||||||
| }, | ||||||
| decorators: [ | ||||||
| () => ({ | ||||||
| template: "<story />", | ||||||
| }), | ||||||
| ], | ||||||
| } | ||||||
|
|
||||||
| function Template(args) { | ||||||
| return { | ||||||
| setup() { | ||||||
| return { args } | ||||||
| }, | ||||||
| components: { Button }, | ||||||
| template: '<Button v-bind="args" @click="args.click" />', | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| // Default stories | ||||||
| export const Primary = Template.bind({}) | ||||||
| Primary.args = { | ||||||
| text: "Primary Button", | ||||||
| onClick: () => { | ||||||
| alert("Primary Button Clicked!") | ||||||
| }, | ||||||
| } | ||||||
|
|
||||||
| export const PrimaryOutlined = Template.bind({}) | ||||||
| PrimaryOutlined.args = { | ||||||
| text: "Primary Outlined Button", | ||||||
| isOutlined: true, | ||||||
| onClick: () => { | ||||||
| alert("Primary Button Clicked!") | ||||||
| }, | ||||||
| } | ||||||
|
|
||||||
| export const PrimaryDisabled = Template.bind({}) | ||||||
| PrimaryDisabled.args = { | ||||||
| text: "Primary Disabled Button", | ||||||
| isDisabled: true, | ||||||
| onClick: () => { | ||||||
| alert("Primary Button Clicked!") | ||||||
| }, | ||||||
| } | ||||||
|
|
||||||
| export const PrimaryGray = Template.bind({}) | ||||||
| PrimaryGray.args = { | ||||||
| text: "Primary Gray Button", | ||||||
| color: ButtonColor.Grey, | ||||||
| onClick: () => { | ||||||
| alert("Primary Button Clicked!") | ||||||
| }, | ||||||
| } | ||||||
|
|
||||||
| export const PrimaryOutlinedGray = Template.bind({}) | ||||||
| PrimaryOutlinedGray.args = { | ||||||
| text: "Primary Outlined Gray Button", | ||||||
| isOutlined: true, | ||||||
| color: ButtonColor.Grey, | ||||||
| onClick: () => { | ||||||
| alert("Primary Button Clicked!") | ||||||
| }, | ||||||
| } | ||||||
|
|
||||||
| export const PrimaryLink = Template.bind({}) | ||||||
| PrimaryLink.args = { | ||||||
| text: "External Link Button", | ||||||
| to: "https://www.google.com", | ||||||
| } | ||||||
|
|
||||||
| export const Secondary = Template.bind({}) | ||||||
| Secondary.args = { | ||||||
| text: "Secondary Button", | ||||||
| variant: ButtonVariant.Secondary, | ||||||
| onClick: () => { | ||||||
| alert("Secondray Button Clicked!") | ||||||
|
||||||
| alert("Secondray Button Clicked!") | |
| alert("Secondary Button Clicked!") |
Copilot
AI
Aug 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo in alert message: "Secondray" should be "Secondary".
| alert("Secondray Button Clicked!") | |
| alert("Secondary Button Clicked!") |
Copilot
AI
Aug 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo in alert message: "Secondray" should be "Secondary".
| alert("Secondray Button Clicked!") | |
| alert("Secondary Button Clicked!") |
Copilot
AI
Aug 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo in alert message: "Secondray" should be "Secondary".
| alert("Secondray Button Clicked!") | |
| alert("Secondary Button Clicked!") |
Copilot
AI
Aug 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo in alert message: "Secondray" should be "Secondary".
| alert("Secondray Button Clicked!") | |
| alert("Secondary Button Clicked!") |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,117 @@ | ||||||||||||||||||
| .button { | ||||||||||||||||||
| --transition-duration: 0.3s; | ||||||||||||||||||
|
|
||||||||||||||||||
| display: inline-flex; | ||||||||||||||||||
| align-items: center; | ||||||||||||||||||
| justify-content: center; | ||||||||||||||||||
| cursor: pointer; | ||||||||||||||||||
|
|
||||||||||||||||||
| transition: background-color var(--transition-duration), | ||||||||||||||||||
| color var(--transition-duration), | ||||||||||||||||||
| border-color var(--transition-duration); | ||||||||||||||||||
|
|
||||||||||||||||||
| // Primary variant | ||||||||||||||||||
| &.primary { | ||||||||||||||||||
| padding: 10px 15px; | ||||||||||||||||||
| border-radius: 30px; | ||||||||||||||||||
| background-color: var(--color-secondary-blue-01); | ||||||||||||||||||
|
|
||||||||||||||||||
| font-size: 18px; | ||||||||||||||||||
| font-family: var(--font-secondary); | ||||||||||||||||||
| font-weight: 400; | ||||||||||||||||||
| line-height: 1; | ||||||||||||||||||
| color: var(--color-white); | ||||||||||||||||||
|
|
||||||||||||||||||
| &.is-outlined { | ||||||||||||||||||
| padding-block: 9px; | ||||||||||||||||||
| background-color: transparent; | ||||||||||||||||||
| border: 1px solid var(--color-secondary-blue-01); | ||||||||||||||||||
| color: var(--color-secondary-blue-01); | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| // Secondary variant | ||||||||||||||||||
| &.secondary { | ||||||||||||||||||
| padding: 9px 20px; | ||||||||||||||||||
| border-radius: 5px; | ||||||||||||||||||
| background-color: $accent-blue; | ||||||||||||||||||
|
||||||||||||||||||
| background-color: $accent-blue; | |
| background-color: var(--color-secondary-blue-01); |
Copilot
AI
Aug 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent use of SCSS variables vs CSS custom properties. Line 61 uses $subtitle-grey while other lines use CSS custom properties. Consider using CSS custom properties consistently.
| color: $subtitle-grey; | |
| background-color: var(--color-subtitle-grey); | |
| color: var(--color-white); | |
| &.is-outlined { | |
| background-color: transparent; | |
| border: 1px solid var(--color-subtitle-grey); | |
| color: var(--color-subtitle-grey); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| // Button component types | ||
| export enum ButtonVariant { | ||
| Primary = "primary", | ||
| Secondary = "secondary", | ||
| } | ||
|
|
||
| export enum ButtonColor { | ||
| Default = "default", | ||
| Grey = "grey", | ||
| } | ||
|
|
||
| export interface ButtonProps { | ||
| text: string | ||
| to?: string | ||
| variant?: ButtonVariant | ||
| type?: "button" | "submit" | "reset" | ||
| isOutlined?: boolean | ||
| isDisabled?: boolean | ||
| color?: ButtonColor | ||
| linkTarget?: string | ||
| isDownload?: boolean | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The prop
isGreyis defined in the defaults but doesn't exist in the ButtonProps interface. This will cause a TypeScript error and the prop is unused in the component.