@ytspar/devbar 0.0.1 → 1.0.0-canary.2b99e1e

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.
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Accessibility Audit Utilities
3
+ *
4
+ * Lazy-loads axe-core and provides accessibility auditing capabilities.
5
+ */
6
+ /**
7
+ * Axe-core result types (simplified)
8
+ */
9
+ export interface AxeViolation {
10
+ id: string;
11
+ impact: 'critical' | 'serious' | 'moderate' | 'minor';
12
+ description: string;
13
+ help: string;
14
+ helpUrl: string;
15
+ tags: string[];
16
+ nodes: Array<{
17
+ html: string;
18
+ target: string[];
19
+ failureSummary?: string;
20
+ }>;
21
+ }
22
+ export interface AxeResult {
23
+ violations: AxeViolation[];
24
+ passes: Array<{
25
+ id: string;
26
+ description: string;
27
+ }>;
28
+ incomplete: AxeViolation[];
29
+ inapplicable: Array<{
30
+ id: string;
31
+ }>;
32
+ timestamp: string;
33
+ url: string;
34
+ }
35
+ /**
36
+ * Accessibility audit state
37
+ */
38
+ export interface A11yState {
39
+ isLoading: boolean;
40
+ lastRun: number | null;
41
+ result: AxeResult | null;
42
+ error: string | null;
43
+ }
44
+ /**
45
+ * Check if axe-core is loaded
46
+ */
47
+ export declare function isAxeLoaded(): boolean;
48
+ /**
49
+ * Preload axe-core without waiting
50
+ */
51
+ export declare function preloadAxe(): void;
52
+ /**
53
+ * Run accessibility audit on the page
54
+ * Returns cached result if within cache duration
55
+ */
56
+ export declare function runA11yAudit(forceRefresh?: boolean): Promise<AxeResult>;
57
+ /**
58
+ * Get violation count by impact level
59
+ */
60
+ export declare function getViolationCounts(violations: AxeViolation[]): Record<string, number>;
61
+ /**
62
+ * Group violations by impact level
63
+ */
64
+ export declare function groupViolationsByImpact(violations: AxeViolation[]): Map<string, AxeViolation[]>;
65
+ /**
66
+ * Get color for impact level
67
+ */
68
+ export declare function getImpactColor(impact: string): string;
69
+ /**
70
+ * Get badge color based on worst violation impact
71
+ */
72
+ export declare function getBadgeColor(violations: AxeViolation[]): string;
73
+ /**
74
+ * Clear cached result
75
+ */
76
+ export declare function clearA11yCache(): void;
77
+ /**
78
+ * Get cached result without running audit
79
+ */
80
+ export declare function getCachedResult(): AxeResult | null;
81
+ /**
82
+ * Format violation for display
83
+ */
84
+ export declare function formatViolation(violation: AxeViolation): string;
@@ -0,0 +1,155 @@
1
+ /**
2
+ * Accessibility Audit Utilities
3
+ *
4
+ * Lazy-loads axe-core and provides accessibility auditing capabilities.
5
+ */
6
+ // Cache duration in milliseconds (30 seconds)
7
+ const CACHE_DURATION_MS = 30000;
8
+ // Module-level state
9
+ let axePromise = null;
10
+ let cachedResult = null;
11
+ let cacheTimestamp = null;
12
+ /**
13
+ * Lazy load axe-core
14
+ */
15
+ async function loadAxe() {
16
+ if (!axePromise) {
17
+ axePromise = import('axe-core');
18
+ }
19
+ return axePromise;
20
+ }
21
+ /**
22
+ * Check if axe-core is loaded
23
+ */
24
+ export function isAxeLoaded() {
25
+ return axePromise !== null;
26
+ }
27
+ /**
28
+ * Preload axe-core without waiting
29
+ */
30
+ export function preloadAxe() {
31
+ loadAxe().catch(() => {
32
+ // Silently ignore preload errors
33
+ });
34
+ }
35
+ /**
36
+ * Run accessibility audit on the page
37
+ * Returns cached result if within cache duration
38
+ */
39
+ export async function runA11yAudit(forceRefresh = false) {
40
+ // Return cached result if valid
41
+ if (!forceRefresh &&
42
+ cachedResult &&
43
+ cacheTimestamp &&
44
+ Date.now() - cacheTimestamp < CACHE_DURATION_MS) {
45
+ return cachedResult;
46
+ }
47
+ const axeModule = await loadAxe();
48
+ // Handle ESM/CJS interop
49
+ const axe = axeModule.default ?? axeModule;
50
+ // Run axe analysis
51
+ const result = await axe.run(document, {
52
+ runOnly: {
53
+ type: 'tag',
54
+ values: ['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa', 'best-practice'],
55
+ },
56
+ });
57
+ // Transform to our format
58
+ const auditResult = {
59
+ violations: result.violations,
60
+ passes: result.passes.map((p) => ({
61
+ id: p.id,
62
+ description: p.description,
63
+ })),
64
+ incomplete: result.incomplete,
65
+ inapplicable: result.inapplicable.map((i) => ({ id: i.id })),
66
+ timestamp: new Date().toISOString(),
67
+ url: window.location.href,
68
+ };
69
+ // Cache the result
70
+ cachedResult = auditResult;
71
+ cacheTimestamp = Date.now();
72
+ return auditResult;
73
+ }
74
+ /**
75
+ * Get violation count by impact level
76
+ */
77
+ export function getViolationCounts(violations) {
78
+ const counts = {
79
+ critical: 0,
80
+ serious: 0,
81
+ moderate: 0,
82
+ minor: 0,
83
+ total: 0,
84
+ };
85
+ for (const violation of violations) {
86
+ counts[violation.impact] = (counts[violation.impact] || 0) + 1;
87
+ counts.total++;
88
+ }
89
+ return counts;
90
+ }
91
+ /**
92
+ * Group violations by impact level
93
+ */
94
+ export function groupViolationsByImpact(violations) {
95
+ const groups = new Map();
96
+ const impactOrder = ['critical', 'serious', 'moderate', 'minor'];
97
+ for (const impact of impactOrder) {
98
+ groups.set(impact, []);
99
+ }
100
+ for (const violation of violations) {
101
+ const group = groups.get(violation.impact);
102
+ if (group) {
103
+ group.push(violation);
104
+ }
105
+ }
106
+ return groups;
107
+ }
108
+ /**
109
+ * Get color for impact level
110
+ */
111
+ export function getImpactColor(impact) {
112
+ const colors = {
113
+ critical: '#ef4444', // red
114
+ serious: '#f97316', // orange
115
+ moderate: '#f59e0b', // amber
116
+ minor: '#84cc16', // lime
117
+ };
118
+ return colors[impact] || '#6b7280';
119
+ }
120
+ /**
121
+ * Get badge color based on worst violation impact
122
+ */
123
+ export function getBadgeColor(violations) {
124
+ if (violations.some((v) => v.impact === 'critical'))
125
+ return getImpactColor('critical');
126
+ if (violations.some((v) => v.impact === 'serious'))
127
+ return getImpactColor('serious');
128
+ if (violations.some((v) => v.impact === 'moderate'))
129
+ return getImpactColor('moderate');
130
+ if (violations.some((v) => v.impact === 'minor'))
131
+ return getImpactColor('minor');
132
+ return '#10b981'; // green - no violations
133
+ }
134
+ /**
135
+ * Clear cached result
136
+ */
137
+ export function clearA11yCache() {
138
+ cachedResult = null;
139
+ cacheTimestamp = null;
140
+ }
141
+ /**
142
+ * Get cached result without running audit
143
+ */
144
+ export function getCachedResult() {
145
+ if (cachedResult && cacheTimestamp && Date.now() - cacheTimestamp < CACHE_DURATION_MS) {
146
+ return cachedResult;
147
+ }
148
+ return null;
149
+ }
150
+ /**
151
+ * Format violation for display
152
+ */
153
+ export function formatViolation(violation) {
154
+ return `[${violation.impact.toUpperCase()}] ${violation.help}\n${violation.description}\n${violation.nodes.length} element(s) affected`;
155
+ }
@@ -0,0 +1,301 @@
1
+ /**
2
+ * DevBar Constants
3
+ *
4
+ * Shared constants used by the DevBar components.
5
+ */
6
+ export { MAX_CONSOLE_LOGS } from '@ytspar/sweetlink/browser/consoleCapture';
7
+ export { DEVBAR_SCREENSHOT_QUALITY } from '@ytspar/sweetlink/browser/screenshotUtils';
8
+ /** Maximum reconnection attempts before giving up */
9
+ export declare const MAX_RECONNECT_ATTEMPTS = 10;
10
+ /** Base delay for exponential backoff (ms) */
11
+ export declare const BASE_RECONNECT_DELAY_MS = 1000;
12
+ /** Maximum delay between reconnection attempts (ms) */
13
+ export declare const MAX_RECONNECT_DELAY_MS = 30000;
14
+ /** Default WebSocket port for Sweetlink connection (legacy fallback) */
15
+ export declare const WS_PORT = 9223;
16
+ /** Port offset from app port to calculate WebSocket port (matches SweetlinkBridge) */
17
+ export declare const WS_PORT_OFFSET = 6223;
18
+ /** Maximum ports to try when scanning for matching server */
19
+ export declare const MAX_PORT_RETRIES = 10;
20
+ /** Delay between port scan attempts (ms) */
21
+ export declare const PORT_RETRY_DELAY_MS = 100;
22
+ /** Delay before restarting port scan from base after all ports fail (ms) */
23
+ export declare const PORT_SCAN_RESTART_DELAY_MS = 3000;
24
+ /** Duration to show screenshot notification (ms) */
25
+ export declare const SCREENSHOT_NOTIFICATION_MS = 3000;
26
+ /** Duration to show clipboard notification (ms) */
27
+ export declare const CLIPBOARD_NOTIFICATION_MS = 2000;
28
+ /** Duration to show design review notification (ms) */
29
+ export declare const DESIGN_REVIEW_NOTIFICATION_MS = 5000;
30
+ /** Delay after blur before capturing screenshot (ms) */
31
+ export declare const SCREENSHOT_BLUR_DELAY_MS = 50;
32
+ /** Scale factor for screenshots (0.75 = 75% of original) */
33
+ export declare const SCREENSHOT_SCALE = 0.75;
34
+ /** Tailwind CSS breakpoint definitions */
35
+ export declare const TAILWIND_BREAKPOINTS: {
36
+ readonly base: {
37
+ readonly min: 0;
38
+ readonly label: "Tailwind base: <640px";
39
+ };
40
+ readonly sm: {
41
+ readonly min: 640;
42
+ readonly label: "Tailwind sm: >=640px";
43
+ };
44
+ readonly md: {
45
+ readonly min: 768;
46
+ readonly label: "Tailwind md: >=768px";
47
+ };
48
+ readonly lg: {
49
+ readonly min: 1024;
50
+ readonly label: "Tailwind lg: >=1024px";
51
+ };
52
+ readonly xl: {
53
+ readonly min: 1280;
54
+ readonly label: "Tailwind xl: >=1280px";
55
+ };
56
+ readonly '2xl': {
57
+ readonly min: 1536;
58
+ readonly label: "Tailwind 2xl: >=1536px";
59
+ };
60
+ };
61
+ export type TailwindBreakpoint = keyof typeof TAILWIND_BREAKPOINTS;
62
+ /** Button colors for devbar toolbar buttons */
63
+ export declare const BUTTON_COLORS: {
64
+ readonly screenshot: "#10b981";
65
+ readonly review: "#a855f7";
66
+ readonly outline: "#06b6d4";
67
+ readonly schema: "#f59e0b";
68
+ readonly error: "#ef4444";
69
+ readonly warning: "#f59e0b";
70
+ };
71
+ /** Category colors for outline display */
72
+ export declare const CATEGORY_COLORS: Record<string, string>;
73
+ /** LocalStorage keys for DevBar persistence */
74
+ export declare const STORAGE_KEYS: {
75
+ /** Theme mode preference: 'dark' | 'light' | 'system' */
76
+ readonly themeMode: "devbar-theme-mode";
77
+ /** Compact mode preference: 'true' | 'false' */
78
+ readonly compactMode: "devbar-compact-mode";
79
+ };
80
+ /** Complete DevBar design system theme */
81
+ export declare const DEVBAR_THEME: {
82
+ readonly colors: {
83
+ readonly primary: "#10b981";
84
+ readonly primaryHover: "#059669";
85
+ readonly primaryGlow: "rgba(16, 185, 129, 0.4)";
86
+ readonly error: "#ef4444";
87
+ readonly warning: "#f59e0b";
88
+ readonly info: "#3b82f6";
89
+ readonly purple: "#a855f7";
90
+ readonly cyan: "#06b6d4";
91
+ readonly pink: "#ec4899";
92
+ readonly lime: "#84cc16";
93
+ readonly bg: "#0a0f1a";
94
+ readonly bgCard: "rgba(17, 24, 39, 0.95)";
95
+ readonly bgElevated: "rgba(17, 24, 39, 0.98)";
96
+ readonly bgInput: "rgba(10, 15, 26, 0.8)";
97
+ readonly text: "#f1f5f9";
98
+ readonly textSecondary: "#94a3b8";
99
+ readonly textMuted: "#6b7280";
100
+ readonly border: "rgba(16, 185, 129, 0.2)";
101
+ readonly borderSubtle: "rgba(255, 255, 255, 0.05)";
102
+ };
103
+ readonly fonts: {
104
+ readonly mono: "'Departure Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace";
105
+ };
106
+ readonly typography: {
107
+ readonly sizeXs: "0.625rem";
108
+ readonly sizeSm: "0.6875rem";
109
+ readonly sizeBase: "0.75rem";
110
+ readonly sizeMd: "0.8125rem";
111
+ readonly sizeLg: "0.875rem";
112
+ readonly sizeXl: "1rem";
113
+ readonly size2xl: "1.5rem";
114
+ readonly leadingTight: "1rem";
115
+ readonly leadingNormal: "1.5";
116
+ readonly leadingRelaxed: "1.6";
117
+ readonly weightNormal: "400";
118
+ readonly weightMedium: "500";
119
+ readonly weightSemibold: "600";
120
+ readonly trackingTight: "-0.02em";
121
+ readonly trackingNormal: "0";
122
+ readonly trackingWide: "0.05em";
123
+ readonly trackingWider: "0.1em";
124
+ };
125
+ readonly radius: {
126
+ readonly sm: "4px";
127
+ readonly md: "6px";
128
+ readonly lg: "12px";
129
+ };
130
+ readonly shadows: {
131
+ readonly sm: "0 1px 2px rgba(0, 0, 0, 0.4)";
132
+ readonly md: "0 4px 12px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(16, 185, 129, 0.1)";
133
+ readonly lg: "0 8px 32px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(16, 185, 129, 0.15)";
134
+ readonly glow: "0 0 20px rgba(16, 185, 129, 0.15)";
135
+ };
136
+ readonly transitions: {
137
+ readonly fast: "150ms";
138
+ };
139
+ };
140
+ export type DevBarTheme = typeof DEVBAR_THEME;
141
+ /** Light theme variant - terminal aesthetic with light green tones */
142
+ export declare const DEVBAR_THEME_LIGHT: {
143
+ readonly colors: {
144
+ readonly primary: "#047857";
145
+ readonly primaryHover: "#065f46";
146
+ readonly primaryGlow: "rgba(4, 120, 87, 0.25)";
147
+ readonly error: "#dc2626";
148
+ readonly warning: "#d97706";
149
+ readonly info: "#2563eb";
150
+ readonly purple: "#7c3aed";
151
+ readonly cyan: "#0891b2";
152
+ readonly pink: "#db2777";
153
+ readonly lime: "#65a30d";
154
+ readonly bg: "#ecfdf5";
155
+ readonly bgCard: "rgba(255, 255, 255, 0.85)";
156
+ readonly bgElevated: "rgba(255, 255, 255, 0.95)";
157
+ readonly bgInput: "rgba(236, 253, 245, 0.9)";
158
+ readonly text: "#064e3b";
159
+ readonly textSecondary: "#065f46";
160
+ readonly textMuted: "#047857";
161
+ readonly border: "rgba(4, 120, 87, 0.3)";
162
+ readonly borderSubtle: "rgba(4, 120, 87, 0.1)";
163
+ };
164
+ readonly fonts: {
165
+ readonly mono: "'Departure Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace";
166
+ };
167
+ readonly typography: {
168
+ readonly sizeXs: "0.625rem";
169
+ readonly sizeSm: "0.6875rem";
170
+ readonly sizeBase: "0.75rem";
171
+ readonly sizeMd: "0.8125rem";
172
+ readonly sizeLg: "0.875rem";
173
+ readonly sizeXl: "1rem";
174
+ readonly size2xl: "1.5rem";
175
+ readonly leadingTight: "1rem";
176
+ readonly leadingNormal: "1.5";
177
+ readonly leadingRelaxed: "1.6";
178
+ readonly weightNormal: "400";
179
+ readonly weightMedium: "500";
180
+ readonly weightSemibold: "600";
181
+ readonly trackingTight: "-0.02em";
182
+ readonly trackingNormal: "0";
183
+ readonly trackingWide: "0.05em";
184
+ readonly trackingWider: "0.1em";
185
+ };
186
+ readonly radius: {
187
+ readonly sm: "4px";
188
+ readonly md: "6px";
189
+ readonly lg: "12px";
190
+ };
191
+ readonly shadows: {
192
+ readonly sm: "0 1px 2px rgba(4, 120, 87, 0.1)";
193
+ readonly md: "0 4px 12px rgba(4, 120, 87, 0.12), 0 0 0 1px rgba(4, 120, 87, 0.15)";
194
+ readonly lg: "0 8px 32px rgba(4, 120, 87, 0.15), 0 0 0 1px rgba(4, 120, 87, 0.2)";
195
+ readonly glow: "0 0 20px rgba(4, 120, 87, 0.15)";
196
+ };
197
+ readonly transitions: {
198
+ readonly fast: "150ms";
199
+ };
200
+ };
201
+ export type DevBarThemeLight = typeof DEVBAR_THEME_LIGHT;
202
+ /** Shorthand for common colors */
203
+ export declare const COLORS: {
204
+ readonly primary: "#10b981";
205
+ readonly primaryHover: "#059669";
206
+ readonly primaryGlow: "rgba(16, 185, 129, 0.4)";
207
+ readonly error: "#ef4444";
208
+ readonly warning: "#f59e0b";
209
+ readonly info: "#3b82f6";
210
+ readonly purple: "#a855f7";
211
+ readonly cyan: "#06b6d4";
212
+ readonly pink: "#ec4899";
213
+ readonly lime: "#84cc16";
214
+ readonly bg: "#0a0f1a";
215
+ readonly bgCard: "rgba(17, 24, 39, 0.95)";
216
+ readonly bgElevated: "rgba(17, 24, 39, 0.98)";
217
+ readonly bgInput: "rgba(10, 15, 26, 0.8)";
218
+ readonly text: "#f1f5f9";
219
+ readonly textSecondary: "#94a3b8";
220
+ readonly textMuted: "#6b7280";
221
+ readonly border: "rgba(16, 185, 129, 0.2)";
222
+ readonly borderSubtle: "rgba(255, 255, 255, 0.05)";
223
+ };
224
+ /** Shorthand for font stack */
225
+ export declare const FONT_MONO: "'Departure Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace";
226
+ /** Flexible input type for theme customization */
227
+ export type DevBarThemeInput = {
228
+ colors: {
229
+ [K in keyof DevBarTheme['colors']]: string;
230
+ };
231
+ fonts: {
232
+ [K in keyof DevBarTheme['fonts']]: string;
233
+ };
234
+ typography: {
235
+ [K in keyof DevBarTheme['typography']]: string;
236
+ };
237
+ radius: {
238
+ [K in keyof DevBarTheme['radius']]: string;
239
+ };
240
+ shadows: {
241
+ [K in keyof DevBarTheme['shadows']]: string;
242
+ };
243
+ transitions: {
244
+ [K in keyof DevBarTheme['transitions']]: string;
245
+ };
246
+ };
247
+ import type { ThemeMode } from './types.js';
248
+ /**
249
+ * Get the stored theme mode preference
250
+ */
251
+ export declare function getStoredThemeMode(): ThemeMode;
252
+ /**
253
+ * Store the theme mode preference
254
+ */
255
+ export declare function setStoredThemeMode(mode: ThemeMode): void;
256
+ /**
257
+ * Get the effective theme (resolves 'system' to 'dark' or 'light')
258
+ */
259
+ export declare function getEffectiveTheme(mode: ThemeMode): 'dark' | 'light';
260
+ /** Union type for both theme color variants */
261
+ export type ThemeColors = DevBarTheme['colors'] | DevBarThemeLight['colors'];
262
+ /**
263
+ * Get theme colors based on the current effective theme
264
+ */
265
+ export declare function getThemeColors(mode: ThemeMode): ThemeColors;
266
+ /**
267
+ * Get full theme based on the current effective theme
268
+ */
269
+ export declare function getTheme(mode: ThemeMode): typeof DEVBAR_THEME | typeof DEVBAR_THEME_LIGHT;
270
+ /**
271
+ * Generate CSS custom properties from the theme
272
+ */
273
+ export declare function generateThemeCSSVars(theme?: DevBarThemeInput): string;
274
+ /**
275
+ * Inject theme CSS variables into the document
276
+ */
277
+ export declare function injectThemeCSS(theme?: DevBarThemeInput): void;
278
+ /**
279
+ * Generate CSS for breakpoint media queries
280
+ */
281
+ export declare function generateBreakpointCSS(selector: string, property: string, values: Record<TailwindBreakpoint, string>): string;
282
+ /** Base styles for toolbar action buttons */
283
+ export declare const ACTION_BUTTON_BASE_STYLES: {
284
+ readonly display: "flex";
285
+ readonly alignItems: "center";
286
+ readonly justifyContent: "center";
287
+ readonly width: "22px";
288
+ readonly height: "22px";
289
+ readonly minWidth: "22px";
290
+ readonly minHeight: "22px";
291
+ readonly flexShrink: "0";
292
+ readonly borderRadius: "50%";
293
+ readonly border: "1px solid";
294
+ readonly transition: "all 150ms";
295
+ };
296
+ /** Common modal overlay styles */
297
+ export declare const MODAL_OVERLAY_STYLES: Record<string, string>;
298
+ /** Common modal box styles */
299
+ export declare const MODAL_BOX_BASE_STYLES: Record<string, string>;
300
+ /** Tooltip and animation CSS styles */
301
+ export declare const TOOLTIP_STYLES: string;