Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 42 additions & 75 deletions src/pages/Examples.data.ts
Original file line number Diff line number Diff line change
@@ -1,78 +1,45 @@
interface Example {
id: string;
name: string;
description: string;
}
import { RouteDataFunc } from 'solid-app-router';
import { createResource } from 'solid-js';
import { useI18n } from '@solid-primitives/i18n';
import { Example, getExamplesDirectory, getExample } from '@solid.js/docs';

const list: Record<string, Example[]> = {
Basic: [
{
id: 'counter',
name: 'Counter',
description: 'A simple standard counter example',
},
{
id: 'todos',
name: 'Simple Todos',
description: 'Todos with LocalStorage persistence',
},
{
id: 'forms',
name: 'Form Validation',
description: 'HTML 5 validators with custom async validation',
},
{
id: 'cssanimations',
name: 'CSS Animations',
description: 'Using Solid Transition Group',
},
{
id: 'context',
name: 'Context',
description: 'A simple color picker using Context.',
},
],
Complex: [
{
id: 'clock',
name: 'Clock',
description: 'Demonstrates Solid reactivity with a real-time clock example.',
},
{
id: 'ethasketch',
name: 'Etch A Sketch',
description: 'Uses Index and createMemo to create a grid graphic.',
},
{
id: 'scoreboard',
name: 'Scoreboard',
description: 'Make use of hooks to do simple transitions',
},
{
id: 'asyncresource',
name: 'Async Resource',
description: 'Ajax requests to SWAPI with Promise cancellation',
},
{
id: 'suspensetabs',
name: 'Suspense Transitions',
description: 'Defered loading spinners for smooth UX',
},
{
id: 'simpletodos',
name: 'Simple Todos Template Literals',
description: 'Simple Todos using Lit DOM Expressions',
},
{
id: 'simpletodoshyperscript',
name: 'Simple Todos Hyperscript',
description: 'Simple Todos using Hyper DOM Expressions',
},
],
};
export interface ExamplesRouteData {
loading: boolean;
list?: [string, Example[]][];
current?: Example;
}

export const ExamplesData = () => ({
list,
});
export const ExamplesData: RouteDataFunc<ExamplesRouteData> = (props) => {
const [, { locale }] = useI18n();
const paramList = () => ({ lang: locale(), id: props.params.id });
const [examplesDirectoryResource] = createResource(paramList, async ({ lang }) => {
const requestedLang = await getExamplesDirectory(lang);
if (requestedLang) return requestedLang;
return await getExamplesDirectory('en');
});
const [exampleResource] = createResource(paramList, async ({ lang, id }) => {
const requestedLang = await getExample(lang, id);
if (requestedLang) return requestedLang;
return await getExample('en', id);
});

export type ExamplesDataRoute = ReturnType<typeof ExamplesData>;
return {
get loading() {
return examplesDirectoryResource.loading || exampleResource.loading;
},
get list() {
const examplesDirectory = examplesDirectoryResource();
if (!examplesDirectory) return undefined;
const result = examplesDirectory.reduce<Record<string, Example[]>>((acc, val) => {
const [category] = val.name.split('/');
if (!acc[category]) acc[category] = [];
acc[category].push(val);
return acc;
}, {});
return Object.entries(result);
},
get current() {
return exampleResource();
},
};
};
36 changes: 12 additions & 24 deletions src/pages/Examples.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import Repl from 'solid-repl/lib/repl';
import { NavLink, useRouteData, useParams } from 'solid-app-router';
import { For, Component, createSignal, createEffect, batch, ErrorBoundary } from 'solid-js';
import { ExamplesDataRoute } from './Examples.data';
import { ExamplesRouteData } from './Examples.data';

import { compiler, formatter } from '../components/setupRepl';
import { useI18n } from '@solid-primitives/i18n';
import { useRouteReadyState } from '../utils/routeReadyState';
import { useAppContext } from '../AppContext';
import { Example } from '@solid.js/docs';

const Examples: Component = () => {
const data = useRouteData<ExamplesDataRoute>();
const data = useRouteData<ExamplesRouteData>();
const context = useAppContext();
const [t] = useI18n();
const params = useParams<{ id: string }>();
Expand All @@ -23,26 +24,13 @@ const Examples: Component = () => {

useRouteReadyState();

createEffect(async () => {
const exampleData = (await fetch(`${location.origin}/examples/${params.id}.json`).then((r) =>
r.json(),
)) as {
files: {
name: string;
type: string;
content: string | string[];
}[];
version?: string;
};
createEffect(() => {
if (data.loading) return;
batch(() => {
const newTabs = exampleData.files.map(
(file: { name: string; type?: string; content: string | string[] }) => {
return {
name: file.name + (file.type ? `.${file.type}` : '.jsx'),
source: Array.isArray(file.content) ? file.content.join('\n') : file.content,
};
},
);
const newTabs = data.current?.files?.map((file) => ({
name: `${file.name}.${file.type}`,
source: file.content,
})) || [];
setTabs(newTabs);
setCurrent(newTabs[0].name);
});
Expand All @@ -53,11 +41,11 @@ const Examples: Component = () => {
<div class="container my-10 w-[98vw] mx-auto">
<div class="md:grid md:grid-cols-12 gap-6">
<div class="md:col-span-4 lg:col-span-3 overflow-auto border dark:border-solid-darkLighterBg p-5 rounded md:h-[82vh]">
<For each={Object.entries(data.list)}>
{([name, examples]) => (
<For each={data.list}>
{([category, examples]: [string, Example[]]) => (
<>
<h3 class="text-xl text-solid-default dark:border-solid-darkLighterBg dark:text-solid-darkdefault border-b-2 font-semibold border-solid pb-2">
{t(`examples.${name.toLowerCase()}`, {}, name)}
{t(`examples.${category.toLowerCase()}`, {}, category)}
</h3>
<div class="mb-10">
<For each={examples}>
Expand Down
Loading