Skip to content

Commit

Permalink
[DevOverlay] Add Next.js version staleness indicator (#74601)
Browse files Browse the repository at this point in the history
This PR added style for the version staleness indicator. The "Turbopack-ness" will be added in the follow up PR.

### Light

![CleanShot 2025-01-08 at 03 03 42](https://github.com/user-attachments/assets/2e8fc270-bf5a-4437-88f5-4a4f0ea0813c)

### Dark

![CleanShot 2025-01-08 at 03 03 13](https://github.com/user-attachments/assets/932ff217-b50e-4d02-97ca-4b4cf26d7b7f)

Closes NDX-575
  • Loading branch information
devjiwonchoi authored Jan 10, 2025
1 parent 3b53d9f commit d29f2f9
Show file tree
Hide file tree
Showing 8 changed files with 202 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { ReadyRuntimeError } from '../../../helpers/get-error-by-type'
import type { VersionInfo } from '../../../../../../../../server/dev/parse-version-info'

import { ErrorOverlayPagination } from '../error-overlay-pagination/error-overlay-pagination'
import { VersionStalenessInfo } from '../../VersionStalenessInfo'
import { VersionStalenessInfo } from '../../VersionStalenessInfo/VersionStalenessInfo'
import { noop as css } from '../../../helpers/noop-template'

type ErrorOverlayFloatingHeaderProps = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import type { VersionInfo } from '../../../../../../../server/dev/parse-version-info'
import { noop as css } from '../../helpers/noop-template'

export function VersionStalenessInfo({
versionInfo,
isTurbopack = !!process.env.TURBOPACK,
}: {
versionInfo: VersionInfo | undefined
isTurbopack?: boolean
}) {
if (!versionInfo) return null
const { staleness } = versionInfo
Expand All @@ -12,11 +15,11 @@ export function VersionStalenessInfo({
if (!text) return null

return (
<span className="nextjs-container-build-error-version-status">
<span className={indicatorClass} />
<small data-nextjs-version-checker title={title}>
<span className="nextjs-container-build-error-version-status dialog-exclude-closing-from-outside-click">
<Eclipse className={`version-staleness-indicator ${indicatorClass}`} />
<span data-nextjs-version-checker title={title}>
{text}
</small>{' '}
</span>{' '}
{staleness === 'fresh' ||
staleness === 'newer-than-npm' ||
staleness === 'unknown' ? null : (
Expand All @@ -28,7 +31,7 @@ export function VersionStalenessInfo({
(learn more)
</a>
)}
{process.env.TURBOPACK ? ' (Turbopack)' : ''}
{isTurbopack && <span className="turbopack-text">Turbopack</span>}
</span>
)
}
Expand All @@ -37,7 +40,7 @@ export function getStaleness({ installed, staleness, expected }: VersionInfo) {
let text = ''
let title = ''
let indicatorClass = ''
const versionLabel = `Next.js (${installed})`
const versionLabel = `Next.js ${installed}`
switch (staleness) {
case 'newer-than-npm':
case 'fresh':
Expand All @@ -47,18 +50,18 @@ export function getStaleness({ installed, staleness, expected }: VersionInfo) {
break
case 'stale-patch':
case 'stale-minor':
text = `${versionLabel} out of date`
text = `${versionLabel} (stale)`
title = `There is a newer version (${expected}) available, upgrade recommended! `
indicatorClass = 'stale'
break
case 'stale-major': {
text = `${versionLabel} is outdated`
text = `${versionLabel} (outdated)`
title = `An outdated version detected (latest is ${expected}), upgrade is highly recommended!`
indicatorClass = 'outdated'
break
}
case 'stale-prerelease': {
text = `${versionLabel} is outdated`
text = `${versionLabel} (stale)`
title = `There is a newer canary version (${expected}) available, please upgrade! `
indicatorClass = 'stale'
break
Expand All @@ -70,3 +73,64 @@ export function getStaleness({ installed, staleness, expected }: VersionInfo) {
}
return { text, indicatorClass, title }
}

export const styles = css`
.nextjs-container-build-error-version-status {
display: flex;
justify-content: center;
align-items: center;
gap: var(--size-1);
padding: var(--size-1_5) var(--size-2);
background: var(--color-background-100);
box-shadow: var(--shadow-sm);
border: 1px solid var(--color-gray-400);
border-radius: var(--rounded-full);
color: var(--color-gray-900);
font-size: var(--size-font-11);
font-weight: 500;
line-height: var(--size-4);
}
.version-staleness-indicator.fresh {
fill: var(--color-green-800);
stroke: var(--color-green-300);
}
.version-staleness-indicator.stale {
fill: var(--color-amber-800);
stroke: var(--color-amber-300);
}
.version-staleness-indicator.outdated {
fill: var(--color-red-800);
stroke: var(--color-red-300);
}
.turbopack-text {
background: linear-gradient(280deg, #0096ff 0%, #ff1e56 100%);
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
@media (prefers-color-scheme: dark) {
.turbopack-text {
background: linear-gradient(280deg, #45b2ff 0%, #ff6d92 100%);
}
}
`

function Eclipse({ className }: { className: string }) {
return (
<svg
width="14"
height="14"
viewBox="0 0 14 14"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<circle className={className} cx="7" cy="7" r="5.5" strokeWidth="3" />
</svg>
)
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import type { Meta, StoryObj } from '@storybook/react'
import { VersionStalenessInfo } from './VersionStalenessInfo'
import { withShadowPortal } from '../../storybook/with-shadow-portal'

const meta: Meta<typeof VersionStalenessInfo> = {
title: 'VersionStalenessInfo',
component: VersionStalenessInfo,
parameters: {
layout: 'centered',
},
decorators: [withShadowPortal],
}

export default meta
type Story = StoryObj<typeof VersionStalenessInfo>

// Mock version info for different scenarios
const mockVersionInfo = {
fresh: {
installed: '15.0.0',
expected: '15.0.0',
staleness: 'fresh' as const,
},
stalePatch: {
installed: '15.0.0',
expected: '15.0.1',
staleness: 'stale-patch' as const,
},
staleMinor: {
installed: '15.0.0',
expected: '15.1.0',
staleness: 'stale-minor' as const,
},
staleMajor: {
installed: '14.0.0',
expected: '15.0.0',
staleness: 'stale-major' as const,
},
stalePrerelease: {
installed: '15.0.0-canary.0',
expected: '15.0.0-canary.1',
staleness: 'stale-prerelease' as const,
},
newerThanNpm: {
installed: '15.0.0-canary.1',
expected: '15.0.0-canary.0',
staleness: 'newer-than-npm' as const,
},
}

export const Fresh: Story = {
args: {
versionInfo: mockVersionInfo.fresh,
},
}

export const StalePatch: Story = {
args: {
versionInfo: mockVersionInfo.stalePatch,
},
}

export const StaleMinor: Story = {
args: {
versionInfo: mockVersionInfo.staleMinor,
},
}

export const StaleMajor: Story = {
args: {
versionInfo: mockVersionInfo.staleMajor,
},
}

export const StalePrerelease: Story = {
args: {
versionInfo: mockVersionInfo.stalePrerelease,
},
}

export const NewerThanNpm: Story = {
args: {
versionInfo: mockVersionInfo.newerThanNpm,
},
}

export const Turbopack: Story = {
args: {
versionInfo: {
...mockVersionInfo.fresh,
},
isTurbopack: true,
},
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ export function Base() {
--size-gap-triple: 24px;
--size-gap-quad: 32px;
--size-font-11: 11px;
--size-font-smaller: 12px;
--size-font-small: 14px;
--size-font: 16px;
--size-font-big: 20px;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { styles as overlay } from '../components/Overlay/styles'
import { styles as footer } from '../components/Errors/error-overlay-footer/styles'
import { styles as terminal } from '../components/Terminal/styles'
import { styles as toast } from '../components/Toast'
import { styles as versionStaleness } from '../components/VersionStalenessInfo'
import { styles as versionStaleness } from '../components/VersionStalenessInfo/VersionStalenessInfo'
import { styles as buildErrorStyles } from '../container/BuildError'
import { styles as containerErrorStyles } from '../container/Errors'
import { styles as containerRuntimeErrorStyles } from '../container/RuntimeError'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ export function Colors() {
<style>
{css`
:host {
/* Background */
/* Background Light */
--color-background-100: #ffffff;
--color-background-200: #fafafa;
/* Syntax */
/* Syntax Light */
--color-syntax-comment: #666666;
--color-syntax-constant: #171717;
--color-syntax-function: #0068d6;
Expand All @@ -21,7 +21,7 @@ export function Colors() {
--color-syntax-string: #067a6e;
--color-syntax-string-expression: #067a6e;
/* Gray Scale */
/* Gray Scale Light */
--color-gray-100: #f2f2f2;
--color-gray-200: #ebebeb;
--color-gray-300: #e6e6e6;
Expand All @@ -33,7 +33,7 @@ export function Colors() {
--color-gray-900: #666666;
--color-gray-1000: #171717;
/* Gray Alpha Scale */
/* Gray Alpha Scale Light */
--color-gray-alpha-100: rgba(0, 0, 0, 0.05);
--color-gray-alpha-200: rgba(0, 0, 0, 0.081);
--color-gray-alpha-300: rgba(0, 0, 0, 0.1);
Expand All @@ -45,7 +45,7 @@ export function Colors() {
--color-gray-alpha-900: rgba(0, 0, 0, 0.605);
--color-gray-alpha-1000: rgba(0, 0, 0, 0.91);
/* Blue Scale */
/* Blue Scale Light */
--color-blue-100: #f0f7ff;
--color-blue-200: #edf6ff;
--color-blue-300: #e1f0ff;
Expand All @@ -57,7 +57,7 @@ export function Colors() {
--color-blue-900: #0067d6;
--color-blue-1000: #0025ad;
/* Red Scale */
/* Red Scale Light */
--color-red-100: #fff0f0;
--color-red-200: #ffebeb;
--color-red-300: #ffe5e5;
Expand All @@ -69,7 +69,19 @@ export function Colors() {
--color-red-900: #ca2a30;
--color-red-1000: #381316;
/* Green Scale */
/* Amber Scale Light */
--color-amber-100: #fff6e5;
--color-amber-200: #fff4d5;
--color-amber-300: #fef0cd;
--color-amber-400: #ffddbf;
--color-amber-500: #ffc96b;
--color-amber-600: #f5b047;
--color-amber-700: #ffb224;
--color-amber-800: #ff990a;
--color-amber-900: #a35200;
--color-amber-1000: #4e2009;
/* Green Scale Light */
--color-green-100: #effbef;
--color-green-200: #eafaea;
--color-green-300: #dcf6dc;
Expand Down Expand Up @@ -147,6 +159,18 @@ export function Colors() {
--color-red-900: #ff6369;
--color-red-1000: #ffecee;
/* Amber Scale Dark */
--color-amber-100: #271700;
--color-amber-200: #341c00;
--color-amber-300: #4a2900;
--color-amber-400: #573300;
--color-amber-500: #693f05;
--color-amber-600: #e79c13;
--color-amber-700: #ffb224;
--color-amber-800: #ff990a;
--color-amber-900: #f1a10d;
--color-amber-1000: #fef3dd;
/* Green Scale Dark */
--color-green-100: #0b2211;
--color-green-200: #0f2c17;
Expand Down

0 comments on commit d29f2f9

Please sign in to comment.