diff --git a/packages/devbar/package.json b/packages/devbar/package.json index c826286..901d9c6 100644 --- a/packages/devbar/package.json +++ b/packages/devbar/package.json @@ -1,6 +1,6 @@ { "name": "@ytspar/devbar", - "version": "1.15.1", + "version": "1.15.2", "type": "module", "private": false, "description": "Development toolbar and utilities with Sweetlink integration - pure vanilla JS, no framework dependencies", diff --git a/packages/devbar/src/modules/rendering/expanded.test.ts b/packages/devbar/src/modules/rendering/expanded.test.ts index f6d93fc..9987b74 100644 --- a/packages/devbar/src/modules/rendering/expanded.test.ts +++ b/packages/devbar/src/modules/rendering/expanded.test.ts @@ -595,7 +595,7 @@ describe('renderExpanded', () => { // Main row only; compact plugin badges should not create a wide second row. expect(state.container!.children.length).toBe(1); - expect(state.container!.dataset.devbarCustomControls).toBe('true'); + expect(state.container!.dataset.devbarCustomControls).toBeUndefined(); const customRow = state.container!.querySelector( '.devbar-custom-controls-inline' ) as HTMLElement; @@ -613,6 +613,14 @@ describe('renderExpanded', () => { expect(state.container!.dataset.devbarCustomControls).toBeUndefined(); }); + it('removes grouped-control layout marker when only inline controls remain', () => { + const state = createMockState(); + state.container!.dataset.devbarCustomControls = 'true'; + renderExpanded(state, [{ id: 'release', label: 'v1.3.0 May 20, 2026', variant: 'info' }]); + + expect(state.container!.dataset.devbarCustomControls).toBeUndefined(); + }); + it('custom control button calls onClick handler', () => { const state = createMockState(); const onClick = vi.fn(); @@ -691,6 +699,7 @@ describe('renderExpanded', () => { const state = createMockState(); renderExpanded(state, [{ id: 'btn1', label: 'First', group: 'Cards', onClick: vi.fn() }]); + expect(state.container!.dataset.devbarCustomControls).toBe('true'); const customRow = state.container!.children[1] as HTMLElement; expect(customRow.className).toBe('devbar-custom-controls devbar-custom-controls-row'); const groupLabel = customRow.querySelector('.devbar-custom-group-label') as HTMLElement; diff --git a/packages/devbar/src/modules/rendering/expanded.ts b/packages/devbar/src/modules/rendering/expanded.ts index 506a1b0..e1b47af 100644 --- a/packages/devbar/src/modules/rendering/expanded.ts +++ b/packages/devbar/src/modules/rendering/expanded.ts @@ -623,10 +623,11 @@ export function renderExpanded(state: DevBarState, customControls: DevBarControl const { position, accentColor, showMetrics, showScreenshot, showConsoleBadges } = state.options; const { errorCount, warningCount, infoCount } = state.getLogCounts(); + const hasGroupedControls = customControls.some((control) => control.group); const isCentered = position === 'bottom-center'; const wrapper = state.container; - if (customControls.length > 0) { + if (hasGroupedControls) { wrapper.dataset.devbarCustomControls = 'true'; } else { delete wrapper.dataset.devbarCustomControls; diff --git a/packages/playground/src/release-notes.json b/packages/playground/src/release-notes.json index eeb9495..b737996 100644 --- a/packages/playground/src/release-notes.json +++ b/packages/playground/src/release-notes.json @@ -1,5 +1,6 @@ { "devbar": { + "1.15.2": "Fix expanded toolbar spacing for inline-only custom controls such as release/version badges. Ungrouped controls no longer enable the grouped plugin responsive layout marker, so a single release badge keeps the toolbar content-sized instead of leaving a wide empty pill. Grouped custom controls still use the grouped responsive layout.", "1.15.1": "Republish of 1.15.0 with the actual `dist/` build of the autoConnect change. 1.15.0 was published from a stale local `dist/` that pre-dated the source edits, so it shipped with the version bump but no runtime/type changes. Use `1.15.1` (or higher); `1.15.0` is deprecated. No source change beyond the rebuild.", "1.15.0": "New `sweetlink.autoConnect` option (defaults to `true`). When set to `false`, devbar skips the initial WebSocket connection attempt to the Sweetlink CLI on startup — useful for projects that load devbar but don't run the Sweetlink daemon, where the unsuppressible browser-level `WebSocket connection to 'ws://...' failed: ECONNREFUSED` log on every page load is otherwise pure noise. Apps can still opt in at runtime by calling `globalDevBar.connectWebSocket()`. No behavior change for existing setups (autoConnect defaults to true).", "1.14.7": "Small-screen toolbar default: devbar now starts in compact mode at 860px and below while keeping explicit compact preferences and wide desktop expanded mode intact. This prevents mobile/tablet layouts from booting into the denser expanded toolbar.",