-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Solid adapter #25
base: main
Are you sure you want to change the base?
Solid adapter #25
Changes from all commits
3a35282
544186e
aa25cf7
c07ad5f
181ca57
12f9083
3465a16
5435ce0
269989c
f188ddd
d442280
6285004
3a026ca
7a8b8c8
df6dc95
94b7514
f58e5ef
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
node_modules | ||
dist |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
## Usage | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's update this with something like what Vue/Svelte has that shows an example of how to use this in a new Solid app |
||
|
||
Those templates dependencies are maintained via [pnpm](https://pnpm.io) via `pnpm up -Lri`. | ||
|
||
This is the reason you see a `pnpm-lock.yaml`. That being said, any package manager will work. This file can be safely be removed once you clone a template. | ||
|
||
```bash | ||
$ npm install # or pnpm install or yarn install | ||
``` | ||
|
||
### Learn more on the [Solid Website](https://solidjs.com) and come chat with us on our [Discord](https://discord.com/invite/solidjs) | ||
|
||
## Available Scripts | ||
|
||
In the project directory, you can run: | ||
|
||
### `npm dev` or `npm start` | ||
|
||
Runs the app in the development mode.<br> | ||
Open [http://localhost:3000](http://localhost:3000) to view it in the browser. | ||
|
||
The page will reload if you make edits.<br> | ||
|
||
### `npm run build` | ||
|
||
Builds the app for production to the `dist` folder.<br> | ||
It correctly bundles Solid in production mode and optimizes the build for the best performance. | ||
|
||
The build is minified and the filenames include the hashes.<br> | ||
Your app is ready to be deployed! | ||
|
||
## Deployment | ||
|
||
You can deploy the `dist` folder to any static host provider (netlify, surge, now, etc.) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="utf-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1" /> | ||
<meta name="theme-color" content="#000000" /> | ||
<link rel="shortcut icon" type="image/ico" href="/src/assets/favicon.ico" /> | ||
<title>Solid App</title> | ||
</head> | ||
<body> | ||
<noscript>You need to enable JavaScript to run this app.</noscript> | ||
<div id="root"></div> | ||
|
||
<script src="/referance-app/index.tsx" type="module"></script> | ||
</body> | ||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
{ | ||
"name": "remix-router-solid", | ||
"version": "0.0.0", | ||
"description": "", | ||
"scripts": { | ||
"start": "vite", | ||
"dev": "vite", | ||
"build": "vite build", | ||
"serve": "vite preview", | ||
"integration:open": "cypress open --config-file ../../cypress.config.ts", | ||
"integration:start": "vite --mode=production --port 3000", | ||
"integration:test": "cypress run --config-file ../../cypress.config.ts", | ||
"integration": "start-server-and-test integration:start http-get://localhost:3000/ integration:test", | ||
"prepublishOnly": "rm -rf dist && npm run build" | ||
}, | ||
"license": "MIT", | ||
"devDependencies": { | ||
"typescript": "^4.9.4", | ||
"vite": "^4.0.3", | ||
Comment on lines
+18
to
+19
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Out of curiosity, do we need these updated versions for Solid? Or would the versions installed in the repo root |
||
"vite-plugin-solid": "^2.5.0" | ||
}, | ||
"dependencies": { | ||
"@remix-run/router": "0.2.0-pre.10", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This has been released as stable since the repo was created. I wouldn't touch anything in this initial PR - but maybe in a follow up we can get it onto the latest (1.2.1, soon to be 1.3.0) |
||
"solid-js": "^1.6.6" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import type { Component } from "solid-js"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Small typo in the folder name her - |
||
import { | ||
createBrowserRouter, | ||
RouteObject, | ||
RouterProvider, | ||
} from "remix-router-solid"; | ||
import { Root } from "./routes/Root"; | ||
import { Index } from "./routes/Index"; | ||
import { Parent, parentLoader } from "./routes/nested/parent"; | ||
import { Child, childLoader } from "./routes/nested/child"; | ||
import { Boundary } from "./components/Boundary"; | ||
import { ErrorComp, errorLoader } from "./routes/Error"; | ||
import { Redirect, redirectLoader } from "./routes/Redirect"; | ||
import { Defer, deferLoader } from "./routes/Defer"; | ||
import { Tasks, tasksAction, tasksLoader } from "./routes/tasks/Tasks"; | ||
import { Task, taskLoader } from "./routes/tasks/Task"; | ||
import { NewTask, newTaskAction } from "./routes/tasks/NewTask"; | ||
|
||
export const App: Component = () => { | ||
const routes: RouteObject[] = [ | ||
{ | ||
path: "/", | ||
element: Root, | ||
children: [ | ||
{ index: true, element: Index }, | ||
{ | ||
path: "parent", | ||
element: Parent, | ||
loader: parentLoader, | ||
errorElement: Boundary, | ||
children: [ | ||
{ path: "child", element: Child, loader: childLoader }, | ||
{ path: "error", loader: errorLoader, element: ErrorComp }, | ||
], | ||
}, | ||
{ path: "error", loader: errorLoader, element: ErrorComp }, | ||
{ path: "redirect", loader: redirectLoader, element: Redirect }, | ||
{ | ||
path: "defer", | ||
loader: deferLoader, | ||
element: Defer, | ||
}, | ||
{ | ||
path: "tasks", | ||
loader: tasksLoader, | ||
action: tasksAction, | ||
element: Tasks, | ||
children: [ | ||
{ | ||
path: ":id", | ||
loader: taskLoader, | ||
element: Task, | ||
}, | ||
{ path: "new", action: newTaskAction, element: NewTask }, | ||
], | ||
}, | ||
], | ||
}, | ||
]; | ||
|
||
const router = createBrowserRouter(routes); | ||
|
||
const fetcher1 = router.getFetcher("1"); | ||
const fetcher2 = router.getFetcher("2"); | ||
|
||
Comment on lines
+63
to
+65
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unused? |
||
|
||
return <RouterProvider router={router} />; | ||
}; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { Link, useRouteError } from "remix-router-solid"; | ||
|
||
export const Boundary = () => { | ||
const error = useRouteError() as () => Error; | ||
|
||
return ( | ||
<> | ||
<h2>Application Error Boundary</h2> | ||
<p>{error().message}</p> | ||
<Link to="/">Go home</Link> | ||
</> | ||
); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { Link, useFetcher } from "remix-router-solid"; | ||
|
||
import type { Task } from "../tasks"; | ||
|
||
export interface TaskItemProps { | ||
task: Task; | ||
} | ||
|
||
export const TaskItem = ({ task }: TaskItemProps) => { | ||
let fetcher = useFetcher(); | ||
let isDeleting = () => { | ||
return fetcher().formData != null | ||
}; | ||
const Form = fetcher().Form | ||
|
||
return ( | ||
<> | ||
<span>{task.task}</span> <Link to={`/tasks/${task.id}`}>Open</Link>{" "} | ||
<Form style={{ display: "inline" }} action="/tasks" method="post"> | ||
<button | ||
type="submit" | ||
name="taskId" | ||
value={task.id} | ||
disabled={isDeleting()} | ||
> | ||
{isDeleting() ? "Deleting..." : "❌"} | ||
</button> | ||
</Form> | ||
</> | ||
); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
/* @refresh reload */ | ||
import { render } from "solid-js/web"; | ||
import { App } from "./App"; | ||
import "./main.css"; | ||
|
||
render(() => <App />, document.getElementById("root") as HTMLElement); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
pre { | ||
display: inline; | ||
} | ||
|
||
nav { | ||
display: flex; | ||
} | ||
|
||
nav > * { | ||
margin-right: 1rem; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { Await, defer, useLoaderData, useAsyncError } from "remix-router-solid"; | ||
import { Suspense } from "solid-js"; | ||
|
||
const resolve = (d: string, ms: number): Promise<string> => | ||
new Promise((r) => setTimeout(() => r(d), ms)); | ||
|
||
const reject = (d: string, ms: number) => | ||
new Promise((_, r) => setTimeout(() => r(d), ms)); | ||
|
||
interface LoaderData { | ||
critical: string; | ||
lazy: Promise<String>; | ||
lazyError: Promise<string>; | ||
} | ||
|
||
export async function deferLoader() { | ||
return defer({ | ||
critical: await resolve("Critical Data", 500), | ||
lazy: resolve("Lazy Data ✅", 1000), | ||
lazyError: reject("Lazy Error 💥", 1500), | ||
}); | ||
} | ||
function ErrorElement() { | ||
let error = useAsyncError(); | ||
return <p id="lazy-error">{`Error: ${error}`}</p>; | ||
} | ||
|
||
export const Defer = () => { | ||
let data = useLoaderData<LoaderData>(); | ||
|
||
return ( | ||
<> | ||
<p id="critical-data">Critical Data: {data().critical}</p> | ||
|
||
<Suspense fallback={<p id="lazy-value">Loading data...</p>}> | ||
<Await resolve={data().lazy}> | ||
{(value) => <p id="lazy-value">Value: {value().toString()}</p>} | ||
</Await> | ||
</Suspense> | ||
|
||
<Suspense fallback={<p id="lazy-error">Loading error...</p>}> | ||
<Await resolve={data().lazyError} errorElement={ErrorElement}> | ||
{() => <p>Nope!</p>} | ||
</Await> | ||
</Suspense> | ||
</> | ||
); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import type { LoaderFunction } from "@remix-run/router"; | ||
import { json, useLoaderData } from "remix-router-solid"; | ||
|
||
export const errorLoader: LoaderFunction = async ({ request }) => { | ||
let isLoaderError = | ||
new URL(request.url).searchParams.get("type") === "loader"; | ||
if (isLoaderError) { | ||
throw new Error("Loader error!"); | ||
} | ||
return json({}); | ||
}; | ||
|
||
export const ErrorComp = () => { | ||
const data = useLoaderData<ReturnType<typeof errorLoader>>(); | ||
|
||
return <h2>Render Error: {data().foo.bar}; </h2>; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
|
||
export const Index = () => { | ||
return <h2>Index Page</h2> | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
|
||
import type { LoaderFunction } from "@remix-run/router"; | ||
import { redirect } from "remix-router-solid"; | ||
import { sleep } from "~/utils"; | ||
|
||
export const redirectLoader: LoaderFunction = async ({ request }) => { | ||
await sleep(); | ||
let location = new URL(request.url).searchParams.get("location") || "/"; | ||
return redirect(location); | ||
}; | ||
|
||
export const Redirect = () => { | ||
return <h2>Shouldn't see me</h2>; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import { | ||
Link, | ||
Outlet, | ||
useLocation, | ||
useMatches, | ||
useNavigate, | ||
useNavigation, | ||
useNavigationType, | ||
} from "remix-router-solid"; | ||
import { For } from "solid-js"; | ||
|
||
export const Root = () => { | ||
const links = { | ||
Index: "/", | ||
Parent: "/parent", | ||
Child: "/parent/child", | ||
Redirect: "/redirect?location=%2Fparent%2Fchild", | ||
"Loader Error": "/error?type=loader", | ||
"Render Error": "/error?type=render", | ||
"Nested Loader Error": "/parent/error?type=loader", | ||
"Nested Render Error": "/parent/error?type=render", | ||
Defer: "/defer", | ||
Tasks: "/tasks", | ||
}; | ||
const hooks = { | ||
navigationType: useNavigationType(), | ||
location: useLocation(), | ||
navigation: useNavigation(), | ||
matches: useMatches(), | ||
}; | ||
|
||
const navigate = useNavigate(); | ||
const router = navigate | ||
return ( | ||
<> | ||
<h1>Root Layout (solid)</h1> | ||
<nav> | ||
<For each={Object.entries(links)}> | ||
{([text, href]) => { | ||
return <Link to={href}>{text}</Link>; | ||
}} | ||
</For> | ||
<button id="back" onClick={() => navigate(-1)}> | ||
Go Back | ||
</button> | ||
</nav> | ||
<For each={Object.entries(hooks)}> | ||
{([k, v]) => { | ||
return ( | ||
<p> | ||
{k}(): | ||
<code id={k}>{JSON.stringify(v())}</code> | ||
</p> | ||
); | ||
}} | ||
</For> | ||
<Outlet /> | ||
</> | ||
); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think changes to this file are unintended :)