Skip to content

Commit 356c3b7

Browse files
committed
feat: integrate A11yDevtoolsPanel with lazy loading and enhance button styles
1 parent 6858d94 commit 356c3b7

8 files changed

Lines changed: 235 additions & 132 deletions

File tree

examples/react/start/src/routes/__root.tsx

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
1+
import * as React from 'react'
12
import { HeadContent, Scripts, createRootRoute } from '@tanstack/react-router'
23
import { TanStackRouterDevtoolsPanel } from '@tanstack/react-router-devtools'
4+
35
import { TanStackDevtools } from '@tanstack/react-devtools'
46

57
import Header from '../components/Header'
68
import { RouteNavigationPanel } from '../devtools'
79

810
import appCss from '../styles.css?url'
911

12+
const A11yDevtoolsPanel = React.lazy(async () => {
13+
const mod = await import('@tanstack/devtools-a11y/react')
14+
return { default: mod.A11yDevtoolsPanel }
15+
})
16+
1017
export const Route = createRootRoute({
1118
head: () => ({
1219
meta: [
@@ -34,6 +41,32 @@ export const Route = createRootRoute({
3441

3542
function RootDocument({ children }: { children: React.ReactNode }) {
3643
console.log('Rendering Root Document')
44+
const isServer = typeof window === 'undefined'
45+
const plugins = [
46+
{
47+
name: 'Tanstack Router',
48+
render: <TanStackRouterDevtoolsPanel />,
49+
},
50+
{
51+
id: 'route-navigation',
52+
name: 'Route Navigation',
53+
render: <RouteNavigationPanel />,
54+
},
55+
...(isServer
56+
? []
57+
: [
58+
{
59+
id: 'a11y',
60+
name: 'Accessibility',
61+
render: (
62+
<React.Suspense fallback={null}>
63+
<A11yDevtoolsPanel />
64+
</React.Suspense>
65+
),
66+
},
67+
]),
68+
]
69+
3770
return (
3871
<html lang="en">
3972
<head>
@@ -46,17 +79,7 @@ function RootDocument({ children }: { children: React.ReactNode }) {
4679
config={{
4780
position: 'bottom-right',
4881
}}
49-
plugins={[
50-
{
51-
name: 'Tanstack Router',
52-
render: <TanStackRouterDevtoolsPanel />,
53-
},
54-
{
55-
id: 'route-navigation',
56-
name: 'Route Navigation',
57-
render: <RouteNavigationPanel />,
58-
},
59-
]}
82+
plugins={plugins}
6083
/>
6184
<Scripts />
6285
</body>

packages/devtools-a11y/src/ui/A11yDevtoolsPanel.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -368,8 +368,7 @@ export function A11yDevtoolsPanel(props: A11yDevtoolsPanelProps) {
368368
<Button
369369
variant="secondary"
370370
outline
371-
onClick={() => handleExport('csv')}
372-
>
371+
onClick={() => handleExport('csv')}>
373372
Export CSV
374373
</Button>
375374
</div>
@@ -399,7 +398,6 @@ export function A11yDevtoolsPanel(props: A11yDevtoolsPanelProps) {
399398
<Button
400399
variant="secondary"
401400
outline
402-
className={styles().compactButton}
403401
onClick={actions.openSettings}
404402
>
405403
Settings

packages/devtools-a11y/src/ui/A11yIssueCard.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,7 @@ export function A11yIssueCard(props: A11yIssueCardProps) {
4949
</a>
5050
<Button
5151
variant="secondary"
52-
outline
53-
className={props.styles.compactButton}
52+
ghost
5453
onClick={(event: MouseEvent) => {
5554
event.stopPropagation()
5655
props.onDisableRule(props.issue.ruleId)

packages/devtools-a11y/src/ui/A11yIssueList.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
import { For, Show } from 'solid-js'
44
import { IMPACTS } from './panelUtils'
55
import { SEVERITY_LABELS } from './styles'
6-
import type { createA11yPanelStyles } from './styles'
76
import { A11yIssueCard } from './A11yIssueCard'
7+
import type { createA11yPanelStyles } from './styles'
88
import type { GroupedIssues, SeverityThreshold } from '../types'
99

1010
type PanelStyles = ReturnType<typeof createA11yPanelStyles>

packages/devtools-a11y/src/ui/A11ySettingsOverlay.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ export function A11ySettingsOverlay(props: A11ySettingsOverlayProps) {
4141
<Button
4242
variant="secondary"
4343
outline
44-
className={props.styles.compactButton}
4544
onClick={props.onClose}
4645
>
4746
Done
@@ -96,15 +95,13 @@ export function A11ySettingsOverlay(props: A11ySettingsOverlayProps) {
9695
<Button
9796
variant="success"
9897
outline
99-
className={props.styles.compactButton}
10098
onClick={props.onEnableAllRules}
10199
>
102100
Enable All
103101
</Button>
104102
<Button
105103
variant="danger"
106104
outline
107-
className={props.styles.compactButton}
108105
onClick={props.onDisableAllRules}
109106
>
110107
Disable All

packages/devtools-a11y/src/ui/styles.ts

Lines changed: 15 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ const fontPx = (size: number) => `calc(${size}px * ${FONT_SCALE})`
6666
export function createA11yPanelStyles(theme: 'light' | 'dark') {
6767
const t = (light: string, dark: string) => (theme === 'light' ? light : dark)
6868

69-
const bg = t('#ffffff', '#191c24')
69+
const bg = t('#f9fafb;', '#191c24')
7070
const fg = t('#1e293b', '#e2e8f0')
7171
const border = t('#e2e8f0', '#292e3d')
7272
const muted = t('#64748b', '#94a3b8')
@@ -163,15 +163,6 @@ export function createA11yPanelStyles(theme: 'light' | 'dark') {
163163
gap: 6px;
164164
align-items: center;
165165
`,
166-
compactButton: css`
167-
padding: 4px 12px;
168-
font-size: 12px;
169-
line-height: 1.2;
170-
border-radius: 4px;
171-
border: 1px solid currentColor;
172-
background: transparent;
173-
opacity: 0.7;
174-
`,
175166
toggleOverlay: css`
176167
padding: 8px 12px;
177168
color: ${fg};
@@ -199,16 +190,6 @@ export function createA11yPanelStyles(theme: 'light' | 'dark') {
199190
statusSpacer: css`
200191
flex: 1;
201192
`,
202-
pill: (active: boolean) => css`
203-
padding: 4px 10px;
204-
background: ${active ? '#10b981' : 'transparent'};
205-
color: ${active ? '#fff' : '#0ea5e9'};
206-
border: 1px solid ${active ? '#10b981' : border};
207-
border-radius: 999px;
208-
cursor: pointer;
209-
font-size: ${fontPx(11)};
210-
font-weight: 600;
211-
`,
212193
smallLinkButton: css`
213194
padding: 4px 10px;
214195
background: transparent;
@@ -276,11 +257,16 @@ export function createA11yPanelStyles(theme: 'light' | 'dark') {
276257
summaryButton: css`
277258
padding: 12px;
278259
color: ${fg};
260+
background: ${bg};
279261
border-radius: 8px;
280262
border: 1px solid ${border};
281263
text-align: left;
282264
cursor: pointer;
283265
box-shadow: none;
266+
267+
&:hover {
268+
background: ${t('#f0f2f5', '#111318')};
269+
}
284270
`,
285271
summaryButtonActive: (impact: SeverityThreshold) => css`
286272
box-shadow: 0 0 0 2px ${SEVERITY_COLORS[impact]};
@@ -368,8 +354,9 @@ export function createA11yPanelStyles(theme: 'light' | 'dark') {
368354
flex-shrink: 0;
369355
`,
370356
helpLink: css`
371-
font-size: ${fontPx(11)};
357+
font-size: ${fontPx(12)};
372358
color: #0ea5e9;
359+
padding: 0 12px;
373360
font-weight: 600;
374361
text-decoration: underline;
375362
text-underline-offset: 2px;
@@ -440,8 +427,8 @@ export function createA11yPanelStyles(theme: 'light' | 'dark') {
440427
`,
441428
doneButton: css`
442429
padding: 6px 12px;
443-
background: #0ea5e9;
444-
color: #fff;
430+
background: ${bg};
431+
color: ${bg};
445432
border: none;
446433
border-radius: 4px;
447434
cursor: pointer;
@@ -505,16 +492,6 @@ export function createA11yPanelStyles(theme: 'light' | 'dark') {
505492
display: flex;
506493
gap: 6px;
507494
`,
508-
smallAction: (variant: 'success' | 'danger') => css`
509-
padding: 4px 8px;
510-
background: ${variant === 'success' ? '#10b981' : '#ef4444'};
511-
color: #fff;
512-
border: none;
513-
border-radius: 4px;
514-
cursor: pointer;
515-
font-size: ${fontPx(10)};
516-
font-weight: 500;
517-
`,
518495
filtersRow: css`
519496
display: flex;
520497
gap: 8px;
@@ -546,6 +523,10 @@ export function createA11yPanelStyles(theme: 'light' | 'dark') {
546523
cursor: pointer;
547524
opacity: 1;
548525
background: transparent;
526+
527+
&:hover {
528+
background: ${t('#f0f2f5', '#111318')};
529+
}
549530
`,
550531
ruleRowDisabled: css`
551532
opacity: 0.6;
@@ -554,7 +535,7 @@ export function createA11yPanelStyles(theme: 'light' | 'dark') {
554535
border-bottom: 1px solid ${border};
555536
`,
556537
ruleCheckbox: css`
557-
margin-top: 4px;
538+
margin-top: 2px;
558539
flex-shrink: 0;
559540
`,
560541
ruleInfo: css`

packages/devtools-ui/src/components/button.tsx

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { splitProps } from 'solid-js'
1+
import { createMemo, splitProps } from 'solid-js'
22
import clsx from 'clsx'
33
import { useStyles } from '../styles/use-styles'
44
import type { JSX } from 'solid-js'
@@ -27,15 +27,17 @@ export function Button(props: ButtonProps) {
2727
'children',
2828
'className',
2929
])
30-
const variant = local.variant || 'primary'
31-
const classes = clsx(
32-
styles().button.base,
33-
styles().button.variant(variant, local.outline, local.ghost),
34-
local.className,
35-
)
30+
const classes = createMemo(() => {
31+
const variant = local.variant || 'primary'
32+
return clsx(
33+
styles().button.base,
34+
styles().button.variant(variant, local.outline, local.ghost),
35+
local.className,
36+
)
37+
})
3638

3739
return (
38-
<button {...rest} class={classes}>
40+
<button {...rest} class={classes()}>
3941
{local.children}
4042
</button>
4143
)

0 commit comments

Comments
 (0)