Skip to content

Commit c5a6229

Browse files
[add] User Rank component (#57)
Co-authored-by: Five-great <[email protected]>
1 parent 49e4491 commit c5a6229

File tree

11 files changed

+438
-21
lines changed

11 files changed

+438
-21
lines changed

ReadMe.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ A **[React][1] advanced components library** based on [TypeScript][2] & [Bootstr
4343
18. [Share Box](source/ShareBox.tsx)
4444
19. [Overlay Box](source/OverlayBox.tsx)
4545
20. [Dialog](source/Dialog.tsx)
46+
21. [User Rank](source/UserRank.tsx)
4647

4748
#### Data components
4849

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "idea-react",
3-
"version": "2.0.0-rc.4",
3+
"version": "2.0.0-rc.5",
44
"license": "LGPL-3.0-or-later",
55
"author": "[email protected]",
66
"description": "A React advanced components library based on TypeScript & Bootstrap, built by idea2app remote developers team.",

preview/content.tsx

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { observable } from 'mobx';
22
import { observer } from 'mobx-react';
3-
import { PureComponent } from 'react';
3+
import { Component } from 'react';
44
import { Button, Form, Image, Modal } from 'react-bootstrap';
55
import { formToJSON, sleep } from 'web-utility';
66

@@ -9,6 +9,7 @@ import {
99
CodeBlock,
1010
Dialog,
1111
DialogClose,
12+
HorizontalMarquee,
1213
Icon,
1314
Loading,
1415
MonthCalendar,
@@ -20,12 +21,14 @@ import {
2021
ShareBox,
2122
SpinnerButton,
2223
TimeDistance,
23-
TypeEcho
24+
TypeEcho,
25+
UserRankView,
26+
VerticalMarquee
2427
} from '../source';
2528
import { CodeExample, Section } from './utility';
2629

2730
@observer
28-
export class Content extends PureComponent {
31+
export class Content extends Component {
2932
@observable
3033
accessor pageIndex = 1;
3134

@@ -92,6 +95,22 @@ export class Content extends PureComponent {
9295
</CodeExample>
9396
</Section>
9497

98+
<Section title="Horizontal Marquee">
99+
<CodeExample>
100+
<HorizontalMarquee>
101+
{'idea2app '.repeat(15).trim()}
102+
</HorizontalMarquee>
103+
</CodeExample>
104+
</Section>
105+
106+
<Section title="Vertical Marquee">
107+
<CodeExample>
108+
<VerticalMarquee style={{ height: '10rem' }}>
109+
<img src="https://tech-query.me/medias/featureimages/22.jpg" />
110+
</VerticalMarquee>
111+
</CodeExample>
112+
</Section>
113+
95114
<Section title="Time Distance">
96115
<CodeExample>
97116
<TimeDistance date="1989-06-04" />
@@ -219,6 +238,27 @@ export class Content extends PureComponent {
219238
{showLoading && <Loading>加载中...</Loading>}
220239
</CodeExample>
221240
</Section>
241+
242+
<Section title="User Rank">
243+
<CodeExample>
244+
<UserRankView
245+
title="GitHub"
246+
rank={[
247+
'Five-great',
248+
'TechQuery',
249+
'stevending1st',
250+
'wangrunlin'
251+
].map((name, index) => ({
252+
id: index + 1,
253+
name,
254+
avatar: `https://github.com/${name}.png`,
255+
website: `https://github.com/${name}`,
256+
score: 100 - index
257+
}))}
258+
linkOf={({ id }) => `/user/${id}`}
259+
/>
260+
</CodeExample>
261+
</Section>
222262
</>
223263
);
224264
}

source/HorizontalMarquee/index.tsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
1-
import { FC, PropsWithChildren } from 'react';
1+
import { FC, HTMLAttributes } from 'react';
22

33
import * as style from './index.module.less';
44

5-
export type HorizontalMarqueeProps = PropsWithChildren<
6-
Partial<Record<'maxWidth' | 'duration' | 'height', string>>
7-
>;
5+
export type HorizontalMarqueeProps = HTMLAttributes<HTMLDivElement> &
6+
Partial<Record<'maxWidth' | 'duration' | 'height', string>>;
87

98
export const HorizontalMarquee: FC<HorizontalMarqueeProps> = ({
9+
className = '',
1010
children,
1111
maxWidth = '100%',
1212
duration,
13-
height
13+
height,
14+
...props
1415
}) => (
15-
<div className="overflow-hidden mw-100">
16+
<div className={`overflow-hidden mw-100 ${className}`} {...props}>
1617
<div
1718
className={`d-inline-block align-top text-nowrap ${style.scrollWrap}`}
1819
style={{

source/Icon.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export const Icon: FC<IconProps> = ({
1414
size,
1515
...props
1616
}) => (
17-
<i
17+
<span
1818
className={classNames(`bi-${name}`, className)}
1919
style={{ fontSize: size && `${size}rem`, ...style }}
2020
{...props}

source/UserRank/Address.tsx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { FC } from 'react';
2+
3+
import { Icon } from '../Icon';
4+
5+
export type UserAddressProps = Partial<Record<'email' | 'website', string>>;
6+
7+
export const UserAddress: FC<UserAddressProps> = ({ email, website }) => (
8+
<address className="mb-0 d-flex justify-content-around gap-2">
9+
{email && (
10+
<a rel="noreferrer" target="_blank" href={'mailto:' + email}>
11+
<Icon name="envelope" />
12+
</a>
13+
)}
14+
{website && (
15+
<a rel="noreferrer" target="_blank" href={website}>
16+
<Icon name="globe2" />
17+
</a>
18+
)}
19+
</address>
20+
);

source/UserRank/index.module.less

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
@keyframes suspension {
2+
0% {
3+
position: relative;
4+
top: 0px;
5+
}
6+
50% {
7+
position: relative;
8+
top: -0.8rem;
9+
}
10+
100% {
11+
position: relative;
12+
top: 0px;
13+
}
14+
}
15+
16+
.topUserRow {
17+
--logo-image: url('https://github.com/idea2app.png');
18+
--title-background-image: url('https://hackathon-api.static.kaiyuanshe.cn/6342619375fa1817e0f56ce1/2022/10/09/rrrr.png');
19+
a {
20+
color: inherit;
21+
text-decoration: none;
22+
}
23+
.imgBox {
24+
width: 2.1rem;
25+
&:hover img {
26+
transition: all 0.3s;
27+
transform: scale(1.1);
28+
}
29+
}
30+
.showTitle {
31+
position: relative;
32+
height: 4.8rem;
33+
padding-top: 1.2rem;
34+
z-index: 4;
35+
background-image: var(--title-background-image);
36+
background-attachment: fixed;
37+
background-size: 21rem auto;
38+
margin-top: 1.5rem;
39+
&::before {
40+
content: '';
41+
display: block;
42+
position: absolute;
43+
top: 0;
44+
left: 0;
45+
width: 100%;
46+
height: 100%;
47+
border-radius: 0.3rem;
48+
background-color: rgba(161, 160, 152, 0.7);
49+
}
50+
.showMedal {
51+
position: absolute;
52+
top: -1.2rem;
53+
left: 5%;
54+
i {
55+
width: 1.7rem;
56+
height: 1.7rem;
57+
background-image: var(--logo-image),
58+
linear-gradient(#ffd83a, #fdeba0);
59+
background-blend-mode: lighten;
60+
background-position: center;
61+
background-size: 1.5rem 1.5rem;
62+
background-repeat: no-repeat;
63+
border: 0.1rem solid #ffd83a;
64+
box-shadow: 0 0 0.5rem 0 #ffd83a;
65+
&:first-child {
66+
border-color: #d8d8d8;
67+
box-shadow: 0 0 0.5rem 0 #d8d8d8;
68+
background-image: var(--logo-image),
69+
linear-gradient(#d8d8d8, #eeeeee);
70+
}
71+
&:last-child {
72+
border-color: #fab36e;
73+
box-shadow: 0 0 0.5rem 0 #fab36e;
74+
background-image: var(--logo-image),
75+
linear-gradient(#fab36e, #fbe7d3);
76+
}
77+
}
78+
}
79+
h3 {
80+
position: relative;
81+
z-index: 2;
82+
font-size: 2rem;
83+
letter-spacing: 0.4rem;
84+
width: 10rem;
85+
cursor: default;
86+
text-shadow:
87+
0px 1px 0px #c0c0c0,
88+
0px 2px 0px #b0b0b0,
89+
0px 3px 0px #a0a0a0,
90+
0px 4px 0px #909090,
91+
0px 5px 10px rgba(0, 0, 0, 0.6);
92+
color: transparent;
93+
font-family: "'book antiqua', palatino, serif";
94+
&::after {
95+
content: attr(data-text);
96+
display: block;
97+
position: absolute;
98+
z-index: 1;
99+
top: 0;
100+
left: 0;
101+
width: 10rem;
102+
margin: 0 auto;
103+
text-shadow: none;
104+
background-image: linear-gradient(
105+
to right,
106+
#d8d8d8 10%,
107+
#ffd83a 60%,
108+
#fab36e 75%
109+
);
110+
background-clip: text;
111+
}
112+
}
113+
}
114+
.topUserUl {
115+
z-index: 5;
116+
li {
117+
text-align: center;
118+
cursor: default;
119+
.showBox {
120+
min-height: 6rem;
121+
letter-spacing: 1px;
122+
z-index: 3;
123+
}
124+
.imgBox {
125+
z-index: 2;
126+
animation: 3.5s suspension ease-in-out infinite;
127+
transition: all 0.6s;
128+
}
129+
&:nth-child(1) {
130+
order: 2;
131+
padding-top: 0.3rem;
132+
.showBox {
133+
color: #ffd83a;
134+
border-bottom: 1.5rem solid #ffd83a;
135+
text-shadow:
136+
0px 1px 0px #969653,
137+
0px 2px 5px rgba(240, 219, 100, 0.4);
138+
i {
139+
width: 2.5rem;
140+
height: 2.6rem;
141+
background-image: var(--logo-image),
142+
linear-gradient(#ffd83a, #fdeba0);
143+
background-blend-mode: lighten;
144+
background-position: center;
145+
background-size: 2.5rem auto;
146+
background-repeat: no-repeat;
147+
}
148+
}
149+
.imgBox {
150+
width: 6.4rem;
151+
animation-delay: 3.5s;
152+
}
153+
}
154+
&:nth-child(2) {
155+
order: 1;
156+
padding-top: 1rem;
157+
.showBox {
158+
color: #d8d8d8;
159+
border-bottom: 1.2rem solid #d8d8d8;
160+
text-shadow: 0px 1px 0px #d9cdcd 0px 2px 5px
161+
rgba(133, 132, 130, 0.4);
162+
i {
163+
background-image: var(--logo-image),
164+
linear-gradient(#d8d8d8, #eeeeee);
165+
}
166+
}
167+
.imgBox {
168+
width: 6rem;
169+
animation-delay: 1.4s;
170+
}
171+
}
172+
&:nth-child(3) {
173+
order: 3;
174+
padding-top: 1.5rem;
175+
.showBox {
176+
border-bottom: 1rem solid #fab36e;
177+
color: #fab36e;
178+
text-shadow:
179+
0px 1px 0px #aa8865,
180+
0px 2px 5px rgba(167, 129, 67, 0.4);
181+
i {
182+
background-image: var(--logo-image),
183+
linear-gradient(#fab36e, #fbe7d3);
184+
}
185+
}
186+
.imgBox {
187+
width: 5.6rem;
188+
animation-delay: 2.4s;
189+
}
190+
}
191+
&:hover .imgBox {
192+
animation-play-state: paused;
193+
}
194+
}
195+
}
196+
.topUserList {
197+
tr {
198+
&::before {
199+
content: '';
200+
position: absolute;
201+
display: block;
202+
right: 0;
203+
bottom: 0;
204+
width: 0;
205+
height: 2px;
206+
background: #9fc2ef;
207+
transition: all 0.5s;
208+
}
209+
&:hover::before {
210+
left: 0;
211+
width: 100%;
212+
}
213+
}
214+
td {
215+
cursor: default;
216+
background-color: transparent;
217+
.usernameBox {
218+
font-size: 0;
219+
&:hover {
220+
.imgBox > img {
221+
transform: scale(1.2);
222+
}
223+
}
224+
}
225+
}
226+
}
227+
}

0 commit comments

Comments
 (0)