Gallery
A gallery Node that renders connected Views.
Features used in this example:
- Example on how to use Viewports and the
web-view[]
datatype.
Example
- Vanilla
- React
- Vue
- Svelte
- Solid
A gallery node that renders a connected View without using any external libraries.
manifest.yaml
name: Gallery
description: A gallery node that renders connected View.
properties.yaml
view:
datatype: web-view
slot:
datatype: web-view[]
src/main.jsx
import { For, Show } from "@nodes-js/components";
// This render function simply renders each connected View
// in a staggered way
function render() {
return (
<Show
when={context.getExtended('slot').length > 0}
fallback={<div>No Views connected to slot!</div>}
>
<div style={{ position: 'relative' }}>
<For each={context.getExtended('slot')}>
{(view, index) => (
<>
<div>{context.data?.()}</div>
</>
)}
</For>
</div>
</Show>
);
}
// Bind a function that returns JSX
context.set('view', render);
A gallery node that renders a connected View using React.
manifest.yaml
name: Gallery
description: A gallery node that renders connected View.
properties.yaml
view:
datatype: web-view
slot:
datatype: web-view[]
src/ReactComponent.tsx
import * as reactDom from 'react-dom/client';
import react from 'react';
import { setup } from 'openexus/react';
setup(context, react, reactDom);
const { useRef, useEffect } = react;
function ChildComponent(props) {
const mountingEl = useRef(null);
useEffect(() => {
props.renderFunction?.(mountingEl.current);
}, []);
return <div ref={mountingEl} />;
}
function ReactComponent() {
const [slot, setSlot] = context.use('slot');
return (
<div>
{slot &&
slot.map((renderFunction) => {
return <ChildComponent renderFunction={renderFunction} />;
})}
</div>
);
}
context.set('view', ReactComponent);
A gallery node that renders a connected View using Vue.
manifest.yaml
name: Gallery
description: A gallery node that renders connected View.
properties.yaml
view:
datatype: web-view
slot:
datatype: web-view[]
src/main.tsx
import * as vue from 'vue';
import { setup } from 'openexus/vue';
import VueComponent from './VueComponent.vue';
setup(context, vue);
context.set('view', VueComponent);
manifest.yaml
name: Gallery
description: A gallery node that renders connected View.
properties.yaml
view:
datatype: web-view
slot:
datatype: web-view[]
src/VueComponent.vue
<script setup>
import ChildComponent from './ChildComponent.vue';
const { context } = defineProps(['context'])
const slot = context.use('slot');
</script>
<template>
<div v-if="slot && Array.isArray(slot)">
<div v-for="renderFunction in slot">
<ChildComponent :renderFunction="renderFunction" />
</div>
</div>
</template>
src/ChildComponent.vue
<script setup>
import { ref, onMounted } from 'vue';
const props = defineProps(['renderFunction']);
const mountingEl = ref(null);
onMounted(() => {
if (mountingEl.value) props.renderFunction?.(mountingEl.value);
});
</script>
<template>
<div ref="mountingEl" />
</template>
A gallery node that renders a connected View using Svelte.
manifest.yaml
name: Gallery
description: A gallery node that renders connected View.
properties.yaml
view:
datatype: web-view
slot:
datatype: web-view[]
src/main.tsx
import * as svelteStore from 'svelte/store';
import * as svelte from 'svelte';
import { setup } from 'openexus/svelte';
import SvelteComponent from './SvelteComponent.svelte';
setup(context, svelte, svelteStore);
context.set('view', SvelteComponent);
src/SvelteComponent.svelte
<script>
import ChildComponent from './ChildComponent.svelte';
const slotWritable = context.use('slot');
let slot = [];
slotWritable.subscribe((value) => {
slot = value || [];
});
</script>
<div>
{#each slot as renderFunction}
<ChildComponent context={context} renderFunction={renderFunction} />
{/each}
</div>
src/ChildComponent.svelte
<script>
import { onMount } from 'svelte';
export let renderFunction;
let mountingEl;
onMount(() => {
if (mountingEl) renderFunction?.(mountingEl);
});
</script>
<div bind:this={mountingEl}></div>
A gallery node that renders a connected View using Solid.
manifest.yaml
name: Gallery
description: A gallery node that renders connected View.
properties.yaml
view:
datatype: web-view
slot:
datatype: web-view[]
src/SolidComponent.tsx
import * as solidWeb from 'solid-js/web';
import * as solid from 'solid-js';
import { setup } from 'openexus/solid';
context = setup(context, solid, solidWeb);
const { onMount, Show, For } = solid;
function ChildComponent(props) {
let mountingEl;
onMount(() => {
props.renderFunction?.(mountingEl);
});
return <div ref={mountingEl} />;
}
function SolidComponent() {
const [slot, setSlot] = context.use('slot');
return (
<Show when={Array.isArray(slot())}>
<For each={slot()}>
{(renderFunction) => <ChildComponent renderFunction={renderFunction} />}
</For>
</Show>
);
}
context.set('view', SolidComponent);