diff --git a/.eslintignore b/.eslintignore index 89e5119e967..1138ac413a8 100644 --- a/.eslintignore +++ b/.eslintignore @@ -26,5 +26,8 @@ lerna.json !api/release-notes.md !app-shell/build/release-notes.md +# components library +storybook-static + # mypy **/.mypy_cache/** diff --git a/.eslintrc.js b/.eslintrc.js index daf265f4d5d..b00107a516e 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -4,7 +4,7 @@ module.exports = { root: true, parserOptions: { - project: './*/tsconfig.json', + project: './tsconfig-eslint.json', }, extends: ['standard-with-typescript', 'plugin:react/recommended', 'prettier'], @@ -97,6 +97,13 @@ module.exports = { 'jest/no-done-callback': 'warn', }, }, + { + files: ['**/*.stories.tsx'], + rules: { + 'import/no-default-export': 'off', + '@typescript-eslint/consistent-type-assertions': 'off', + }, + }, { files: ['**/cypress/**'], extends: ['plugin:cypress/recommended'], diff --git a/.flowconfig b/.flowconfig index 83705fe154a..a792b070250 100644 --- a/.flowconfig +++ b/.flowconfig @@ -38,7 +38,7 @@ merge_timeout=300 esproposal.optional_chaining=enable ; default value of 19 (16 * 2^19 bytes > 8ish MB) isn't quite enough and can ; result in flow crashing with `Unhandled exception: SharedMem.Hash_table_full` -sharedmemory.hash_table_pow=20 +sharedmemory.hash_table_pow=21 ; enable types-first mode for speed and explicitness ; https://flow.org/en/docs/lang/types-first/ types_first=true diff --git a/.github/workflows/components-test-build-deploy.yaml b/.github/workflows/components-test-build-deploy.yaml index 5c8d22dd17c..b108d79d12a 100644 --- a/.github/workflows/components-test-build-deploy.yaml +++ b/.github/workflows/components-test-build-deploy.yaml @@ -5,6 +5,7 @@ name: 'Components test, build, and deploy' on: pull_request: paths: + - 'Makefile' - 'components/**' - 'webpack-config/**' - 'package.json' @@ -78,17 +79,16 @@ jobs: yarn config set cache-folder ./.yarn-cache make setup-js - name: 'build components' - run: | - make -C components + run: make -C components - name: 'upload github artifact' uses: actions/upload-artifact@v2 with: name: 'components-artifact' - path: components/dist + path: storybook-static deploy-components: name: 'deploy components artifact to S3' runs-on: 'ubuntu-18.04' - needs: ["js-unit-test", "build-components"] + needs: ['js-unit-test', 'build-components'] if: github.event_name != 'pull_request' steps: - uses: 'actions/checkout@v2' diff --git a/.gitignore b/.gitignore index 8af7101b844..170725f29ef 100755 --- a/.gitignore +++ b/.gitignore @@ -122,3 +122,6 @@ api/pyproject.toml # typescript incremental files *.tsbuildinfo + +# Static storybook build artifacts +storybook-static/ \ No newline at end of file diff --git a/.storybook/main.js b/.storybook/main.js new file mode 100644 index 00000000000..0fd53c7b80d --- /dev/null +++ b/.storybook/main.js @@ -0,0 +1,13 @@ +'use strict' + +const { baseConfig } = require('@opentrons/webpack-config') + +module.exports = { + webpackFinal: config => ({ + ...config, + module: { ...config.module, rules: baseConfig.module.rules }, + plugins: [...config.plugins, ...baseConfig.plugins], + }), + stories: ['../components/**/*.stories.@(js|jsx|ts|tsx)'], + addons: ['@storybook/addon-links', '@storybook/addon-essentials'], +} diff --git a/.storybook/preview.js b/.storybook/preview.js new file mode 100644 index 00000000000..cc5da362027 --- /dev/null +++ b/.storybook/preview.js @@ -0,0 +1,17 @@ +export const parameters = { + actions: { argTypesRegex: '^on[A-Z].*' }, +} + +import React from 'react' + +import { GlobalStyle } from '../app/src/atoms/GlobalStyle' + +// Global decorator to apply the styles to all stories +export const decorators = [ + Story => ( + <> + + + + ), +] diff --git a/Makefile b/Makefile index 7e693c2d6b2..952cfb554d4 100755 --- a/Makefile +++ b/Makefile @@ -12,14 +12,15 @@ SHELL := bash PATH := $(shell yarn bin):$(PATH) API_DIR := api +APP_SHELL_DIR := app-shell +COMPONENTS_DIR := components DISCOVERY_CLIENT_DIR := discovery-client LABWARE_LIBRARY_DIR := labware-library +NOTIFY_SERVER_DIR := notify-server PROTOCOL_DESIGNER_DIR := protocol-designer SHARED_DATA_DIR := shared-data UPDATE_SERVER_DIR := update-server ROBOT_SERVER_DIR := robot-server -NOTIFY_SERVER_DIR := notify-server -APP_SHELL_DIR := app-shell # This may be set as an environment variable (and is by CI tasks that upload # to test pypi) to add a .dev extension to the python package versions. If @@ -57,6 +58,7 @@ clean-py: .PHONY: clean-js clean-js: clean-ts $(MAKE) -C $(DISCOVERY_CLIENT_DIR) clean + $(MAKE) -C $(COMPONENTS_DIR) clean .PHONY: setup-py setup-py: diff --git a/components/Makefile b/components/Makefile index cfe491a3d4a..eb838a54fcd 100644 --- a/components/Makefile +++ b/components/Makefile @@ -1,7 +1,7 @@ # opentrons component library makefile # dev server port -port ?= 8081 +port ?= 6060 # type definitions typedefs := $(shell yarn -s shx find "lib/**/*.d.ts") @@ -13,21 +13,16 @@ flow_out := $(patsubst lib/%.d.ts,flow-types/%.js.flow,$(typedefs)) .PHONY: all all: clean dist -.PHONY: setup -setup: - yarn - .PHONY: clean clean: - yarn shx rm -rf dist + yarn --cwd .. shx rm -rf storybook-static # artifacts ##################################################################### .PHONY: dist -dist: export NODE_ENV := development dist: - yarn styleguidist build + yarn --cwd .. build-storybook .PHONY: flow-types flow-types: $(flow_out) @@ -39,6 +34,5 @@ flow-types/%.js.flow: lib/%.d.ts ##################################################################### .PHONY: dev -build: export NODE_ENV := development dev: - yarn styleguidist server + yarn --cwd .. start-storybook --port $(port) diff --git a/components/src/alerts/AlertItem.md b/components/src/alerts/AlertItem.md deleted file mode 100644 index 135cb59ded0..00000000000 --- a/components/src/alerts/AlertItem.md +++ /dev/null @@ -1,157 +0,0 @@ -Basic usage: - -```js -const [state, setState] = React.useState({ alert: 'success' }) -;
- {state.alert && ( - setState({ alert: '' })} - title={'good job!'} - /> - )} -
-``` - -```js -const [state, setState] = React.useState({ alert: 'warning' }) -;
- {state.alert && ( - setState({ alert: '' })} - title={'some sort of warning...'} - /> - )} -
-``` - -```js -
- -
-``` - -```js -const [state, setState] = React.useState({ alert: 'info' }) -;
- {state.alert && ( - setState({ alert: '' })} - title={'some informative text...'} - /> - )} -
-``` - -Override the default icon with iconName: - -```js -const [state, setState] = React.useState({ alert: 'info' }) -;
- {state.alert && ( - setState({ alert: '' })} - icon={{ name: 'pause-circle' }} - title={'alert icon default override'} - /> - )} -
-``` - -Add additional information with children: - -```js -const [state, setState] = React.useState({ alert: 'warning' }) -;
- {state.alert && ( - setState({ alert: '' })} - title={'some sort of warning...'} - > -

More informative warning title

-

- and some info on how to fix it -

-
- )} -
-``` - -Stackable: - -```js -
- console.log('dismiss warning 1')} - title={ - 'Warning 1 with longer text longer text longer text longer text longer text longer text has X' - } - /> - - - console.log('dismiss warning 3')} - title={'Warning 3'} - > -

Some additional info

-
- console.log('dismiss warning 4')} - title={'Warning 4'} - /> -
-``` diff --git a/components/src/alerts/AlertItem.stories.tsx b/components/src/alerts/AlertItem.stories.tsx new file mode 100644 index 00000000000..23607281b75 --- /dev/null +++ b/components/src/alerts/AlertItem.stories.tsx @@ -0,0 +1,49 @@ +import * as React from 'react' +import { AlertItem } from './AlertItem' + +import type { Story, Meta } from '@storybook/react' + +export default { + title: 'Library/Molecules/AlertItem', + component: AlertItem, + argTypes: { onCloseClick: { action: 'clicked' } }, +} as Meta + +const Template: Story> = args => ( + +) + +export const Basic = Template.bind({}) +Basic.args = { + type: 'success', + title: 'good job!', +} + +export const OverriddenIcon = Template.bind({}) +OverriddenIcon.args = { + type: 'info', + title: 'Alert with overridden icon', + icon: { name: 'pause-circle' }, +} + +export const Stackable: Story< + React.ComponentProps +> = args => ( +
+