Skip to content

Commit 635cd70

Browse files
Merge pull request #57 from code4rena-dev/develop
Major Version - Image Upload Component
2 parents b825666 + dc92d8d commit 635cd70

17 files changed

+689
-11
lines changed

.github/workflows/test-runner.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
name: Jest
55
on:
66
workflow_dispatch:
7-
push:
8-
branches: [ develop ]
97
pull_request:
108
branches: [ develop, main ]
119
jobs:

.npmignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,6 @@ vercel.jsontsconfig.json
55
jest.config.ts
66
.storybook
77
.github
8-
*DS_Store
8+
*DS_Store
9+
*.stories.tsx
10+
*.test.tsx

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@code4rena/components-library",
3-
"version": "3.2.1",
3+
"version": "4.0.0",
44
"description": "Code4rena's official components library ",
55
"types": "./dist/lib.d.ts",
66
"exports": {

src/lib/ContestTile/CompactTemplate.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ const IsContest = ({title, isDarkTile = true, contestData, sponsorUrl, sponsorIm
178178
{languages
179179
&& languages.length > 0
180180
&& languages.map((language) => <Tag
181+
key={language}
181182
variant={isDarkTile ? TagVariant.DEFAULT : TagVariant.WHITE_OUTLINE}
182183
label={language}
183184
size={TagSize.NARROW}
@@ -259,6 +260,7 @@ const IsBounty = ({title, isDarkTile = true, bountyData, sponsorUrl, sponsorImag
259260
{languages
260261
&& languages.length > 0
261262
&& languages.map((language) => <Tag
263+
key={language}
262264
variant={isDarkTile ? TagVariant.DEFAULT : TagVariant.WHITE_OUTLINE}
263265
label={language}
264266
size={TagSize.NARROW} />

src/lib/ContestTile/ContestTile.types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export enum ContestTileVariant {
1010

1111
export type ContestEcosystem = "Algorand" | "Aptos" | "Blast" | "Cosmos" | "EVM" | "NEAR" | "Polkadot" | "Scroll" | "Sei" | "Solana" | "StarkNet" | "Stellar" | "Sui" | "Other";
1212

13-
export type CodingLanguage = "Cairo" | "GO" | "HUFF" | "Ink" | "Move" | "Noir" | "Other" | "Rain" | "Rust" | "Rust evm" | "Solidity" | "Vyper" | "Yui";
13+
export type CodingLanguage = "Cairo" | "GO" | "HUFF" | "Ink" | "Move" | "Noir" | "Other" | "Rain" | "Rust" | "Rust evm" | "Solidity" | "Vyper" | "Yul";
1414

1515
export interface ContestTileProps {
1616
/** An html `id` for the contest tile's wrapping div. */

src/lib/ContestTile/DefaultTemplate.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,7 @@ function IsContest({
338338
{languages
339339
&& languages.length > 0
340340
&& languages.map((language) => <Tag
341+
key={language}
341342
variant={isDarkTile ? TagVariant.DEFAULT : TagVariant.WHITE_OUTLINE}
342343
label={language}
343344
size={TagSize.NARROW} />
@@ -475,6 +476,7 @@ function IsBounty({
475476
{languages
476477
&& languages.length > 0
477478
&& languages.map((language) => <Tag
479+
key={language}
478480
variant={isDarkTile ? TagVariant.DEFAULT : TagVariant.WHITE_OUTLINE}
479481
label={language}
480482
size={TagSize.NARROW} />

src/lib/Icon/iconList.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export const icons = (size: string, color: string, className?: string): Record<s
1313
<path fill={color} fillRule="evenodd" clipRule="evenodd" d="M10.6803 4.2636C11.0317 3.91213 11.6016 3.91213 11.953 4.2636L18.3697 10.6803C18.5385 10.8491 18.6333 11.078 18.6333 11.3167C18.6333 11.5554 18.5385 11.7843 18.3697 11.9531L11.953 18.3697C11.6016 18.7212 11.0317 18.7212 10.6803 18.3697C10.3288 18.0183 10.3288 17.4484 10.6803 17.0969L15.5605 12.2167H4.89998C4.40293 12.2167 3.99998 11.8137 3.99998 11.3167C3.99998 10.8196 4.40293 10.4167 4.89998 10.4167H15.5605L10.6803 5.5364C10.3288 5.18492 10.3288 4.61508 10.6803 4.2636Z" />
1414
</g>
1515
</svg>,
16-
"bell": <svg width={size} height={size} viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
16+
"bell": <svg className={className} width={size} height={size} viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
1717
<path stroke={color} d="M15.1333 8.33333C15.1333 7.18406 14.6768 6.08186 13.8641 5.2692C13.0515 4.45655 11.9493 4 10.8 4C9.65072 4 8.54852 4.45655 7.73586 5.2692C6.9232 6.08186 6.46665 7.18406 6.46665 8.33333C6.46665 13.3889 4.29999 14.8333 4.29999 14.8333H17.3C17.3 14.8333 15.1333 13.3889 15.1333 8.33333Z" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
1818
<path stroke={color} d="M12.0495 17.7223C11.9225 17.9412 11.7402 18.1229 11.521 18.2492C11.3017 18.3755 11.0531 18.442 10.8 18.442C10.547 18.442 10.2983 18.3755 10.0791 18.2492C9.85979 18.1229 9.67754 17.9412 9.55057 17.7223" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
1919
</svg>,
@@ -110,13 +110,13 @@ export const icons = (size: string, color: string, className?: string): Record<s
110110
</g>
111111
</g>
112112
</svg>,
113-
"eye-closed": <svg width={size} height={size} viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
113+
"eye-closed": <svg className={className} width={size} height={size} viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
114114
<path fill={color} fillRule="evenodd" clipRule="evenodd" d="M15.0171 11.662C15.4634 11.3367 16.0889 11.4348 16.4142 11.8812L18.6831 14.9943C19.0084 15.4407 18.9103 16.0662 18.464 16.3915C18.0177 16.7168 17.3921 16.6186 17.0669 16.1723L14.7979 13.0591C14.4726 12.6128 14.5708 11.9873 15.0171 11.662Z" />
115115
<path fill={color} fillRule="evenodd" clipRule="evenodd" d="M11 12.75C11.5523 12.75 12 13.1977 12 13.75V16.9583C12 17.5106 11.5523 17.9583 11 17.9583C10.4477 17.9583 10 17.5106 10 16.9583V13.75C10 13.1977 10.4477 12.75 11 12.75Z" />
116116
<path fill={color} fillRule="evenodd" clipRule="evenodd" d="M6.9772 11.6699C7.42352 11.9952 7.52164 12.6207 7.19635 13.067L4.93314 16.1723C4.60785 16.6186 3.98234 16.7168 3.53601 16.3915C3.08969 16.0662 2.99157 15.4407 3.31686 14.9943L5.58007 11.889C5.90536 11.4427 6.53087 11.3446 6.9772 11.6699Z" />
117117
<path fill={color} fillRule="evenodd" clipRule="evenodd" d="M2.33964 7.33808C2.84328 7.11144 3.43529 7.336 3.66192 7.83964C6.60814 14.3868 15.3919 14.3868 18.3381 7.83964C18.5647 7.336 19.1567 7.11144 19.6604 7.33808C20.164 7.56472 20.3886 8.15673 20.1619 8.66037C16.5081 16.7799 5.49186 16.7799 1.83808 8.66037C1.61144 8.15673 1.836 7.56472 2.33964 7.33808Z" />
118118
</svg>,
119-
"eye-open": <svg width={size} height={size} viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
119+
"eye-open": <svg className={className} width={size} height={size} viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
120120
<path fill={color} fillRule="evenodd" clipRule="evenodd" d="M18.3381 11.4104C15.3919 4.86321 6.60814 4.86321 3.66192 11.4104C3.43529 11.914 2.84328 12.1386 2.33964 11.9119C1.836 11.6853 1.61144 11.0933 1.83808 10.5896C5.49186 2.47012 16.5081 2.47012 20.1619 10.5896C20.3886 11.0933 20.164 11.6853 19.6604 11.9119C19.1567 12.1386 18.5647 11.914 18.3381 11.4104Z" />
121121
<path fill={color} fillRule="evenodd" clipRule="evenodd" d="M3.66192 10.5896C6.60814 17.1368 15.3919 17.1368 18.3381 10.5896C18.5647 10.086 19.1567 9.86144 19.6604 10.0881C20.164 10.3147 20.3886 10.9067 20.1619 11.4104C16.5081 19.5299 5.49186 19.5299 1.83808 11.4104C1.61144 10.9067 1.836 10.3147 2.33964 10.0881C2.84328 9.86144 3.43528 10.086 3.66192 10.5896Z" />
122122
<path fill={color} fillRule="evenodd" clipRule="evenodd" d="M11 9.25C10.0335 9.25 9.25 10.0335 9.25 11C9.25 11.9665 10.0335 12.75 11 12.75C11.9665 12.75 12.75 11.9665 12.75 11C12.75 10.0335 11.9665 9.25 11 9.25ZM7.25 11C7.25 8.92889 8.92889 7.25 11 7.25C13.0711 7.25 14.75 8.92889 14.75 11C14.75 13.0711 13.0711 14.75 11 14.75C8.92889 14.75 7.25 13.0711 7.25 11Z" />
@@ -134,7 +134,7 @@ export const icons = (size: string, color: string, className?: string): Record<s
134134
</g>
135135
</g>
136136
</svg>,
137-
"grab-vertical": <svg width={size} height={size} viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
137+
"grab-vertical": <svg className={className} width={size} height={size} viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
138138
<circle fill={color} cx="13.75" cy="5.08325" r="1.75" />
139139
<circle fill={color} cx="13.75" cy="11.0833" r="1.75" />
140140
<circle fill={color} cx="13.75" cy="17.0833" r="1.75" />

src/lib/ImageUpload/ImageUpload.scss

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
@import "../../styles/variables";
2+
3+
.c4imgupload--wrapper {
4+
display: flex;
5+
flex-direction: column;
6+
gap: 0.5rem;
7+
max-width: 275px;
8+
align-items: center;
9+
10+
.c4imgupload--preview {
11+
width: 100%;
12+
13+
.preview {
14+
position: relative;
15+
height: 155px;
16+
background: $color__n-90;
17+
18+
img {
19+
width: 100%;
20+
height: 100%;
21+
object-fit: cover;
22+
}
23+
24+
.cutout {
25+
position: absolute;
26+
display: flex;
27+
flex-direction: row;
28+
inset: 0;
29+
30+
.left, .right {
31+
height: 100%;
32+
width: calc((100% - 155px) / 2);
33+
background: black;
34+
opacity: 0.6;
35+
}
36+
37+
.center{
38+
border-radius: 0.25rem;
39+
width: 155px;
40+
height: 155px;
41+
background: white;
42+
opacity: 0.3;
43+
}
44+
}
45+
}
46+
47+
.file-name {
48+
display: flex;
49+
flex-direction: row;
50+
align-items: center;
51+
justify-content: space-between;
52+
gap: 0.5rem;
53+
padding: 0.5rem 1.5rem;
54+
background: $color__n-90;
55+
border: 1px solid $color__n-60;
56+
border-top: 0;
57+
58+
p {
59+
margin: 0;
60+
font-size: $font-size__text;
61+
line-height: 145%;
62+
color: $color__n-20;
63+
overflow: hidden;
64+
text-overflow: ellipsis;
65+
white-space: nowrap;
66+
}
67+
68+
button {
69+
padding: 0;
70+
background: transparent;
71+
border: 0;
72+
height: 24px;
73+
width: 24px;
74+
cursor: pointer;
75+
}
76+
}
77+
}
78+
79+
.c4imgupload {
80+
position: relative;
81+
width: 100%;
82+
83+
&:hover {
84+
.c4imgupload--container {
85+
background: $color__n-80 !important;
86+
border: 1px solid $color__n-50 !important;
87+
}
88+
}
89+
90+
.c4imgupload--container {
91+
position: relative;
92+
border: 1px solid $color__n-60;
93+
background: $color__n-90;
94+
height: auto;
95+
border-radius: 0.25rem;
96+
padding: 1rem;
97+
display: flex;
98+
flex-direction: column;
99+
justify-content: center;
100+
align-items: center;
101+
102+
&.active {
103+
background: $color__n-80 !important;
104+
border: 1px solid $color__n-50 !important;
105+
}
106+
107+
input {
108+
position: absolute;
109+
inset: 0;
110+
z-index: 1;
111+
opacity: 0 !important;
112+
color: transparent !important;
113+
cursor: pointer;
114+
}
115+
116+
svg {
117+
width: 100%;
118+
height: 100%;
119+
min-width: 48px;
120+
min-height: 48px;
121+
max-width: 48px;
122+
max-height: 48px;
123+
124+
path {
125+
fill: $color__n-20;
126+
}
127+
}
128+
129+
.c4imgupload--caption {
130+
line-height: 125%;
131+
font-family: $font__default;
132+
font-size: $font-size__text;
133+
font-weight: bold;
134+
text-align: center;
135+
margin: 0;
136+
color: $color__n-20;
137+
max-width: 150px;
138+
139+
strong {
140+
color: $color__blurple__text;
141+
}
142+
}
143+
}
144+
145+
.c4imgupload--dragindicator {
146+
visibility: hidden;
147+
position: absolute;
148+
inset: 0.35rem;
149+
border-radius: 0.25rem;
150+
border: 3px dashed $color__blurple__text;
151+
z-index: 1;
152+
153+
&.active {
154+
visibility: visible;
155+
}
156+
}
157+
}
158+
159+
.c4imgupload--error {
160+
color: $color__red;
161+
margin: 0;
162+
text-align: center;
163+
width: 100%;
164+
max-width: 420px;
165+
font-size: 0.875rem;
166+
line-height: normal;
167+
}
168+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import React from "react";
2+
import { Meta, StoryObj } from "@storybook/react";
3+
import { ImageUpload } from "./ImageUpload"
4+
import { ImageType } from "./ImageUpload.types";
5+
6+
const meta: Meta<typeof ImageUpload> = {
7+
component: ImageUpload,
8+
title: "Components/Image Upload",
9+
tags: ["autodocs"]
10+
};
11+
export default meta;
12+
13+
type Story = StoryObj<typeof ImageUpload>;
14+
15+
export const SampleComponent: Story = (args) => (
16+
<div style={{ minWidth: '300px', maxWidth: '420px' }}>
17+
<ImageUpload {...args} />
18+
</div>
19+
)
20+
21+
SampleComponent.parameters = {
22+
docs: {
23+
canvas: {sourceState: "shown" }
24+
}
25+
};
26+
SampleComponent.args = {
27+
id: "c4_img_uploader",
28+
accept: [ImageType.png, ImageType.jpeg],
29+
maxSize: 2
30+
}

0 commit comments

Comments
 (0)