Saltar al contenido principal

Integraciones Framework UI

  • No se puede importar componentes de Astro dentro de otros frameworks, aunque si se pueden pasar como props.
  • Ejemplo con Svelte

Instalación

npx astro add svelte
bun astro add svelte

Componente

src\components\Counter.svelte
<script>
  let count = $state(0);
  console.log('Counter component loaded');
</script>

<h1>Counter</h1>
<h3>Value: {count}</h3>

<button onclick={() => count--}> -1 </button>
<button onclick={() => count++}> +1 </button>

Uso

---
import MainLayout from "src/layouts/MainLayout.astro";

import Counter from "@components/Counter.svelte";
---

<MainLayout title="Favoritos">
  <div
    style={{
      height: "3000px",
      backgroundColor: "blue",
      opacity: 0.2,
    }}
  >
  </div>

  <Counter client:visible />
</MainLayout>

Props

Definir props

src\components\Counter.svelte
<script lang="ts">

  interface Props {
    initValue: number;
    title: string;
  }

  let { initValue, title: description }: Props = $props();

  let count = $state(initValue);
  console.log("Counter component loaded");
</script>

<h1>{description}</h1>
<h3>Valor: {count}</h3>

<button onclick={() => count--}> -1 </button>
<button onclick={() => count++}> +1 </button>
// Otra forma de definir props
let {
initValue,
title
} : {
initValue: number;
title: string;
} = $props();

Enviar props

src\pages\favorites\index.astro
---
import Counter from "@components/Counter.svelte";
const initValue = 20;
---

<Counter
transition:persist="counter"

title="Svelte"
initValue={initValue}

client:load
/>

Preservar estado

  • Para preservar el estado de un mismo componente en diferentes páginas
  • Únicamente se agrega transition:persist="algunnombre" en el componente repetido en las diferentes páginas
  • transition:persist-props no es necesario, se utilizaba ya que si dos componentes tienen diferentes valores en los props, como el initValue de un counter, entonces al hacer counter++ no tomaba la referencia si ya se había cambiad en otro componente

Página 1

pagina1.astro
---
import Counter from "@components/Counter.svelte";
const initValue = 20;
---

<Counter
transition:persist="counter"

  title="Svelte"
  initValue={initValue}
  client:visible
/>

Página 2

pagina2.astro
---
import Counter from "@components/Counter.svelte";
const initValue = 10;
---

<Counter
  transition:persist="counter"
 
  title="Svelte"
  initValue={initValue}
  client:visible
/>

Componentes de Astro como props

Svelte

src\components\Counter.svelte
 <script lang="ts">
  interface Props {
    initValue: number;
    children: any;
  }

  let { initValue, title: description, children }: Props = $props();
  let count = $state(initValue);
</script>

{@render children?.()}

<p>Ejemplo con Svelte</p>
<h3>Valor: {count}</h3>

Pasando el componente Astro

src\pages\islands\index.astro
---
import Title from "@components/shared/Title.astro";
import Counter from "@components/Counter.svelte";
const initValue = 10;
---

<Counter
transition:persist="counter"
title="Svelte"
initValue={initValue}
client:visible
>
<Title>Titulo con Astro</Title>
</Counter>

View Transitions

  • Ya que no es un componente de Astro, entonces se debe escribir manualmente
  • Deben tener el mismo nombre, tanto en el componente de la integración, como Svelte, y en el componente de Astro.
Card.svelte
<img
src={imageSrc}
alt={pokemon.name}
width="96"
height="96"
style={`view-transition-name: ${pokemon.name}-image`}
/>
index.astro
<img
transition:name={`${name}-image`}
src={imageUrl}
alt={name}
/>