Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Settings: New about page design #23357

Merged
merged 6 commits into from
Jul 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions code/ui/.storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ const config: StorybookConfig = {
'@storybook/addon-essentials',
'@storybook/addon-interactions',
'@storybook/addon-storysource',
'@storybook/addon-designs',
],
framework: {
name: '@storybook/react-vite',
Expand Down
27 changes: 27 additions & 0 deletions code/ui/components/src/clipboard/ClipboardCode.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from 'react';
import { color, styled, typography } from '@storybook/theming';

const Code = styled.pre`
line-height: 18px;
padding: 11px 1rem;
white-space: pre-wrap;
background: rgba(0, 0, 0, 0.05);
color: ${color.darkest};
border-radius: 3px;
margin: 1rem 0;
width: 100%;
display: block;
overflow: hidden;
font-family: ${typography.fonts.mono};
font-size: ${typography.size.s2 - 1}px;
`;

interface ClipboardCodeProps {
code: string;
}

export const ClipboardCode = ({ code, ...props }: ClipboardCodeProps) => (
<Code id="clipboard-code" {...props}>
{code}
</Code>
);
3 changes: 2 additions & 1 deletion code/ui/components/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ export { Span } from './typography/elements/Span';
export { Table } from './typography/elements/Table';
export { TT } from './typography/elements/TT';
export { UL } from './typography/elements/UL';

export { Badge } from './Badge/Badge';

// Typography
Expand Down Expand Up @@ -85,6 +84,8 @@ export * from './typography/ResetWrapper';

export { withReset, codeCommon } from './typography/lib/common';

export { ClipboardCode } from './clipboard/ClipboardCode';

// eslint-disable-next-line prefer-destructuring
export const components = typography.components;

Expand Down
1 change: 1 addition & 0 deletions code/ui/manager/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
},
"devDependencies": {
"@fal-works/esbuild-plugin-global-externals": "^2.1.2",
"@storybook/addon-designs": "^7.0.0",
"@storybook/addons": "7.1.0-beta.2",
"@storybook/api": "7.1.0-beta.2",
"@storybook/channel-postmessage": "7.1.0-beta.2",
Expand Down
1 change: 1 addition & 0 deletions code/ui/manager/src/globals/exports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export default {
'Bar',
'Blockquote',
'Button',
'ClipboardCode',
'Code',
'DL',
'Div',
Expand Down
44 changes: 0 additions & 44 deletions code/ui/manager/src/settings/about.stories.jsx

This file was deleted.

39 changes: 39 additions & 0 deletions code/ui/manager/src/settings/about.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import type { Meta, StoryObj } from '@storybook/react';
import React from 'react';
import { AboutScreen } from './about';

const meta = {
component: AboutScreen,
title: 'Settings/AboutScreen',
decorators: [
(Story) => (
<div
style={{
position: 'relative',
height: '100vh',
width: '100vw',
}}
>
<Story />
</div>
),
],
} satisfies Meta<typeof AboutScreen>;

export default meta;

type Story = StoryObj<typeof meta>;

export const Default: Story = {
args: {
current: {
version: '7.0.1',
},
},
parameters: {
design: {
type: 'figma',
url: 'https://www.figma.com/file/ur4kydUbRqdDyfoZWzdiIw/Storybook-app?type=design&node-id=9564-120444&mode=design&t=0TPINZFpwgFQFQeX-4',
},
},
};
203 changes: 124 additions & 79 deletions code/ui/manager/src/settings/about.tsx
Original file line number Diff line number Diff line change
@@ -1,114 +1,159 @@
/* eslint-disable no-nested-ternary */
import type { FC } from 'react';
import React from 'react';
import semver from 'semver';
import React, { useState } from 'react';
import { styled } from '@storybook/theming';
import type { State } from '@storybook/manager-api';

import { StorybookIcon, SyntaxHighlighter, DocumentWrapper } from '@storybook/components';

import SettingsFooter from './SettingsFooter';
import { Button as BaseButton, Icons, Link, StorybookIcon } from '@storybook/components';

const Header = styled.header(({ theme }) => ({
marginBottom: 20,
fontSize: theme.typography.size.m3,
marginBottom: 32,
fontSize: theme.typography.size.l2,
color: theme.base === 'light' ? theme.color.darkest : theme.color.lightest,
fontWeight: theme.typography.weight.bold,
alignItems: 'center',
display: 'flex',

'> svg': {
height: 32,
height: 48,
width: 'auto',
marginRight: 8,
},
}));

const UpdateMessage = styled.div<{ status: 'positive' | 'negative' | string }>(
({ status, theme }) => {
if (status === 'positive') {
return { background: theme.background.positive, color: theme.color.positiveText };
}
if (status === 'negative') {
return { background: theme.background.negative, color: theme.color.negativeText };
}
return {
background: theme.base === 'light' ? '#EAF3FC' : theme.color.darkest,
color: theme.base === 'light' ? theme.color.darkest : theme.defaultText,
};
},
const Container = styled.div({
display: `flex`,
alignItems: 'center',
justifyContent: 'center',
height: 'calc(100% - 40px)',
flexDirection: 'column',
});

({ theme }) => ({
fontWeight: theme.typography.weight.bold,
const UpgradeBlock = styled.div(({ theme }) => {
return {
border: '1px solid',
borderRadius: 5,
padding: 20,
margin: 20,
maxWidth: 400,
borderColor: theme.appBorderColor,
fontSize: theme.typography.size.s2,
padding: '10px 20px',
marginBottom: 24,
borderRadius: theme.appBorderRadius,
border: `1px solid ${theme.appBorderColor}`,
textAlign: 'center',
})
);
};
});

const Upgrade = styled.div(({ theme }) => ({
marginTop: 20,
borderTop: `1px solid ${theme.appBorderColor}`,
const Code = styled.pre(({ theme }) => ({
background: theme.base === 'light' ? 'rgba(0, 0, 0, 0.05)' : theme.appBorderColor,
fontSize: theme.typography.size.s2 - 1,
margin: '4px 0 16px',
}));

const Container = styled.div({
padding: `3rem 20px`,
maxWidth: 600,
margin: '0 auto',
});
const Footer = styled.div(({ theme }) => ({
marginBottom: 24,
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
color: theme.base === 'light' ? theme.color.dark : theme.color.lightest,
fontWeight: theme.typography.weight.regular,
fontSize: theme.typography.size.s2,
}));

const AboutScreen: FC<{
latest: State['versions']['latest'];
current: State['versions']['current'];
}> = ({ latest = null, current }) => {
const canUpdate = latest && semver.gt(latest.version, current.version);
const SquareButton = styled(BaseButton)(({ theme }) => ({
'&&': {
borderRadius: 4,
fontSize: '13px',
lineHeight: '14px',
color: theme.base === 'light' ? theme.color.darker : theme.color.lightest,
padding: '9px 12px',
svg: {
marginRight: 6,
},
},
}));

const TabButton = styled(BaseButton)<{ active: boolean }>(({ theme, active }) => ({
'&&': {
padding: 2,
paddingRight: 8,
margin: 0,
color: active
? theme.color.secondary
: theme.base === 'light'
? theme.color.dark
: theme.color.lightest,
},
}));

let updateMessage;
if (latest) {
if (canUpdate) {
updateMessage = (
<UpdateMessage status="positive">
Storybook {latest.version} is available. Upgrade from {current.version} now.
</UpdateMessage>
);
} else {
updateMessage = (
<UpdateMessage status="neutral">Looking good! You're up to date.</UpdateMessage>
);
}
} else {
updateMessage = (
<UpdateMessage status="negative">
Oops! The latest version of Storybook couldn't be fetched.
</UpdateMessage>
);
}
const StyledLink = styled(Link as any)(({ theme }) => ({
'&&': {
fontWeight: theme.typography.weight.bold,
color: theme.base === 'light' ? theme.color.dark : theme.color.light,
},
'&:hover': {
color: theme.base === 'light' ? theme.color.darkest : theme.color.lightest,
},
}));

const AboutScreen: FC<{
current: State['versions']['current'];
onNavigateToWhatsNew?: () => void;
}> = ({ current, onNavigateToWhatsNew }) => {
const [activeTab, setActiveTab] = useState<'npm' | 'pnpm'>('npm');
return (
<Container>
<div style={{ flex: '1' }} />
<Header>
<StorybookIcon />
Storybook {current.version}
<StorybookIcon /> Storybook
</Header>
<UpgradeBlock>
<strong>You are on Storybook {current.version}</strong>
<p>Run the following script to check for updates and upgrade to the latest version.</p>
<div>
<TabButton active={activeTab === 'npm'} onClick={() => setActiveTab('npm')}>
npm
</TabButton>
<TabButton active={activeTab === 'pnpm'} onClick={() => setActiveTab('pnpm')}>
pnpm
</TabButton>
</div>

{updateMessage}
<Code>
{activeTab === 'npm'
? 'npx storybook@latest upgrade'
: 'pnpm dlx storybook@latest upgrade'}
</Code>
{onNavigateToWhatsNew && (
// eslint-disable-next-line jsx-a11y/anchor-is-valid
<Link onClick={onNavigateToWhatsNew}>See what's new in Storybook</Link>
)}
</UpgradeBlock>

{canUpdate && (
<Upgrade>
<DocumentWrapper>
<p>
<b>Upgrade all Storybook packages to latest:</b>
</p>
<SyntaxHighlighter language="bash" copyable padded bordered>
npx storybook@latest upgrade
</SyntaxHighlighter>
</DocumentWrapper>
</Upgrade>
)}
<div style={{ flex: '1.2' }} />
<Footer>
<div style={{ marginBottom: 12 }}>
<SquareButton
isLink
outline
small
href="https://github.com/storybookjs/storybook"
style={{ marginRight: 12 }}
>
<Icons icon="github" style={{ display: 'inline', marginRight: 5 }} />
GitHub
</SquareButton>

<SettingsFooter />
<SquareButton isLink outline small href="https://storybook.js.org/docs">
<Icons icon="document" style={{ display: 'inline', marginRight: 5 }} />
Documentation
</SquareButton>
</div>
<div>
Open source software maintained by{' '}
<StyledLink href="https://www.chromatic.com/">Chromatic</StyledLink> and the{' '}
<StyledLink href="https://github.com/storybookjs/storybook/graphs/contributors">
Storybook Community
</StyledLink>
</div>
</Footer>
</Container>
);
};
Expand Down
Loading