master
1---
2title: Components
3slug: q1k423y0
4category: Example
5tags:
6 - astro
7 - mdx
8 - example
9published: 2025-02-10T21:23:23+08:00
10---
11
12import { Collapse, FileTree, Icon, LinkCard, Repl, RepoCard, Ruby, TabItem, Tabs, Tooltip } from '@components/user';
13
14Components let you easily reuse a piece of UI or styling consistently. You can use them not just in `.astro` files, but also in `.mdx` files.
15
16> [!TIP]
17> [MDX](https://mdxjs.com/) is a format that lets you write JSX embedded inside Markdown.
18> And it has no difference with markdown files in other ways.
19
20> [!TIP]
21> Some components are both available in `.md` and `.mdx` files, but some are only available in `.mdx` files.
22> In `.md` files, you can use components with [remark-directive](https://github.com/remarkjs/remark-directive).
23> Components that available in `.md` files will have a `md` tab in the example.
24
25## Containers
26
27### Collapse
28
29<Repl>
30 <Collapse title="Click me">This is the content of the collapse.</Collapse>
31 <Collapse title="Default open!" open>
32 Hey there, I'm opened by default!
33 </Collapse>
34 <Fragment slot="desc">
35 <Tabs>
36 <TabItem label="mdx" active>
37 ```jsx
38 <Collapse title="Click me">This is the content of the collapse.</Collapse>
39 <Collapse title="Default open!" open>
40 Hey there, I'm opened by default!
41 </Collapse>
42 ```
43 </TabItem>
44 <TabItem label="md">
45 ```md
46 :::collapse{title="Click me"}
47 This is the content of the collapse.
48 :::
49 :::collapse{title="Default open!" open}
50 Hey there, I'm opened by default!
51 :::
52 ```
53 </TabItem>
54 </Tabs>
55 </Fragment>
56</Repl>
57
58### Tabs
59
60<Repl>
61 <Tabs>
62 <TabItem label="Foo">This is the content of common Tab 1</TabItem>
63 <TabItem label="Bar" active>
64 This is the content of common Tab 2
65 </TabItem>
66 </Tabs>
67 <Tabs>
68 <TabItem label="Lorem">This is the content of spoiler Tab 1</TabItem>
69 <TabItem label="Ipsum">This is the content of spoiler Tab 2</TabItem>
70 </Tabs>
71 <Tabs syncKey="test-tabs-sync">
72 <TabItem label="Tab 1" active>
73 This is the content of sync Tab 1, sync with next Tabs.
74 </TabItem>
75 <TabItem label="Tab 2">This is the content of sync Tab 2, sync with next Tabs.</TabItem>
76 </Tabs>
77 <Tabs syncKey="test-tabs-sync">
78 <TabItem label="NPM" active>
79 ```bash
80 npm install foo bar
81 ```
82 </TabItem>
83 <TabItem label="PNPM">
84 ```bash
85 pnpm add foo bar
86 ```
87 </TabItem>
88 </Tabs>
89 <Fragment slot="desc">
90 ````jsx
91 <Tabs>
92 <TabItem label="Foo">This is the content of common Tab 1</TabItem>
93 <TabItem label="Bar" active>
94 This is the content of common Tab 2
95 </TabItem>
96 </Tabs>
97 <Tabs>
98 <TabItem label="Lorem">This is the content of spoiler Tab 1</TabItem>
99 <TabItem label="Ipsum">This is the content of spoiler Tab 2</TabItem>
100 </Tabs>
101 <Tabs syncKey="test-tabs-sync">
102 <TabItem label="Tab 1" active>
103 This is the content of sync Tab 1, sync with next Tabs.
104 </TabItem>
105 <TabItem label="Tab 2">This is the content of sync Tab 2, sync with next Tabs.</TabItem>
106 </Tabs>
107 <Tabs syncKey="test-tabs-sync">
108 <TabItem label="NPM" active>
109 ```bash
110 npm install foo bar
111 ```
112 </TabItem>
113 <TabItem label="PNPM">
114 ```bash
115 pnpm add foo bar
116 ```
117 </TabItem>
118 </Tabs>
119 ````
120 </Fragment>
121</Repl>
122
123### Repl
124
125<Repl>
126 <Repl>
127 <div>Hello</div>
128 <Fragment slot="desc">
129 ```jsx
130 <div>Hello</div>
131 ```
132 </Fragment>
133 </Repl>
134 <Fragment slot="desc">
135 ````jsx
136 <Repl>
137 <div class="text-center">Hello</div>
138 <Fragment slot="desc">
139 ```jsx
140 <div class="text-center">Hello</div>
141 ```
142 </Fragment>
143 </Repl>
144 ````
145 </Fragment>
146</Repl>
147
148### FileTree
149
150<Repl>
151 <FileTree
152 files={[
153 {
154 name: "src",
155 children: [
156 { name: "components", children: ["Button.astro", "Card.astro"] },
157 { name: "layouts", children: ["BaseLayout.astro"] },
158 { name: "pages", children: ["index.astro", "about.astro"] },
159 ],
160 },
161 { name: "public", children: ["favicon.ico", "robots.txt"] },
162 ".gitignore",
163 "astro.config.mjs",
164 "package.json",
165 "README.md",
166 ]}
167 />
168 <Fragment slot="desc">
169 <Tabs>
170 <TabItem label="mdx" active>
171 ```jsx
172 <FileTree
173 files={[
174 {
175 name: "src",
176 children: [
177 { name: "components", children: ["Button.astro", "Card.astro"] },
178 { name: "layouts", children: ["BaseLayout.astro"] },
179 { name: "pages", children: ["index.astro", "about.astro"] },
180 ],
181 },
182 { name: "public", children: ["favicon.ico", "robots.txt"] },
183 ".gitignore",
184 "astro.config.mjs",
185 "package.json",
186 "README.md",
187 ]}
188 />
189 ```
190 </TabItem>
191 <TabItem label="md">
192 ```md
193 :::filetree
194 - src
195 - components
196 - Button.astro
197 - Card.astro
198 - layouts
199 - BaseLayout.astro
200 - pages
201 - index.astro
202 - about.astro
203 - public
204 - favicon.ico
205 - robots.txt
206 - .gitignore
207 - astro.config.mjs
208 - package.json
209 - README.md
210 :::
211 ```
212 </TabItem>
213 </Tabs>
214 </Fragment>
215</Repl>
216
217> [!NOTE]
218> `FileTree` has an optional `open` prop for both `.mdx` and `.md` components to make the tree expanded by default.
219
220## Inline Containers
221
222### Tooltip
223
224<Repl>
225 <div class="flex flex-col gap-2 w-fit mx-auto">
226 <Tooltip tip="I'm here!" position="top">
227 Hover me
228 </Tooltip>
229 <Tooltip tip="I'm here!" position="bottom">
230 Hover me
231 </Tooltip>
232 <Tooltip tip="I'm here!" position="left">
233 Hover me
234 </Tooltip>
235 <Tooltip tip="I'm here!" position="right">
236 Hover me
237 </Tooltip>
238 </div>
239 <Fragment slot="desc">
240 <Tabs>
241 <TabItem label="mdx" active>
242 ```jsx
243 <Tooltip tip="I'm here!" position="top">
244 Hover me
245 </Tooltip>
246 <Tooltip tip="I'm here!" position="bottom">
247 Hover me
248 </Tooltip>
249 <Tooltip tip="I'm here!" position="left">
250 Hover me
251 </Tooltip>
252 <Tooltip tip="I'm here!" position="right">
253 Hover me
254 </Tooltip>
255 ```
256 </TabItem>
257 <TabItem label="md">
258 ```md
259 ::tooltip[Hover me]{tip="I'm here!" position="top"}
260 ::tooltip[Hover me]{tip="I'm here!" position="bottom"}
261 ::tooltip[Hover me]{tip="I'm here!" position="left"}
262 ::tooltip[Hover me]{tip="I'm here!" position="right"}
263 ```
264 </TabItem>
265 </Tabs>
266 </Fragment>
267</Repl>
268
269### Icon
270
271<Repl>
272 <div class="flex flex-col gap-2 w-fit mx-auto">
273 <span>You can get this template in <Icon name="mdi:github" />[GitHub](https://github.com/HPCesia/astral-halo)</span>
274 <span>This is an open source project <Icon name="mdi:open-source-initiative" /></span>
275 <span>A huge icon is here: <Icon name="mdi:alert-octagon" size="5em" /></span>
276 </div>
277 <Fragment slot="desc">
278 <Tabs>
279 <TabItem label="mdx" active>
280 ```jsx
281 <span>You can get this template in <Icon name="mdi:github" />[GitHub](https://github.com/HPCesia/astral-halo)</span>
282 <span>This is an open source project <Icon name="mdi:open-source-initiative" /></span>
283 <span>A huge icon is here: <Icon name="mdi:alert-octagon" size="5em" /></span>
284 ```
285 </TabItem>
286 <TabItem label="md">
287 ```md
288 :icon{name="mdi:github"}
289 :icon{name="mdi:open-source-initiative"}
290 :icon{name="mdi:alert-octagon" size="5em"}
291 ```
292 </TabItem>
293 </Tabs>
294 </Fragment>
295</Repl>
296
297### Ruby
298
299<Repl>
300 <div class="flex flex-col gap-2 w-fit mx-auto">
301 <Ruby pairs={[{base: "汉", text: "hàn"}, {base: "字", text: "zì"}]} />
302 <Ruby pairs={[["漢", "ㄏㄢ"], ["字", "ㄗ"]]} />
303 <Ruby base="漢字" text="からじ" />
304 </div>
305 <Fragment slot="desc">
306 <Tabs>
307 <TabItem label="mdx" active>
308 ```jsx
309 <Ruby pairs={[{base: "汉", text: "hàn"}, {base: "字", text: "zì"}]} />
310 <Ruby pairs={[["漢", "ㄏㄢ"], ["字", "ㄗ"]]} />
311 <Ruby base="漢字" text="からじ" />
312 ```
313 </TabItem>
314 <TabItem label="md">
315 ```md
316 ::rubyc{base="汉|字" text="hàn|zì"}
317 ::rubyc{base="漢|字" text="ㄏㄢ|ㄗ"}
318 ::rubyc{base="漢字" text="からじ"}
319 ```
320 </TabItem>
321 </Tabs>
322 </Fragment>
323</Repl>
324
325## Web Contents
326
327### LinkCard
328
329<Repl>
330 <LinkCard url="https://codeberg.org/HPCesia" />
331 <LinkCard
332 url="https://codeberg.org/HPCesia/AstralHalo"
333 title="Astral Halo"
334 />
335 <LinkCard
336 title="Astro"
337 description="The all-in-one web framework designed for speed."
338 favicon = "https://astro.build/favicon.svg"
339 image = "https://astro.build/og/astro.jpg"
340 url="https://astro.build/"
341 />
342 <Fragment slot="desc">
343 <Tabs>
344 <TabItem label="mdx" active>
345 ```jsx
346 <LinkCard url="https://codeberg.org/HPCesia" />
347 <LinkCard
348 url="https://codeberg.org/HPCesia/AstralHalo"
349 title="Astral Halo"
350 />
351 <LinkCard
352 title="Astro"
353 description="The all-in-one web framework designed for speed."
354 favicon = "https://astro.build/favicon.svg"
355 image = "https://astro.build/og/astro.jpg"
356 url="https://astro.build/"
357 />
358 ```
359 </TabItem>
360 <TabItem label="md">
361 ```md
362 ::linkcard{url="https://codeberg.org/HPCesia"}
363 ::linkcard{url="https://codeberg.org/HPCesia/AstralHalo" title="Astral Halo"}
364 ::linkcard{title="Astro" description="The all-in-one web framework designed for speed." favicon="https://astro.build/favicon.svg" image="https://astro.build/og/astro.jpg" url="https://astro.build/"}
365 ```
366 </TabItem>
367 </Tabs>
368 </Fragment>
369</Repl>
370
371> [!TIP]
372> `LinkCard`'s preview data is fetched on build time, the output is static.
373
374### RepoCard
375
376<Repl>
377 <RepoCard repo="HPCesia/astral-halo" platform='github' />
378 <RepoCard repo="HPCesia/AstralHalo" platform='forgejo' host='https://codeberg.org' icon='simple-icons:codeberg' />
379 <RepoCard repo="gitea/awesome-gitea" platform='gitea' host='https://gitea.com' icon='simple-icons:gitea' />
380 <Fragment slot="desc">
381 ```jsx
382 <RepoCard repo="HPCesia/astral-halo" platform='github' />
383 <RepoCard repo="HPCesia/AstralHalo" platform='forgejo' host='https://codeberg.org' icon='simple-icons:codeberg' />
384 <RepoCard repo="gitea/awesome-gitea" platform='gitea' host='https://gitea.com' icon='simple-icons:gitea' />
385 ```
386 </Fragment>
387</Repl>