@tanstack/devtools-a11y 0.0.1 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/esm/core/components/IssueCard.d.ts +10 -0
- package/dist/esm/core/components/IssueCard.js +83 -0
- package/dist/esm/core/components/IssueCard.js.map +1 -0
- package/dist/esm/core/components/IssueList.d.ts +6 -0
- package/dist/esm/core/components/IssueList.js +134 -0
- package/dist/esm/core/components/IssueList.js.map +1 -0
- package/dist/esm/core/components/Settings.d.ts +6 -0
- package/dist/esm/core/components/Settings.js +251 -0
- package/dist/esm/core/components/Settings.js.map +1 -0
- package/dist/esm/core/components/Shell.d.ts +2 -0
- package/dist/esm/core/components/Shell.js +214 -0
- package/dist/esm/core/components/Shell.js.map +1 -0
- package/dist/esm/core/components/index.d.ts +2 -0
- package/dist/esm/core/components/index.js +14 -0
- package/dist/esm/core/components/index.js.map +1 -0
- package/dist/esm/core/contexts/allyContext.d.ts +17 -0
- package/dist/esm/core/contexts/allyContext.js +66 -0
- package/dist/esm/core/contexts/allyContext.js.map +1 -0
- package/dist/esm/core/core.d.ts +19 -0
- package/dist/esm/core/core.js +8 -0
- package/dist/esm/core/core.js.map +1 -0
- package/dist/esm/core/index.d.ts +9 -0
- package/dist/esm/core/index.js +9 -0
- package/dist/esm/core/index.js.map +1 -0
- package/dist/esm/core/production.d.ts +2 -0
- package/dist/esm/core/production.js +4 -0
- package/dist/esm/core/styles/styles.d.ts +85 -0
- package/dist/esm/core/styles/styles.js +547 -0
- package/dist/esm/core/styles/styles.js.map +1 -0
- package/dist/esm/core/types/types.d.ts +141 -0
- package/dist/esm/core/utils/ally-audit.utils.d.ts +19 -0
- package/dist/esm/core/utils/ally-audit.utils.js +226 -0
- package/dist/esm/core/utils/ally-audit.utils.js.map +1 -0
- package/dist/esm/core/utils/config.utils.d.ts +17 -0
- package/dist/esm/core/utils/config.utils.js +63 -0
- package/dist/esm/core/utils/config.utils.js.map +1 -0
- package/dist/esm/core/utils/custom-audit.utils.d.ts +13 -0
- package/dist/esm/core/utils/custom-audit.utils.js +426 -0
- package/dist/esm/core/utils/custom-audit.utils.js.map +1 -0
- package/dist/esm/core/utils/export-audit.uitls.d.ts +17 -0
- package/dist/esm/core/utils/export-audit.uitls.js +83 -0
- package/dist/esm/core/utils/export-audit.uitls.js.map +1 -0
- package/dist/esm/core/utils/ui.utils.d.ts +24 -0
- package/dist/esm/core/utils/ui.utils.js +330 -0
- package/dist/esm/core/utils/ui.utils.js.map +1 -0
- package/dist/esm/react/A11yDevtools.d.ts +5 -0
- package/dist/esm/react/A11yDevtools.js +8 -0
- package/dist/esm/react/A11yDevtools.js.map +1 -0
- package/dist/esm/react/index.d.ts +8 -0
- package/dist/esm/react/index.js +11 -0
- package/dist/esm/react/index.js.map +1 -0
- package/dist/esm/react/plugin.d.ts +12 -0
- package/dist/esm/react/plugin.js +11 -0
- package/dist/esm/react/plugin.js.map +1 -0
- package/dist/esm/react/production/A11yDevtools.d.ts +5 -0
- package/dist/esm/react/production/A11yDevtools.js +8 -0
- package/dist/esm/react/production/A11yDevtools.js.map +1 -0
- package/dist/esm/react/production/plugin.d.ts +7 -0
- package/dist/esm/react/production/plugin.js +11 -0
- package/dist/esm/react/production/plugin.js.map +1 -0
- package/dist/esm/react/production.d.ts +3 -0
- package/dist/esm/react/production.js +5 -0
- package/dist/esm/solid/A11yDevtools.d.ts +5 -0
- package/dist/esm/solid/A11yDevtools.js +8 -0
- package/dist/esm/solid/A11yDevtools.js.map +1 -0
- package/dist/esm/solid/index.d.ts +8 -0
- package/dist/esm/solid/index.js +9 -0
- package/dist/esm/solid/index.js.map +1 -0
- package/dist/esm/solid/plugin.d.ts +12 -0
- package/dist/esm/solid/plugin.js +11 -0
- package/dist/esm/solid/plugin.js.map +1 -0
- package/dist/esm/solid/production/A11yDevtools.d.ts +5 -0
- package/dist/esm/solid/production/A11yDevtools.js +8 -0
- package/dist/esm/solid/production/A11yDevtools.js.map +1 -0
- package/dist/esm/solid/production/plugin.d.ts +7 -0
- package/dist/esm/solid/production/plugin.js +11 -0
- package/dist/esm/solid/production/plugin.js.map +1 -0
- package/dist/esm/solid/production.d.ts +3 -0
- package/dist/esm/solid/production.js +3 -0
- package/package.json +110 -7
- package/src/core/components/IssueCard.tsx +75 -0
- package/src/core/components/IssueList.tsx +155 -0
- package/src/core/components/Settings.tsx +221 -0
- package/src/core/components/Shell.tsx +154 -0
- package/src/core/components/index.tsx +12 -0
- package/src/core/contexts/allyContext.tsx +118 -0
- package/src/core/core.tsx +11 -0
- package/src/core/index.ts +10 -0
- package/src/core/production.ts +5 -0
- package/src/core/styles/styles.ts +556 -0
- package/src/core/types/types.ts +177 -0
- package/src/core/utils/ally-audit.utils.ts +345 -0
- package/src/core/utils/config.utils.ts +68 -0
- package/src/core/utils/custom-audit.utils.ts +643 -0
- package/src/core/utils/export-audit.uitls.ts +180 -0
- package/src/core/utils/ui.utils.ts +483 -0
- package/src/react/A11yDevtools.ts +12 -0
- package/src/react/index.ts +16 -0
- package/src/react/plugin.ts +9 -0
- package/src/react/production/A11yDevtools.ts +11 -0
- package/src/react/production/plugin.ts +9 -0
- package/src/react/production.ts +7 -0
- package/src/solid/A11yDevtools.ts +11 -0
- package/src/solid/index.ts +14 -0
- package/src/solid/plugin.ts +9 -0
- package/src/solid/production/A11yDevtools.ts +10 -0
- package/src/solid/production/plugin.ts +9 -0
- package/src/solid/production.ts +5 -0
- package/README.md +0 -45
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/** @jsxImportSource solid-js */
|
|
2
|
+
|
|
3
|
+
import { Match, Show, Switch, createMemo, createSignal } from 'solid-js'
|
|
4
|
+
import { Button, Header, MainPanel } from '@tanstack/devtools-ui'
|
|
5
|
+
import { useAllyContext } from '../contexts/allyContext'
|
|
6
|
+
import { RULE_SET_LABELS, SEVERITY_LABELS } from '../utils/ui.utils'
|
|
7
|
+
import { useStyles } from '../styles/styles'
|
|
8
|
+
import { A11yIssueList } from './IssueList'
|
|
9
|
+
import { A11ySettingsOverlay } from './Settings'
|
|
10
|
+
|
|
11
|
+
export function Shell() {
|
|
12
|
+
const styles = useStyles()
|
|
13
|
+
|
|
14
|
+
// ally context
|
|
15
|
+
const { filteredIssues, allyResult, config, setConfig, triggerAllyScan } =
|
|
16
|
+
useAllyContext()
|
|
17
|
+
|
|
18
|
+
// ui state
|
|
19
|
+
const selectedIssueSignal = createSignal<string>('')
|
|
20
|
+
const [displaySettings, setDisplaySettings] = createSignal<boolean>(false)
|
|
21
|
+
|
|
22
|
+
const handleExport = (format: 'json' | 'csv') => {
|
|
23
|
+
if (allyResult.audit) return
|
|
24
|
+
// Keep export logic in runtime via event -> overlay? export is still a direct helper.
|
|
25
|
+
// We keep this import local to avoid pulling export code into the runtime module.
|
|
26
|
+
|
|
27
|
+
void import('../utils/export-audit.uitls').then((m) =>
|
|
28
|
+
m.exportAuditResults(allyResult.audit!, { format }),
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const showOverlayState = createMemo(() => config.showOverlays)
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<MainPanel class={styles().root} withPadding={false}>
|
|
36
|
+
<Header class={styles().header}>
|
|
37
|
+
<div class={styles().headerTitleRow}>
|
|
38
|
+
<h2 class={styles().headerTitle}>Accessibility Audit</h2>
|
|
39
|
+
|
|
40
|
+
<Show when={allyResult.state === 'done' && filteredIssues()}>
|
|
41
|
+
<span class={styles().headerSub}>
|
|
42
|
+
{`${filteredIssues().length} issue${filteredIssues().length !== 1 ? 's' : ''}`}
|
|
43
|
+
</span>
|
|
44
|
+
</Show>
|
|
45
|
+
</div>
|
|
46
|
+
|
|
47
|
+
<div class={styles().headerActions}>
|
|
48
|
+
<Button
|
|
49
|
+
variant="primary"
|
|
50
|
+
onClick={triggerAllyScan}
|
|
51
|
+
disabled={allyResult.state === 'scanning'}
|
|
52
|
+
>
|
|
53
|
+
{allyResult.state === 'scanning' ? 'Scanning...' : 'Run Audit'}
|
|
54
|
+
</Button>
|
|
55
|
+
|
|
56
|
+
<Show
|
|
57
|
+
when={
|
|
58
|
+
allyResult.state === 'done' &&
|
|
59
|
+
allyResult.audit &&
|
|
60
|
+
allyResult.audit.issues.length > 0
|
|
61
|
+
}
|
|
62
|
+
>
|
|
63
|
+
<div class={styles().buttonRow}>
|
|
64
|
+
<Button
|
|
65
|
+
variant="secondary"
|
|
66
|
+
outline
|
|
67
|
+
onClick={() => handleExport('json')}
|
|
68
|
+
>
|
|
69
|
+
Export JSON
|
|
70
|
+
</Button>
|
|
71
|
+
|
|
72
|
+
<Button
|
|
73
|
+
variant="secondary"
|
|
74
|
+
outline
|
|
75
|
+
onClick={() => handleExport('csv')}
|
|
76
|
+
>
|
|
77
|
+
Export CSV
|
|
78
|
+
</Button>
|
|
79
|
+
</div>
|
|
80
|
+
|
|
81
|
+
<Button
|
|
82
|
+
variant={showOverlayState() ? 'success' : 'warning'}
|
|
83
|
+
onClick={() => setConfig('showOverlays', !config.showOverlays)}
|
|
84
|
+
>
|
|
85
|
+
{showOverlayState() ? 'Hide' : 'Show'} Overlays
|
|
86
|
+
</Button>
|
|
87
|
+
</Show>
|
|
88
|
+
</div>
|
|
89
|
+
</Header>
|
|
90
|
+
|
|
91
|
+
<div class={styles().statusBar}>
|
|
92
|
+
<span>
|
|
93
|
+
<Show when={allyResult.state === 'done'}>
|
|
94
|
+
{`${SEVERITY_LABELS[config.threshold]}+ | ${RULE_SET_LABELS[config.ruleSet]}`}
|
|
95
|
+
|
|
96
|
+
<Show when={config.disabledRules.length > 0}>
|
|
97
|
+
{` | ${config.disabledRules.length} rule(s) disabled`}
|
|
98
|
+
</Show>
|
|
99
|
+
</Show>
|
|
100
|
+
</span>
|
|
101
|
+
|
|
102
|
+
<div class={styles().statusSpacer} />
|
|
103
|
+
|
|
104
|
+
<Button
|
|
105
|
+
variant="secondary"
|
|
106
|
+
outline
|
|
107
|
+
onClick={() => setDisplaySettings(true)}
|
|
108
|
+
>
|
|
109
|
+
Settings
|
|
110
|
+
</Button>
|
|
111
|
+
</div>
|
|
112
|
+
|
|
113
|
+
<div class={styles().content}>
|
|
114
|
+
<Switch>
|
|
115
|
+
<Match when={allyResult.state === 'init'}>
|
|
116
|
+
<div class={styles().emptyState}>
|
|
117
|
+
<p class={styles().emptyPrimary}>No audit results yet</p>
|
|
118
|
+
|
|
119
|
+
<p class={styles().emptySecondary}>
|
|
120
|
+
Click "Run Audit" to scan for accessibility issues
|
|
121
|
+
</p>
|
|
122
|
+
</div>
|
|
123
|
+
</Match>
|
|
124
|
+
|
|
125
|
+
<Match
|
|
126
|
+
when={
|
|
127
|
+
allyResult.state === 'done' &&
|
|
128
|
+
allyResult.audit &&
|
|
129
|
+
allyResult.audit.issues.length === 0
|
|
130
|
+
}
|
|
131
|
+
>
|
|
132
|
+
<div class={styles().successState}>
|
|
133
|
+
<p class={styles().successTitle}>
|
|
134
|
+
No accessibility issues found!
|
|
135
|
+
</p>
|
|
136
|
+
|
|
137
|
+
<p class={styles().successSub}>
|
|
138
|
+
Scanned in {allyResult.audit!.duration.toFixed(0)}ms
|
|
139
|
+
</p>
|
|
140
|
+
</div>
|
|
141
|
+
</Match>
|
|
142
|
+
|
|
143
|
+
<Match when={allyResult.audit && allyResult.audit.issues.length > 0}>
|
|
144
|
+
<A11yIssueList selectedIssueSignal={selectedIssueSignal} />
|
|
145
|
+
</Match>
|
|
146
|
+
</Switch>
|
|
147
|
+
</div>
|
|
148
|
+
|
|
149
|
+
<Show when={displaySettings()}>
|
|
150
|
+
<A11ySettingsOverlay onClose={() => setDisplaySettings(false)} />
|
|
151
|
+
</Show>
|
|
152
|
+
</MainPanel>
|
|
153
|
+
)
|
|
154
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/** @jsxImportSource solid-js */
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
createContext,
|
|
5
|
+
createEffect,
|
|
6
|
+
createMemo,
|
|
7
|
+
createSignal,
|
|
8
|
+
useContext,
|
|
9
|
+
} from 'solid-js'
|
|
10
|
+
import { createStore } from 'solid-js/store'
|
|
11
|
+
import { filterIssuesAboveThreshold, runAudit } from '../utils/ally-audit.utils'
|
|
12
|
+
import { mergeConfig, saveConfig } from '../utils/config.utils'
|
|
13
|
+
import { clearHighlights, highlightAllIssues } from '../utils/ui.utils'
|
|
14
|
+
|
|
15
|
+
// types
|
|
16
|
+
import type {
|
|
17
|
+
A11yAuditResult,
|
|
18
|
+
A11yPluginOptions,
|
|
19
|
+
SeverityThreshold,
|
|
20
|
+
} from '../types/types'
|
|
21
|
+
import type { ParentComponent } from 'solid-js'
|
|
22
|
+
|
|
23
|
+
//
|
|
24
|
+
// context state
|
|
25
|
+
//
|
|
26
|
+
|
|
27
|
+
function useAllyValue() {
|
|
28
|
+
const [config, setConfig] =
|
|
29
|
+
createStore<Required<A11yPluginOptions>>(mergeConfig())
|
|
30
|
+
|
|
31
|
+
const [allyResult, setAllyResult] = createStore<{
|
|
32
|
+
audit?: A11yAuditResult
|
|
33
|
+
state: 'init' | 'scanning' | 'done'
|
|
34
|
+
}>({ state: 'init' })
|
|
35
|
+
|
|
36
|
+
const [impactKey, setImpactKey] = createSignal<SeverityThreshold | 'all'>(
|
|
37
|
+
'all',
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
const triggerAllyScan = async () => {
|
|
41
|
+
setAllyResult('state', 'scanning')
|
|
42
|
+
setAllyResult({ audit: await runAudit(config), state: 'done' })
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const filteredIssues = createMemo(() => {
|
|
46
|
+
if (allyResult.state !== 'done' || !allyResult.audit?.issues) return []
|
|
47
|
+
let results = allyResult.audit.issues
|
|
48
|
+
|
|
49
|
+
results = filterIssuesAboveThreshold(results, config.threshold)
|
|
50
|
+
|
|
51
|
+
// removes excluded rules
|
|
52
|
+
if (config.disabledRules.length > 0) {
|
|
53
|
+
results = results.filter(
|
|
54
|
+
(issue) => !config.disabledRules.includes(issue.ruleId),
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// early return if all impacts selected
|
|
59
|
+
if (impactKey() === 'all') return results
|
|
60
|
+
|
|
61
|
+
return results.filter((val) => val.impact === impactKey())
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
createEffect(() => {
|
|
65
|
+
if (config.showOverlays === false) {
|
|
66
|
+
clearHighlights()
|
|
67
|
+
return
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (allyResult.state === 'done') highlightAllIssues(filteredIssues())
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
createEffect(() => {
|
|
74
|
+
saveConfig(config)
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
impactKey,
|
|
79
|
+
setImpactKey,
|
|
80
|
+
|
|
81
|
+
filteredIssues,
|
|
82
|
+
|
|
83
|
+
triggerAllyScan,
|
|
84
|
+
|
|
85
|
+
setConfig,
|
|
86
|
+
config,
|
|
87
|
+
|
|
88
|
+
allyResult,
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
type ContextType = ReturnType<typeof useAllyValue>
|
|
93
|
+
|
|
94
|
+
//
|
|
95
|
+
// context
|
|
96
|
+
//
|
|
97
|
+
|
|
98
|
+
const AllyContext = createContext<ContextType | null>(null)
|
|
99
|
+
|
|
100
|
+
type AllyProviderProps = {}
|
|
101
|
+
|
|
102
|
+
export const AllyProvider: ParentComponent<AllyProviderProps> = (props) => {
|
|
103
|
+
const value = useAllyValue()
|
|
104
|
+
|
|
105
|
+
return (
|
|
106
|
+
<AllyContext.Provider value={value}>{props.children}</AllyContext.Provider>
|
|
107
|
+
)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export function useAllyContext() {
|
|
111
|
+
const context = useContext(AllyContext)
|
|
112
|
+
|
|
113
|
+
if (context === null) {
|
|
114
|
+
throw new Error('useAllyContext must be used within an AllyProvider')
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return context
|
|
118
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** @jsxImportSource solid-js */
|
|
2
|
+
|
|
3
|
+
import { constructCoreClass } from '@tanstack/devtools-utils/solid'
|
|
4
|
+
|
|
5
|
+
export interface A11yDevtoolsInit {}
|
|
6
|
+
|
|
7
|
+
const [A11yDevtoolsCore, A11yDevtoolsCoreNoOp] = constructCoreClass(
|
|
8
|
+
() => import('./components'),
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
export { A11yDevtoolsCore, A11yDevtoolsCoreNoOp }
|