Skip to content

Commit 3dfaeb4

Browse files
committed
refactor: refactor some components with forwardRef
1 parent 23c2269 commit 3dfaeb4

16 files changed

+103
-82
lines changed

.vercelignore

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
.github
22
.husky
3-
docs
43
node_modules
4+
**/.gitkeep
5+
docs
56
scripts
6-
*.md
7+
*.md

public/.gitkeep

Whitespace-only changes.

public/next.svg

Lines changed: 0 additions & 1 deletion
This file was deleted.

public/vercel.svg

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/components/form/FormWrapper.tsx

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { useMultistepContext } from "@/hooks/useMultistepContext";
33
import { cn } from "@/lib/utils/cn";
44
import { FormHTMLAttributes, ReactNode } from "react";
55
import { AiOutlineSetting } from "react-icons/ai";
6-
import { CgEnter, CgErase } from "react-icons/cg";
6+
import { CgErase } from "react-icons/cg";
77

88
interface Props extends FormHTMLAttributes<HTMLFormElement> {
99
title: string;
@@ -50,28 +50,31 @@ const FormWrapper = ({ title, children, className, ...props }: Props) => {
5050
<div className="flex items-center gap-2 border-t border-gh-border px-4 py-2">
5151
<Button
5252
onClick={resetCard}
53-
label="Reset"
5453
variant="danger"
5554
size="small"
5655
icon={<CgErase />}
57-
/>
56+
>
57+
Reset
58+
</Button>
5859

5960
<Button
6061
onClick={previousPage}
6162
disabled={isFirstPage}
62-
label="Previous"
6363
variant="secondary"
6464
size="small"
6565
className="ml-auto"
66-
/>
66+
>
67+
Previous
68+
</Button>
6769

6870
<Button
6971
type="submit"
7072
disabled={isLastPage}
71-
label="Next"
7273
variant="success"
7374
size="small"
74-
/>
75+
>
76+
Next
77+
</Button>
7578
</div>
7679
</form>
7780
);

src/components/form/PageOne.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ const PageOne = () => {
1515
alt="Tech Stack"
1616
/>
1717

18-
<p className="text-center text-gh-text">
18+
<P className="text-center">
1919
This website allows you to easily customize and preview your README card
2020
in live. You can play around with the different settings so you don't
2121
have to write the query parameters manually.
22-
</p>
22+
</P>
2323

2424
<P>
2525
You can find an example card above. It is in my{" "}

src/components/form/PageTwo.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ const PageTwo = () => {
5757
select={(val) => updateCard({ theme: val.value })}
5858
/>
5959

60-
<Button label="Load Colors" onClick={loadColors} />
60+
<Button onClick={loadColors}>Load Colors</Button>
6161
</Flex>
6262

6363
<Hr />
@@ -75,7 +75,7 @@ const PageTwo = () => {
7575
id="bg-color"
7676
value={card.backgroundColor}
7777
onChange={(e) => updateCard({ backgroundColor: e.target.value })}
78-
setColor={(c) => updateCard({ backgroundColor: c })}
78+
onColorChange={(c) => updateCard({ backgroundColor: c })}
7979
/>
8080
</InputWrapper>
8181

@@ -85,7 +85,7 @@ const PageTwo = () => {
8585
id="border-color"
8686
value={card.borderColor}
8787
onChange={(e) => updateCard({ borderColor: e.target.value })}
88-
setColor={(c) => updateCard({ borderColor: c })}
88+
onColorChange={(c) => updateCard({ borderColor: c })}
8989
/>
9090
</InputWrapper>
9191
</Flex>
@@ -97,7 +97,7 @@ const PageTwo = () => {
9797
id="title-color"
9898
value={card.titleColor}
9999
onChange={(e) => updateCard({ titleColor: e.target.value })}
100-
setColor={(c) => updateCard({ titleColor: c })}
100+
onColorChange={(c) => updateCard({ titleColor: c })}
101101
/>
102102
</InputWrapper>
103103

@@ -107,7 +107,7 @@ const PageTwo = () => {
107107
id="badge-color"
108108
value={card.badgeColor}
109109
onChange={(e) => updateCard({ badgeColor: e.target.value })}
110-
setColor={(c) => updateCard({ badgeColor: c })}
110+
onColorChange={(c) => updateCard({ badgeColor: c })}
111111
/>
112112
</InputWrapper>
113113
</Flex>

src/components/layout/Flex.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import { cn } from "@/lib/utils/cn";
2-
import { ReactNode } from "react";
2+
import { ElementType, ReactNode } from "react";
33

44
type Props = {
55
children: ReactNode;
66
className?: string;
7+
variant?: ElementType;
78
};
89

9-
const Flex = ({ children, className }: Props) => (
10-
<div className={cn("flex gap-4", className)}>{children}</div>
10+
const Flex = ({ children, className, variant: Tag = "div" }: Props) => (
11+
<Tag className={cn("flex gap-4", className)}>{children}</Tag>
1112
);
1213

1314
export default Flex;

src/components/lines/NewBadge.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ const NewBadge = ({ addBadge }: Props) => {
8888
disabled={file !== null}
8989
value={color}
9090
onChange={(e) => setColor(e.target.value)}
91-
setColor={(c) => setColor(c)}
91+
onColorChange={(c) => setColor(c)}
9292
placeholder={file === null ? "#58a6ff" : "auto"}
9393
canBeAuto={true}
9494
/>

src/components/lines/Upload.tsx

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,9 @@ const Upload = ({ closePopup, uploadFile, file, clearIcon }: Props) => {
7676
</div>
7777

7878
<div className="border-border flex items-stretch gap-2 border-t border-gh-border px-3 py-2">
79-
<Button
80-
size="small"
81-
variant="secondary"
82-
onClick={() => closePopup()}
83-
label="Cancel"
84-
/>
79+
<Button size="small" variant="secondary" onClick={() => closePopup()}>
80+
Cancel
81+
</Button>
8582

8683
{file !== null && (
8784
<Button
@@ -91,8 +88,9 @@ const Upload = ({ closePopup, uploadFile, file, clearIcon }: Props) => {
9188
clearIcon();
9289
closePopup();
9390
}}
94-
label="Remove icon"
95-
/>
91+
>
92+
Remove icon
93+
</Button>
9694
)}
9795
</div>
9896
</>

src/components/ui/Button.tsx

Lines changed: 41 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { cn } from "@/lib/utils/cn";
22
import { VariantProps, cva } from "class-variance-authority";
3-
import { ButtonHTMLAttributes, FC, ReactElement } from "react";
3+
import { ButtonHTMLAttributes, ReactElement, forwardRef } from "react";
44

55
const buttonVariants = cva(
66
"leading-none rounded-md border transition-all duration-200 flex items-center gap-2 text-gh-text outline-none focus-visible:outline-2 focus-visible:outline-gh-blue-active outline-offset-0 select-none",
@@ -40,41 +40,49 @@ const buttonVariants = cva(
4040
interface ButtonProps
4141
extends ButtonHTMLAttributes<HTMLButtonElement>,
4242
VariantProps<typeof buttonVariants> {
43-
label?: string;
43+
children?: string;
4444
icon?: ReactElement;
4545
badge?: string | number;
4646
}
4747

48-
const Button: FC<ButtonProps> = ({
49-
label,
50-
icon,
51-
className,
52-
size,
53-
variant,
54-
fontWeight,
55-
width,
56-
badge,
57-
type = "button",
58-
...props
59-
}) => {
60-
return (
61-
<button
62-
className={cn(
63-
buttonVariants({ variant, size, fontWeight, width, className })
64-
)}
65-
type={type}
66-
aria-label={label ?? props["aria-label"]}
67-
{...props}
68-
>
69-
{icon}
70-
{label}
71-
{badge && (
72-
<div className="rounded-full bg-gh-gray-active px-1.5 py-1 text-[.8rem] leading-none text-gh-text">
73-
{badge}
74-
</div>
75-
)}
76-
</button>
77-
);
78-
};
48+
const Button = forwardRef<HTMLButtonElement, ButtonProps>(
49+
(
50+
{
51+
children,
52+
icon,
53+
className,
54+
size,
55+
variant,
56+
fontWeight,
57+
width,
58+
badge,
59+
type = "button",
60+
...rest
61+
},
62+
ref
63+
) => {
64+
return (
65+
<button
66+
ref={ref}
67+
className={cn(
68+
buttonVariants({ variant, size, fontWeight, width, className })
69+
)}
70+
type={type}
71+
aria-label={children ?? rest["aria-label"]}
72+
{...rest}
73+
>
74+
{icon}
75+
{children}
76+
{badge && (
77+
<div className="rounded-full bg-gh-gray-active px-1.5 py-1 text-[.8rem] leading-none text-gh-text">
78+
{badge}
79+
</div>
80+
)}
81+
</button>
82+
);
83+
}
84+
);
85+
86+
Button.displayName = "Button";
7987

8088
export default Button;

src/components/ui/ColorInput.tsx

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { IoMdColorFilter } from "react-icons/io";
1010

1111
interface ColorInputProps
1212
extends Omit<InputHTMLAttributes<HTMLInputElement>, "type"> {
13-
setColor: (color: string) => void;
13+
onColorChange: (color: string) => void;
1414
canBeAuto?: boolean;
1515
}
1616

@@ -21,7 +21,7 @@ const ColorInput = forwardRef<HTMLInputElement, ColorInputProps>(
2121
required,
2222
value = "",
2323
disabled,
24-
setColor,
24+
onColorChange,
2525
canBeAuto = false,
2626
...props
2727
},
@@ -79,23 +79,28 @@ const ColorInput = forwardRef<HTMLInputElement, ColorInputProps>(
7979
: "pointer-events-none opacity-0"
8080
)}
8181
>
82-
<HexColorPicker color={value} onChange={setColor} className="m-2" />
82+
<HexColorPicker
83+
color={value}
84+
onChange={onColorChange}
85+
className="m-2"
86+
/>
8387

8488
<div className="flex items-center justify-center border-t border-gh-border px-4 py-1">
8589
<Button
8690
onClick={() =>
87-
setColor(`#${Math.random().toString(16).slice(2, 8)}`)
91+
onColorChange(`#${Math.random().toString(16).slice(2, 8)}`)
8892
}
8993
variant="secondary"
9094
size="small"
91-
label="Random Color"
9295
className="text-[.8rem]"
9396
style={{
9497
color:
9598
disabled || !HEX_COLOR_REGEX.test(value) ? "#7d8590" : value,
9699
}}
97100
icon={<BsArrowRepeat className="rotate-[30deg] text-base" />}
98-
/>
101+
>
102+
Random Color
103+
</Button>
99104
</div>
100105
</div>
101106
</div>

src/components/ui/Link.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
1+
import { cn } from "@/lib/utils/cn";
12
import { AnchorHTMLAttributes, FC, ReactNode } from "react";
23

34
interface LinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
45
children: ReactNode;
56
}
67

7-
const Link: FC<LinkProps> = ({ children, ...props }) => {
8+
const Link: FC<LinkProps> = ({ children, className, ...props }) => {
89
return (
910
<a
1011
rel="noreferrer"
1112
target="_blank"
13+
className={cn(
14+
"text-gh-blue outline-none hover:underline focus-visible:underline",
15+
className
16+
)}
1217
{...props}
13-
className="text-gh-blue outline-none hover:underline focus-visible:underline"
1418
>
1519
{children}
1620
</a>

src/components/ui/P.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1+
import { cn } from "@/lib/utils/cn";
12
import { ReactNode } from "react";
23

34
type Props = {
45
children: ReactNode;
6+
className?: string;
57
};
68

7-
const P = ({ children }: Props) => {
8-
return <p className="text-gh-text">{children}</p>;
9+
const P = ({ children, className }: Props) => {
10+
return <p className={cn("text-gh-text", className)}>{children}</p>;
911
};
1012

1113
export default P;

src/components/ui/RepositoryLink.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,19 +66,22 @@ const RepositoryLink = async ({ user, repository }: Props) => {
6666

6767
<div className="flex items-center gap-2">
6868
<Button
69-
label="Fork"
7069
badge={githubStats.forks_count}
7170
variant="secondary"
7271
size="small"
7372
icon={<BiGitRepoForked className="text-gh-text-secondary" />}
74-
/>
73+
>
74+
Fork
75+
</Button>
76+
7577
<Button
76-
label="Starred"
7778
badge={githubStats.stargazers_count}
7879
variant="secondary"
7980
size="small"
8081
icon={<FaStar className="text-gh-yellow" />}
81-
/>
82+
>
83+
Starred
84+
</Button>
8285
</div>
8386
</div>
8487

0 commit comments

Comments
 (0)