diff --git a/packages/next/client/dev/dev-build-watcher.js b/packages/next/client/dev/dev-build-watcher.js index 3d3e043eed2cdd2..27a93fc6025df47 100644 --- a/packages/next/client/dev/dev-build-watcher.js +++ b/packages/next/client/dev/dev-build-watcher.js @@ -5,21 +5,14 @@ export default function initializeBuildWatcher( position = 'bottom-right' ) { const shadowHost = document.createElement('div') + const [verticalProperty, horizontalProperty] = position.split('-') shadowHost.id = '__next-build-watcher' // Make sure container is fixed and on a high zIndex so it shows shadowHost.style.position = 'fixed' // Ensure container's position to be top or bottom (default) - if (['top-left', 'top-right'].indexOf(position) > -1) { - shadowHost.style.top = '10px' - } else { - shadowHost.style.bottom = '10px' - } + shadowHost.style[verticalProperty] = '10px' // Ensure container's position to be left or right (default) - if (['bottom-left', 'top-left'].indexOf(position) > -1) { - shadowHost.style.left = '20px' - } else { - shadowHost.style.right = '20px' - } + shadowHost.style[horizontalProperty] = '20px' shadowHost.style.width = 0 shadowHost.style.height = 0 shadowHost.style.zIndex = 99999 @@ -43,7 +36,7 @@ export default function initializeBuildWatcher( shadowRoot.appendChild(container) // CSS - const css = createCss(prefix) + const css = createCss(prefix, { horizontalProperty, verticalProperty }) shadowRoot.appendChild(css) // State @@ -134,13 +127,13 @@ function createContainer(prefix) { return container } -function createCss(prefix) { +function createCss(prefix, { horizontalProperty, verticalProperty }) { const css = document.createElement('style') css.textContent = ` #${prefix}container { position: absolute; - bottom: 10px; - right: 30px; + ${verticalProperty}: 10px; + ${horizontalProperty}: 30px; border-radius: 3px; background: #000; @@ -158,7 +151,7 @@ function createCss(prefix) { display: none; opacity: 0; - transition: opacity 0.1s ease, bottom 0.1s ease; + transition: opacity 0.1s ease, ${verticalProperty} 0.1s ease; animation: ${prefix}fade-in 0.1s ease-in-out; } @@ -167,7 +160,7 @@ function createCss(prefix) { } #${prefix}container.${prefix}building { - bottom: 20px; + ${verticalProperty}: 20px; opacity: 1; } @@ -187,11 +180,11 @@ function createCss(prefix) { @keyframes ${prefix}fade-in { from { - bottom: 10px; + ${verticalProperty}: 10px; opacity: 0; } to { - bottom: 20px; + ${verticalProperty}: 20px; opacity: 1; } } diff --git a/packages/next/server/config.ts b/packages/next/server/config.ts index 27153a073db99af..6a049172c5ae949 100644 --- a/packages/next/server/config.ts +++ b/packages/next/server/config.ts @@ -616,6 +616,24 @@ function assignDefaults(userConfig: { [key: string]: any }) { result.pageExtensions = pageExtensions } + if (result.devIndicators?.buildActivityPosition) { + const { buildActivityPosition } = result.devIndicators + const allowedValues = [ + 'top-left', + 'top-right', + 'bottom-left', + 'bottom-right', + ] + + if (!allowedValues.includes(buildActivityPosition)) { + throw new Error( + `Invalid "devIndicator.buildActivityPosition" provided, expected one of ${allowedValues.join( + ', ' + )}, received ${buildActivityPosition}` + ) + } + } + return result } diff --git a/test/integration/build-indicator/test/index.test.js b/test/integration/build-indicator/test/index.test.js index 56e31eaf32b04da..713451d2faa995c 100644 --- a/test/integration/build-indicator/test/index.test.js +++ b/test/integration/build-indicator/test/index.test.js @@ -24,6 +24,37 @@ const installCheckVisible = (browser) => { } describe('Build Activity Indicator', () => { + it('should validate buildActivityPosition config', async () => { + let stderr = '' + const configPath = join(appDir, 'next.config.js') + await fs.writeFile( + configPath, + ` + module.exports = { + devIndicators: { + buildActivityPosition: 'ttop-leff' + } + } + ` + ) + const app = await launchApp(appDir, await findPort(), { + onStderr(msg) { + stderr += msg + }, + }).catch((err) => { + console.error('got err', err) + }) + await fs.remove(configPath) + + expect(stderr).toContain( + `Invalid "devIndicator.buildActivityPosition" provided, expected one of top-left, top-right, bottom-left, bottom-right, received ttop-leff` + ) + + if (app) { + await killApp(app) + } + }) + describe('Enabled', () => { beforeAll(async () => { await fs.remove(nextConfig)