Skip to content

Commit 855bbc5

Browse files
committed
feat: carousel improved.
1 parent eeb38b8 commit 855bbc5

8 files changed

Lines changed: 5468 additions & 5567 deletions

File tree

app/components/Events.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export default function Events() {
5555
<Container
5656
id="events"
5757
sx={{
58-
pt: { xs: 4, sm: 12 },
58+
pt: { xs: 1, sm: 4 },
5959
pb: { xs: 0, sm: 0 },
6060
position: "relative",
6161
display: "flex",
@@ -74,7 +74,9 @@ export default function Events() {
7474
Events
7575
</Typography>
7676
<Typography variant="body1" sx={{ color: "text.secondary" }}>
77-
ACSSZ organizes various events throughout the year to foster community engagement, cultural exchange, and professional development. From career insights to cultural talks, we aim to create a platform for students and scholars to connect and grow.
77+
ACSSZ organizes various events throughout the year to foster community engagement, cultural
78+
exchange, and professional development. From career insights to cultural talks, we aim to create a
79+
platform for students and scholars to connect and grow.
7880
</Typography>
7981
</Box>
8082
<Grid container spacing={2}>

app/components/Hero.tsx

Lines changed: 16 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import * as React from "react";
22
import Box from "@mui/material/Box";
33
import Container from "@mui/material/Container";
44
import { styled } from "@mui/material/styles";
5-
import Carousel from "react-material-ui-carousel";
6-
import Paper from "@mui/material/Paper";
5+
import { EmblaOptionsType } from "embla-carousel";
6+
import Carousel from "./carousel/Carousel";
77

88
const StyledBox = styled("div")<{ src: string }>(({ theme, src }) => ({
99
alignSelf: "center",
@@ -31,38 +31,17 @@ const StyledBox = styled("div")<{ src: string }>(({ theme, src }) => ({
3131
}),
3232
}));
3333

34+
const OPTIONS: EmblaOptionsType = { loop: true };
35+
const SLIDES = new Map<string, string>([
36+
["Slide 1", "media/slider_food.jpeg"],
37+
["Slide 2", "media/slider_erhu.jpeg"],
38+
["Slide 3", "media/slider_hanfu.jpg"],
39+
["Slide 4", "media/slider-china.jpg"],
40+
["Slide 5", "media/slider_music.jpg"],
41+
]);
42+
3443
function HeroImages() {
35-
const items = [
36-
{
37-
imgSrc: "media/slider_food.jpeg",
38-
title: "Slide 1",
39-
},
40-
{
41-
imgSrc: "media/slider_erhu.jpeg",
42-
title: "Slide 2",
43-
},
44-
{
45-
imgSrc: "media/slider_hanfu.jpg",
46-
title: "Slide 3",
47-
},
48-
{
49-
imgSrc: "media/slider-china.jpg",
50-
title: "Slide 4",
51-
},
52-
{
53-
imgSrc: "media/slider_music.jpg",
54-
title: "Slide 5",
55-
},
56-
];
57-
return (
58-
<Carousel>
59-
{items.map((item, i) => (
60-
<Paper>
61-
<StyledBox src={item.imgSrc} id="image" />
62-
</Paper>
63-
))}
64-
</Carousel>
65-
);
44+
return <Carousel slides={SLIDES} options={OPTIONS} />;
6645
}
6746

6847
export default function Hero() {
@@ -77,11 +56,12 @@ export default function Hero() {
7756
...theme.applyStyles("dark", {
7857
backgroundImage: "radial-gradient(ellipse 80% 50% at 50% -20%, hsl(210, 100%, 16%), transparent)",
7958
}),
59+
pt: { xs: 12, sm: 0 },
60+
ml: { xs: 0, sm: 0 },
61+
mr: { xs: 0, sm: 0 },
8062
})}
8163
>
82-
<Container>
83-
<HeroImages />
84-
</Container>
64+
<HeroImages />
8565
</Box>
8666
);
8767
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import React from "react";
2+
import { EmblaOptionsType } from "embla-carousel";
3+
import useEmblaCarousel from "embla-carousel-react";
4+
import AutoScroll from "embla-carousel-auto-scroll";
5+
6+
type PropType = {
7+
slides: Map<string, string>;
8+
options?: EmblaOptionsType;
9+
};
10+
11+
const Carousel: React.FC<PropType> = (props) => {
12+
const { slides, options } = props;
13+
const [emblaRef, emblaApi] = useEmblaCarousel(options, [AutoScroll({ playOnInit: true })]);
14+
15+
return (
16+
<section className="embla">
17+
<div className="embla__viewport" ref={emblaRef}>
18+
<div className="embla__container">
19+
{Array.from(slides.entries()).map(([alt, src], index) => (
20+
<img className="embla__slide" key={index} src={src} alt={alt} />
21+
))}
22+
</div>
23+
</div>
24+
</section>
25+
);
26+
};
27+
28+
export default Carousel;

app/css/base.css

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
.theme-light {
2+
--brand-primary: rgb(47, 112, 193);
3+
--brand-secondary: rgb(116, 97, 195);
4+
--brand-alternative: rgb(19, 120, 134);
5+
--background-site: rgb(249, 249, 249);
6+
--background-code: rgb(244, 244, 244);
7+
--text-body: rgb(54, 49, 61);
8+
--text-comment: rgb(99, 94, 105);
9+
--text-high-contrast: rgb(49, 49, 49);
10+
--text-medium-contrast: rgb(99, 94, 105);
11+
--text-low-contrast: rgb(116, 109, 118);
12+
--detail-high-contrast: rgb(192, 192, 192);
13+
--detail-medium-contrast: rgb(234, 234, 234);
14+
--detail-low-contrast: rgb(240, 240, 242);
15+
--admonition-note: rgb(46, 109, 188);
16+
--admonition-warning: rgb(255, 196, 9);
17+
--admonition-danger: rgb(220, 38, 38);
18+
--brand-primary-rgb-value: 47, 112, 193;
19+
--brand-secondary-rgb-value: 116, 97, 195;
20+
--brand-alternative-rgb-value: 19, 120, 134;
21+
--background-site-rgb-value: 249, 249, 249;
22+
--background-code-rgb-value: 244, 244, 244;
23+
--text-body-rgb-value: 54, 49, 61;
24+
--text-comment-rgb-value: 99, 94, 105;
25+
--text-high-contrast-rgb-value: 49, 49, 49;
26+
--text-medium-contrast-rgb-value: 99, 94, 105;
27+
--text-low-contrast-rgb-value: 116, 109, 118;
28+
--detail-high-contrast-rgb-value: 192, 192, 192;
29+
--detail-medium-contrast-rgb-value: 234, 234, 234;
30+
--detail-low-contrast-rgb-value: 240, 240, 242;
31+
--admonition-note-rgb-value: 46, 109, 188;
32+
--admonition-warning-rgb-value: 255, 196, 9;
33+
--admonition-danger-rgb-value: 220, 38, 38;
34+
}
35+
.theme-dark {
36+
--brand-primary: rgb(138, 180, 248);
37+
--brand-secondary: rgb(193, 168, 226);
38+
--brand-alternative: rgb(136, 186, 191);
39+
--background-site: rgb(0, 0, 0);
40+
--background-code: rgb(12, 12, 12);
41+
--text-body: rgb(222, 222, 222);
42+
--text-comment: rgb(170, 170, 170);
43+
--text-high-contrast: rgb(230, 230, 230);
44+
--text-medium-contrast: rgb(202, 202, 202);
45+
--text-low-contrast: rgb(170, 170, 170);
46+
--detail-high-contrast: rgb(101, 101, 101);
47+
--detail-medium-contrast: rgb(25, 25, 25);
48+
--detail-low-contrast: rgb(21, 21, 21);
49+
--admonition-note: rgb(138, 180, 248);
50+
--admonition-warning: rgb(253, 186, 116);
51+
--admonition-danger: rgb(220, 38, 38);
52+
--brand-primary-rgb-value: 138, 180, 248;
53+
--brand-secondary-rgb-value: 193, 168, 226;
54+
--brand-alternative-rgb-value: 136, 186, 191;
55+
--background-site-rgb-value: 0, 0, 0;
56+
--background-code-rgb-value: 12, 12, 12;
57+
--text-body-rgb-value: 222, 222, 222;
58+
--text-comment-rgb-value: 170, 170, 170;
59+
--text-high-contrast-rgb-value: 230, 230, 230;
60+
--text-medium-contrast-rgb-value: 202, 202, 202;
61+
--text-low-contrast-rgb-value: 170, 170, 170;
62+
--detail-high-contrast-rgb-value: 101, 101, 101;
63+
--detail-medium-contrast-rgb-value: 25, 25, 25;
64+
--detail-low-contrast-rgb-value: 21, 21, 21;
65+
--admonition-note-rgb-value: 138, 180, 248;
66+
--admonition-warning-rgb-value: 253, 186, 116;
67+
--admonition-danger-rgb-value: 220, 38, 38;
68+
}

app/css/embla.css

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
.embla {
2+
--slide-height: 19rem;
3+
--slide-spacing: 1rem;
4+
--slide-size: 70%;
5+
}
6+
.embla__viewport {
7+
overflow: hidden;
8+
mask-image: linear-gradient(transparent, black 10%, black 90%, transparent 100%);
9+
-webkit-mask-image: linear-gradient(to right, transparent, black 10%, black 90%, transparent 100%);
10+
}
11+
.embla__container {
12+
display: flex;
13+
touch-action: pan-y pinch-zoom;
14+
margin-left: calc(var(--slide-spacing) * -1);
15+
}
16+
.embla__slide {
17+
transform: translate3d(0, 0, 0);
18+
flex: 0 0 var(--slide-size);
19+
min-width: 0;
20+
padding-left: var(--slide-spacing);
21+
}
22+
.embla__slide__number {
23+
box-shadow: inset 0 0 0 0.2rem var(--detail-medium-contrast);
24+
border-radius: 1.8rem;
25+
font-size: 4rem;
26+
font-weight: 600;
27+
display: flex;
28+
align-items: center;
29+
justify-content: center;
30+
height: var(--slide-height);
31+
user-select: none;
32+
}
33+
.embla__controls {
34+
display: grid;
35+
grid-template-columns: auto 1fr;
36+
justify-content: space-between;
37+
gap: 1.2rem;
38+
}
39+
.embla__buttons {
40+
display: grid;
41+
grid-template-columns: repeat(2, 1fr);
42+
gap: 0.6rem;
43+
align-items: center;
44+
}
45+
.embla__button {
46+
-webkit-tap-highlight-color: rgba(var(--text-high-contrast-rgb-value), 0.5);
47+
-webkit-appearance: none;
48+
appearance: none;
49+
background-color: transparent;
50+
touch-action: manipulation;
51+
display: inline-flex;
52+
text-decoration: none;
53+
cursor: pointer;
54+
border: 0;
55+
padding: 0;
56+
margin: 0;
57+
box-shadow: inset 0 0 0 0.2rem var(--detail-medium-contrast);
58+
width: 3.6rem;
59+
height: 3.6rem;
60+
z-index: 1;
61+
border-radius: 50%;
62+
color: var(--text-body);
63+
display: flex;
64+
align-items: center;
65+
justify-content: center;
66+
}
67+
.embla__button:disabled {
68+
color: var(--detail-high-contrast);
69+
}
70+
.embla__button__svg {
71+
width: 20%;
72+
height: 20%;
73+
}
74+
.embla__dots {
75+
display: flex;
76+
flex-wrap: wrap;
77+
justify-content: flex-end;
78+
align-items: center;
79+
margin-right: calc((2.6rem - 1.4rem) / 2 * -1);
80+
}
81+
.embla__dot {
82+
-webkit-tap-highlight-color: rgba(var(--text-high-contrast-rgb-value), 0.5);
83+
-webkit-appearance: none;
84+
appearance: none;
85+
background-color: transparent;
86+
touch-action: manipulation;
87+
display: inline-flex;
88+
text-decoration: none;
89+
cursor: pointer;
90+
border: 0;
91+
padding: 0;
92+
margin: 0;
93+
width: 2.6rem;
94+
height: 2.6rem;
95+
display: flex;
96+
align-items: center;
97+
justify-content: center;
98+
border-radius: 50%;
99+
}
100+
.embla__dot:after {
101+
box-shadow: inset 0 0 0 0.2rem;
102+
width: 1.4rem;
103+
height: 1.4rem;
104+
border-radius: 50%;
105+
display: flex;
106+
align-items: center;
107+
content: "";
108+
width: 20%;
109+
height: 20%;
110+
}
111+
.embla__dot--selected:after {
112+
box-shadow: inset 0 0 0 0.5rem;
113+
width: 30%;
114+
height: 30%;
115+
}

app/routes/home.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import Manual from "../components/Manual";
1010
import Events from "../components/Events";
1111
import FAQ from "../components/FAQ";
1212
import Footer from "../components/Footer";
13+
import "../css/base.css";
14+
import "../css/embla.css";
1315

1416
export function meta() {
1517
return [

0 commit comments

Comments
 (0)