Astro

Components

Terminal-kommandoer

npm create astro@latest .

Start et nyt projekt

OBS! Kun én gang pr. projekt

I gruppeprojekter, er der kun én, der skal køre denne

Terminal-kommandoer

npm install

Installer et eksisterende projekt (package.json)

Mangler node_modules, så kør denne

Terminal-kommandoer

npm run dev

"Live server"

Terminal-kommandoer

ctrl + c

Stop server

Luk den, når du er færdig for dagen, eller inden du evt. opstarter et nyt projekt

Hvornår er noget en component?

  • En genbrugelig skabelon, der kan modtage data
  • Hvis noget html skal copy/pastes, så er det nok en component
  • Hvis du kan give det et navn (a la footer) så er det nok en component

Fra HTML til Astro

<header>
  <h1>Heading</h1>
  <nav>
    <ul>
      <li><a href="#">Home</a></li>
      <li><a href="#">About</a></li>
      <li><a href="#">Contact</a></li>
    </ul>
  </nav>
</header>

<section id="hero">
  <h2>Dette er et Hero-Image</h2>
  <p>Her er noget introduktionstekst om denne side.</p>
  <button>Lær Mere</button>
</section>

<section id="services">
  <h2>Vores Services</h2>
  <div class="service">
    <h3>Service 1</h3>
    <p>Beskrivelse af service 1.</p>
  </div>
  <div class="service">
    <h3>Service 2</h3>
    <p>Beskrivelse af service 2.</p>
  </div>
  <div class="service">
    <h3>Service 3</h3>
    <p>Beskrivelse af service 3.</p>
  </div>
</section>

<footer>
  <p>© 2024 Min Side. Alle rettigheder forbeholdes.</p>
</footer>
<header>
  <h1>Velkommen til Min Side</h1>
  <nav>
    <ul>
      <li><a href="#">Home</a></li>
      <li><a href="#">About</a></li>
      <li><a href="#">Contact</a></li>
    </ul>
  </nav>
</header>
<header>
  <h1>Heading</h1>
  <nav>
    <ul>
      <li><a href="#">Home</a></li>
      <li><a href="#">About</a></li>
      <li><a href="#">Contact</a></li>
    </ul>
  </nav>
</header>

<section id="hero">
  <h2>Dette er et Hero-Image</h2>
  <p>Her er noget introduktionstekst om denne side.</p>
  <button>Lær Mere</button>
</section>

<section id="services">
  <h2>Vores Services</h2>
  <div class="service">
    <h3>Service 1</h3>
    <p>Beskrivelse af service 1.</p>
  </div>
  <div class="service">
    <h3>Service 2</h3>
    <p>Beskrivelse af service 2.</p>
  </div>
  <div class="service">
    <h3>Service 3</h3>
    <p>Beskrivelse af service 3.</p>
  </div>
</section>

<footer>
  <p>© 2024 Min Side. Alle rettigheder forbeholdes.</p>
</footer>
<section id="hero">
  <h2>Dette er et Hero-Image</h2>
  <p>Her er noget introduktionstekst om denne side.</p>
  <button>Lær Mere</button>
</section>
<div class="service">
  <h3>Service 1</h3>
  <p>Beskrivelse af service 1.</p>
</div>
<section id="services">
  <h2>Vores Services</h2>
  <Service />
  <Service />
  <Service />
</section>

Fra HTML til Astro

Fra HTML til Astro

<header>
  <h1>Velkommen til Min Side</h1>
  <nav>
    <ul>
      <li><a href="#">Home</a></li>
      <li><a href="#">About</a></li>
      <li><a href="#">Contact</a></li>
    </ul>
  </nav>
</header>
<header>
  <h1>Heading</h1>
  <nav>
    <ul>
      <li><a href="#">Home</a></li>
      <li><a href="#">About</a></li>
      <li><a href="#">Contact</a></li>
    </ul>
  </nav>
</header>

<section id="hero">
  <h2>Dette er et Hero-Image</h2>
  <p>Her er noget introduktionstekst om denne side.</p>
  <button>Lær Mere</button>
</section>

<section id="services">
  <h2>Vores Services</h2>
  <div class="service">
    <h3>Service 1</h3>
    <p>Beskrivelse af service 1.</p>
  </div>
  <div class="service">
    <h3>Service 2</h3>
    <p>Beskrivelse af service 2.</p>
  </div>
  <div class="service">
    <h3>Service 3</h3>
    <p>Beskrivelse af service 3.</p>
  </div>
</section>

<footer>
  <p>© 2024 Min Side. Alle rettigheder forbeholdes.</p>
</footer>
<section id="hero">
  <h2>Dette er et Hero-Image</h2>
  <p>Her er noget introduktionstekst om denne side.</p>
  <button>Lær Mere</button>
</section>
<div class="service">
  <h3>Service 1</h3>
  <p>Beskrivelse af service 1.</p>
</div>
<section id="services">
  <h2>Vores Services</h2>
  <Service />
  <Service />
  <Service />
</section>
<header>
  <h1>Velkommen til Min Side</h1>
  <nav>
    <ul>
      <li><a href="#">Home</a></li>
      <li><a href="#">About</a></li>
      <li><a href="#">Contact</a></li>
    </ul>
  </nav>
</header>
<section id="hero">
  <h2>Dette er et Hero-Image</h2>
  <p>Her er noget introduktionstekst om denne side.</p>
  <button>Lær Mere</button>
</section>
<div class="service">
  <h3>Service 1</h3>
  <p>Beskrivelse af service 1.</p>
</div>
<section id="services">
  <h2>Vores Services</h2>
  <Service />
  <Service />
  <Service />
</section>
<Layout>
  <Hero />
  <Services />
</Layout>
<header>
  <h1>Heading</h1>
  <nav>
    <ul>
      <li><a href="#">Home</a></li>
      <li><a href="#">About</a></li>
      <li><a href="#">Contact</a></li>
    </ul>
  </nav>
</header>

<section id="hero">
  <h2>Dette er et Hero-Image</h2>
  <p>Her er noget introduktionstekst om denne side.</p>
  <button>Lær Mere</button>
</section>

<section id="services">
  <h2>Vores Services</h2>
  <div class="service">
    <h3>Service 1</h3>
    <p>Beskrivelse af service 1.</p>
  </div>
  <div class="service">
    <h3>Service 2</h3>
    <p>Beskrivelse af service 2.</p>
  </div>
  <div class="service">
    <h3>Service 3</h3>
    <p>Beskrivelse af service 3.</p>
  </div>
</section>

<footer>
  <p>© 2024 Min Side. Alle rettigheder forbeholdes.</p>
</footer>

Fra HTML til Astro

<Layout>
  <Hero />
  <Services />
</Layout>
<header>
  <h1>Heading</h1>
  <nav>
    <ul>
      <li><a href="#">Home</a></li>
      <li><a href="#">About</a></li>
      <li><a href="#">Contact</a></li>
    </ul>
  </nav>
</header>

<section id="hero">
  <h2>Dette er et Hero-Image</h2>
  <p>Her er noget introduktionstekst om denne side.</p>
  <button>Lær Mere</button>
</section>

<section id="services">
  <h2>Vores Services</h2>
  <div class="service">
    <h3>Service 1</h3>
    <p>Beskrivelse af service 1.</p>
  </div>
  <div class="service">
    <h3>Service 2</h3>
    <p>Beskrivelse af service 2.</p>
  </div>
  <div class="service">
    <h3>Service 3</h3>
    <p>Beskrivelse af service 3.</p>
  </div>
</section>

<footer>
  <p>© 2024 Min Side. Alle rettigheder forbeholdes.</p>
</footer>

Fra HTML til Astro

Opbygning

Astro-components

---

---

<article>
  <h2></h2>
  <p></p>
</article>

<style>
  article {...}
</style>

"Single file component", som betyder, at vi samler al relevant HTML, CSS (og JavaScript) i den enkelte component

Opbygning

Astro-components

---

---

<article>
  <h2></h2>
  <p></p>
</article>

<style>
  article {...}
</style>

<script>
  ...
</script>

"Single file component", som betyder, at vi samler al relevant HTML, CSS (og JavaScript) i den enkelte component

Fences

Astro-components og pages

---

---

"Frontmatter"

import "../styles/global.css"
---

---
import "../styles/global.css"
import Component from "../components/Component.astro"

Importer stylesheet

Fences

Astro-components og pages

---

---
import "../styles/global.css"
import Component from "../components/Component.astro"
const { prop } = Astro.props;

Importer component

Fences

Astro-components og pages

---

---
import "../styles/global.css"
import Component from "../components/Component.astro"
const { prop } = Astro.props;

Saml props op

const now = new Date();
const localTime = now.toLocaleTimeString("da-DK");

Fences

Astro-components og pages

---


---
import "../styles/global.css"
const { prop } = Astro.props;

JavaScript på serveren ("build time")

const now = new Date();
const localTime = now.toLocaleTimeString("da-DK");

Fences

Astro-components og pages

---


---

<p>Hej, klokken er {localTime}</p>

JavaScript på serveren ("build time")

const now = new Date();
const localTime = now.toLocaleTimeString("da-DK");

Hvad var klokken, der jeg byggede siden (statisk)

Fences

Astro-components og pages

Components

Header.astro

Button.astro

Footer.astro

Card.astro

CardSection.astro

Hero.astro

Components

Opbygning

Astro-components

├── src/
    └── components/
    	└── Header.astro
    	└── CardSection.astro
    	└── 
    	└── Button.astro
    	└── Footer.astro
Card.astro

Opbygning

Astro-components

<li>
  <h3>Animation</h3>
  <p>
    Learn the latest animation techniques to create stunning motion
    design and captivate your audience.
  </p>
  <a href="/animation" class="btn" data-variant="ghost">Get started</a>
</li>
Card.astro

Opbygning

Astro-components

---
import Card from "../components/          ";
---

<Card />
<Card />
<Card />
<Card />
<Card />
<Card />
Card.astro

Konvention: Samme navn

😕

Props

Astro-components

<li>
  <h3>Animation</h3>
  <p>
    Learn the latest animation techniques to create stunning motion
    design and captivate your audience.
  </p>
  <a href="/animation" class="btn" data-variant="ghost">Get started</a>
</li>
Card.astro

Props

Astro-components

<li>
  <h3>{title}</h3>
  <p>
    {body}
  </p>
  <a href={link} class="btn" data-variant="ghost">Get started</a>
</li>
Card.astro

Props

Astro-components

---
const { title, body, link } = Astro.props;
---

<li>
  <h3>{title}</h3>
  <p>
    {body}
  </p>
  <a href={link} class="btn" data-variant="ghost">Get started</a>
</li>
Card.astro

Props

Astro-components

---
import Card from "../components/          ";
---

<Card
      title="Animation"
      body="This is the body of Animation."
      link="/animation" />
<Card
      title="Design"
      body="This is the body of Design."
      link="/design" />
Card.astro

Hvert card har nu forskelligt indhold

---
import Card from "../components/          ";
---

<Card
      title="Animation"
      body="This is the body of Animation."
      link="/animation" />
Card.astro
---
const { title, body, link } = Astro.props;
---

<li>
  <h3>{title}</h3>
  <p>
    {body}
  </p>
  <a href={link}>Get started</a>
</li>

øvelse

Fra HTML til Astro

Lav Astro-components på baggrund af eksisterende HTML (se øvelsen på Fronter)

øvelse

Fra HTML til Astro

Lav Astro-components på baggrund af eksisterende HTML (se øvelsen på Fronter)

Tilgange til components

Tilgange til components

Hvor starter man?

<article>
  <h2>Jeg er en overskrift</h2>
  <p>Jeg er en beskrivelse.</p>
</article>

Hvordan skal strukturen være?

<Card title="Jeg er en overskrift"
      description="Jeg er en beskrivelse"
/>

Hvordan vil jeg gerne bruge den?

Udefra og ind

Først API, og så markup

<Card title="Jeg er en overskrift"
      description="Jeg er en beskrivelse"
/>

<Card title="Jeg er anderledes"
      description="Også mig..."
/>

God DX... måske?

Indefra og ud

Først markup, og så props

<article>
  <h2>Jeg er en overskrift</h2>
  <p>Jeg er en beskrivelse.</p>
</article>

God til prototype..?

Ikon

Titel

Knap

Beskrivelse

Ikon

Titel

Knap

Beskrivelse

Ikon

Titel

Knap

Beskrivelse

<Card iconName="running-man"
      title="Animation"
      description="Learn the latest..."
      link="/animation" />

"Variants"

Samme knap, forskelligt udseende

"primary"

"accent"

"secondary"

"ghost"

"Variants"

Samme knap, forskelligt udseende

<Button variant="primary">Get Started</Button>
<Button variant="accent">Get Started</Button>
<Button variant="secondary">Get Started</Button>
<Button variant="ghost">Get Started</Button>
<Button variant="primary" label="Get Started" />
---
const { variant } = Astro.props;
---

<button class={variant}>
  <slot />
</button>

<style>
  .primary {}
  .secondary {}
  .accent {}
  .ghost {}
</style>
<button>
  <slot />
</button>
<Button variant="secondary">Get started</Button>
<button>
  <slot />
</button>
Get started
<Button variant="secondary">Get started</Button>
<button>
  <slot />
</button>
Get started

Components

PlaylistCard

Shelf

Button

Sidebar

Navigation

Footer

Components

PlaylistCard

Shelf

Button

Sidebar

Navigation

Footer

Button

Primær

Sekundær

Tertiær

variant props

Button

<Button
  variant="primary">
  Log in
</Button>

MEDIUM

SMALL

size props

Button

<Button
  variant="primary"
  size="medium">
  Log in
</Button>

MEDIUM

SMALL

Button

---
const { variant } = Astro.props;
---

<button class={variant}>
  <slot />
</button>

<style>
  .primary { ... }
</style>

MEDIUM

SMALL

Button

---
const { variant, size } = Astro.props;
---

<button class={`${variant} ${size}`}>
  <slot />
</button>

<style>
  .primary { ... }
  .medium { ... }
</style>

øvelse

Props & Variants

Sæt knapper op, så de kan blive vist forskelligt på baggrund af props (se øvelsen på Fronter)

Pages

speciel mappe

Pages

  • I /pages-mappen findes diverse (under)sider
  • Filer, der ender på .astro eller endda .html
  • Sider i /pages begynder altid med små bogstaver, selvom de har endelsen .astro (til forskel fra components)
  • Der kan linkes imellem siderne med et normalt a-tag:
<nav>
  <a href="/">Home</a> <!-- index.astro -->
  <a href="/search">Search</a> <!-- search.astro -->
</nav>

Genbrugelige sideskabeloner

Layout-components

<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
    <meta name="viewport" content="width=device-width" />
    <meta name="generator" content={Astro.generator} />
    <title>Search</title>
  </head>
  <body>
    <h1>Search</h1>
  </body>
</html>

point of interest

---
import MainLayout from '../layouts/MainLayout.astro';
---
<MainLayout title="Search">
  <h1>Search</h1>
</MainLayout>

point of interest

skabelon med prop

Genbrugelige sideskabeloner

Layout-components

---
const { title } = Astro.props;
---
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
    <meta name="viewport" content="width=device-width" />
    <meta name="generator" content={Astro.generator} />
    <title>{title}</title>
  </head>
  <body>
    <slot />
  </body>
</html>

prop

---
import MainLayout from '../layouts/MainLayout.astro';
---
<MainLayout title="Search">
  <h1>Search</h1>
</MainLayout>

Genbrugelige sideskabeloner

Layout-components

---
const { title } = Astro.props;
---
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
    <meta name="viewport" content="width=device-width" />
    <meta name="generator" content={Astro.generator} />
    <title>{title}</title>
  </head>
  <body>
    <slot />
  </body>
</html>
---
import MainLayout from '../layouts/MainLayout.astro';
---
<MainLayout title="Search">
  <h1>Search</h1>
</MainLayout>

sideindhold her

Genbrugelige sideskabeloner

Layout-components

We conventionally use the term “layout” for Astro components that provide common UI elements shared across pages such as headers, navigation bars, and footers.

Genbrugelige sideskabeloner

Layout-components

Layout-components

---
const { title } = Astro.props;
---
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
    <meta name="viewport" content="width=device-width" />
    <meta name="generator" content={Astro.generator} />
    <title>{title}</title>
  </head>
  <body>
    <Header />
    <Sidebar />
    <main>
   	  <slot />
    </main>
    <Footer />
  </body>
</html>

Layout-components

Layout-components

Layout-components

---
const { title } = Astro.props;
---
<section>
  <h3>{title}</h3>
  <div>
    <slot /> <!-- indhold -->
  </div>
</section>


<style>
  div {
    display: flex;
    /*....*/
  }
</style>

Skal vi bygge Instagram-light?

Start nyt projekt

npm create astro@latest .

Start nyt projekt

npm create astro@latest .

Start nyt projekt

Astro Components

By Dannie Vinther

Astro Components

Props & layouts

  • 53