Skip to content

Commit c7e8d76

Browse files
authored
Merge pull request #2647 from appwrite/feat-SER-652-new-video-card-component-for-docs
feat: new video card component for docs
2 parents ef5df99 + de841b7 commit c7e8d76

File tree

6 files changed

+247
-26
lines changed

6 files changed

+247
-26
lines changed

bun.lock

Lines changed: 26 additions & 26 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
<script lang="ts">
2+
import { cn } from '$lib/utils/cn';
3+
import Icon from './ui/icon/icon.svelte';
4+
5+
interface Props {
6+
href: string;
7+
title: string;
8+
duration?: string; // Duration in time format like "1:20" or "1:05:30"
9+
class?: string;
10+
}
11+
12+
const { href, title, duration, class: className = '' }: Props = $props();
13+
</script>
14+
15+
<a
16+
{href}
17+
target="_blank"
18+
rel="noopener noreferrer"
19+
class={cn(
20+
'video-card no-underline',
21+
'bg-white/90 dark:bg-white/[0.04]',
22+
'border-black/8 dark:border-white/[0.06]',
23+
'hover:bg-white/95 dark:hover:bg-white/[0.06]',
24+
className
25+
)}
26+
>
27+
<div class="video-card-desktop">
28+
<div
29+
class="video-tutorial-label bg-greyscale-200 flex shrink-0 items-center gap-1.5 rounded-md px-2 py-0.5 dark:bg-[rgb(51,51,51)]"
30+
>
31+
<Icon
32+
name="play"
33+
class="video-tutorial-icon text-greyscale-900 dark:text-greyscale-100 h-5 w-5 shrink-0"
34+
/>
35+
<span class="text-greyscale-900 dark:text-greyscale-100 whitespace-nowrap"
36+
>Video tutorial</span
37+
>
38+
</div>
39+
40+
<!-- Main title -->
41+
<span class="video-card-title text-greyscale-900 dark:text-greyscale-100 flex-1">
42+
{title}
43+
{#if duration}
44+
<span class="video-card-duration-separator"> · </span>
45+
<span class="video-card-duration">{duration}</span>
46+
{/if}
47+
</span>
48+
49+
<Icon
50+
name="ext-link"
51+
class={cn(
52+
'video-card-ext-link h-5 w-5 shrink-0 transition-transform group-hover:translate-x-0.5 group-hover:-translate-y-0.5',
53+
'text-greyscale-900 dark:text-greyscale-100'
54+
)}
55+
/>
56+
</div>
57+
58+
<div class="video-card-mobile">
59+
<div class="video-card-header">
60+
<!-- video label -->
61+
<div
62+
class="video-tutorial-label bg-greyscale-200 flex shrink-0 items-center gap-1.5 rounded-md px-2 py-0.5 dark:bg-[rgb(51,51,51)]"
63+
>
64+
<Icon
65+
name="play"
66+
class="video-tutorial-icon text-greyscale-900 dark:text-greyscale-100 h-5 w-5 shrink-0"
67+
/>
68+
<span class="text-greyscale-900 dark:text-greyscale-100 whitespace-nowrap"
69+
>Video tutorial</span
70+
>
71+
</div>
72+
73+
<Icon
74+
name="ext-link"
75+
class={cn(
76+
'video-card-ext-link h-5 w-5 shrink-0 transition-transform group-hover:translate-x-0.5 group-hover:-translate-y-0.5',
77+
'text-greyscale-900 dark:text-greyscale-100'
78+
)}
79+
/>
80+
</div>
81+
82+
<span class="video-card-title text-greyscale-900 dark:text-greyscale-100 flex-1">
83+
{title}
84+
{#if duration}
85+
<span class="video-card-duration-separator"> · </span>
86+
<span class="video-card-duration">{duration}</span>
87+
{/if}
88+
</span>
89+
</div>
90+
</a>
91+
92+
<style>
93+
.video-card {
94+
display: flex;
95+
align-items: center;
96+
gap: 12px;
97+
padding: 12px;
98+
border-radius: 12px;
99+
border-width: 1px;
100+
border-style: solid;
101+
backdrop-filter: blur(7.5px);
102+
transition: background-color 0.2s;
103+
text-decoration: none;
104+
width: 100%;
105+
box-sizing: border-box;
106+
}
107+
108+
.video-card-desktop {
109+
display: flex;
110+
align-items: center;
111+
gap: 12px;
112+
width: 100%;
113+
}
114+
115+
.video-card-mobile {
116+
display: none;
117+
}
118+
119+
.video-card-header {
120+
display: flex;
121+
align-items: center;
122+
justify-content: space-between;
123+
width: 100%;
124+
gap: 12px;
125+
}
126+
127+
/* Tablet and below (max-width: 1023.9px) */
128+
@media (max-width: 1023.9px) {
129+
.video-card {
130+
flex-wrap: wrap;
131+
}
132+
}
133+
134+
/* Mobile (max-width: 767.9px) */
135+
@media (max-width: 767.9px) {
136+
.video-card {
137+
width: 100%;
138+
max-width: 100%;
139+
padding: 12px;
140+
align-items: flex-start;
141+
gap: 12px;
142+
flex-direction: column;
143+
}
144+
145+
.video-card-desktop {
146+
display: none;
147+
}
148+
149+
.video-card-mobile {
150+
display: flex;
151+
flex-direction: column;
152+
gap: 12px;
153+
width: 100%;
154+
}
155+
156+
.video-card-header {
157+
width: 100%;
158+
}
159+
160+
.video-card-title {
161+
width: 100%;
162+
}
163+
}
164+
165+
/* Small mobile (max-width: 375px) */
166+
@media (max-width: 375px) {
167+
.video-card {
168+
padding: 10px;
169+
gap: 10px;
170+
}
171+
172+
.video-card-mobile {
173+
gap: 10px;
174+
}
175+
}
176+
177+
.video-card-title {
178+
font-family: var(--font-family-sansSerif, Inter);
179+
font-size: var(--font-size-small, 16px);
180+
font-style: normal;
181+
font-weight: 400;
182+
line-height: var(--line-height-xs, 22px);
183+
letter-spacing: -0.072px;
184+
}
185+
186+
.video-tutorial-label span,
187+
.video-card-duration-separator,
188+
.video-card-duration {
189+
font-family: var(--font-family-sansSerif, Inter);
190+
font-size: var(--font-size-tiny, 14px);
191+
font-style: normal;
192+
font-weight: 400;
193+
line-height: var(--line-height-xs, 22px);
194+
letter-spacing: -0.063px;
195+
}
196+
197+
.video-tutorial-label span {
198+
text-align: center;
199+
}
200+
201+
.video-card-duration-separator,
202+
.video-card-duration {
203+
color: var(--secondary, var(--color-secondary));
204+
}
205+
</style>

src/lib/components/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ export { default as Select } from './Select.svelte';
1414
export { default as MetricCard } from './MetricCard.svelte';
1515
export { default as IsLoggedIn } from './IsLoggedIn.svelte';
1616
export { default as Search } from './Search.svelte';
17+
export { default as VideoCard } from './VideoCard.svelte';

src/markdoc/tags/Video_Card.svelte

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<script lang="ts">
2+
import { VideoCard } from '$lib/components';
3+
4+
interface Props {
5+
href: string;
6+
title: string;
7+
duration?: string;
8+
}
9+
10+
const { href, title, duration }: Props = $props();
11+
</script>
12+
13+
<VideoCard {href} {title} {duration} />

src/markdoc/tags/_Module.svelte

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,6 @@
2121
export { default as Youtube } from './Youtube.svelte';
2222
export { default as Call_To_Action } from './Call_To_Action.svelte';
2323
export { default as Storage_Image } from './Storage_Image.svelte';
24+
export { default as Video_Card } from './Video_Card.svelte';
2425
export { default as Appwrite_Network_Map } from '../../lib/components/appwrite-network/map.svelte';
2526
</script>

src/routes/docs/products/databases/quick-start/+page.markdoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ title: Start with Databases
44
description: Get started with Appwrite Databases. Follow a step-by-step guide to create your first database, define tables, and perform basic data operations.
55
---
66

7+
78
{% section #create-database step=1 title="Create database" %}
89
Head to your [Appwrite Console](https://cloud.appwrite.io/console/) and create a database and name it `Oscar`.
910
Optionally, add a custom database ID.

0 commit comments

Comments
 (0)