Merge pull request #4934 from urbit/lf/chromatic

interface: add more stories, integrate Chromatic CI
This commit is contained in:
matildepark 2021-05-27 09:58:28 -04:00 committed by GitHub
commit d9a1980974
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 1788 additions and 35 deletions

27
.github/workflows/chromatic.yml vendored Normal file
View File

@ -0,0 +1,27 @@
name: Chromatic Deployment
on:
pull_request:
paths:
- 'pkg/interface/**'
push:
paths:
- 'pkg/interface/**'
branches:
- 'release/next-userspace'
jobs:
chromatic-deployment:
runs-on: ubuntu-latest
name: "Deploy Chromatic"
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- run: cd 'pkg/interface' && npm i
- name: Publish to Chromatic
uses: chromaui/action@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
workingDir: pkg/interface

View File

@ -1,10 +1,28 @@
module.exports = {
"stories": [
"../src/**/*.stories.mdx",
"../src/**/*.stories.@(js|jsx|ts|tsx)"
],
"addons": [
"@storybook/addon-links",
"@storybook/addon-essentials"
]
}
stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
addons: ['@storybook/addon-links', '@storybook/addon-essentials'],
webpackFinal: (config) => {
config.module.rules.push({
test: /\.(j|t)sx?$/,
use: {
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
'@babel/typescript',
'@babel/preset-react',
],
plugins: [
'@babel/transform-runtime',
'@babel/plugin-proposal-object-rest-spread',
'@babel/plugin-proposal-optional-chaining',
'@babel/plugin-proposal-class-properties',
],
},
},
exclude: /node_modules\/(?!(@tlon\/indigo-dark|@tlon\/indigo-light|@tlon\/indigo-react)\/).*/,
});
return config;
},
};

View File

@ -1,3 +1,4 @@
import React from 'react';
import dark from '@tlon/indigo-dark';
import light from '@tlon/indigo-light';
import { Reset } from '@tlon/indigo-react';
@ -5,6 +6,7 @@ import { BrowserRouter } from 'react-router-dom';
import { ThemeProvider } from 'styled-components';
import useGraphState from '~/logic/state/graph';
import useMetadataState from '~/logic/state/metadata';
import useContactState from '~/logic/state/contact';
import '~/views/landscape/css/custom.css';
import '~/views/css/fonts.css';
import '~/views/apps/chat/css/custom.css';
@ -88,6 +90,21 @@ export const decorators = [
},
});
useContactState.setState({
contacts: {
'~sampel-palnet': {
status: 'Just urbiting',
'last-updated': 1621511447583,
avatar: null,
cover: null,
bio: 'An urbit user',
nickname: 'Sample Planet',
color: '0xee.5432',
groups: [],
},
},
});
useGraphState.setState({
looseNodes: {
'darrux-landes/development': {

File diff suppressed because it is too large Load Diff

View File

@ -87,6 +87,7 @@
"babel-loader": "^8.2.2",
"babel-plugin-lodash": "^3.3.4",
"babel-plugin-root-import": "^6.6.0",
"chromatic": "^5.8.3",
"clean-webpack-plugin": "^3.0.0",
"cross-env": "^7.0.3",
"eslint": "^7.26.0",
@ -119,7 +120,8 @@
"test": "jest",
"prepare": "cd ../.. && husky install pkg/interface/.husky",
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook"
"build-storybook": "build-storybook",
"chromatic": "chromatic --exit-zero-on-changes"
},
"author": "",
"license": "MIT",

View File

@ -0,0 +1,69 @@
import React from 'react';
import { Story, Meta } from '@storybook/react';
import { Box } from '@tlon/indigo-react';
import Author, { AuthorProps } from '~/views/components/Author';
export default {
title: 'Identity/Author',
component: Author
} as Meta;
const date = 1622093233566;
const Template: Story<AuthorProps> = args => (
<Box backgroundColor="white" p="2" width="fit-content">
<Author {...args} />
</Box>
);
export const WithNicknameTime = Template.bind({});
WithNicknameTime.args = {
ship: 'sampel-palnet',
showImage: true,
size: 24,
sigilPadding: 6,
date
};
export const WithNickname = Template.bind({});
WithNickname.args = {
ship: 'sampel-palnet',
showImage: true,
size: 24,
sigilPadding: 6,
dontShowTime: true
};
export const NoContactTime = Template.bind({});
NoContactTime.args = {
ship: 'sampel-sampel',
showImage: true,
size: 24,
sigilPadding: 6,
date
};
export const NoContact = Template.bind({});
NoContact.args = {
ship: 'sampel-sampel',
showImage: true,
size: 24,
sigilPadding: 6,
dontShowTime: true
};
export const RelativeTime = Template.bind({});
RelativeTime.args = {
ship: 'sampel-palnet',
showImage: true,
size: 24,
sigilPadding: 6,
isRelativeTime: true,
date: date - 3600000
};

View File

@ -0,0 +1,42 @@
import React from 'react';
import { Story, Meta } from '@storybook/react';
import { Box } from '@tlon/indigo-react';
import { Formik } from 'formik';
import { ColorInput, ColorInputProps } from '~/views/components/ColorInput';
const initialValues = {
color: '#33FF22'
};
export default {
title: 'Form/ColorInput',
component: ColorInput
} as Meta;
const Template: Story<ColorInputProps> = args => (
<Box backgroundColor="white" p="2" width="fit-content">
<Formik initialValues={initialValues} onSubmit={() => {}}>
<ColorInput {...args} id="color" />
</Formik>
</Box>
);
export const Label = Template.bind({});
Label.args = {
label: 'A color input',
placeholder: '#444444'
};
export const NoLabel = Template.bind({});
NoLabel.args = {
placeholder: '#444444'
};
export const Disabled = Template.bind({});
Disabled.args = {
disabled: true
};

View File

@ -35,6 +35,7 @@ const Template: Story<GraphContentProps> = args => (
export const Omnibus = Template.bind({});
Omnibus.args = {
tall: true,
contents: [
{
text: `# Structure of Document

View File

@ -0,0 +1,31 @@
import React from 'react';
import { Story, Meta } from '@storybook/react';
import { Box } from '@tlon/indigo-react';
import { Formik } from 'formik';
import { ImageInput, ImageInputProps } from '~/views/components/ImageInput';
const initialValues = {
url: undefined
};
export default {
title: 'Form/ImageInput',
component: ImageInput
} as Meta;
const Template: Story<ImageInputProps> = args => (
<Box backgroundColor="white" p="2">
<Formik initialValues={initialValues} onSubmit={() => {}}>
<ImageInput {...args} id="url" />
</Formik>
</Box>
);
export const Label = Template.bind({});
Label.args = {
id: 'url',
label: 'An image upload',
placeholder: 'http://image.hoster'
};

View File

@ -0,0 +1,40 @@
import React from 'react';
import { Story, Meta } from '@storybook/react';
import { Box } from '@tlon/indigo-react';
import RemoteContent, {
RemoteContentProps
} from '~/views/components/RemoteContent';
export default {
title: 'Content/RemoteContent',
component: RemoteContent
} as Meta;
const Template: Story<RemoteContentProps> = args => (
<Box backgroundColor="white" p="2" width="500px">
<RemoteContent {...args} />
</Box>
);
export const Youtube = Template.bind({});
Youtube.args = {
unfold: true,
url: 'https://www.youtube.com/watch?v=M04AKTCDavc&t=1s'
};
export const Video = Template.bind({});
Video.args = {
url: 'https://media.urbit.org/site/sea30-1440.mp4',
unfold: true
};
export const Twitter = Template.bind({});
Twitter.args = {
url: 'https://twitter.com/urbit/status/1396947489656213504',
// massive test flake
unfold: false
};

View File

@ -1,7 +1,6 @@
import { BaseImage, Box, Row } from '@tlon/indigo-react';
import moment from 'moment';
import React, { ReactElement, ReactNode, useState } from 'react';
import { useHistory } from 'react-router-dom';
import React, { ReactElement, ReactNode } from 'react';
import GlobalApi from '~/logic/api/global';
import { Sigil } from '~/logic/lib/sigil';
import { useCopy } from '~/logic/lib/useCopy';
@ -13,7 +12,7 @@ import { PropFunc } from '~/types';
import ProfileOverlay from './ProfileOverlay';
import Timestamp from './Timestamp';
interface AuthorProps {
export interface AuthorProps {
ship: string;
date?: number;
showImage?: boolean;
@ -34,7 +33,6 @@ export default function Author(props: AuthorProps & PropFunc<typeof Box>): React
fullNotIcon,
children,
unread,
group,
isRelativeTime,
dontShowTime,
lineHeight = 'tall',
@ -45,7 +43,6 @@ export default function Author(props: AuthorProps & PropFunc<typeof Box>): React
const size = props.size || 16;
const sigilPadding = props.sigilPadding || 2;
const history = useHistory();
const osDark = useLocalState(state => state.dark);
const theme = useSettingsState(s => s.display.theme);
@ -61,13 +58,7 @@ export default function Author(props: AuthorProps & PropFunc<typeof Box>): React
const { hideAvatars } = useSettingsState(selectCalmState);
const name = showNickname && contact ? contact.nickname : cite(ship);
const stamp = moment(date);
const { copyDisplay, doCopy, didCopy } = useCopy(`~${ship}`, name);
const [showOverlay, setShowOverlay] = useState(false);
const toggleOverlay = () => {
setShowOverlay(value => !value);
};
const { copyDisplay, doCopy } = useCopy(`~${ship}`, name);
const sigil = fullNotIcon ? (
<Sigil ship={ship} size={size} color={color} padding={sigilPadding} />
@ -91,10 +82,6 @@ export default function Author(props: AuthorProps & PropFunc<typeof Box>): React
return (
<Row {...rest} alignItems='center' width='auto'>
<Box
onClick={(e) => {
e.stopPropagation();
toggleOverlay();
}}
height={`${size}px`}
overflow='hidden'
position='relative'
@ -129,7 +116,8 @@ export default function Author(props: AuthorProps & PropFunc<typeof Box>): React
fontSize={0}
time={time}
ml={2}
color={unread ? 'blue' : 'gray'} />
color={unread ? 'blue' : 'gray'}
/>
)}
{children}
</Box>

View File

@ -10,7 +10,7 @@ import { useField } from 'formik';
import React, { FormEvent } from 'react';
import { hexToUx } from '~/logic/lib/util';
type ColorInputProps = Parameters<typeof Col>[0] & {
export type ColorInputProps = Parameters<typeof Col>[0] & {
id: string;
label?: string;
placeholder?: string;

View File

@ -11,7 +11,7 @@ import { useField } from 'formik';
import React, { ReactElement, useCallback, useRef } from 'react';
import useStorage from '~/logic/lib/useStorage';
type ImageInputProps = Parameters<typeof Box>[0] & {
export type ImageInputProps = Parameters<typeof Box>[0] & {
id: string;
label?: string;
placeholder?: string;

View File

@ -1,14 +1,9 @@
import {
BaseImage, Box,
BoxProps,
Center, Col,
Icon, Row,
Text
@ -52,6 +47,7 @@ const ProfileOverlay = (props: ProfileOverlayProps) => {
children,
...rest
} = props;
const [open, _setOpen] = useState(false);
const [coords, setCoords] = useState({});
const [visible, setVisible] = useState(false);
@ -64,6 +60,7 @@ const ProfileOverlay = (props: ProfileOverlayProps) => {
const { copyDisplay, doCopy, didCopy } = useCopy(`~${ship}`);
const contact = useContact(`~${ship}`);
console.log(contact);
const color = `#${uxToHex(contact?.color ?? '0x0')}`;
const showNickname = useShowNickname(contact, hideNicknames);

View File

@ -8,7 +8,7 @@ import withState from '~/logic/lib/withState';
import useSettingsState from '~/logic/state/settings';
import { RemoteContentPolicy } from '~/types/local-update';
type RemoteContentProps = VirtualContextProps & {
export type RemoteContentProps = VirtualContextProps & {
url: string;
text?: string;
unfold?: boolean;