Skip to content
Draft
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
8 changes: 7 additions & 1 deletion .changeset/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"fixed": [],
"fixed": [
[
"@tanstack/form-devtools",
"@tanstack/react-form-devtools",
"@tanstack/solid-form-devtools"
]
],
"linked": [],
"ignore": []
}
60 changes: 60 additions & 0 deletions docs/framework/solid/guides/devtools.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
id: devtools
title: Devtools
---

TanStack Form comes with a ready to go suit of devtools.

## Setup

Install the [TanStack Devtools](https://tanstack.com/devtools/latest/docs/quick-start) library and the [TanStack Form plugin](http://npmjs.com/package/@tanstack/solid-form-devtools), from the framework adapter that your working in (in this case `@tanstack/solid-devtools`, and `@tanstack/solid-form-devtools`).

```bash
npm i @tanstack/solid-devtools
npm i @tanstack/solid-form-devtools
```

Next in the root of your application import the `TanStackDevtools`.

```tsx
import { TanStackDevtools } from '@tanstack/solid-devtools'

import App from './App'

render(
() => (
<>
<App />

<TanStackDevtools />
</>
),
root!,
)
```

Import the `FormDevtoolsPlugin` from **TanStack Form** and provide it to the `TanStackDevtools` component.

```tsx
import { TanStackDevtools } from '@tanstack/solid-devtools'
import { formDevtoolsPlugin } from '@tanstack/solid-form-devtools'

import App from './app'

const root = document.getElementById('root')

render(
() => (
<>
<App />

<TanStackDevtools plugins={[formDevtoolsPlugin()]} />
</>
),
root!,
)
```

Finally add any additional configuration you desire to the `TanStackDevtools` component, more information can be found under the [TanStack Devtools Configuration](https://tanstack.com/devtools/) section.

A complete working example can be found in our [examples section](https://tanstack.com/form/latest/docs/framework/solid/examples/devtools).
4 changes: 2 additions & 2 deletions examples/react/devtools/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'

import { TanStackDevtools } from '@tanstack/react-devtools'
import { FormDevtoolsPlugin } from '@tanstack/react-form-devtools'
import { formDevtoolsPlugin } from '@tanstack/react-form-devtools'

import App from './App'

createRoot(document.getElementById('root')!).render(
<StrictMode>
<App />

<TanStackDevtools plugins={[FormDevtoolsPlugin()]} />
<TanStackDevtools plugins={[formDevtoolsPlugin()]} />
</StrictMode>,
)
24 changes: 24 additions & 0 deletions examples/solid/devtools/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
28 changes: 28 additions & 0 deletions examples/solid/devtools/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
## Usage

```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 run dev`

Runs the app in the development mode.<br>
Open [http://localhost:5173](http://localhost:5173) to view it in the browser.

### `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

Learn more about deploying your application with the [documentations](https://vitejs.dev/guide/static-deploy.html)
12 changes: 12 additions & 0 deletions examples/solid/devtools/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>TanStack Form Solid Devtools Example App</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/index.tsx"></script>
</body>
</html>
22 changes: 22 additions & 0 deletions examples/solid/devtools/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "@tanstack/form-example-solid-devtools",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"test:types": "tsc",
"preview": "vite preview"
},
"dependencies": {
"@tanstack/solid-devtools": "^0.7.0",
"@tanstack/solid-form": "^1.23.5",
"@tanstack/solid-form-devtools": "workspace:*",
"solid-js": "^1.9.9"
},
"devDependencies": {
"typescript": "5.8.2",
"vite": "^7.1.6",
"vite-plugin-solid": "^2.11.8"
}
}
112 changes: 112 additions & 0 deletions examples/solid/devtools/src/app.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { createForm } from '@tanstack/solid-form'
import type { AnyFieldApi } from '@tanstack/solid-form'

interface FieldInfoProps {
field: AnyFieldApi
}

function FieldInfo(props: FieldInfoProps) {
return (
<>
{props.field.state.meta.isTouched && !props.field.state.meta.isValid ? (
<em>{props.field.state.meta.errors.join(',')}</em>
) : null}
{props.field.state.meta.isValidating ? 'Validating...' : null}
</>
)
}

export default function App() {
const form = createForm(() => ({
defaultValues: {
firstName: '',
lastName: '',
},
onSubmit: async ({ value }) => {
// Do something with form data
console.log(value)
},
}))

return (
<div>
<h1>Simple Form Example</h1>
<form
onSubmit={(e) => {
e.preventDefault()
e.stopPropagation()
form.handleSubmit()
}}
>
<div>
{/* A type-safe field component*/}
<form.Field
name="firstName"
validators={{
onChange: ({ value }) =>
!value
? 'A first name is required'
: value.length < 3
? 'First name must be at least 3 characters'
: undefined,
onChangeAsyncDebounceMs: 500,
onChangeAsync: async ({ value }) => {
await new Promise((resolve) => setTimeout(resolve, 1000))
return (
value.includes('error') && 'No "error" allowed in first name'
)
},
}}
children={(field) => {
// Avoid hasty abstractions. Render props are great!
return (
<>
<label for={field().name}>First Name:</label>
<input
id={field().name}
name={field().name}
value={field().state.value}
onBlur={field().handleBlur}
onInput={(e) => field().handleChange(e.target.value)}
/>
<FieldInfo field={field()} />
</>
)
}}
/>
</div>
<div>
<form.Field
name="lastName"
children={(field) => (
<>
<label for={field().name}>Last Name:</label>
<input
id={field().name}
name={field().name}
value={field().state.value}
onBlur={field().handleBlur}
onInput={(e) => field().handleChange(e.target.value)}
/>
<FieldInfo field={field()} />
</>
)}
/>
</div>
<form.Subscribe
selector={(state) => ({
canSubmit: state.canSubmit,
isSubmitting: state.isSubmitting,
})}
children={(state) => {
return (
<button type="submit" disabled={!state().canSubmit}>
{state().isSubmitting ? '...' : 'Submit'}
</button>
)
}}
/>
</form>
</div>
)
}
21 changes: 21 additions & 0 deletions examples/solid/devtools/src/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// lib
import { render } from 'solid-js/web'

import { TanStackDevtools } from '@tanstack/solid-devtools'
import { formDevtoolsPlugin } from '@tanstack/solid-form-devtools'

// components
import App from './app'

const root = document.getElementById('root')

render(
() => (
<>
<App />

<TanStackDevtools plugins={[formDevtoolsPlugin()]} />
</>
),
root!,
)
25 changes: 25 additions & 0 deletions examples/solid/devtools/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"module": "ESNext",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"skipLibCheck": true,

/* Bundler mode */
"moduleResolution": "Bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "preserve",
"jsxImportSource": "solid-js",

/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src", "vite.config.ts"]
}
6 changes: 6 additions & 0 deletions examples/solid/devtools/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { defineConfig } from 'vite'
import solid from 'vite-plugin-solid'

export default defineConfig({
plugins: [solid()],
})
3 changes: 2 additions & 1 deletion packages/form-devtools/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@
"src"
],
"dependencies": {
"@tanstack/devtools-ui": "^0.3.5",
"@tanstack/devtools-ui": "^0.4.0",
"@tanstack/devtools-utils": "^0.0.3",
"@tanstack/form-core": "workspace:*",
"clsx": "^2.1.1",
"dayjs": "^1.11.18",
Expand Down
4 changes: 2 additions & 2 deletions packages/form-devtools/src/components/DetailsPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export function DetailsPanel({ selectedKey }: DetailsPanelProps) {
>
{fieldName}
</div>
<JsonTree copyable value={fieldData} />
<JsonTree copyable value={fieldData as unknown} />
</div>
)}
</For>
Expand All @@ -128,7 +128,7 @@ export function DetailsPanel({ selectedKey }: DetailsPanelProps) {
<div class={styles().detailSection}>
<div class={styles().detailSectionHeader}>{section.title}</div>
<div class={styles().stateContent}>
<JsonTree copyable value={section.value} />
<JsonTree copyable value={section.value as unknown} />
</div>
</div>
)}
Expand Down
3 changes: 1 addition & 2 deletions packages/form-devtools/src/components/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { FormEventClientProvider } from '../contexts/eventClientContext'

import { Shell } from './Shell'

export function Devtools() {
export default function Devtools() {
return (
<FormEventClientProvider>
<Shell />
Expand Down
Loading
Loading