@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,75 @@
1
+ /**
2
+ * DevBar Type Definitions
3
+ *
4
+ * Re-exports shared types from @ytspar/sweetlink and defines DevBar-specific types.
5
+ *
6
+ * NOTE: We import from the types sub-path to avoid pulling in Node.js-only modules.
7
+ */
8
+ export type { ConsoleLog, OutlineNode, PageSchema, SweetlinkCommand, } from '@ytspar/sweetlink/types';
9
+ /**
10
+ * Theme mode for DevBar display
11
+ */
12
+ export type ThemeMode = 'dark' | 'light' | 'system';
13
+ /**
14
+ * Debug configuration for DevBar
15
+ * When true, all debug options are enabled.
16
+ * When an object, specific options can be toggled.
17
+ */
18
+ export interface DebugConfig {
19
+ /** Enable debug logging. Default: false */
20
+ enabled: boolean;
21
+ /** Log lifecycle events (init, destroy). Default: true when enabled */
22
+ logLifecycle?: boolean;
23
+ /** Log state changes (collapse, modals). Default: true when enabled */
24
+ logStateChanges?: boolean;
25
+ /** Log WebSocket events (connect, disconnect, messages). Default: true when enabled */
26
+ logWebSocket?: boolean;
27
+ /** Log performance measurements (FCP, LCP, CLS, INP). Default: true when enabled */
28
+ logPerformance?: boolean;
29
+ }
30
+ /**
31
+ * Options for configuring the GlobalDevBar
32
+ */
33
+ export interface GlobalDevBarOptions {
34
+ /** Position of the devbar. Default: 'bottom-left' */
35
+ position?: 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right' | 'bottom-center';
36
+ /** Primary accent color (CSS color). Default: '#10b981' (emerald) */
37
+ accentColor?: string;
38
+ /** Which metrics to show. Default: all enabled */
39
+ showMetrics?: {
40
+ breakpoint?: boolean;
41
+ fcp?: boolean;
42
+ lcp?: boolean;
43
+ cls?: boolean;
44
+ inp?: boolean;
45
+ pageSize?: boolean;
46
+ };
47
+ /** Whether to show the screenshot button. Default: true */
48
+ showScreenshot?: boolean;
49
+ /** Whether to show console error/warning badges. Default: true */
50
+ showConsoleBadges?: boolean;
51
+ /** Whether to show tooltips on hover. Default: true */
52
+ showTooltips?: boolean;
53
+ /** Size overrides for special layouts (e.g., when other dev bars are present) */
54
+ sizeOverrides?: {
55
+ /** Custom width (CSS value). Default: calc(100vw - 140px) for centered, fit-content otherwise */
56
+ width?: string;
57
+ /** Custom max-width (CSS value). Default: 600px for centered, calc(100vw - 32px) otherwise */
58
+ maxWidth?: string;
59
+ /** Custom min-width (CSS value). Optional */
60
+ minWidth?: string;
61
+ };
62
+ /** Enable debug logging. Pass true for all options, or an object for specific options. */
63
+ debug?: boolean | DebugConfig;
64
+ }
65
+ /**
66
+ * Custom control that can be registered by host applications
67
+ */
68
+ export interface DevBarControl {
69
+ id: string;
70
+ label: string;
71
+ onClick: () => void;
72
+ active?: boolean;
73
+ disabled?: boolean;
74
+ variant?: 'default' | 'warning';
75
+ }
package/dist/types.js ADDED
@@ -0,0 +1,8 @@
1
+ /**
2
+ * DevBar Type Definitions
3
+ *
4
+ * Re-exports shared types from @ytspar/sweetlink and defines DevBar-specific types.
5
+ *
6
+ * NOTE: We import from the types sub-path to avoid pulling in Node.js-only modules.
7
+ */
8
+ export {};
@@ -0,0 +1,21 @@
1
+ /**
2
+ * DevBar Buttons
3
+ *
4
+ * Button creation and styling utilities for the DevBar UI.
5
+ */
6
+ /**
7
+ * Get button styling based on active state and color
8
+ */
9
+ export declare function getButtonStyles(color: string, isActive: boolean, isDisabled: boolean): Record<string, string>;
10
+ /**
11
+ * Create a styled button with common properties
12
+ */
13
+ export declare function createStyledButton(options: {
14
+ color: string;
15
+ text: string;
16
+ padding?: string;
17
+ borderRadius?: string;
18
+ fontSize?: string;
19
+ width?: string;
20
+ height?: string;
21
+ }): HTMLButtonElement;
@@ -0,0 +1,55 @@
1
+ /**
2
+ * DevBar Buttons
3
+ *
4
+ * Button creation and styling utilities for the DevBar UI.
5
+ */
6
+ import { ACTION_BUTTON_BASE_STYLES } from '../constants.js';
7
+ /**
8
+ * Get button styling based on active state and color
9
+ */
10
+ export function getButtonStyles(color, isActive, isDisabled) {
11
+ return {
12
+ ...ACTION_BUTTON_BASE_STYLES,
13
+ borderColor: isActive ? color : `${color}80`,
14
+ backgroundColor: isActive ? `${color}33` : 'transparent',
15
+ color: isActive ? color : `${color}99`,
16
+ cursor: isDisabled ? 'not-allowed' : 'pointer',
17
+ opacity: '1',
18
+ };
19
+ }
20
+ /**
21
+ * Apply hover effects to a button element (internal helper)
22
+ */
23
+ function applyButtonHoverEffects(btn, color, isActive = false) {
24
+ btn.onmouseenter = () => {
25
+ btn.style.backgroundColor = `${color}20`;
26
+ };
27
+ btn.onmouseleave = () => {
28
+ btn.style.backgroundColor = isActive ? `${color}33` : 'transparent';
29
+ };
30
+ }
31
+ /**
32
+ * Create a styled button with common properties
33
+ */
34
+ export function createStyledButton(options) {
35
+ const { color, text, padding = '6px 12px', borderRadius = '6px', fontSize = '0.75rem', width, height, } = options;
36
+ const btn = document.createElement('button');
37
+ Object.assign(btn.style, {
38
+ padding: width ? undefined : padding,
39
+ width,
40
+ height,
41
+ display: 'flex',
42
+ alignItems: 'center',
43
+ justifyContent: 'center',
44
+ backgroundColor: 'transparent',
45
+ border: `1px solid ${color}60`,
46
+ borderRadius,
47
+ color,
48
+ fontSize,
49
+ cursor: 'pointer',
50
+ transition: 'all 150ms',
51
+ });
52
+ btn.textContent = text;
53
+ applyButtonHoverEffects(btn, color);
54
+ return btn;
55
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * DevBar Icons
3
+ *
4
+ * SVG icon creation utilities for the DevBar UI.
5
+ */
6
+ /**
7
+ * Create an SVG icon element with the given path data
8
+ */
9
+ export declare function createSvgIcon(pathData: string, options: {
10
+ viewBox?: string;
11
+ fill?: boolean;
12
+ stroke?: boolean;
13
+ }): SVGSVGElement;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * DevBar Icons
3
+ *
4
+ * SVG icon creation utilities for the DevBar UI.
5
+ */
6
+ /**
7
+ * Create an SVG icon element with the given path data
8
+ */
9
+ export function createSvgIcon(pathData, options) {
10
+ const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
11
+ svg.setAttribute('width', '12');
12
+ svg.setAttribute('height', '12');
13
+ svg.setAttribute('viewBox', options.viewBox || '0 0 24 24');
14
+ if (options.fill) {
15
+ svg.style.fill = 'currentColor';
16
+ }
17
+ if (options.stroke) {
18
+ svg.style.stroke = 'currentColor';
19
+ svg.style.fill = 'none';
20
+ }
21
+ const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
22
+ path.setAttribute('d', pathData);
23
+ svg.appendChild(path);
24
+ return svg;
25
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * DevBar UI Components
3
+ *
4
+ * Re-exports all UI utilities.
5
+ */
6
+ export { createStyledButton, getButtonStyles } from './buttons.js';
7
+ export { createSvgIcon } from './icons.js';
8
+ export { createEmptyMessage, createInfoBox, createModalBox, createModalContent, createModalHeader, createModalOverlay, type ModalConfig, } from './modals.js';
@@ -0,0 +1,8 @@
1
+ /**
2
+ * DevBar UI Components
3
+ *
4
+ * Re-exports all UI utilities.
5
+ */
6
+ export { createStyledButton, getButtonStyles } from './buttons.js';
7
+ export { createSvgIcon } from './icons.js';
8
+ export { createEmptyMessage, createInfoBox, createModalBox, createModalContent, createModalHeader, createModalOverlay, } from './modals.js';
@@ -0,0 +1,44 @@
1
+ /**
2
+ * DevBar Modals
3
+ *
4
+ * Modal creation utilities for the DevBar UI.
5
+ */
6
+ /**
7
+ * Configuration for creating a modal
8
+ */
9
+ export interface ModalConfig {
10
+ color: string;
11
+ title: string;
12
+ onClose: () => void;
13
+ onCopyMd: () => Promise<void>;
14
+ onSave?: () => void;
15
+ sweetlinkConnected: boolean;
16
+ /** Whether a save operation is in progress */
17
+ isSaving?: boolean;
18
+ /** Path where data was saved (shows confirmation) */
19
+ savedPath?: string | null;
20
+ }
21
+ /**
22
+ * Create modal overlay with click-outside-to-close behavior
23
+ */
24
+ export declare function createModalOverlay(onClose: () => void): HTMLDivElement;
25
+ /**
26
+ * Create modal box with border and shadow
27
+ */
28
+ export declare function createModalBox(color: string): HTMLDivElement;
29
+ /**
30
+ * Create modal header with title, copy/save/close buttons
31
+ */
32
+ export declare function createModalHeader(config: ModalConfig): HTMLDivElement;
33
+ /**
34
+ * Create modal content container
35
+ */
36
+ export declare function createModalContent(): HTMLDivElement;
37
+ /**
38
+ * Create empty state message for modals
39
+ */
40
+ export declare function createEmptyMessage(text: string): HTMLDivElement;
41
+ /**
42
+ * Create a colored info box (for error states, cost estimates, etc.)
43
+ */
44
+ export declare function createInfoBox(color: string, title: string, content: string | HTMLElement[]): HTMLDivElement;
@@ -0,0 +1,190 @@
1
+ /**
2
+ * DevBar Modals
3
+ *
4
+ * Modal creation utilities for the DevBar UI.
5
+ */
6
+ import { MODAL_BOX_BASE_STYLES, MODAL_OVERLAY_STYLES } from '../constants.js';
7
+ import { createStyledButton } from './buttons.js';
8
+ /**
9
+ * Create modal overlay with click-outside-to-close behavior
10
+ */
11
+ export function createModalOverlay(onClose) {
12
+ const overlay = document.createElement('div');
13
+ overlay.setAttribute('data-devbar', 'true');
14
+ Object.assign(overlay.style, MODAL_OVERLAY_STYLES);
15
+ overlay.onclick = (e) => {
16
+ if (e.target === overlay)
17
+ onClose();
18
+ };
19
+ return overlay;
20
+ }
21
+ /**
22
+ * Create modal box with border and shadow
23
+ */
24
+ export function createModalBox(color) {
25
+ const modal = document.createElement('div');
26
+ Object.assign(modal.style, {
27
+ ...MODAL_BOX_BASE_STYLES,
28
+ border: `1px solid ${color}`,
29
+ boxShadow: `0 20px 60px rgba(0, 0, 0, 0.6), 0 0 0 1px ${color}33`,
30
+ });
31
+ return modal;
32
+ }
33
+ /**
34
+ * Create modal header with title, copy/save/close buttons
35
+ */
36
+ export function createModalHeader(config) {
37
+ const { color, title, onClose, onCopyMd, onSave, sweetlinkConnected, isSaving, savedPath } = config;
38
+ const header = document.createElement('div');
39
+ Object.assign(header.style, {
40
+ display: 'flex',
41
+ alignItems: 'center',
42
+ justifyContent: 'space-between',
43
+ padding: '16px 20px',
44
+ borderBottom: `1px solid ${color}40`,
45
+ flexWrap: 'wrap',
46
+ gap: '8px',
47
+ });
48
+ const titleEl = document.createElement('h2');
49
+ Object.assign(titleEl.style, {
50
+ color,
51
+ fontSize: '1rem',
52
+ fontWeight: '600',
53
+ margin: '0',
54
+ });
55
+ titleEl.textContent = title;
56
+ header.appendChild(titleEl);
57
+ const headerButtons = document.createElement('div');
58
+ Object.assign(headerButtons.style, { display: 'flex', gap: '10px', alignItems: 'center' });
59
+ // Copy MD button
60
+ const copyBtn = createStyledButton({ color, text: 'Copy MD' });
61
+ copyBtn.onclick = async () => {
62
+ try {
63
+ await onCopyMd();
64
+ copyBtn.textContent = 'Copied!';
65
+ setTimeout(() => {
66
+ copyBtn.textContent = 'Copy MD';
67
+ }, 1500);
68
+ }
69
+ catch {
70
+ console.error('[GlobalDevBar] Failed to copy to clipboard');
71
+ }
72
+ };
73
+ headerButtons.appendChild(copyBtn);
74
+ // Save button (if Sweetlink connected)
75
+ if (sweetlinkConnected && onSave) {
76
+ const saveBtn = createStyledButton({
77
+ color,
78
+ text: isSaving ? 'Saving...' : 'Save',
79
+ });
80
+ if (isSaving) {
81
+ saveBtn.style.opacity = '0.6';
82
+ saveBtn.style.cursor = 'not-allowed';
83
+ }
84
+ else {
85
+ saveBtn.onclick = onSave;
86
+ }
87
+ headerButtons.appendChild(saveBtn);
88
+ }
89
+ // Close button - use same padding as other buttons for consistent height
90
+ const closeBtn = createStyledButton({
91
+ color,
92
+ text: '×',
93
+ padding: '6px 10px',
94
+ fontSize: '0.875rem',
95
+ });
96
+ closeBtn.onclick = onClose;
97
+ headerButtons.appendChild(closeBtn);
98
+ header.appendChild(headerButtons);
99
+ // Show saved path confirmation below buttons
100
+ if (savedPath) {
101
+ const savedConfirm = document.createElement('div');
102
+ Object.assign(savedConfirm.style, {
103
+ width: '100%',
104
+ marginTop: '4px',
105
+ padding: '8px 12px',
106
+ backgroundColor: `${color}15`,
107
+ border: `1px solid ${color}30`,
108
+ borderRadius: '6px',
109
+ fontSize: '0.75rem',
110
+ color: color,
111
+ display: 'flex',
112
+ alignItems: 'center',
113
+ gap: '6px',
114
+ });
115
+ // Checkmark icon
116
+ const checkmark = document.createElement('span');
117
+ checkmark.textContent = '✓';
118
+ Object.assign(checkmark.style, { fontWeight: '600' });
119
+ savedConfirm.appendChild(checkmark);
120
+ // Path text
121
+ const pathText = document.createElement('span');
122
+ Object.assign(pathText.style, {
123
+ color: '#9ca3af',
124
+ fontFamily: 'monospace',
125
+ fontSize: '0.6875rem',
126
+ wordBreak: 'break-all',
127
+ });
128
+ pathText.textContent = `Saved to ${savedPath}`;
129
+ savedConfirm.appendChild(pathText);
130
+ header.appendChild(savedConfirm);
131
+ }
132
+ return header;
133
+ }
134
+ /**
135
+ * Create modal content container
136
+ */
137
+ export function createModalContent() {
138
+ const content = document.createElement('div');
139
+ Object.assign(content.style, {
140
+ flex: '1',
141
+ overflow: 'auto',
142
+ padding: '16px 20px',
143
+ });
144
+ return content;
145
+ }
146
+ /**
147
+ * Create empty state message for modals
148
+ */
149
+ export function createEmptyMessage(text) {
150
+ const emptyMsg = document.createElement('div');
151
+ Object.assign(emptyMsg.style, {
152
+ textAlign: 'center',
153
+ color: '#6b7280',
154
+ fontSize: '0.875rem',
155
+ padding: '40px',
156
+ });
157
+ emptyMsg.textContent = text;
158
+ return emptyMsg;
159
+ }
160
+ /**
161
+ * Create a colored info box (for error states, cost estimates, etc.)
162
+ */
163
+ export function createInfoBox(color, title, content) {
164
+ const box = document.createElement('div');
165
+ Object.assign(box.style, {
166
+ backgroundColor: `${color}15`,
167
+ border: `1px solid ${color}40`,
168
+ borderRadius: '8px',
169
+ padding: '14px',
170
+ marginBottom: '16px',
171
+ });
172
+ const titleEl = document.createElement('div');
173
+ Object.assign(titleEl.style, {
174
+ color,
175
+ fontWeight: '600',
176
+ marginBottom: '8px',
177
+ });
178
+ titleEl.textContent = title;
179
+ box.appendChild(titleEl);
180
+ if (typeof content === 'string') {
181
+ const textEl = document.createElement('div');
182
+ Object.assign(textEl.style, { color: '#94a3b8' });
183
+ textEl.textContent = content;
184
+ box.appendChild(textEl);
185
+ }
186
+ else {
187
+ content.forEach((el) => box.appendChild(el));
188
+ }
189
+ return box;
190
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * DevBar Utility Functions
3
+ *
4
+ * Re-exports shared utilities from @ytspar/sweetlink for use by DevBar components.
5
+ * This avoids code duplication between packages.
6
+ *
7
+ * NOTE: We import from specific sub-paths to avoid pulling in Node.js-only modules
8
+ * that would break browser/test environments.
9
+ */
10
+ export { formatArg, formatArgs } from '@ytspar/sweetlink/browser/consoleCapture';
11
+ export { canvasToDataUrl, copyCanvasToClipboard, delay, prepareForCapture, } from '@ytspar/sweetlink/browser/screenshotUtils';
package/dist/utils.js ADDED
@@ -0,0 +1,13 @@
1
+ /**
2
+ * DevBar Utility Functions
3
+ *
4
+ * Re-exports shared utilities from @ytspar/sweetlink for use by DevBar components.
5
+ * This avoids code duplication between packages.
6
+ *
7
+ * NOTE: We import from specific sub-paths to avoid pulling in Node.js-only modules
8
+ * that would break browser/test environments.
9
+ */
10
+ // Re-export console formatting utilities from sweetlink's browser module
11
+ export { formatArg, formatArgs } from '@ytspar/sweetlink/browser/consoleCapture';
12
+ // Re-export screenshot utilities from sweetlink's browser module
13
+ export { canvasToDataUrl, copyCanvasToClipboard, delay, prepareForCapture, } from '@ytspar/sweetlink/browser/screenshotUtils';
package/package.json CHANGED
@@ -1,10 +1,62 @@
1
1
  {
2
2
  "name": "@ytspar/devbar",
3
- "version": "0.0.1",
4
- "description": "OIDC trusted publishing setup package for @ytspar/devbar",
3
+ "version": "1.0.0-canary.2b99e1e",
4
+ "type": "module",
5
+ "private": false,
6
+ "description": "Development toolbar and utilities with Sweetlink integration - pure vanilla JS, no framework dependencies",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/ytspar/devtools.git",
10
+ "directory": "packages/devbar"
11
+ },
5
12
  "keywords": [
6
- "oidc",
7
- "trusted-publishing",
8
- "setup"
9
- ]
13
+ "development",
14
+ "debug",
15
+ "devtools",
16
+ "sweetlink",
17
+ "vanilla-js"
18
+ ],
19
+ "author": "ytspar",
20
+ "license": "MIT",
21
+ "main": "./dist/index.js",
22
+ "types": "./dist/index.d.ts",
23
+ "exports": {
24
+ ".": {
25
+ "types": "./dist/index.d.ts",
26
+ "import": "./dist/index.js",
27
+ "default": "./dist/index.js"
28
+ },
29
+ "./GlobalDevBar": {
30
+ "types": "./dist/GlobalDevBar.d.ts",
31
+ "import": "./dist/GlobalDevBar.js",
32
+ "default": "./dist/GlobalDevBar.js"
33
+ }
34
+ },
35
+ "files": [
36
+ "dist",
37
+ "README.md",
38
+ "LICENSE"
39
+ ],
40
+ "scripts": {
41
+ "build": "tsc",
42
+ "typecheck": "tsc --noEmit",
43
+ "clean": "rm -rf dist"
44
+ },
45
+ "peerDependencies": {
46
+ "@ytspar/sweetlink": "^1.0.0 || ^2.0.0"
47
+ },
48
+ "peerDependenciesMeta": {
49
+ "@ytspar/sweetlink": {
50
+ "optional": true
51
+ }
52
+ },
53
+ "dependencies": {
54
+ "axe-core": "^4.10.2",
55
+ "html2canvas-pro": "^1.5.8"
56
+ },
57
+ "devDependencies": {
58
+ "@ytspar/sweetlink": "workspace:*",
59
+ "@types/node": "^22.0.0",
60
+ "typescript": "^5.0.0"
61
+ }
10
62
  }