Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
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
52 changes: 51 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,45 @@ function App() {
<Button onClick={() => setWin(window.open('', '', 'popup'))}>
Click me to open new window
</Button>
<tsd-main-panel>
<tsd-json-tree value={value} />
<tsd-button
text="test"
value="test"
variant="secondary"
onClick={() => console.log('Button clicked!')}
/>
<tsd-checkbox checked label="test"></tsd-checkbox>
<tsd-section>
<tsd-section-title>Test Title</tsd-section-title>
<tsd-section-description>
Test Description
</tsd-section-description>
<tsd-section-icon>🔥</tsd-section-icon>
</tsd-section>
<tsd-select
options={[
{
value: '1',
label: '1',
},
{
value: '2',
label: '2',
},
]}
/>
<tsd-header>
<tsd-header-logo
flavor={{
light: 'red',
dark: 'red',
}}
>
test
</tsd-header-logo>
</tsd-header>
</tsd-main-panel>
{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 @@ -24,6 +24,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>
)
},
)
31 changes: 29 additions & 2 deletions packages/devtools-ui/src/components/checkbox.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { createSignal } from 'solid-js'
import { Show, createEffect, createSignal } from 'solid-js'
import { customElement, noShadowDOM } from 'solid-element'
import { useStyles } from '../styles/use-styles'

interface CheckboxProps {
export interface CheckboxProps {
label?: string
checked?: boolean
onChange?: (checked: boolean) => void
Expand Down Expand Up @@ -41,3 +42,29 @@ export function Checkbox(props: CheckboxProps) {
</div>
)
}

export const registerCheckboxComponent = (elName: string = 'tsd-checkbox') =>
customElement<CheckboxProps>(
elName,
{
checked: false,
label: '',
description: '',
},
(props, { element }) => {
noShadowDOM()
const [checkboxProps, setCheckboxProps] = createSignal(props)

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

return (
<Show keyed when={checkboxProps()}>
<Checkbox {...checkboxProps()} />
</Show>
)
},
)
60 changes: 48 additions & 12 deletions packages/devtools-ui/src/components/header.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,35 @@
import clsx from 'clsx'
import { customElement, noShadowDOM } from 'solid-element'
import { createEffect, createSignal } from 'solid-js'
import { useStyles } from '../styles/use-styles'
import type { JSX } from 'solid-js/jsx-runtime'

export function Header({
children,
class: className,
...rest
}: JSX.IntrinsicElements['header']) {
export type HeaderProps = Omit<JSX.IntrinsicElements['header'], 'children'> & {
className?: string
children?: any
}

export function Header({ children, class: className, ...rest }: HeaderProps) {
const styles = useStyles()
return (
<header
class={clsx(styles().header.row, 'tsqd-header', className)}
class={clsx(styles().header.row, 'tsd-header', className)}
{...rest}
>
{children}
</header>
)
}

export function HeaderLogo({
children,
flavor,
}: {
children: JSX.Element
export type HeaderLogoProps = {
children?: any
flavor: {
light: string
dark: string
}
}) {
}

export function HeaderLogo({ children, flavor }: HeaderLogoProps) {
const styles = useStyles()
return (
<div class={styles().header.logoAndToggleContainer}>
Expand All @@ -42,3 +44,37 @@ export function HeaderLogo({
</div>
)
}

export const registerHeaderComponent = (elName: string = 'tsd-header') =>
customElement<HeaderProps>(
elName,
{ className: '' },
(props, { element }) => {
noShadowDOM()
const [headerProps, setHeaderProps] = createSignal(props)
createEffect(() => {
element.addPropertyChangedCallback((name, value) => {
setHeaderProps((prev) => ({ ...prev, [name]: value }))
})
})
return <Header {...headerProps()}>{headerProps().children}</Header>
},
)

export const registerHeaderLogoComponent = (
elName: string = 'tsd-header-logo',
) =>
customElement<HeaderLogoProps>(
elName,
{ flavor: { light: '', dark: '' } },
(props, { element }) => {
noShadowDOM()
const [logoProps, setLogoProps] = createSignal(props)
createEffect(() => {
element.addPropertyChangedCallback((name, value) => {
setLogoProps((prev) => ({ ...prev, [name]: value }))
})
})
return <HeaderLogo {...logoProps()}>{logoProps().children}</HeaderLogo>
},
)
20 changes: 19 additions & 1 deletion packages/devtools-ui/src/components/input.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { createSignal } from 'solid-js'
import { customElement, noShadowDOM } from 'solid-element'
import { useStyles } from '../styles/use-styles'

interface InputProps {
export interface InputProps {
label?: string
type?: 'text' | 'number' | 'password' | 'email'
value?: string
Expand Down Expand Up @@ -40,3 +41,20 @@ export function Input(props: InputProps) {
</div>
)
}

export const registerInputComponent = (elName: string = 'tsd-input') =>
customElement<InputProps>(
elName,
{ label: '', type: 'text', value: '', placeholder: '', description: '' },
(props, { element }) => {
noShadowDOM()
const [inputProps, setInputProps] = createSignal(props)
createSignal(() => {
element.addPropertyChangedCallback((name, value) => {
setInputProps((prev) => ({ ...prev, [name]: value }))
})
})

return <Input {...inputProps()} />
},
)
21 changes: 20 additions & 1 deletion packages/devtools-ui/src/components/main-panel.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import clsx from 'clsx'
import { createEffect, createSignal } from 'solid-js'
import { customElement, noShadowDOM } from 'solid-element'
import { useStyles } from '../styles/use-styles'
import type { JSX } from 'solid-js/jsx-runtime'

type PanelProps = JSX.IntrinsicElements['div'] & {
export type PanelProps = Omit<JSX.IntrinsicElements['div'], 'children'> & {
children?: any
className?: string
withPadding?: boolean
Expand All @@ -28,3 +30,20 @@ export const MainPanel = ({
</div>
)
}

export const registerMainPanelComponent = (elName: string = 'tsd-main-panel') =>
customElement<PanelProps>(
elName,
{ className: '', withPadding: false },
(props, { element }) => {
noShadowDOM()
const [panelProps, setPanelProps] = createSignal(props)
createEffect(() => {
element.addPropertyChangedCallback((name, value) => {
setPanelProps((prev) => ({ ...prev, [name]: value }))
})
})

return <MainPanel {...panelProps()}>{panelProps().children}</MainPanel>
},
)
Loading