|
1 |
| -import { useState, useRef } from "preact/hooks"; |
| 1 | +import { useState, useRef, useEffect } from "preact/hooks"; |
2 | 2 |
|
3 | 3 | import html from "../html";
|
4 | 4 | import style from "../style";
|
5 | 5 |
|
6 |
| -import { cascading, bounceInRight, outLeft, spin } from "./animations"; |
| 6 | +import { spin } from "./animations"; |
7 | 7 |
|
8 | 8 | const CardsContainer = style("article")({
|
9 | 9 | height: "100%",
|
@@ -31,122 +31,45 @@ const Arrow = style("button")(({ show }) => ({
|
31 | 31 | }
|
32 | 32 | }));
|
33 | 33 |
|
34 |
| -const CardContainer = style("section")(({ exiting }) => |
35 |
| - cascading( |
36 |
| - { |
37 |
| - display: "flex", |
38 |
| - flexDirection: "column", |
39 |
| - justifyContent: "center", |
40 |
| - alignItems: "center", |
41 |
| - opacity: "0", |
42 |
| - animation: exiting |
43 |
| - ? `${outLeft} .3s forwards` |
44 |
| - : `${bounceInRight} .3s forwards`, |
45 |
| - height: "100%", |
46 |
| - flex: "0 0 300px" |
47 |
| - }, |
48 |
| - 0 |
49 |
| - ) |
50 |
| -); |
51 |
| - |
52 |
| -const ImageContainer = style("div")({ |
53 |
| - padding: "20px", |
54 |
| - width: "300px", |
55 |
| - height: "200px" |
56 |
| -}); |
57 |
| - |
58 |
| -const ImageBox = style("div")({ |
59 |
| - width: "100%", |
60 |
| - height: "100%", |
61 |
| - overflow: "hidden" |
62 |
| -}); |
63 |
| - |
64 |
| -const Image = style("img")({ |
65 |
| - width: "100%", |
66 |
| - height: "100%", |
67 |
| - objectFit: "cover", |
68 |
| - transition: "transform .3s" |
69 |
| -}); |
70 |
| - |
71 |
| -const Break = style("hr")({ |
72 |
| - width: "95%", |
73 |
| - opacity: ".3", |
74 |
| - transition: "opacity .3s" |
75 |
| -}); |
76 |
| - |
77 |
| -const Title = style("h3")({ |
78 |
| - padding: "20px", |
79 |
| - margin: "0", |
80 |
| - height: "100px", |
81 |
| - fontWeight: "normal", |
82 |
| - textAlign: "center", |
83 |
| - transition: "transform .3s" |
84 |
| -}); |
85 |
| - |
86 |
| -const Description = style("p")({ |
87 |
| - padding: "20px", |
88 |
| - margin: "0", |
89 |
| - height: "100px", |
90 |
| - fontSize: "16px", |
91 |
| - opacity: "0.5" |
92 |
| -}); |
| 34 | +const Cards = ({ children, loaded }) => { |
| 35 | + const scrollRef = useRef(); |
| 36 | + const [showArrows, setShowArrows] = useState([false, false]); |
93 | 37 |
|
94 |
| -const ClickZone = style("a")({ |
95 |
| - margin: "0", |
96 |
| - ":hover img": { |
97 |
| - transform: "scale(1.2)" |
98 |
| - }, |
99 |
| - ":hover hr": { |
100 |
| - opacity: "1" |
101 |
| - }, |
102 |
| - ":hover h3": { |
103 |
| - transform: "scale(1.2)" |
104 |
| - } |
105 |
| -}); |
| 38 | + const getArrows = () => { |
| 39 | + const element = scrollRef.current.base; |
| 40 | + const scrollValue = element.scrollLeft; |
| 41 | + const maxScrollLeft = element.scrollWidth - element.clientWidth; |
| 42 | + return [scrollValue > 0, scrollValue < maxScrollLeft]; |
| 43 | + }; |
106 | 44 |
|
107 |
| -export const Cards = ({ children }) => { |
108 |
| - const scrollRef = useRef(); |
109 |
| - const [showArrows, setShowArrows] = useState([false, true]); |
| 45 | + useEffect(() => { |
| 46 | + if (loaded === true) { |
| 47 | + setShowArrows(getArrows()); |
| 48 | + } |
| 49 | + }, [loaded]); |
110 | 50 |
|
111 | 51 | const scroll = direction => () => {
|
112 | 52 | const element = scrollRef.current.base;
|
113 | 53 | element.scrollBy({
|
114 | 54 | left: (direction * element.clientWidth * 80) / 100,
|
115 | 55 | behavior: "smooth"
|
116 | 56 | });
|
117 |
| - setTimeout(() => { |
118 |
| - const scrollValue = element.scrollLeft; |
119 |
| - const maxScrollLeft = element.scrollWidth - element.clientWidth; |
120 |
| - setShowArrows([scrollValue > 0, scrollValue < maxScrollLeft]); |
121 |
| - }, 500); |
| 57 | + setTimeout(() => setShowArrows(getArrows()), 500); |
122 | 58 | };
|
123 | 59 |
|
124 | 60 | return html`
|
125 | 61 | <${CardsContainer}>
|
126 |
| - <${Arrow} onClick=${scroll(-1)} show=${showArrows[0]}> |
| 62 | + <${Arrow} onClick=${scroll(-1)} show=${loaded && showArrows[0]}> |
127 | 63 | ${"<"}
|
128 | 64 | <//>
|
129 | 65 | <${CardsScroll} ref=${scrollRef}>
|
130 | 66 | ${children}
|
131 | 67 | <//>
|
132 |
| - <${Arrow} onClick=${scroll(1)} show=${showArrows[1]}> |
| 68 | + <${Arrow} onClick=${scroll(1)} show=${loaded && showArrows[1]}> |
133 | 69 | ${">"}
|
134 | 70 | <//>
|
135 | 71 | <//>
|
136 | 72 | `;
|
137 | 73 | };
|
138 | 74 |
|
139 |
| -export const Card = ({ title, image, link, description, exiting }) => html` |
140 |
| - <${CardContainer} exiting=${exiting}> |
141 |
| - <${ClickZone} href=${link} target="_blank" draggable=${false}> |
142 |
| - <${ImageContainer}> |
143 |
| - <${ImageBox}> |
144 |
| - <${Image} src=${image} alt=${title} draggable=${false} /> |
145 |
| - <//> |
146 |
| - <//> |
147 |
| - <${Break} /> |
148 |
| - <${Title} draggable=${false}>${title}<//> |
149 |
| - <${Description} draggable=${false}>${description}<//> |
150 |
| - <//> |
151 |
| - <//> |
152 |
| -`; |
| 75 | +export default Cards; |
0 commit comments