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:
parent
1b205c2b42
commit
2bcf642eb0
16 changed files with 365 additions and 0 deletions
|
@ -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;
|
||||
|
|
|
@ -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()],
|
||||
});
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
const { id } = Astro.props
|
||||
---
|
||||
|
||||
<div id={id} class="children">
|
||||
<h1>Hello Astro (A)</h1>
|
||||
</div>
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
const { id } = Astro.props
|
||||
---
|
||||
|
||||
<div id={id} class="children">
|
||||
<h1>Hello Astro (B)</h1>
|
||||
</div>
|
|
@ -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);
|
|
@ -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>
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -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>
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -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>
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -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>
|
|
@ -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>
|
|
@ -0,0 +1,2 @@
|
|||
export { default as A } from './A.astro';
|
||||
export { default as B } from './B.astro';
|
|
@ -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>
|
|
@ -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 })
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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:*
|
||||
|
|
Loading…
Reference in a new issue