0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2024-12-16 21:46:22 -05:00

WIP: adding an E2E fixture to test stores and context locally

This commit is contained in:
Tony Sullivan 2022-06-05 10:54:31 -05:00
parent 1b205c2b42
commit 2bcf642eb0
16 changed files with 365 additions and 0 deletions

View file

@ -155,4 +155,7 @@ export function derived<T>(stores: Stores, fn: Function, initialValue?: T): Read
});
}
console.log("SSR?", typeof window === 'undefined');
export const store = typeof window === 'undefined' ? readable : writable;
export const get = getStoreValue;

View file

@ -0,0 +1,12 @@
import { defineConfig } from 'astro/config';
import preact from '@astrojs/preact';
import react from '@astrojs/react';
import svelte from '@astrojs/svelte';
import vue from '@astrojs/vue';
import solid from '@astrojs/solid-js';
// https://astro.build/config
export default defineConfig({
// Enable many frameworks to support all different kinds of components.
integrations: [preact(), react(), svelte(), vue(), solid()],
});

View file

@ -0,0 +1,25 @@
{
"name": "@e2e/multiple-frameworks-stores",
"version": "0.0.0",
"private": true,
"devDependencies": {
"@astrojs/lit": "workspace:*",
"@astrojs/preact": "workspace:*",
"@astrojs/react": "workspace:*",
"@astrojs/solid-js": "workspace:*",
"@astrojs/store": "workspace:*",
"@astrojs/svelte": "workspace:*",
"@astrojs/vue": "workspace:*",
"astro": "workspace:*"
},
"dependencies": {
"@webcomponents/template-shadowroot": "^0.1.0",
"lit": "^2.2.5",
"preact": "^10.7.3",
"react": "^18.1.0",
"react-dom": "^18.1.0",
"solid-js": "^1.4.3",
"svelte": "^3.48.0",
"vue": "^3.2.36"
}
}

View file

@ -0,0 +1,7 @@
---
const { id } = Astro.props
---
<div id={id} class="children">
<h1>Hello Astro (A)</h1>
</div>

View file

@ -0,0 +1,7 @@
---
const { id } = Astro.props
---
<div id={id} class="children">
<h1>Hello Astro (B)</h1>
</div>

View file

@ -0,0 +1,33 @@
import { LitElement, html } from 'lit';
export const tagName = 'my-counter';
class Counter extends LitElement {
static get properties() {
return {
count: {
type: Number,
},
};
}
constructor() {
super();
this.count = 0;
}
increment() {
this.count++;
}
render() {
return html`
<div>
<p>Count: ${this.count}</p>
<button type="button" @click=${this.increment}>Increment</button>
</div>
`;
}
}
customElements.define(tagName, Counter);

View file

@ -0,0 +1,20 @@
import { h } from 'preact';
import { getContext } from '@astrojs/store';
import { useStore } from '@astrojs/preact/store';
/** a counter written in Preact */
export function PreactCounter({ children, id }) {
const counter = getContext('counter');
const state = useStore(counter);
return (
<>
<div id={id} class="counter">
<button class="decrement" onClick={counter.decrement}>-</button>
<pre>{state.count}</pre>
<button class="increment" onClick={counter.increment}>+</button>
</div>
<div class="counter-message">{children}</div>
</>
);
}

View file

@ -0,0 +1,20 @@
import { React } from 'react';
import { getContext } from '@astrojs/store';
import { useStore } from '@astrojs/react/store';
/** a counter written in React */
export function Counter({ children, id }) {
const counter = getContext('counter');
const state = useStore(counter);
return (
<>
<div id={id} className="counter">
<button className="decrement" onClick={counter.decrement}>-</button>
<pre>{state.count}</pre>
<button className="increment" onClick={counter.increment}>+</button>
</div>
<div className="counter-message">{children}</div>
</>
);
}

View file

@ -0,0 +1,23 @@
import { createSignal } from 'solid-js';
import { getContext } from '@astrojs/store';
import { useStore } from '@astrojs/solid-js/store';
/** a counter written with Solid */
export default function SolidCounter({ children, id }) {
// TODO: Astro can't resolve the renderer without this?
const test = createSignal(0);
const counter = getContext('counter');
const state = useStore(counter);
return (
<>
<div id={id} class="counter">
<button class="decrement" onClick={counter.decrement}>-</button>
<pre>{state().count}</pre>
<button class="increment" onClick={counter.increment}>+</button>
</div>
<div class="counter-message">{children}</div>
</>
);
}

View file

@ -0,0 +1,25 @@
<script>
import { useStore } from '@astrojs/svelte/store';
import { getContext } from '@astrojs/store';
export let id;
const counter = getContext('counter');
const state = useStore(counter);
</script>
<div {id} class="counter">
<button class="decrement" on:click={counter.decrement}>-</button>
<pre>{ $state.count }</pre>
<button class="increment" on:click={counter.increment}>+</button>
</div>
<div class="counter-message">
<slot />
</div>
<style>
.counter {
background: white;
}
</style>

View file

@ -0,0 +1,34 @@
<template>
<div :id="id" class="counter">
<button class="decrement" @click="decrement">-</button>
<pre>{{ state.count }}</pre>
<button class="increment" @click="increment">+</button>
</div>
<div class="counter-message">
<slot />
</div>
</template>
<script>
import { useStore } from '@astrojs/vue/store';
import { getContext } from '@astrojs/store';
export default {
props: {
id: {
type: String,
required: true
}
},
setup(props) {
const counter = getContext('counter');
const state = useStore(counter);
return {
id: props.id,
state,
increment: counter.increment,
decrement: counter.decrement,
};
},
};
</script>

View file

@ -0,0 +1,2 @@
export { default as A } from './A.astro';
export { default as B } from './B.astro';

View file

@ -0,0 +1,69 @@
---
// Style Imports
import '../styles/global.css';
// Component Imports
import { A, B as Renamed } from '../components';
import * as react from '../components/ReactCounter.jsx';
import { PreactCounter } from '../components/PreactCounter.tsx';
import SolidCounter from '../components/SolidCounter.tsx';
import VueCounter from '../components/VueCounter.vue';
import SvelteCounter from '../components/SvelteCounter.svelte';
import createCounter from '../stores/counter';
import { setContext } from '@astrojs/store';
const state = {
count: 0
};
const counter = createCounter(state);
setContext("counter", counter);
// Full Astro Component Syntax:
// https://docs.astro.build/core-concepts/astro-components/
---
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
<script>
import createCounter from '../stores/counter';
import { setContext } from '@astrojs/store';
const counter = createCounter({
count: 0
});
setContext('counter', counter);
</script>
</head>
<body>
<main>
<react.Counter id="react-counter" client:idle>
<h1>Hello React!</h1>
<p>What's up?</p>
</react.Counter>
<PreactCounter id="preact-counter" client:idle>
<h1>Hello Preact!</h1>
</PreactCounter>
<SolidCounter id="solid-counter" client:idle>
<h1>Hello Solid!</h1>
</SolidCounter>
<VueCounter id="vue-counter" client:idle>
<h1>Hello Vue!</h1>
</VueCounter>
<SvelteCounter id="svelte-counter" client:idle>
<h1>Hello Svelte!</h1>
</SvelteCounter>
<A id="astro-a" />
<Renamed id="astro-b" />
</main>
</body>
</html>

View file

@ -0,0 +1,26 @@
import { Readable, writable, store } from '@astrojs/store';
export interface CounterState {
count: number;
}
export interface CounterStore extends Readable<CounterState> {
increment(): void;
decrement(): void;
reset(): void;
}
export default function createCounter(initial: CounterState = { count: 0 }): CounterStore {
const { subscribe, set, update } = store<CounterState>(initial);
return {
subscribe,
increment: () => update(({ count }) => ({
count: count + 1
})),
decrement: () => update(({ count }) => ({
count: count - 1
})),
reset: () => set({ count: 0 })
}
}

View file

@ -0,0 +1,21 @@
html,
body {
font-family: system-ui;
margin: 0;
}
body {
padding: 2rem;
}
.counter {
display: grid;
font-size: 2em;
grid-template-columns: repeat(3, minmax(0, 1fr));
margin-top: 2em;
place-items: center;
}
.counter-message {
text-align: center;
}

View file

@ -761,6 +761,43 @@ importers:
'@astrojs/vue': link:../../../../integrations/vue
astro: link:../../..
packages/astro/e2e/fixtures/multiple-frameworks-stores:
specifiers:
'@astrojs/lit': ^0.1.4
'@astrojs/preact': ^0.1.3
'@astrojs/react': ^0.1.3
'@astrojs/solid-js': ^0.1.3
'@astrojs/store': workspace:*
'@astrojs/svelte': ^0.1.4
'@astrojs/vue': ^0.1.5
'@webcomponents/template-shadowroot': ^0.1.0
astro: ^1.0.0-beta.38
lit: ^2.2.5
preact: ^10.7.3
react: ^18.1.0
react-dom: ^18.1.0
solid-js: ^1.4.3
svelte: ^3.48.0
vue: ^3.2.36
dependencies:
'@webcomponents/template-shadowroot': 0.1.0
lit: 2.2.5
preact: 10.7.3
react: 18.1.0
react-dom: 18.1.0_react@18.1.0
solid-js: 1.4.3
svelte: 3.48.0
vue: 3.2.36
devDependencies:
'@astrojs/lit': link:../../../../integrations/lit
'@astrojs/preact': link:../../../../integrations/preact
'@astrojs/react': link:../../../../integrations/react
'@astrojs/solid-js': link:../../../../integrations/solid
'@astrojs/store': link:../../../../astro-store
'@astrojs/svelte': link:../../../../integrations/svelte
'@astrojs/vue': link:../../../../integrations/vue
astro: link:../../..
packages/astro/e2e/fixtures/nested-in-preact:
specifiers:
'@astrojs/preact': workspace:*
@ -1874,6 +1911,7 @@ importers:
packages/integrations/svelte:
specifiers:
'@astrojs/store': workspace:*
'@sveltejs/vite-plugin-svelte': ^1.0.0-next.47
astro: workspace:*
astro-scripts: workspace:*