Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
assets/images
1 change: 1 addition & 0 deletions .storybook/main.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { StorybookConfig } from "@storybook/react-webpack5";

const config: StorybookConfig = {
staticDirs: ['../src/assets/images'],
stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"],
addons: [
"@storybook/addon-webpack5-compiler-swc",
Expand Down
3 changes: 3 additions & 0 deletions dist/search-icon-HDCX3UXV.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/good-first-issues.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/whitepaper.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions src/components/badge/ByBdp.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from "react";
import { Pangolins } from "../../icons";

export const ByBDPBadge = () => {
return (
<div className="shadow-by-bdp text-brand-dark-100 border border-[#A9A49B] w-fit flex gap-1 p-1 rounded-md items-center bg-[#F6F0E6]">
<Pangolins />
<span className="font-quicksand font-bold text-[11px] ">By BDP</span>
</div>
);
};
1 change: 1 addition & 0 deletions src/components/badge/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./ByBdp";
11 changes: 11 additions & 0 deletions src/components/button/Button.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,14 @@ Disabled.args = {
label: "Disabled Button",
disabled: true,
};
export const PillButton = Template.bind({});
PillButton.args = {
label: "Learn",
variant: "navigation",
};

export const Rebrand = Template.bind({});
Rebrand.args = {
label: "Clear Filters",
variant: "rebrand",
};
16 changes: 12 additions & 4 deletions src/components/button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import React from "react";
export interface ButtonProps {
label: string;
onClick?: () => void;
variant?: "primary" | "secondary";
variant?: "primary" | "secondary" | "navigation" | "rebrand";
size?: "small" | "medium" | "large";
disabled?: boolean;
className?: string;
}

export const Button: React.FC<ButtonProps> = ({
Expand All @@ -15,11 +16,18 @@ export const Button: React.FC<ButtonProps> = ({
variant = "primary",
size = "medium",
disabled = false,
className: customClass,
}) => {
const baseStyles = "font-bold py-2 px-4 rounded";
const baseStyles = "font-bold";
const variantStyles = {
primary: "bg-blue-500 hover:bg-blue-700 text-white",
secondary: "bg-gray-300 hover:bg-gray-400 text-gray-800",
primary: "bg-blue-500 hover:bg-blue-700 py-2 px-4 text-white",
secondary: "bg-gray-300 hover:bg-gray-400 py-2 px-4 text-gray-800",
navigation: `border-brand-gray-100/60 rounded-lg bg-transparent border py-1 px-2 text-brand-gray-100/60
hover:bg-brand-gray-200/20 active:bg-brand-gray-100/60 active:text-brand-gray-400 active:border-0
`,
rebrand:
"bg-brand-orange-100 text-brand-light-100 px-2 py-2.5 rounded-lg font-bold hover:bg-brand-dark-100 w-full",
custom: `${customClass}`,
};
const sizeStyles = {
small: "text-sm",
Expand Down
32 changes: 32 additions & 0 deletions src/components/button/Leaves.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// src/components/Button/Button.stories.tsx

import React from "react";
import { StoryFn, Meta } from "@storybook/react";
import { LeavesProps, Leaf } from "./Leaves";

export default {
title: "Components/Leaves",
component: Leaf,
argTypes: {
variant: {
control: { type: "select", options: [1, 2, 3] },
},
selected: {
control: "boolean",
},
onClick: { action: "clicked" },
},
} as Meta;

const Template: StoryFn<LeavesProps> = (args) => <Leaf {...args} />;

export const OneLeaf = Template.bind({});
OneLeaf.args = {
leavesCount: 1,
};

export const TwoLeaf = Template.bind({});
TwoLeaf.args = {
leavesCount: 1,
selected: true,
};
48 changes: 48 additions & 0 deletions src/components/button/Leaves.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// src/components/Button/Leaves.tsx

import LeafIcon from "../../icons/LeafIcon";
import React from "react";

export interface LeavesProps {
leavesCount: number;
onClick?: () => void;
disabled?: boolean;
withBorder?: boolean;
selected?: boolean;
showLeftOvers?: boolean;
}

export const Leaf: React.FC<LeavesProps> = ({
leavesCount = 1,
selected = false,
withBorder,
showLeftOvers,
}) => {
const baseStyles = `rounded-md w-max py-1 px-2 flex gap-1 `;
const allStyles = `
${baseStyles}
${selected ? "bg-brand-green text-white" : " text-brand-green"}
${withBorder ? "border border-brand-green" : "border-0"}
${showLeftOvers ? "bg-none! hover:bg-none" : "hover:bg-brand-green/30 active:bg-brand-green active:text-white"}
`.trim();

const leaves = showLeftOvers
? Array.from({ length: 3 }).map((_, i) => ({
active: i + 1 <= leavesCount,
}))
: [];
return (
<div className={allStyles} role="button" tabIndex={0}>
{!showLeftOvers &&
Array.from({ length: leavesCount }).map((_, i) => <LeafIcon key={i} />)}

{showLeftOvers &&
leaves.map((leave, i) => (
<LeafIcon
key={i}
className={`${leave.active ? "text-brand-green" : "text-[#A9A49B99]"}`}
/>
))}
</div>
);
};
1 change: 1 addition & 0 deletions src/components/button/index.tsx
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from "./Button";
export * from "./Leaves";
99 changes: 99 additions & 0 deletions src/components/card/BDPCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// src/components/card/BDPCard.tsx

import React from "react";
import { ByBDPBadge } from "../badge";
import { Leaf } from "../button";
import { Tag, TagType } from "../tag";
export interface CardProps {
title: string;
description: string;
bannerColor: string;
onClick: () => void;
logo: string;
link: string;
difficulty: Difficulty;
tagList: TagType[];
byBDP?: boolean;
}
export type Difficulty = "easy" | "medium" | "hard";
enum DIFFICULTY {
EASY = "easy",
MEDIUM = "medium",
HARD = "hard",
}

export const BDPCard: React.FC<CardProps> = ({
difficulty = "easy",
logo,
onClick,
title,
description,
bannerColor,
link,
tagList,
byBDP,
}) => {
const baseStyles = `border border-brand-stroke-on-base p-2
flex min-h-[290px] w-[374px] rounded-2xl bg-brand-card-bg`;

const className = `
${baseStyles}
`.trim();

const convertToLeavesCount = (level: string) => {
switch (level) {
case DIFFICULTY.EASY:
return 1;
case DIFFICULTY.MEDIUM:
return 2;
case DIFFICULTY.HARD:
return 3;
default:
return 0;
}
};
return (
<a href={link} target="_blank" className={className} onClick={onClick} rel="noreferrer">
<div className="flex flex-col rounded-xl border border-brand-stroke-on-base w-full min-h-full bg-brand-card-bg">
<div
className={`h-[126px] flex border border-l-0 border-r-0 border-t-0
border-brand-stroke-on-base rounded-lg relative flex-col items-center justify-center`}
style={{ backgroundColor: bannerColor }}
>
<div>
<img
className="w-fit h-fit object-contain max-w-[100px]"
src={logo}
/>
</div>

{byBDP && (
<div className="absolute bottom-3 left-3">
<ByBDPBadge />
</div>
)}
</div>
{/* Footer */}
<div className="flex flex-col w-full p-3 gap-2">
<div className="w-full flex items-center justify-between">
<h6 className="font-montserrat text-lg font-semibold">{title}</h6>
<Leaf
showLeftOvers
leavesCount={convertToLeavesCount(difficulty)}
/>
</div>
<p className="font-light font-quicksand">{description}</p>

<div className="flex gap-[9px] flex-wrap">
{tagList &&
tagList.map((tag) => (
<Tag className="capitalize" key={tag} type={tag}>
{tag}
</Tag>
))}
</div>
</div>
</div>
</a>
);
};
36 changes: 36 additions & 0 deletions src/components/card/Card.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// src/components/Card/BDPCard.tsx

import React from "react";
import { StoryFn, Meta } from "@storybook/react";
import { BDPCard, CardProps } from "./BDPCard";

export default {
title: "Components/Card",
component: BDPCard,
tags: ["autodocs"],
} as Meta;

const Template: StoryFn<CardProps> = (args) => <BDPCard {...args} />;

export const Default = Template.bind({});
Default.args = {
bannerColor: "#D5BBA4",
logo: "whitepaper.png",
difficulty: "easy",
title: "Bitcoin TLDR",
description:
"The foundational document that introduced Bitcoin, explaining its decentralized, P2P, electronic cash system.",
tagList: ["guide", "interactive"],
};
export const MediumDifficulty = Template.bind({});

MediumDifficulty.args = {
bannerColor: "#0E9158",
logo: "good-first-issues.png",
difficulty: "medium",
title: "Good first issues",
byBDP: true,
description:
"Discover beginner-friendly issues from BOSS projects to start contributing today.",
tagList: ["tool"],
};
1 change: 1 addition & 0 deletions src/components/card/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { BDPCard } from "./BDPCard";
11 changes: 4 additions & 7 deletions src/components/search/Search.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { forwardRef, useState } from "react";
import PropTypes from "prop-types";
import { cn } from "../../utils/cn";
import searchIcon from "../../assets/search-icon.svg";
import { RebrandSearchIcon } from "../../icons";

export interface SearchProps
extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "size"> {
Expand Down Expand Up @@ -67,15 +67,12 @@ export const Search = forwardRef<HTMLInputElement, SearchProps>(
)}
>
{showIcon && (
<img
src={searchIcon}
alt="Search"
className={cn(
<RebrandSearchIcon className={ cn(
"absolute pointer-events-none",
sizeStyles[size].icon,
iconClassName,
)}
style={{ filter: "brightness(0)" }}
)}
style={{ filter: "brightness(0)" }}
/>
)}
<input
Expand Down
2 changes: 2 additions & 0 deletions src/icons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ export { default as PlusIcon } from "./icons/PlusIcon";
export { default as PlusNewIcon } from "./icons/PlusNewIcon";
export { default as MinusIcon } from "./icons/MinusIcon";
export { default as MenuIcon } from "./icons/MenuIcon";
export { default as Pangolins } from "./icons/Pangolins";
export { default as RightArrowIcon } from "./icons/RightArrowIcon";
export {default as RebrandSearchIcon} from "./icons/RebrandSearchIcon"
export { default as XIcon } from "./icons/XIcon";
export { default as SearchIcon } from "./icons/SearchIcon";
export { default as SortIcon } from "./icons/SortIcon";
Expand Down
19 changes: 19 additions & 0 deletions src/icons/Pangolins.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import * as React from "react";
import { SVGProps } from "react";

const Pangolins = (props: SVGProps<SVGSVGElement>) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width={23}
height={8}
viewBox="0 0 23 8"
fill="none"
{...props}
>
<path
d="M22.9933 6.66478L21.9771 4.80274C21.9732 4.796 21.9682 4.79012 21.962 4.7851L19.4494 2.71101C19.3929 2.66185 19.2934 2.70343 19.3073 2.77113C19.3178 2.82282 19.305 2.86608 19.2784 2.90934C19.2557 2.94642 19.2245 2.97227 19.195 2.98997C19.1575 3.01244 19.105 2.99783 19.0898 2.96103C19.0209 2.79248 18.9029 2.56774 18.6987 2.33625C18.5062 2.11826 18.298 1.96347 18.1262 1.85756C18.0763 1.82666 18.007 1.86149 18.0158 1.91374C18.0274 1.98144 18.0257 2.06488 17.9859 2.15056C17.9774 2.16911 17.9679 2.18624 17.9577 2.20197C17.9302 2.24439 17.8579 2.24215 17.8339 2.19804C17.719 1.98735 17.5452 1.72609 17.2834 1.45921C16.9987 1.16901 16.7002 0.965058 16.4568 0.825717C16.4058 0.796501 16.3395 0.833866 16.3497 0.885834C16.3647 0.964776 16.3632 1.06423 16.3021 1.15777C16.2879 1.17997 16.2718 1.19907 16.2551 1.2162C16.2262 1.24542 16.1727 1.24261 16.1461 1.21171C15.9608 0.995677 15.6478 0.69087 15.167 0.435513C14.5941 0.13127 14.0388 0.0332305 13.6802 0.000359887C13.6177 -0.00526364 13.5783 0.0562658 13.6184 0.0975599C13.7271 0.208525 13.8585 0.386909 13.7938 0.553223C13.7888 0.565583 13.7829 0.578501 13.7751 0.591427C13.7567 0.622893 13.7133 0.634125 13.6779 0.616148C13.4499 0.500407 13.0929 0.353481 12.6275 0.288305C12.0833 0.212454 11.6234 0.280721 11.3243 0.352917C11.2635 0.367528 11.255 0.438038 11.3108 0.463042C11.4038 0.504619 11.5085 0.573168 11.5703 0.683568C11.5798 0.700705 11.5876 0.71756 11.5939 0.734415C11.6113 0.778799 11.5627 0.821787 11.5094 0.809701C11.2175 0.742281 10.7226 0.667834 10.131 0.766438C9.50338 0.870948 9.05314 1.12209 8.79433 1.30104C8.74374 1.33588 8.77097 1.40611 8.83595 1.40723C9.03901 1.41032 9.34084 1.44937 9.4876 1.63787L9.48889 1.63928C9.52046 1.68002 9.484 1.73395 9.42686 1.73086C9.10501 1.71316 8.53515 1.72468 7.91212 1.96852C7.40298 2.1677 7.05852 2.44385 6.85195 2.64612C6.8082 2.6891 6.85287 2.75427 6.91822 2.74387C7.14786 2.70679 7.50488 2.69078 7.79849 2.86776C7.80828 2.87366 7.81852 2.87984 7.82831 2.88659C7.87861 2.91974 7.85434 2.98856 7.7912 2.99278C7.43326 3.01778 6.93142 3.09223 6.38421 3.30629C5.98253 3.46361 5.66822 3.65267 5.437 3.81842C5.38642 3.85438 5.41664 3.92517 5.48233 3.92376C5.73554 3.91787 5.9244 3.97827 5.97629 4.08502C5.98253 4.09822 5.98778 4.11423 5.99009 4.13362C5.9937 4.16704 5.96184 4.19626 5.92242 4.19682C5.68727 4.20103 5.30398 4.23725 4.89639 4.41788C4.70097 4.50447 4.54463 4.60416 4.4241 4.696C4.37877 4.73027 4.40209 4.79522 4.46219 4.8C4.54135 4.80674 4.63495 4.82776 4.721 4.88227C4.72593 4.88541 4.73053 4.88847 4.7348 4.89129C4.78505 4.92557 4.75976 4.99467 4.69572 4.99773C4.45694 5.00925 4.15215 5.04549 3.81485 5.14188C3.46933 5.24071 3.19212 5.37333 2.98456 5.49443C2.9297 5.5262 2.95303 5.60031 3.01937 5.60314C3.10936 5.60706 3.21183 5.62643 3.3097 5.67843C3.36094 5.70596 3.41612 5.73514 3.40955 5.76047C3.39181 5.83098 2.92905 5.73098 2.47646 5.82314C2.32243 5.85459 2.11321 5.91945 1.87838 6.07059C1.82352 6.10573 1.85374 6.17984 1.92239 6.17851C1.98216 6.17733 2.04883 6.18212 2.11945 6.19788L2.12273 6.19867C2.18842 6.21357 2.17922 6.29616 2.11157 6.30149C1.88955 6.3189 1.6015 6.36729 1.29409 6.49027C1.07435 6.5782 0.898641 6.68298 0.763329 6.77969C0.71176 6.81647 0.74461 6.88918 0.811611 6.88525C0.834594 6.88384 0.858574 6.88329 0.883532 6.88329L0.888793 6.88361C0.973202 6.88447 1.40721 6.90737 0.939448 6.99435C0.93259 6.99561 0.884852 7.00408 0.877625 7.00525C0.646734 7.04031 0.487109 7.07325 0.363288 7.11396C0.293988 7.13671 0.248004 7.15694 0.150461 7.212C0.0939727 7.244 -0.166555 7.36212 0.16581 7.39623C0.37297 7.40016 0.496062 7.39639 0.721406 7.36925C1.67835 7.25388 1.51927 7.2567 4.40263 6.48894C6.48394 5.93498 7.09627 6.10714 7.17408 6.13294C7.17675 6.14227 7.17971 6.15176 7.18202 6.16165C7.18958 6.19082 7.19475 6.22282 7.19808 6.25741C7.20038 6.28463 7.20168 6.31357 7.2014 6.34447L7.20269 6.48918L7.20334 6.55294L7.2158 7.80674C7.21617 7.83961 7.24736 7.86596 7.28576 7.86596H9.50929C9.54805 7.86596 9.57925 7.83929 9.57925 7.8062V6.87851C9.57925 6.57569 9.73985 6.28635 10.0236 6.10518C10.197 5.99474 10.428 5.90259 10.7281 5.88094C10.7806 5.87733 10.8352 5.87561 10.892 5.87647V7.51733H13.1937L13.1668 6.82855C13.1757 6.83419 13.1845 6.83953 13.1937 6.8451C13.8841 7.27294 14.6917 7.71145 15.9546 7.85984C15.9877 7.86345 16.0193 7.8469 16.0304 7.82023L16.0649 7.73678C16.1398 7.69686 16.3438 7.59937 16.5796 7.57247C16.7103 7.55757 16.86 7.54039 17.0206 7.60612C17.1632 7.66431 17.2467 7.76008 17.2811 7.8C17.3462 7.87639 17.38 7.94996 17.3977 8C17.4099 7.94886 17.5879 7.56455 17.1209 7.24769C16.7819 7.01788 16.3546 7.23561 16.2456 7.29827L16.2547 7.27608L16.2932 7.18306C16.3067 7.1502 16.285 7.11427 16.2452 7.10557C15.994 7.0491 15.1943 6.8069 15.3325 6.02118C15.3381 5.98941 15.372 5.96698 15.4091 5.97059C15.6202 5.99082 16.3194 6.05012 17.1067 6.02674H17.1084L17.7159 7.54549H19.5624L18.8123 5.7978C18.8169 5.7967 18.8215 5.79561 18.8264 5.79388C18.8287 5.79333 18.8307 5.79247 18.833 5.79161C18.8629 5.77929 19.1349 5.67678 19.5476 5.81694C20.2039 6.03945 22.1351 7.01702 22.4783 7.19176C22.5086 7.20722 22.547 7.20078 22.569 7.17749L22.9851 6.72714C23.0012 6.70941 23.0048 6.68525 22.9933 6.66478ZM21.1737 5.33537C21.0978 5.46871 20.9808 5.55372 20.9122 5.52518C20.8435 5.49671 20.8495 5.36541 20.9252 5.23208C21.001 5.09867 21.118 5.01372 21.1866 5.0422C21.2553 5.07074 21.2495 5.20196 21.1737 5.33537Z"
fill="currentColor"
/>
</svg>
);
export default Pangolins;
27 changes: 27 additions & 0 deletions src/icons/RebrandSearchIcon.tsx

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ export * from "./components/banner";
export * from "./components/search";
export * from "./components/tag";
export * from "./components/pill";
export * from "./components/badge";
export * from "./components/card";
1 change: 1 addition & 0 deletions src/styles/tailwind.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@import url("https://fonts.googleapis.com/css2?family=Quicksand:wght@300;400;500;600;700&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap");

@tailwind base;
@tailwind components;
Expand Down
Loading
Loading