11
Layout, Sidebar, dan Tema
Halaman-halaman FreeStuffDev tidak menulis kerangka HTML sendiri. Berkas src/layouts/Layout.astro mengimpor ../styles/main.sass, memasang <ViewTransitions /> dari astro:transitions, mengimpor Sidebar, serta mendeklarasikan interface Props berisi title, description, dan noIndex. src/layouts/Layout.astro:1-191 Setiap halaman memakai pola yang sama: <Layout> di lapisan luar, <Header> di dalam, lalu konten halaman. src/pages/index.astro:21-292
Satu kerangka, satu slot
Diagram berikut menunjukkan pembagian tugas antara halaman, Layout, dan komponen lain. Satu-satunya jalur masuk konten halaman adalah slot bawaan.
graph TD
Page["halaman di src/pages/*.astro"] --> Layout["Layout.astro"]
Page --> Header["Header.astro"]
Layout --> Sass["../styles/main.sass"]
Layout --> VT["ViewTransitions"]
Layout --> Sidebar["Sidebar.astro"]
Layout --> Slot["slot default di dalam main"]
Sidebar --> AllTags["AllTags.astro"]
Header -. "children" .-> Slot
style Layout fill:#2d7d46,color:#fff
style Sass fill:#f59e0b,color:#000
style VT fill:#8b5cf6,color:#fff
style AllTags fill:#8b5cf6,color:#fff
%% fig: Pohon komponen Layout dan slot
%% desc: Halaman mengisi slot Layout, sementara Layout memasang Sidebar, main.sass, dan ViewTransitions.<body> hanya berisi satu <div> pembungkus; di dalamnya ada <Sidebar /> dan <main>, dan isi halaman masuk lewat <slot /> yang diletakkan sebagai anak terakhir <main>. src/layouts/Layout.astro:92-1123 src/layouts/Layout.astro:110-1114 Sebelum slot, <main> membuka <section class="flex justify-end space-x-3 mb-5"> berisi tiga tautan ikon: repository GitHub di hilmanski/freeStuffDev, akun @fullofdev, dan /about. src/layouts/Layout.astro:96-1085
Prop yang diterima Layout
Kontrak Layout hanya tiga prop, dan hanya noIndex yang opsional.
| Prop | Tipe | Wajib | Yang dihasilkan |
|---|---|---|---|
title | string | ya | <title> dan og:title |
description | string | ya | meta description dan og:description |
noIndex | boolean | tidak, default false | <meta name="robots" content="noindex" /> bila true |
Tipe ketiganya dideklarasikan di interface Props dan di-destructure dengan noIndex = false. src/layouts/Layout.astro:7-116 Untuk title dan description, Layout merender <title>, <meta name="description">, lalu tiga meta og:; perhatikan tag meta deskripsi mencampur atribut name dan property dalam satu tag, dan og:description diulang pada tag terpisah. src/layouts/Layout.astro:29-447 Cabang noIndex && menyisipkan meta robots hanya ketika prop itu true. src/layouts/Layout.astro:32-368 Dari tujuh halaman, tiga memakainya: about, submit, dan favorites. src/pages/favorites.astro:14-189
Sidebar: identitas dan navigasi situs
Sidebar.astro membuka <header id="sidebar"> dan mengisinya dengan logo /freestuffdev-logo.webp berukuran w-[100px] md:w-[250px], tautan ke /, nama situs, serta tagline italic. src/layouts/Sidebar.astro:5-2410 Setelah itu ada <nav class="flex space-x-3 my-5"> dengan dua tombol bergaya border-rose-300 hover:bg-rose-400 hover:text-white: Submit+ ke /submit dan Saved ke /favorites. src/layouts/Sidebar.astro:26-2911 Di bawahnya <AllTags /> dipanggil dari ../components/AllTags.astro; komponen itu merender daftar tag dan menyimpan tombol Show Categories untuk layar kecil. src/layouts/Sidebar.astro:1-3 src/layouts/Sidebar.astro:31 src/components/AllTags.astro:52-62 Rincian isi daftar tag dibahas di Indeks Tag dan Halaman Tag, dan alur tombol Submit+ di Alur Form Submit ke Pull Request.
Blok sponsor masih ada di berkas ini, tetapi dinonaktifkan sebagai komentar HTML, sehingga tidak ikut ter-render. src/layouts/Sidebar.astro:33-4015 Atribut id="sidebar" itulah satu-satunya pengait yang dipakai main.sass untuk menata panel ini.
Header: judul yang dikirim halaman
Header.astro tidak punya logika frontmatter: nilai title dan description dibaca dari Astro.props lalu dirender sebagai <h1 class="text-2xl"> dan <h2 class="max-w-2xl mx-auto"> di dalam <div class="text-center md:mb-15 mb-10">. src/components/Header.astro:1-1216
⚠️ Kelas
md:mb-15tidak ada di skala spacing bawaan Tailwind, dantailwind.config.mjstidak menambah spacing sendiri, sehingga kelas itu tidak menghasilkan CSS. Jarak bawah header tetapmb-10di semua lebar. src/components/Header.astro:1-1216 tailwind.config.mjs:1-817
Tema gelap dari main.sass
Berkas src/styles/main.sass adalah entri Tailwind sekaligus sumber warna situs: ia memuat @tailwind base, @tailwind components, dan @tailwind utilities. src/styles/main.sass:1-318 Sisanya adalah aturan global bernilai hex tetap.
Diagram berikut memisahkan tiga lapisan yang bertemu: konfigurasi Tailwind, utility class di komponen, dan aturan global di main.sass beserta media query-nya.
graph LR
CFG["tailwind.config.mjs: content globs"] --> TW["@tailwind base, components, utilities"]
TW --> UT["utility class di Layout, Sidebar, Header"]
MS["main.sass global: body, a, #sidebar, main"] --> DARK["tampilan gelap"]
MS --> MQ["@media 1200px, 1300px, 768px"]
UT --> DARK
MQ --> DARK
style CFG fill:#f59e0b,color:#000
style MS fill:#f59e0b,color:#000
style TW fill:#8b5cf6,color:#fff
style MQ fill:#dc2626,color:#fff
style DARK fill:#2d7d46,color:#fff
%% fig: Lapisan gaya yang membentuk tema gelap
%% desc: main.sass menjadi entri Tailwind sekaligus sumber warna gelap, dan media query menimpanya pada lebar tertentu.| Selector | Deklarasi | Nilai |
|---|---|---|
body | background, color, font-size | #363940, #F6F7F9, 16px |
a | color, &:hover color | #f6bfd4, #f08383 |
#sidebar | background, min-width, width, padding, position, min-height | #262628, 350px, 20%, 30px, fixed, 100% |
main | margin-left, padding, max-width, display | 350px, 30px, 900px, block |
Warna tautan #f6bfd4 dan sorotan hover #f08383 senada dengan tombol bernuansa rose di Sidebar. src/styles/main.sass:5-1319 src/layouts/Sidebar.astro:26-2911 Panel sidebar ditata position: fixed, background: #262628, min-width: 350px, dan width: 20%, sedangkan main diberi margin-left: 350px serta max-width: 900px. src/styles/main.sass:15-2120 src/styles/main.sass:23-2721
Tidak ada satu pun kelas dark: di repository ini, dan tailwind.config.mjs hanya mengisi content dengan glob ./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue} sementara theme.extend kosong. tailwind.config.mjs:1-817 Jadi tampilan gelap berasal dari nilai hex di main.sass, bukan dari varian mode gelap Tailwind.
Dua sistem breakpoint yang berdampingan
| Media query | Berkas | Yang berubah |
|---|---|---|
max-width: 1200px | main.sass | #sidebar menjadi position: relative, width: 100%, max-width: 100%; main menjadi margin-left: 0, max-width: 95% |
min-width: 1300px | main.sass | main memakai margin-left: max(calc(20% + 50px), 350px) |
max-width: 768px | main.sass | .sponsors a dan .sponsors img |
Ketiga blok itu adalah satu-satunya breakpoint yang ditulis manual, dan tidak ada satu pun yang menyentuh min-width. src/styles/main.sass:29-4022 src/styles/main.sass:42-4423 src/styles/main.sass:47-60 Di sisi lain, komponen memakai utility md: dan lg: — misalnya md:block pada pembungkus logo sidebar dan lg:hidden/lg:block pada AllTags — yang dihitung dari breakpoint bawaan Tailwind karena theme.screens tidak diubah. src/layouts/Sidebar.astro:5-24 src/components/AllTags.astro:52-62 tailwind.config.mjs:1-8
⚠️
#sidebartetap memaksamin-width: 350pxdi semua lebar: media querymax-width: 1200pxhanya me-resetwidthdanmax-width, tidakmin-width. Saat sidebar berubah menjadiposition: relative, batas minimum itu masih berlaku dan bisa memaksa scroll horizontal di layar sempit. src/styles/main.sass:15-2120 src/styles/main.sass:29-4022
Bagian lain di dalam Layout
Dua hal menempel di Layout di luar urusan visual. Pertama, <ViewTransitions /> dipasang di <head>. src/layouts/Layout.astro:4625 Kedua, <body> menyimpan <script is:inline> yang mengurus penyimpanan favorit di localStorage dengan kunci FAV_KEY_NAME; perilakunya dijelaskan di Fitur Favorit di Local Storage. src/layouts/Layout.astro:51-5626 Terakhir, sebelum </body> ada script analitik https://sa-api.hilman.space/latest.js beserta <noscript> berisi gambar pelacak. src/layouts/Layout.astro:11427
Perubahan pada Layout, Sidebar, dan main.sass ikut terkirim ke semua halaman sekaligus, jadi berhati-hatilah: pnpm build tidak memvalidasi tampilan, dan pemeriksaan yang tersedia hanya astro check sebelum astro build seperti dijelaskan di Build, Pemeriksaan Tipe, dan Deploy.