Skip to content
Open
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
22 changes: 21 additions & 1 deletion examples/react/basic/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createRoot } from 'react-dom/client'
import { createContext, useContext, useState } from 'react'
import { createContext, useContext, useEffect, useState } from 'react'
import { createPortal } from 'react-dom'
import {
QueryClient,
Expand Down Expand Up @@ -167,6 +167,17 @@ function App() {
const [state, setState] = useState(1)
const [win, setWin] = useState<Window | null>(null)
const [postId, setPostId] = useState(-1)
const [value, setValue] = useState<any>({
initial: 'value',
should: 'change',
in: 2,
array: [1, 2, 3],
})
useEffect(() => {
setTimeout(() => {
setValue({ title: 'Test Event', description: 'This is a test event.' })
}, 2000)
}, [])
return (
<div>
<Context.Provider value={{ count: state, setCount: setState }}>
Expand All @@ -177,6 +188,15 @@ function App() {
<Button onClick={() => setWin(window.open('', '', 'popup'))}>
Click me to open new window
</Button>
<tsd-json-tree value={value} />
<tsd-button
text="test"
ghost={true}
disabled
value="test"
variant="secondary"
onClick={() => console.log('Button clicked!')}
/>
{win && createPortal(<Mounted />, win.document.body)}
<Feature />
<p>
Expand Down
1 change: 1 addition & 0 deletions examples/react/start/src/components/client-plugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export default function ClientPlugin() {
<div>
<h1>Client Plugin Initialized</h1>
<p>Devtools Client is connected.</p>

<button
className="bg-blue-500 text-white px-4 py-2 rounded"
onClick={() => {
Expand Down
9 changes: 9 additions & 0 deletions examples/solid/basic/src/setup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,15 @@ const rootRoute = createRootRoute({
About
</Link>
</div>
<tsd-json-tree
value={{ title: 'Test Event', description: 'This is a test event.' }}
/>
<tsd-button
text="test"
value="test"
variant="secondary"
onClick={() => console.log('Button clicked!')}
/>
<hr />
<Outlet />
</>
Expand Down
2 changes: 2 additions & 0 deletions packages/devtools-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,11 @@
"dependencies": {
"clsx": "^2.1.1",
"goober": "^2.1.16",
"solid-element": "^1.9.1",
"solid-js": "^1.9.7"
},
"peerDependencies": {
"@types/react": ">=17.0.0",
"solid-js": ">=1.9.7"
},
"devDependencies": {
Expand Down
41 changes: 39 additions & 2 deletions packages/devtools-ui/src/components/button.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { splitProps } from 'solid-js'
import { Show, createEffect, createSignal, splitProps } from 'solid-js'
import clsx from 'clsx'
import { customElement, noShadowDOM } from 'solid-element'
import { useStyles } from '../styles/use-styles'
import type { JSX } from 'solid-js'

Expand All @@ -10,12 +11,14 @@ export type ButtonVariant =
| 'success'
| 'info'
| 'warning'
type ButtonProps = JSX.ButtonHTMLAttributes<HTMLButtonElement> & {

export type ButtonProps = JSX.ButtonHTMLAttributes<HTMLButtonElement> & {
variant?: ButtonVariant
outline?: boolean
ghost?: boolean
children?: any
className?: string
text?: string
}

export function Button(props: ButtonProps) {
Expand All @@ -40,3 +43,37 @@ export function Button(props: ButtonProps) {
</button>
)
}

export interface ButtonWebComponentProps
extends Exclude<ButtonProps, 'children'> {
text: string
}

export const registerButtonComponent = (elName: string = 'tsd-button') =>
customElement<ButtonWebComponentProps>(
elName,
{
variant: 'primary',
outline: false,
ghost: false,
text: '',
disabled: false,
autofocus: false,
},
(props, { element }) => {
noShadowDOM()
const [buttonProps, setButtonProps] = createSignal(props)

createEffect(() => {
element.addPropertyChangedCallback((name, value) => {
setButtonProps((prev) => ({ ...prev, [name]: value }))
})
})

return (
<Show keyed when={buttonProps()}>
<Button {...buttonProps()}>{buttonProps().text}</Button>
</Show>
)
},
)
43 changes: 42 additions & 1 deletion packages/devtools-ui/src/components/tree.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { For, Match, Show, Switch, createSignal } from 'solid-js'
import { For, Match, Show, Switch, createEffect, createSignal } from 'solid-js'
import clsx from 'clsx'
import { customElement, noShadowDOM } from 'solid-element'
import { css, useStyles } from '../styles/use-styles'
import { CopiedCopier, Copier, ErrorCopier } from './icons'

Expand Down Expand Up @@ -281,3 +282,43 @@ const ObjectValue = ({
</span>
)
}

// web component
export interface JsonTreeWebComponentProps {
value: any
}

export const registerJsonTreeComponent = (elName: string = 'tsd-json-tree') =>
customElement<JsonTreeWebComponentProps>(
elName,
{ value: {} },
(props, { element }) => {
noShadowDOM()
function getValue(value: any) {
if (typeof value === 'string') {
try {
const parsedValue = JSON.parse(value)
return parsedValue
} catch (e) {
return value
}
}
return value
}
const [value, setValue] = createSignal(getValue(props.value))

createEffect(() => {
element.addPropertyChangedCallback((name, value) => {
if (name === 'value') {
const finalValue = getValue(value)
setValue(finalValue)
}
})
})
return (
<Show keyed when={value()}>
<JsonTree value={value()} />
</Show>
)
},
)
7 changes: 5 additions & 2 deletions packages/devtools-ui/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ export { Checkbox } from './components/checkbox'
export { Input } from './components/input'
export { Select } from './components/select'
export { TanStackLogo } from './components/logo'
export { JsonTree } from './components/tree'
export { Button } from './components/button'
export { JsonTree, registerJsonTreeComponent } from './components/tree'
export { Button, registerButtonComponent } from './components/button'
export { Tag } from './components/tag'
export type { JsonTreeWebComponentProps } from './components/tree'
export type { ButtonProps } from './components/button'
export type { CustomElements } from './types'
export { MainPanel } from './components/main-panel'
export {
Section,
Expand Down
7 changes: 7 additions & 0 deletions packages/devtools-ui/src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { ButtonWebComponentProps } from './components/button'
import type { JsonTreeWebComponentProps } from './components/tree'

export interface CustomElements {
'tsd-json-tree': JsonTreeWebComponentProps
'tsd-button': ButtonWebComponentProps
}
1 change: 0 additions & 1 deletion packages/devtools-vite/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@
### Minor Changes

- Added event bus functionality into @tanstack/devtools ([#11](https://github.com/TanStack/devtools/pull/11))

- @tanstack/devtools now comes with an integrated Event Bus on the Client.
- The Event Bus allows for seamless communication between different parts of your running application
without tight coupling.
Expand Down
1 change: 0 additions & 1 deletion packages/devtools/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,6 @@
### Minor Changes

- Added event bus functionality into @tanstack/devtools ([#11](https://github.com/TanStack/devtools/pull/11))

- @tanstack/devtools now comes with an integrated Event Bus on the Client.
- The Event Bus allows for seamless communication between different parts of your running application
without tight coupling.
Expand Down
7 changes: 7 additions & 0 deletions packages/devtools/src/core.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { lazy } from 'solid-js'
import { Portal, render } from 'solid-js/web'
import { ClientEventBus } from '@tanstack/devtools-event-bus/client'
import {
registerButtonComponent,
registerJsonTreeComponent,
} from '@tanstack/devtools-ui'
import { DevtoolsProvider } from './context/devtools-context'
import { initialState } from './context/devtools-store'
import { PiPProvider } from './context/pip-context'
Expand Down Expand Up @@ -73,6 +77,8 @@ export class TanStackDevtoolsCore {
const Devtools = this.#Component
this.#eventBus = new ClientEventBus(this.#eventBusConfig)
this.#eventBus.start()
registerJsonTreeComponent()
registerButtonComponent()
return (
<DevtoolsProvider plugins={this.#plugins} config={this.#config}>
<PiPProvider>
Expand All @@ -93,6 +99,7 @@ export class TanStackDevtoolsCore {
throw new Error('Devtools is not mounted')
}
this.#eventBus?.stop()

this.#dispose?.()
this.#isMounted = false
}
Expand Down
1 change: 0 additions & 1 deletion packages/event-bus-client/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
### Minor Changes

- Added event bus functionality into @tanstack/devtools ([#11](https://github.com/TanStack/devtools/pull/11))

- @tanstack/devtools now comes with an integrated Event Bus on the Client.
- The Event Bus allows for seamless communication between different parts of your running application
without tight coupling.
Expand Down
1 change: 0 additions & 1 deletion packages/event-bus/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
### Minor Changes

- Added event bus functionality into @tanstack/devtools ([#11](https://github.com/TanStack/devtools/pull/11))

- @tanstack/devtools now comes with an integrated Event Bus on the Client.
- The Event Bus allows for seamless communication between different parts of your running application
without tight coupling.
Expand Down
1 change: 0 additions & 1 deletion packages/react-devtools/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,6 @@
### Minor Changes

- Added event bus functionality into @tanstack/devtools ([#11](https://github.com/TanStack/devtools/pull/11))

- @tanstack/devtools now comes with an integrated Event Bus on the Client.
- The Event Bus allows for seamless communication between different parts of your running application
without tight coupling.
Expand Down
1 change: 1 addition & 0 deletions packages/react-devtools/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
},
"devDependencies": {
"@eslint-react/eslint-plugin": "^1.48.5",
"@tanstack/devtools-ui": "workspace:*",
"@types/react": "^19.1.12",
"@vitejs/plugin-react": "^4.5.2",
"eslint-plugin-react-compiler": "19.1.0-rc.1",
Expand Down
7 changes: 7 additions & 0 deletions packages/react-devtools/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
'use client'

import * as Devtools from './devtools'
import type { CustomElements } from '@tanstack/devtools-ui'

declare module 'react' {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace JSX {
interface IntrinsicElements extends CustomElements {}
}
}
export const TanStackDevtools: (typeof Devtools)['TanStackDevtools'] =
process.env.NODE_ENV !== 'development'
? function () {
Expand Down
1 change: 0 additions & 1 deletion packages/solid-devtools/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,6 @@
### Minor Changes

- Added event bus functionality into @tanstack/devtools ([#11](https://github.com/TanStack/devtools/pull/11))

- @tanstack/devtools now comes with an integrated Event Bus on the Client.
- The Event Bus allows for seamless communication between different parts of your running application
without tight coupling.
Expand Down
1 change: 1 addition & 0 deletions packages/solid-devtools/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"@tanstack/devtools": "workspace:*"
},
"devDependencies": {
"@tanstack/devtools-ui": "workspace:*",
"solid-js": "^1.9.7",
"vite-plugin-solid": "^2.11.6"
},
Expand Down
8 changes: 8 additions & 0 deletions packages/solid-devtools/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import { isDev } from 'solid-js/web'
import * as Devtools from './devtools'
import type { CustomElements } from '@tanstack/devtools-ui'

declare module 'solid-js' {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace JSX {
interface IntrinsicElements extends CustomElements {}
}
}

export const TanStackDevtools: (typeof Devtools)['TanStackDevtools'] = isDev
? Devtools.TanStackDevtools
Expand Down
28 changes: 28 additions & 0 deletions patches/component-register.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
diff --git a/dist/component-register.js b/dist/component-register.js
index 726c10dabade8ebd316021f4bd8d7e84c0995dea..2a34321e30ece9fa343e3cb2e6874eb0bbe4a815 100644
--- a/dist/component-register.js
+++ b/dist/component-register.js
@@ -118,6 +118,9 @@ function createElementType(BaseElement, propDefinition) {
this.__propertyChangedCallbacks = [];
this.__updating = {};
this.props = {};
+ for (let propKey of propKeys) {
+ this[propKey] = undefined
+ }
}
connectedCallback() {
if (this.__initialized) return;
diff --git a/lib/component-register.js b/lib/component-register.js
index a06bc4928fa96d74725c7a63387b3abcd1276eea..09698d85764b9157fde3708039bbefec370362aa 100644
--- a/lib/component-register.js
+++ b/lib/component-register.js
@@ -122,6 +122,9 @@ function createElementType(BaseElement, propDefinition) {
this.__propertyChangedCallbacks = [];
this.__updating = {};
this.props = {};
+ for (let propKey of propKeys) {
+ this[propKey] = undefined
+ }
}
connectedCallback() {
if (this.__initialized) return;
Loading
Loading