Skip to content

Commit 005e663

Browse files
committed
+
1 parent 8a5c5de commit 005e663

File tree

2 files changed

+218
-1
lines changed

2 files changed

+218
-1
lines changed

src/ui/components/RightAside.astro

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import AsideSponsors from "./AsideSponsors.astro";
44
import CarbonCard from "./CarbonCard.astro";
55
import SmallProgressBar from "./SmallProgressBar.astro";
66
import progress from "../../data/progress";
7+
import Toasts from "./Toasts.astro";
78
---
89

910
<div class="aside-right">
@@ -14,7 +15,8 @@ import progress from "../../data/progress";
1415
<AsideArticle />
1516
<AsideSponsors />
1617
</div>
17-
<CarbonCard />
18+
<!-- <CarbonCard /> -->
19+
<Toasts />
1820
</div>
1921
<style>
2022
.aside-right {

src/ui/components/Toasts.astro

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
---
2+
3+
const toasts = [
4+
// {
5+
// icon: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-dollar-sign"><line x1="12" y1="1" x2="12" y2="23"></line><path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"></path></svg>`,
6+
// title: "Two",
7+
// description: "One",
8+
// href: ""
9+
// },
10+
// {
11+
// icon: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-dollar-sign"><line x1="12" y1="1" x2="12" y2="23"></line><path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"></path></svg>`,
12+
// title: "Three",
13+
// description: "One",
14+
// href: ""
15+
// },
16+
{
17+
icon: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-trending-up"><polyline points="22 7 13.5 15.5 8.5 10.5 2 17"/><polyline points="16 7 22 7 22 13"/></svg>`,
18+
title: "One Dollar Stats",
19+
description: "$1 per mo web analytics",
20+
href: "https://onedollarstats.com/"
21+
},
22+
];
23+
---
24+
<div data-toasts class="toasts-wrap animated_bottom" transition:persist="toasts">
25+
<div class="by-drizzle">Product by Drizzle</div>
26+
{
27+
toasts.map((toast, index) => (
28+
<a
29+
href={toast.href}
30+
target="_blank"
31+
rel="noreferrer nofollow"
32+
data-toast={index}
33+
style={`transform: translateY(${(toasts.length - index - 1) * 100}%) scale(${1 - (toasts.length - index - 1) * 0.06});`}
34+
class="toast"
35+
>
36+
<div class="toast-content">
37+
<div class="toast-icon">
38+
<Fragment set:html={toast.icon} />
39+
</div>
40+
<div class="toast-text">
41+
<span class="toast-title">{toast.title}</span>
42+
<span class="toast-description">{toast.description}</span>
43+
</div>
44+
</div>
45+
</a>
46+
))
47+
}
48+
</div>
49+
<style>
50+
.toasts-wrap {
51+
display: flex;
52+
flex-direction: column;
53+
position: absolute;
54+
z-index: 1000;
55+
bottom: 0;
56+
left: 0;
57+
right: 0;
58+
width: 100%;
59+
opacity: 1;
60+
transition: opacity 1s;
61+
margin-bottom: 32px;
62+
}
63+
64+
.toasts-wrap-fade {
65+
opacity: 0.5;
66+
transition: opacity 0.3s;
67+
}
68+
69+
.toast {
70+
transition: transform 0.2s cubic-bezier(0.41, 0.41, 0.35, 1.3);
71+
}
72+
73+
.toasts-wrap:has(.toast:hover) .toast {
74+
transform: none !important;
75+
}
76+
77+
.toasts-wrap-fade:has(.toast:hover) {
78+
opacity: 1 !important;
79+
}
80+
81+
html.dark .toast-content {
82+
background: #111;
83+
border: 1px solid #292929;
84+
}
85+
86+
.toast-content {
87+
display: flex;
88+
align-items: center;
89+
width: 100%;
90+
/* box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px 0px; */
91+
background: #FBFBFC;
92+
border-radius: 8px;
93+
border: 1px solid #E0E1E3;
94+
}
95+
96+
.toast-text {
97+
display: flex;
98+
flex-direction: column;
99+
gap: 2px;
100+
}
101+
102+
.toast-title {
103+
text-transform: uppercase;
104+
font-size: 12px;
105+
font-weight: 600;
106+
line-height: normal;
107+
}
108+
109+
.toast-description {
110+
font-size: 12px;
111+
line-height: normal;
112+
113+
}
114+
115+
.toast:not(:last-child) .toast-content {
116+
margin-bottom: 8px;
117+
}
118+
119+
@keyframes bottom {
120+
0% {
121+
transform: translateY(20%);
122+
opacity: 0;
123+
}
124+
75% {
125+
transform: translateY(-10%);
126+
opacity: 0.75;
127+
}
128+
100% {
129+
transform: translateY(0);
130+
opacity: 1;
131+
}
132+
}
133+
134+
.animated_bottom {
135+
animation: bottom 0.3s;
136+
}
137+
138+
.animated_fadeout {
139+
animation: fadeOut 3s;
140+
}
141+
142+
html.dark .toast-icon {
143+
background: #111;
144+
border: 1px solid #292929;
145+
}
146+
147+
.toast-icon {
148+
width: 32px;
149+
height: 32px;
150+
border-radius: 50%;
151+
background-color: #f0f0f0;
152+
padding: 6px;
153+
margin: 8px;
154+
aspect-ratio: 1;
155+
border: 1px solid #E0E1E3;
156+
}
157+
158+
html.dark .by-drizzle {
159+
background: #111;
160+
border: 1px solid #292929;
161+
}
162+
163+
.by-drizzle {
164+
text-transform: uppercase;
165+
font-size: 12px;
166+
bottom: 0;
167+
position: absolute;
168+
transition: bottom 0.2s;
169+
margin-bottom: 8px;
170+
left: 50%;
171+
border: 1px solid #E0E1E3;
172+
white-space: pre;
173+
z-index: -1;
174+
transform: translateX(-50%);
175+
background-color: #FBFBFC;
176+
padding: 0 8px;
177+
border-bottom-left-radius: 8px;
178+
border-bottom-right-radius: 8px;
179+
}
180+
181+
.toasts-wrap:has(.toast:hover) .by-drizzle{
182+
bottom: -26px;
183+
}
184+
</style>
185+
<style is:global>
186+
.toast-icon svg {
187+
width: 100%;
188+
height: 100%;
189+
}
190+
</style>
191+
<script>
192+
document.addEventListener("DOMContentLoaded", (e) => {
193+
const toasts = document.querySelectorAll("[data-toast]");
194+
toasts.forEach((toast, index) => {
195+
setTimeout(() => {
196+
toast.setAttribute(
197+
"style",
198+
`transform: translateY(calc(${(toasts.length - index - 1) * 100}% - ${(toasts.length - index - 1) * 12}px)) scale(${1 - (toasts.length - index - 1) * 0.06});`
199+
);
200+
}, 100 * toasts.length - index * 100);
201+
if (index !== toasts.length - 1) {
202+
toast.classList.add("animated_fadeout");
203+
}
204+
});
205+
const toastsWrap = document.querySelector("[data-toasts]");
206+
if (toastsWrap) {
207+
setTimeout(() => {
208+
toastsWrap.classList.remove("animated_bottom");
209+
}, 300);
210+
setTimeout(() => {
211+
toastsWrap.classList.add("toasts-wrap-fade");
212+
}, 3000);
213+
}
214+
});
215+
</script>

0 commit comments

Comments
 (0)