diff --git a/apps/frontend/.storybook/preview.ts b/apps/frontend/.storybook/preview.ts
index ff58bbd..0832f89 100644
--- a/apps/frontend/.storybook/preview.ts
+++ b/apps/frontend/.storybook/preview.ts
@@ -1,8 +1,9 @@
-import type { Preview } from "@storybook/react";
+import type { Preview } from '@storybook/react';
+import '../src/App.scss';
const preview: Preview = {
parameters: {
- actions: { argTypesRegex: "^on[A-Z].*" },
+ actions: { argTypesRegex: '^on[A-Z].*' },
controls: {
matchers: {
color: /(background|color)$/i,
diff --git a/apps/frontend/src/App.scss b/apps/frontend/src/App.scss
index 4f61b80..c719760 100644
--- a/apps/frontend/src/App.scss
+++ b/apps/frontend/src/App.scss
@@ -42,8 +42,8 @@
}
// Fonts
-$gellix-font-family: "Gellix";
-$gellix-fonts-path: "./stories/assets/fonts/";
+$gellix-font-family: 'Gellix';
+$gellix-fonts-path: './stories/assets/fonts/';
$font-weight-thin: 100;
$font-weight-light: 300;
$font-weight-regular: 400;
@@ -54,20 +54,32 @@ $font-weight-black: 900;
@font-face {
font-family: $gellix-font-family;
- src: url("./stories/assets/fonts/Gellix-Light_R.woff2") format("woff2");
+ src: url('./stories/assets/fonts/Gellix-Light_R.woff2') format('woff2');
font-weight: $font-weight-light;
}
@font-face {
font-family: $gellix-font-family;
- src: url("./stories/assets/fonts/Gellix-Regular_R.woff2") format("woff2");
+ src: url('./stories/assets/fonts/Gellix-Regular_R.woff2') format('woff2');
font-weight: $font-weight-regular;
font-style: normal;
}
@font-face {
font-family: $gellix-font-family;
- src: url("./stories/assets/fonts/Gellix-SemiBold_R.woff2") format("woff2");
+ src: url('./stories/assets/fonts/Gellix-SemiBold_R.woff2') format('woff2');
font-weight: $font-weight-semibold;
font-style: normal;
}
+
+// BUTTON STYLES
+.btn-secondary {
+ &:hover {
+ svg path {
+ fill: theme('colors.midnight-blue');
+ }
+ }
+ svg path {
+ fill: theme('colors.link-blue');
+ }
+}
diff --git a/apps/frontend/src/assets/icons/arrow-right-bold.svg b/apps/frontend/src/assets/icons/arrow-right-bold.svg
new file mode 100644
index 0000000..bcf5411
--- /dev/null
+++ b/apps/frontend/src/assets/icons/arrow-right-bold.svg
@@ -0,0 +1,3 @@
+
diff --git a/apps/frontend/src/components/Button.stories.ts b/apps/frontend/src/components/Button.stories.ts
deleted file mode 100644
index e640f2a..0000000
--- a/apps/frontend/src/components/Button.stories.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import type { Meta, StoryObj } from '@storybook/react';
-
-import { Button } from './Button';
-
-const meta = {
- title: 'Example/Button',
- component: Button,
- parameters: {
- layout: 'centered',
- },
- // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs
- tags: ['autodocs'],
-} satisfies Meta;
-
-export default meta;
-type Story = StoryObj;
-
-// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args
-export const Primary: Story = {
- args: {
- label: 'Button',
- size: 'default',
- },
-};
-
-export const Secondary: Story = {
- args: {
- label: 'Button',
- },
-};
-
-export const Large: Story = {
- args: {
- size: 'large',
- label: 'Button',
- },
-};
-
-export const Small: Story = {
- args: {
- size: 'small',
- label: 'Button',
- },
-};
diff --git a/apps/frontend/src/components/Button.tsx b/apps/frontend/src/components/Button.tsx
index 09b9631..3799a12 100644
--- a/apps/frontend/src/components/Button.tsx
+++ b/apps/frontend/src/components/Button.tsx
@@ -1,9 +1,82 @@
+import clsx from 'clsx';
+
+type Icon = React.FunctionComponent<
+ React.SVGProps & {
+ title?: string | undefined;
+ }
+>;
+
export interface ButtonProps extends React.ButtonHTMLAttributes {
variant?: 'primary' | 'secondary' | 'link';
size?: 'default' | 'small' | 'large' | 'tiny';
label: string;
+ /**
+ * import { ReactComponent as YourIcon } from '/assets/icons/...svg
+ */
+ IconLeft?: Icon;
+ /**
+ * import { ReactComponent as YourIcon } from '/assets/icons/...svg
+ */
+ IconRight?: Icon;
}
-export const Button = ({ variant = 'primary', size = 'default', onClick, label, ...props }: ButtonProps) => {
- return ;
+const common = 'btn font-gellix flex items-center gap-5px rounded-full font-semibold disabled:opacity-25';
+const defaultSize = 'text-xl leading-5 py-15px px-25px';
+const small = 'leading-4 px-5 py-3';
+const large = 'text-25px leading-25px px-31.25px py-18.75px';
+const tiny = 'text-xs leading-3 px-15px py-9px';
+
+const primary =
+ 'bg-dark-teal text-midnight-blue hover:bg-medium-teal active:bg-light-teal focus:outline focus:outline-2 focus:outline-offset-1 focus:outline-link-blue';
+const secondary =
+ 'btn-secondary border-2 border-link-blue border-solid text-link-blue hover:text-midnight-blue hover:border-midnight-blue focus:outline focus:outline-2 focus:outline-offset-1 focus:outline-link-blue';
+const link = `${secondary} !p-0 !border-none focus:!outline-none`;
+
+export const Button = ({
+ variant = 'primary',
+ size = 'default',
+ onClick,
+ label,
+ IconRight,
+ IconLeft,
+ disabled,
+ ...props
+}: ButtonProps) => {
+ return (
+
+ );
};
diff --git a/apps/frontend/src/stories/Button.stories.ts b/apps/frontend/src/stories/Button.stories.ts
new file mode 100644
index 0000000..e482901
--- /dev/null
+++ b/apps/frontend/src/stories/Button.stories.ts
@@ -0,0 +1,108 @@
+import type { Meta, StoryObj } from '@storybook/react';
+
+import { Button } from '../components/Button';
+
+const meta = {
+ title: 'Button',
+ component: Button,
+ parameters: {
+ layout: 'centered',
+ },
+ tags: ['autodocs'],
+} satisfies Meta;
+
+export default meta;
+type Story = StoryObj;
+
+// --- PRIMARY ---
+export const PrimaryDefault: Story = {
+ args: {
+ label: 'Button',
+ variant: 'primary',
+ },
+};
+
+export const PrimaryLarge: Story = {
+ args: {
+ label: 'Button',
+ size: 'large',
+ },
+};
+
+export const PrimarySmall: Story = {
+ args: {
+ label: 'Button',
+ size: 'small',
+ },
+};
+
+export const PrimaryTiny: Story = {
+ args: {
+ label: 'Button',
+ size: 'tiny',
+ },
+};
+
+// --- SECONDARY ---
+export const SecondaryDefault: Story = {
+ args: {
+ label: 'Button',
+ variant: 'secondary',
+ },
+};
+
+export const SecondaryLarge: Story = {
+ args: {
+ label: 'Button',
+ variant: 'secondary',
+ size: 'large',
+ },
+};
+
+export const SecondarySmall: Story = {
+ args: {
+ label: 'Button',
+ variant: 'secondary',
+ size: 'small',
+ },
+};
+
+export const SecondaryTiny: Story = {
+ args: {
+ label: 'Button',
+ variant: 'secondary',
+ size: 'tiny',
+ },
+};
+
+// --- LINK ---
+export const LinkDefault: Story = {
+ args: {
+ label: 'Button',
+ variant: 'link',
+ },
+};
+
+export const LinkLarge: Story = {
+ args: {
+ label: 'Button',
+ variant: 'link',
+ size: 'large',
+ },
+};
+
+export const LinkSmall: Story = {
+ args: {
+ label: 'Button',
+ variant: 'link',
+ size: 'small',
+ },
+};
+
+export const LinkTiny: Story = {
+ args: {
+ label: 'Button',
+ variant: 'link',
+ size: 'tiny',
+ },
+};
diff --git a/apps/frontend/src/stories/button.css b/apps/frontend/src/stories/button.css
deleted file mode 100644
index dc91dc7..0000000
--- a/apps/frontend/src/stories/button.css
+++ /dev/null
@@ -1,30 +0,0 @@
-.storybook-button {
- font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
- font-weight: 700;
- border: 0;
- border-radius: 3em;
- cursor: pointer;
- display: inline-block;
- line-height: 1;
-}
-.storybook-button--primary {
- color: white;
- background-color: #1ea7fd;
-}
-.storybook-button--secondary {
- color: #333;
- background-color: transparent;
- box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 0px 1px inset;
-}
-.storybook-button--small {
- font-size: 12px;
- padding: 10px 16px;
-}
-.storybook-button--medium {
- font-size: 14px;
- padding: 11px 20px;
-}
-.storybook-button--large {
- font-size: 16px;
- padding: 12px 24px;
-}
diff --git a/apps/frontend/tailwind.config.js b/apps/frontend/tailwind.config.js
index 11f14f2..1ab8f1a 100644
--- a/apps/frontend/tailwind.config.js
+++ b/apps/frontend/tailwind.config.js
@@ -4,7 +4,22 @@ const colors = require('tailwindcss/colors');
module.exports = {
content: ['./src/**/*.{html,js,jsx,ts,tsx}'],
theme: {
- extend: {},
+ extend: {
+ spacing: {
+ '5px': '5px',
+ '15px': '15px',
+ '9px': '9px',
+ '25px': '25px',
+ '31.25px': '31.25px',
+ '18.75px': '18.75px',
+ },
+ lineHeight: {
+ '25px': '25px',
+ },
+ fontSize: {
+ '25px': '25px',
+ },
+ },
colors: {
black: colors.black,
white: colors.white,
@@ -13,10 +28,11 @@ module.exports = {
waterspout: '#A8F9F6',
'midnight-blue': '#000048',
'dark-teal': '#11C7CC',
- 'medium-teal': '#26EFE9',
- 'light-teal': 'C9FBFA',
+ 'medium-teal': '#29EEE9',
+ 'light-teal': '#A8F9F6',
+ 'lightest-teal': '#C9FBFA',
'disabled-teal': '#26EFE9',
- 'medium-blue': '#2F78C4',
+ 'link-blue': '#2F78C4',
},
fontFamily: {
gellix: ['Gellix', 'sans-serif'],