@ytspar/devbar 1.0.0-canary.4b73445 → 1.0.0-canary.6349f79

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.
@@ -259,30 +259,10 @@ export declare class GlobalDevBar {
259
259
  private resetToDefaults;
260
260
  private renderCollapsed;
261
261
  private renderExpanded;
262
- /** Base styles for tooltip containers */
263
- private readonly TOOLTIP_BASE_STYLES;
264
- /** Create a tooltip container element */
265
- private createTooltipContainer;
266
- /** Add a bold title to tooltip (metric name, feature name, etc.) */
267
- private addTooltipTitle;
268
- /** Add a description paragraph to tooltip */
269
- private addTooltipDescription;
270
- /** Add a muted uppercase section header to tooltip */
271
- private addTooltipSectionHeader;
272
- /** Add a colored row with dot + label + value (for thresholds) */
273
- private addTooltipColoredRow;
274
- /** Add an info row with label + value (for breakpoint details) */
275
- private addTooltipInfoRow;
276
- /** Position tooltip above the anchor element, adjusting for screen edges */
277
- private positionTooltip;
278
- /** Attach an HTML tooltip to an element with custom content builder */
279
- private attachHtmlTooltip;
280
- /** Attach a metric tooltip with title, description, and colored thresholds */
262
+ /**
263
+ * Attach an HTML tooltip with colored threshold labels to a metric element
264
+ */
281
265
  private attachMetricTooltip;
282
- /** Attach a breakpoint tooltip showing current breakpoint and all breakpoint ranges */
283
- private attachBreakpointTooltip;
284
- /** Attach a simple info tooltip with title and description */
285
- private attachInfoTooltip;
286
266
  /**
287
267
  * Create a console badge for error/warning counts
288
268
  */
@@ -131,23 +131,6 @@ export class GlobalDevBar {
131
131
  this.showSettingsPopover = false;
132
132
  // Overlay element for modals
133
133
  this.overlayElement = null;
134
- // ============================================================================
135
- // Tooltip Helpers (DRY system for HTML tooltips)
136
- // ============================================================================
137
- /** Base styles for tooltip containers */
138
- this.TOOLTIP_BASE_STYLES = {
139
- position: 'fixed',
140
- zIndex: '10004',
141
- backgroundColor: 'rgba(17, 24, 39, 0.98)',
142
- border: `1px solid ${COLORS.border}`,
143
- borderRadius: '6px',
144
- padding: '10px 12px',
145
- fontSize: '0.6875rem',
146
- fontFamily: FONT_MONO,
147
- maxWidth: '280px',
148
- boxShadow: '0 4px 12px rgba(0, 0, 0, 0.4)',
149
- pointerEvents: 'none',
150
- };
151
134
  // Initialize debug config first so we can log during construction
152
135
  this.debugConfig = normalizeDebugConfig(options.debug);
153
136
  this.debug = new DebugLogger(this.debugConfig);
@@ -2643,10 +2626,9 @@ export class GlobalDevBar {
2643
2626
  const bp = this.breakpointInfo.tailwindBreakpoint;
2644
2627
  const breakpointData = TAILWIND_BREAKPOINTS[bp];
2645
2628
  const bpSpan = document.createElement('span');
2646
- bpSpan.className = 'devbar-item';
2629
+ bpSpan.className = this.tooltipClass('left', 'devbar-item');
2647
2630
  Object.assign(bpSpan.style, { opacity: '0.9', cursor: 'default' });
2648
- // Use HTML tooltip for breakpoint info
2649
- this.attachBreakpointTooltip(bpSpan, bp, this.breakpointInfo.dimensions, breakpointData?.label || '');
2631
+ bpSpan.setAttribute('data-tooltip', `Tailwind Breakpoint: ${bp}\n${breakpointData?.label || ''}\n\nViewport: ${this.breakpointInfo.dimensions}\n\nBreakpoints:\nbase: <640px | sm: >=640px\nmd: >=768px | lg: >=1024px\nxl: >=1280px | 2xl: >=1536px`);
2650
2632
  let bpText = bp;
2651
2633
  if (bp !== 'base') {
2652
2634
  bpText =
@@ -2671,7 +2653,7 @@ export class GlobalDevBar {
2671
2653
  fcpSpan.className = 'devbar-item';
2672
2654
  Object.assign(fcpSpan.style, { opacity: '0.85', cursor: 'default' });
2673
2655
  fcpSpan.textContent = `FCP ${this.perfStats.fcp}`;
2674
- this.attachMetricTooltip(fcpSpan, 'First Contentful Paint (FCP)', 'Time until the first text or image renders on screen.', { good: '<1.8s', needsWork: '1.8-3s', poor: '>3s' });
2656
+ this.attachMetricTooltip(fcpSpan, 'First Contentful Paint (FCP): Time until first text/image renders.', { good: '<1.8s', needsWork: '1.8-3s', poor: '>3s' });
2675
2657
  infoSection.appendChild(fcpSpan);
2676
2658
  }
2677
2659
  if (showMetrics.lcp) {
@@ -2680,7 +2662,7 @@ export class GlobalDevBar {
2680
2662
  lcpSpan.className = 'devbar-item';
2681
2663
  Object.assign(lcpSpan.style, { opacity: '0.85', cursor: 'default' });
2682
2664
  lcpSpan.textContent = `LCP ${this.perfStats.lcp}`;
2683
- this.attachMetricTooltip(lcpSpan, 'Largest Contentful Paint (LCP)', 'Time until the largest visible element renders on screen.', { good: '<2.5s', needsWork: '2.5-4s', poor: '>4s' });
2665
+ this.attachMetricTooltip(lcpSpan, 'Largest Contentful Paint (LCP): Time until largest visible element renders.', { good: '<2.5s', needsWork: '2.5-4s', poor: '>4s' });
2684
2666
  infoSection.appendChild(lcpSpan);
2685
2667
  }
2686
2668
  if (showMetrics.cls) {
@@ -2689,7 +2671,7 @@ export class GlobalDevBar {
2689
2671
  clsSpan.className = 'devbar-item';
2690
2672
  Object.assign(clsSpan.style, { opacity: '0.85', cursor: 'default' });
2691
2673
  clsSpan.textContent = `CLS ${this.perfStats.cls}`;
2692
- this.attachMetricTooltip(clsSpan, 'Cumulative Layout Shift (CLS)', 'Visual stability score. Higher values mean more unexpected layout shifts.', { good: '<0.1', needsWork: '0.1-0.25', poor: '>0.25' });
2674
+ this.attachMetricTooltip(clsSpan, 'Cumulative Layout Shift (CLS): Visual stability score. Higher values mean more unexpected layout shifts.', { good: '<0.1', needsWork: '0.1-0.25', poor: '>0.25' });
2693
2675
  infoSection.appendChild(clsSpan);
2694
2676
  }
2695
2677
  if (showMetrics.inp) {
@@ -2698,15 +2680,15 @@ export class GlobalDevBar {
2698
2680
  inpSpan.className = 'devbar-item';
2699
2681
  Object.assign(inpSpan.style, { opacity: '0.85', cursor: 'default' });
2700
2682
  inpSpan.textContent = `INP ${this.perfStats.inp}`;
2701
- this.attachMetricTooltip(inpSpan, 'Interaction to Next Paint (INP)', 'Responsiveness to user input. Measures the longest interaction delay.', { good: '<200ms', needsWork: '200-500ms', poor: '>500ms' });
2683
+ this.attachMetricTooltip(inpSpan, 'Interaction to Next Paint (INP): Responsiveness to user input. Measures the longest interaction delay.', { good: '<200ms', needsWork: '200-500ms', poor: '>500ms' });
2702
2684
  infoSection.appendChild(inpSpan);
2703
2685
  }
2704
2686
  if (showMetrics.pageSize) {
2705
2687
  addSeparator();
2706
2688
  const sizeSpan = document.createElement('span');
2707
- sizeSpan.className = 'devbar-item';
2689
+ sizeSpan.className = this.tooltipClass('left', 'devbar-item');
2708
2690
  Object.assign(sizeSpan.style, { opacity: '0.7', cursor: 'default' });
2709
- this.attachInfoTooltip(sizeSpan, 'Total Page Size', 'Compressed/transferred size including HTML, CSS, JS, images, and other resources.');
2691
+ sizeSpan.setAttribute('data-tooltip', 'Total page size (compressed/transferred).\nIncludes HTML, CSS, JS, images, and other resources.');
2710
2692
  sizeSpan.textContent = this.perfStats.totalSize;
2711
2693
  infoSection.appendChild(sizeSpan);
2712
2694
  }
@@ -2787,206 +2769,104 @@ export class GlobalDevBar {
2787
2769
  wrapper.appendChild(customRow);
2788
2770
  }
2789
2771
  }
2790
- /** Create a tooltip container element */
2791
- createTooltipContainer() {
2792
- const tooltip = document.createElement('div');
2793
- tooltip.setAttribute('data-devbar', 'true');
2794
- Object.assign(tooltip.style, this.TOOLTIP_BASE_STYLES);
2795
- return tooltip;
2796
- }
2797
- /** Add a bold title to tooltip (metric name, feature name, etc.) */
2798
- addTooltipTitle(container, title) {
2799
- const titleEl = document.createElement('div');
2800
- const accentColor = this.settingsManager.get('accentColor') || COLORS.primary;
2801
- Object.assign(titleEl.style, {
2802
- color: accentColor,
2803
- fontWeight: '600',
2804
- marginBottom: '4px',
2805
- });
2806
- titleEl.textContent = title;
2807
- container.appendChild(titleEl);
2808
- }
2809
- /** Add a description paragraph to tooltip */
2810
- addTooltipDescription(container, description) {
2811
- const descEl = document.createElement('div');
2812
- Object.assign(descEl.style, {
2813
- color: COLORS.text,
2814
- marginBottom: '10px',
2815
- lineHeight: '1.4',
2816
- });
2817
- descEl.textContent = description;
2818
- container.appendChild(descEl);
2819
- }
2820
- /** Add a muted uppercase section header to tooltip */
2821
- addTooltipSectionHeader(container, header) {
2822
- const headerEl = document.createElement('div');
2823
- Object.assign(headerEl.style, {
2824
- color: COLORS.textMuted,
2825
- fontSize: '0.625rem',
2826
- textTransform: 'uppercase',
2827
- letterSpacing: '0.05em',
2828
- marginBottom: '6px',
2829
- });
2830
- headerEl.textContent = header;
2831
- container.appendChild(headerEl);
2832
- }
2833
- /** Add a colored row with dot + label + value (for thresholds) */
2834
- addTooltipColoredRow(container, label, value, color, labelWidth = '70px') {
2835
- const row = document.createElement('div');
2836
- Object.assign(row.style, { display: 'flex', alignItems: 'center', gap: '8px' });
2837
- const dot = document.createElement('span');
2838
- Object.assign(dot.style, {
2839
- width: '6px',
2840
- height: '6px',
2841
- borderRadius: '50%',
2842
- backgroundColor: color,
2843
- flexShrink: '0',
2844
- });
2845
- row.appendChild(dot);
2846
- const labelSpan = document.createElement('span');
2847
- Object.assign(labelSpan.style, {
2848
- color,
2849
- fontWeight: '500',
2850
- minWidth: labelWidth,
2851
- });
2852
- labelSpan.textContent = label;
2853
- row.appendChild(labelSpan);
2854
- const valueSpan = document.createElement('span');
2855
- Object.assign(valueSpan.style, { color: COLORS.textMuted });
2856
- valueSpan.textContent = value;
2857
- row.appendChild(valueSpan);
2858
- container.appendChild(row);
2859
- }
2860
- /** Add an info row with label + value (for breakpoint details) */
2861
- addTooltipInfoRow(container, label, value) {
2862
- const row = document.createElement('div');
2863
- Object.assign(row.style, {
2864
- display: 'flex',
2865
- gap: '8px',
2866
- lineHeight: '1.4',
2867
- });
2868
- const labelSpan = document.createElement('span');
2869
- Object.assign(labelSpan.style, { color: COLORS.textMuted });
2870
- labelSpan.textContent = label;
2871
- row.appendChild(labelSpan);
2872
- const valueSpan = document.createElement('span');
2873
- Object.assign(valueSpan.style, { color: COLORS.text });
2874
- valueSpan.textContent = value;
2875
- row.appendChild(valueSpan);
2876
- container.appendChild(row);
2877
- }
2878
- /** Position tooltip above the anchor element, adjusting for screen edges */
2879
- positionTooltip(tooltip, anchor) {
2880
- const rect = anchor.getBoundingClientRect();
2881
- tooltip.style.left = `${rect.left}px`;
2882
- tooltip.style.bottom = `${window.innerHeight - rect.top + 8}px`;
2883
- document.body.appendChild(tooltip);
2884
- // Adjust if off-screen
2885
- const tooltipRect = tooltip.getBoundingClientRect();
2886
- if (tooltipRect.right > window.innerWidth - 10) {
2887
- tooltip.style.left = `${window.innerWidth - tooltipRect.width - 10}px`;
2888
- }
2889
- if (tooltipRect.left < 10) {
2890
- tooltip.style.left = '10px';
2891
- }
2892
- }
2893
- /** Attach an HTML tooltip to an element with custom content builder */
2894
- attachHtmlTooltip(element, buildContent) {
2772
+ /**
2773
+ * Attach an HTML tooltip with colored threshold labels to a metric element
2774
+ */
2775
+ attachMetricTooltip(element, description, thresholds) {
2895
2776
  let tooltipEl = null;
2896
2777
  element.onmouseenter = () => {
2897
- tooltipEl = this.createTooltipContainer();
2898
- buildContent(tooltipEl);
2899
- this.positionTooltip(tooltipEl, element);
2900
- };
2901
- element.onmouseleave = () => {
2902
- if (tooltipEl) {
2903
- tooltipEl.remove();
2904
- tooltipEl = null;
2905
- }
2906
- };
2907
- }
2908
- // ============================================================================
2909
- // Tooltip Attachment Methods (specific tooltip types)
2910
- // ============================================================================
2911
- /** Attach a metric tooltip with title, description, and colored thresholds */
2912
- attachMetricTooltip(element, title, description, thresholds) {
2913
- this.attachHtmlTooltip(element, (tooltip) => {
2914
- this.addTooltipTitle(tooltip, title);
2915
- this.addTooltipDescription(tooltip, description);
2916
- this.addTooltipSectionHeader(tooltip, 'Thresholds');
2917
- const thresholdsContainer = document.createElement('div');
2918
- Object.assign(thresholdsContainer.style, {
2919
- display: 'flex',
2920
- flexDirection: 'column',
2921
- gap: '4px',
2778
+ tooltipEl = document.createElement('div');
2779
+ tooltipEl.setAttribute('data-devbar', 'true');
2780
+ Object.assign(tooltipEl.style, {
2781
+ position: 'fixed',
2782
+ zIndex: '10004',
2783
+ backgroundColor: 'rgba(17, 24, 39, 0.98)',
2784
+ border: `1px solid ${COLORS.border}`,
2785
+ borderRadius: '6px',
2786
+ padding: '10px 12px',
2787
+ fontSize: '0.6875rem',
2788
+ fontFamily: FONT_MONO,
2789
+ maxWidth: '280px',
2790
+ boxShadow: '0 4px 12px rgba(0, 0, 0, 0.4)',
2791
+ pointerEvents: 'none',
2922
2792
  });
2923
- this.addTooltipColoredRow(thresholdsContainer, 'Good', thresholds.good, COLORS.primary);
2924
- this.addTooltipColoredRow(thresholdsContainer, 'Needs work', thresholds.needsWork, COLORS.warning);
2925
- this.addTooltipColoredRow(thresholdsContainer, 'Poor', thresholds.poor, COLORS.error);
2926
- tooltip.appendChild(thresholdsContainer);
2927
- });
2928
- }
2929
- /** Attach a breakpoint tooltip showing current breakpoint and all breakpoint ranges */
2930
- attachBreakpointTooltip(element, breakpoint, dimensions, breakpointLabel) {
2931
- this.attachHtmlTooltip(element, (tooltip) => {
2932
- this.addTooltipTitle(tooltip, 'Tailwind Breakpoint');
2933
- // Current breakpoint info
2934
- const currentSection = document.createElement('div');
2935
- Object.assign(currentSection.style, { marginBottom: '10px' });
2936
- this.addTooltipInfoRow(currentSection, 'Current:', `${breakpoint} (${breakpointLabel})`);
2937
- this.addTooltipInfoRow(currentSection, 'Viewport:', dimensions);
2938
- tooltip.appendChild(currentSection);
2939
- // Breakpoints reference
2940
- this.addTooltipSectionHeader(tooltip, 'Breakpoints');
2941
- const bpContainer = document.createElement('div');
2942
- Object.assign(bpContainer.style, {
2793
+ // Description
2794
+ const descEl = document.createElement('div');
2795
+ Object.assign(descEl.style, {
2796
+ color: COLORS.text,
2797
+ marginBottom: '10px',
2798
+ lineHeight: '1.4',
2799
+ });
2800
+ descEl.textContent = description;
2801
+ tooltipEl.appendChild(descEl);
2802
+ // Thresholds header
2803
+ const thresholdsHeader = document.createElement('div');
2804
+ Object.assign(thresholdsHeader.style, {
2805
+ color: COLORS.textMuted,
2806
+ fontSize: '0.625rem',
2807
+ textTransform: 'uppercase',
2808
+ letterSpacing: '0.05em',
2809
+ marginBottom: '6px',
2810
+ });
2811
+ thresholdsHeader.textContent = 'Thresholds';
2812
+ tooltipEl.appendChild(thresholdsHeader);
2813
+ // Thresholds with colors
2814
+ const thresholdsEl = document.createElement('div');
2815
+ Object.assign(thresholdsEl.style, {
2943
2816
  display: 'flex',
2944
2817
  flexDirection: 'column',
2945
- gap: '2px',
2946
- fontSize: '0.625rem',
2818
+ gap: '4px',
2947
2819
  });
2948
- const breakpoints = [
2949
- { name: 'base', range: '<640px' },
2950
- { name: 'sm', range: '≥640px' },
2951
- { name: 'md', range: '≥768px' },
2952
- { name: 'lg', range: '≥1024px' },
2953
- { name: 'xl', range: '≥1280px' },
2954
- { name: '2xl', range: '≥1536px' },
2955
- ];
2956
- for (const bp of breakpoints) {
2820
+ const addThreshold = (label, value, color) => {
2957
2821
  const row = document.createElement('div');
2958
- Object.assign(row.style, { display: 'flex', gap: '8px' });
2959
- const nameSpan = document.createElement('span');
2960
- Object.assign(nameSpan.style, {
2961
- color: bp.name === breakpoint ? COLORS.primary : COLORS.textMuted,
2962
- fontWeight: bp.name === breakpoint ? '600' : '400',
2963
- minWidth: '32px',
2822
+ Object.assign(row.style, { display: 'flex', alignItems: 'center', gap: '8px' });
2823
+ const dot = document.createElement('span');
2824
+ Object.assign(dot.style, {
2825
+ width: '6px',
2826
+ height: '6px',
2827
+ borderRadius: '50%',
2828
+ backgroundColor: color,
2829
+ flexShrink: '0',
2964
2830
  });
2965
- nameSpan.textContent = bp.name;
2966
- row.appendChild(nameSpan);
2967
- const rangeSpan = document.createElement('span');
2968
- Object.assign(rangeSpan.style, {
2969
- color: bp.name === breakpoint ? COLORS.text : COLORS.textMuted,
2831
+ row.appendChild(dot);
2832
+ const labelSpan = document.createElement('span');
2833
+ Object.assign(labelSpan.style, {
2834
+ color,
2835
+ fontWeight: '500',
2836
+ minWidth: '70px',
2970
2837
  });
2971
- rangeSpan.textContent = bp.range;
2972
- row.appendChild(rangeSpan);
2973
- bpContainer.appendChild(row);
2838
+ labelSpan.textContent = label;
2839
+ row.appendChild(labelSpan);
2840
+ const valueSpan = document.createElement('span');
2841
+ Object.assign(valueSpan.style, { color: COLORS.textMuted });
2842
+ valueSpan.textContent = value;
2843
+ row.appendChild(valueSpan);
2844
+ thresholdsEl.appendChild(row);
2845
+ };
2846
+ addThreshold('Good', thresholds.good, COLORS.primary);
2847
+ addThreshold('Needs work', thresholds.needsWork, COLORS.warning);
2848
+ addThreshold('Poor', thresholds.poor, COLORS.error);
2849
+ tooltipEl.appendChild(thresholdsEl);
2850
+ // Position tooltip above element
2851
+ const rect = element.getBoundingClientRect();
2852
+ tooltipEl.style.left = `${rect.left}px`;
2853
+ tooltipEl.style.bottom = `${window.innerHeight - rect.top + 8}px`;
2854
+ document.body.appendChild(tooltipEl);
2855
+ // Adjust if off-screen
2856
+ const tooltipRect = tooltipEl.getBoundingClientRect();
2857
+ if (tooltipRect.right > window.innerWidth - 10) {
2858
+ tooltipEl.style.left = `${window.innerWidth - tooltipRect.width - 10}px`;
2974
2859
  }
2975
- tooltip.appendChild(bpContainer);
2976
- });
2977
- }
2978
- /** Attach a simple info tooltip with title and description */
2979
- attachInfoTooltip(element, title, description) {
2980
- this.attachHtmlTooltip(element, (tooltip) => {
2981
- this.addTooltipTitle(tooltip, title);
2982
- const descEl = document.createElement('div');
2983
- Object.assign(descEl.style, {
2984
- color: COLORS.text,
2985
- lineHeight: '1.4',
2986
- });
2987
- descEl.textContent = description;
2988
- tooltip.appendChild(descEl);
2989
- });
2860
+ if (tooltipRect.left < 10) {
2861
+ tooltipEl.style.left = '10px';
2862
+ }
2863
+ };
2864
+ element.onmouseleave = () => {
2865
+ if (tooltipEl) {
2866
+ tooltipEl.remove();
2867
+ tooltipEl = null;
2868
+ }
2869
+ };
2990
2870
  }
2991
2871
  /**
2992
2872
  * Create a console badge for error/warning counts
@@ -3026,9 +2906,6 @@ export class GlobalDevBar {
3026
2906
  btn.type = 'button';
3027
2907
  btn.className = this.tooltipClass('right');
3028
2908
  const hasSuccessState = this.copiedToClipboard || this.copiedPath || this.lastScreenshot;
3029
- const isDisabled = this.capturing;
3030
- // Grey out when not connected (save won't work, but clipboard still does)
3031
- const isGreyedOut = !this.sweetlinkConnected && !hasSuccessState;
3032
2909
  const tooltip = this.getScreenshotTooltip();
3033
2910
  btn.setAttribute('data-tooltip', tooltip);
3034
2911
  Object.assign(btn.style, {
@@ -3045,11 +2922,11 @@ export class GlobalDevBar {
3045
2922
  borderColor: hasSuccessState ? accentColor : `${accentColor}80`,
3046
2923
  backgroundColor: hasSuccessState ? `${accentColor}33` : 'transparent',
3047
2924
  color: hasSuccessState ? accentColor : `${accentColor}99`,
3048
- cursor: !isDisabled ? 'pointer' : 'not-allowed',
3049
- opacity: isGreyedOut ? '0.4' : '1',
2925
+ cursor: !this.capturing ? 'pointer' : 'not-allowed',
2926
+ opacity: '1',
3050
2927
  transition: 'all 150ms',
3051
2928
  });
3052
- btn.disabled = isDisabled;
2929
+ btn.disabled = this.capturing;
3053
2930
  btn.onclick = (e) => {
3054
2931
  // If we have a saved screenshot path, clicking copies the path
3055
2932
  if (this.lastScreenshot && !e.shiftKey) {
@@ -3106,10 +2983,10 @@ export class GlobalDevBar {
3106
2983
  if (this.lastScreenshot) {
3107
2984
  return `Screenshot saved!\n${this.lastScreenshot}\n\nClick to copy path`;
3108
2985
  }
3109
- if (!this.sweetlinkConnected) {
3110
- return `Screenshot (Disconnected)\n\nShift+Click: Copy to clipboard\n\n⚠ Sweetlink not connected\nSave to file unavailable`;
3111
- }
3112
- return `Screenshot\n\nClick: Save to file\nShift+Click: Copy to clipboard\n\nKeyboard:\nCmd/Ctrl+Shift+S: Save\nCmd/Ctrl+Shift+C: Copy`;
2986
+ const baseTooltip = `Screenshot\n\nClick: Save to file\nShift+Click: Copy to clipboard\n\nKeyboard:\nCmd/Ctrl+Shift+S: Save\nCmd/Ctrl+Shift+C: Copy`;
2987
+ return this.sweetlinkConnected
2988
+ ? baseTooltip
2989
+ : `${baseTooltip}\n\nWarning: Sweetlink not connected`;
3113
2990
  }
3114
2991
  /**
3115
2992
  * Get the tooltip text for the AI review button based on current state
@@ -3169,16 +3046,9 @@ export class GlobalDevBar {
3169
3046
  const btn = document.createElement('button');
3170
3047
  btn.type = 'button';
3171
3048
  btn.className = this.tooltipClass('right');
3172
- let tooltip;
3173
- if (this.lastOutline) {
3174
- tooltip = `Outline saved to:\n${this.lastOutline}`;
3175
- }
3176
- else if (!this.sweetlinkConnected) {
3177
- tooltip = `Document Outline\n\nView page heading structure.\n\n⚠ Sweetlink not connected\nSave to file unavailable`;
3178
- }
3179
- else {
3180
- tooltip = `Document Outline\n\nView page heading structure and\nsave as markdown.`;
3181
- }
3049
+ const tooltip = this.lastOutline
3050
+ ? `Outline saved to:\n${this.lastOutline}`
3051
+ : `Document Outline\n\nView page heading structure and\nsave as markdown.`;
3182
3052
  btn.setAttribute('data-tooltip', tooltip);
3183
3053
  const isActive = this.showOutlineModal || !!this.lastOutline;
3184
3054
  Object.assign(btn.style, getButtonStyles(BUTTON_COLORS.outline, isActive, false));
@@ -3196,16 +3066,9 @@ export class GlobalDevBar {
3196
3066
  const btn = document.createElement('button');
3197
3067
  btn.type = 'button';
3198
3068
  btn.className = this.tooltipClass('right');
3199
- let tooltip;
3200
- if (this.lastSchema) {
3201
- tooltip = `Schema saved to:\n${this.lastSchema}`;
3202
- }
3203
- else if (!this.sweetlinkConnected) {
3204
- tooltip = `Page Schema\n\nView JSON-LD, Open Graph, and\nother structured data.\n\n⚠ Sweetlink not connected\nSave to file unavailable`;
3205
- }
3206
- else {
3207
- tooltip = `Page Schema\n\nView JSON-LD, Open Graph, and\nother structured data.`;
3208
- }
3069
+ const tooltip = this.lastSchema
3070
+ ? `Schema saved to:\n${this.lastSchema}`
3071
+ : `Page Schema\n\nView JSON-LD, Open Graph, and\nother structured data.`;
3209
3072
  btn.setAttribute('data-tooltip', tooltip);
3210
3073
  const isActive = this.showSchemaModal || !!this.lastSchema;
3211
3074
  Object.assign(btn.style, getButtonStyles(BUTTON_COLORS.schema, isActive, false));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ytspar/devbar",
3
- "version": "1.0.0-canary.4b73445",
3
+ "version": "1.0.0-canary.6349f79",
4
4
  "type": "module",
5
5
  "private": false,
6
6
  "description": "Development toolbar and utilities with Sweetlink integration - pure vanilla JS, no framework dependencies",