Skip to content

Commit 8dda75c

Browse files
authored
feat: button story Components and Component reusability (#809)
Co-authored-by: TenzDelek <tibetdelek@gmail.com> Co-authored-by: Azeez Elegbede <40604284+AceTheCreator@users.noreply.github.com>
1 parent 762534b commit 8dda75c

18 files changed

Lines changed: 250 additions & 141 deletions

File tree

components/About/about.tsx

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import Heading from '../Typography/heading';
44
import Paragraph from '../Typography/paragraph';
55
import Button from '../Buttons/button';
66
import Image from 'next/image';
7+
import Download from '../illustration/download';
78

89
function About(): JSX.Element {
910
return (
@@ -51,27 +52,21 @@ function About(): JSX.Element {
5152
target="_blank"
5253
rel="noreferrer"
5354
>
54-
<Button type="button" className="w-[200px]">
55-
Become a sponsor now
56-
</Button>
55+
<Button type="button" className="w-[200px]" text="Become a sponsor now"/>
5756
</a>
5857
<a
5958
className="flex justify-center "
6059
href="/pdf/conf-2025.pdf"
6160
download={`conf ${new Date().getFullYear()}.pdf`}
6261
>
63-
<Button type="button" overlay={true} className="w-[240px] border">
64-
<div className="flex gap-2 justify-center items-center">
65-
<Image
66-
src="/img/Download_icon.png"
67-
height={20}
68-
width={20}
69-
alt="Download-icon"
70-
objectFit="contain"
71-
/>
72-
<div>Sponsorship prospectus</div>
73-
</div>
74-
</Button>
62+
<Button
63+
type="button"
64+
outline={true}
65+
className="w-[240px] border"
66+
text="Sponsorship prospectus"
67+
icon={<Download />}
68+
iconPosition="left"
69+
/>
7570
</a>
7671
</div>
7772
</div>
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import type { Meta, StoryObj } from '@storybook/nextjs';
2+
import Button from './button';
3+
import Download from '../illustration/download';
4+
5+
const meta: Meta<typeof Button> = {
6+
title: 'Components/Buttons',
7+
component: Button,
8+
argTypes: {
9+
children: {
10+
control: { type: 'text' },
11+
description: 'Button content (alternative to text prop)',
12+
defaultValue: 'Button',
13+
},
14+
text: {
15+
control: { type: 'text' },
16+
description: 'Button text (alternative to children)',
17+
},
18+
type: {
19+
options: ['button', 'submit', 'reset'],
20+
control: { type: 'select' },
21+
defaultValue: 'button',
22+
},
23+
className: {
24+
control: { type: 'text' },
25+
description: 'Custom CSS classes',
26+
},
27+
outline: {
28+
control: { type: 'boolean' },
29+
description: 'Remove gradient background if true',
30+
},
31+
disabled: {
32+
control: { type: 'boolean' },
33+
description: 'Disable the button',
34+
},
35+
test: {
36+
control: { type: 'text' },
37+
description: 'Test attribute',
38+
},
39+
icon: {
40+
control: { type: 'object' },
41+
description: 'Icon component to display',
42+
},
43+
iconPosition: {
44+
options: ['left', 'right', 'center'],
45+
control: { type: 'select' },
46+
description: 'Position of the icon relative to text',
47+
defaultValue: 'right',
48+
},
49+
onClick: { action: 'clicked' },
50+
},
51+
};
52+
53+
export default meta;
54+
55+
type Story = StoryObj<typeof Button>;
56+
57+
export const Default: Story = {
58+
args: {
59+
text: 'Default Button',
60+
type: 'button',
61+
},
62+
};
63+
64+
export const Outline: Story = {
65+
args: {
66+
text: 'Outline Button',
67+
outline: true,
68+
className: 'border',
69+
type: 'button',
70+
},
71+
};
72+
73+
export const Submit: Story = {
74+
args: {
75+
text: 'Submit Button',
76+
type: 'submit',
77+
},
78+
};
79+
80+
export const Reset: Story = {
81+
args: {
82+
text: 'Reset Button',
83+
type: 'reset',
84+
},
85+
};
86+
87+
export const WithIconRight: Story = {
88+
args: {
89+
text: 'Download File',
90+
icon: <Download />,
91+
iconPosition: 'right',
92+
type: 'button',
93+
},
94+
};
95+
96+
export const WithIconLeft: Story = {
97+
args: {
98+
text: 'Download File',
99+
icon: <Download />,
100+
iconPosition: 'left',
101+
type: 'button',
102+
},
103+
};
104+
105+
export const IconWithOutline: Story = {
106+
args: {
107+
text: 'Sponsorship Prospectus',
108+
icon: <Download />,
109+
iconPosition: 'left',
110+
outline: true,
111+
className: 'w-[240px] border',
112+
type: 'button',
113+
},
114+
};

components/Buttons/button.tsx

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,54 @@
11
import React from 'react';
22

33
type ButtonType = 'button' | 'submit' | 'reset' | undefined;
4+
type IconPosition = 'left' | 'right';
45

56
interface IButton {
67
className?: string;
7-
children: React.ReactNode;
8-
overlay?: boolean;
8+
children?: React.ReactNode;
9+
text?: string | React.ReactNode;
10+
outline?: boolean;
911
onClick?: React.MouseEventHandler;
1012
type: ButtonType;
1113
disabled?: boolean;
1214
test?: string;
15+
icon?: React.ReactNode;
16+
iconPosition?: IconPosition;
1317
}
1418

1519
function Button({
1620
className,
1721
children,
18-
overlay,
22+
text,
23+
outline,
1924
onClick,
2025
type,
2126
disabled,
2227
test,
28+
icon,
29+
iconPosition = 'right',
2330
}: IButton): React.JSX.Element {
31+
const content = text || children;
32+
2433
return (
2534
<button
2635
disabled={disabled}
27-
data-test={test || ''}
36+
{...(test && { 'data-test': test })}
2837
type={type}
2938
onClick={onClick}
30-
className={`${overlay ? '' : 'gradient-bg'} ${disabled && 'cursor-not-allowed'} flex items-center justify-center text-white h-[54px] rounded-md p-[8px] ${className}`}
39+
className={`${!outline && 'gradient-bg'} ${disabled && 'cursor-not-allowed'} flex items-center justify-center text-white h-14 rounded-md p-2 ${iconPosition === 'left' ? 'justify-start' : 'justify-end'} ${className}`}
3140
>
32-
{children}
41+
{icon && iconPosition === 'left' && (
42+
<span className="inline-block">
43+
{icon}
44+
</span>
45+
)}
46+
<span className="inline-block">{content}</span>
47+
{icon && iconPosition === 'right' && (
48+
<span className="inline-block">
49+
{icon}
50+
</span>
51+
)}
3352
</button>
3453
);
3554
}

components/Dropdown/dropdown.tsx

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import React, { useState, useRef, useEffect, SetStateAction, JSX } from 'react';
2+
import { City } from '../../types/types';
3+
import Arrows from '../illustration/arrows';
24

35
interface IDropdown<T> {
46
selectedItem: T | null;
@@ -55,19 +57,7 @@ function Dropdown<T>({
5557
onClick={() => setShow(!show)}
5658
>
5759
<div>{displayValue}</div>
58-
<svg
59-
className={`-mr-1 h-5 w-5 text-gray-400 transition-transform ${show ? 'rotate-180' : ''
60-
}`}
61-
viewBox="0 0 20 20"
62-
fill="currentColor"
63-
aria-hidden="true"
64-
>
65-
<path
66-
fillRule="evenodd"
67-
d="M5.23 7.21a.75.75 0 011.06.02L10 11.168l3.71-3.938a.75.75 0 111.08 1.04l-4.25 4.5a.75.75 0 01-1.08 0l-4.25-4.5a.75.75 0 01.02-1.06z"
68-
clipRule="evenodd"
69-
/>
70-
</svg>
60+
<Arrows direction='down' className='w-5 h-5' />
7161
</button>
7262
</div>
7363

components/Form/Cfp/stepFour.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
import React, { FormEvent, useState } from 'react';
33
import { toast } from 'react-hot-toast';
44
import axios from 'axios';
5-
import ActivityLoader from '../../illustration/activityLoader';
65
import Button from '../../Buttons/button';
76
import { CfpStepProps } from '../../../types/types';
7+
import ActivityLoader from '../../illustration/activityLoader';
88

99
function StepFour({ setStep, setForm, data }: CfpStepProps) {
1010
const [submitting, setSubmitting] = useState<boolean>(false);
@@ -71,9 +71,8 @@ function StepFour({ setStep, setForm, data }: CfpStepProps) {
7171
disabled={submitting || disabled}
7272
className="bg-tetiary-pink p-3 rounded-md text-white mt-3 w-36 lg:w-full lg:mt-5"
7373
test="step-four-next"
74-
>
75-
{submitting ? <ActivityLoader /> : 'Submit'}
76-
</Button>
74+
text={submitting ? <ActivityLoader /> : 'Submit'}
75+
/>
7776
</div>
7877
</div>
7978
</form>

components/Form/Cfp/stepOne.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,8 @@ function StepOne({ setStep, setForm, data }: CfpStepProps): JSX.Element {
5151
className="bg-tetiary-pink p-3 rounded-md text-white mt-6 float-right w-36 lg:w-full lg:mt-8"
5252
disabled={!data.Fullname && true}
5353
test="step-one-next"
54-
>
55-
Next
56-
</Button>
54+
text="Next"
55+
/>
5756
</div>
5857
</form>
5958
);

components/Form/Cfp/stepThree.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,8 @@ function StepThree({ setStep, setForm, data }: CfpStepProps): JSX.Element {
7676
disabled={!data.Description || (!data.Title && true)}
7777
className="bg-tetiary-pink p-3 rounded-md text-white mt-3 w-36 lg:w-full lg:mt-5"
7878
test="step-three-next"
79-
>
80-
Next
81-
</Button>
79+
text="Next"
80+
/>
8281
</div>
8382
</div>
8483
</form>

components/Form/Cfp/stepTwo.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,8 @@ function StepTwo({ setStep, setForm, data }: CfpStepProps): JSX.Element {
4040
disabled={!data.Description || (!data.Title && true)}
4141
className="bg-tetiary-pink p-3 rounded-md text-white mt-3 w-36 lg:w-full lg:mt-3"
4242
test="step-two-next"
43-
>
44-
Next
45-
</Button>
43+
text="Next"
44+
/>
4645
</div>
4746
</div>
4847
</form>

components/Form/subscription.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@ function Subscription(): JSX.Element {
1515
className="sm:w-full"
1616
data-test="subscribe-button"
1717
>
18-
<Button type="submit" className="w-full md:w-[200px] mt-8 px-10">
19-
Subscribe
20-
</Button>
18+
<Button type="submit" className="w-full md:w-[200px] mt-8 px-10" text="Subscribe" />
2119
</a>
2220
</div>
2321
</div>

components/Header/header.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,7 @@ function Header(): JSX.Element {
3838
</div>
3939
<div className="mt-[54px] relative flex items-center justify-center">
4040
<Link href="#tickets">
41-
<Button type="button" className="w-[250px]">
42-
Register Now
43-
</Button>
41+
<Button type="button" className="w-[250px]" text="Register Now" />
4442
</Link>
4543
</div>
4644
</div>

0 commit comments

Comments
 (0)