mirror of
https://github.com/urbit/shrub.git
synced 2025-01-03 10:02:32 +03:00
Merge pull request #4934 from urbit/lf/chromatic
interface: add more stories, integrate Chromatic CI
This commit is contained in:
commit
d9a1980974
27
.github/workflows/chromatic.yml
vendored
Normal file
27
.github/workflows/chromatic.yml
vendored
Normal 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
|
@ -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;
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -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': {
|
||||
|
1521
pkg/interface/package-lock.json
generated
1521
pkg/interface/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -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",
|
||||
|
69
pkg/interface/src/stories/Author.stories.tsx
Normal file
69
pkg/interface/src/stories/Author.stories.tsx
Normal 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
|
||||
};
|
42
pkg/interface/src/stories/ColorInput.stories.tsx
Normal file
42
pkg/interface/src/stories/ColorInput.stories.tsx
Normal 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
|
||||
};
|
@ -35,6 +35,7 @@ const Template: Story<GraphContentProps> = args => (
|
||||
|
||||
export const Omnibus = Template.bind({});
|
||||
Omnibus.args = {
|
||||
tall: true,
|
||||
contents: [
|
||||
{
|
||||
text: `# Structure of Document
|
||||
|
31
pkg/interface/src/stories/ImageInput.stories.tsx
Normal file
31
pkg/interface/src/stories/ImageInput.stories.tsx
Normal 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'
|
||||
};
|
40
pkg/interface/src/stories/RemoteContent.stories.tsx
Normal file
40
pkg/interface/src/stories/RemoteContent.stories.tsx
Normal 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
|
||||
};
|
@ -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>
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user