diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index ae300972..f11301ce 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -1,4 +1,4 @@
-name: 'my-workflow'
+name: 'Lint check'
on: [pull_request]
jobs:
@@ -6,4 +6,4 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- - uses: bradennapier/eslint-plus-action@v3.4.0
+ - uses: gnosis/safe-react-eslint-plus-action@main
diff --git a/.storybook/gnosisTheme.js b/.storybook/gnosisTheme.js
index 9ffba40e..64b97a7c 100644
--- a/.storybook/gnosisTheme.js
+++ b/.storybook/gnosisTheme.js
@@ -10,11 +10,7 @@ export default create({
appBg: 'white',
appContentBg: 'white',
appBorderColor: 'grey',
- appBorderRadius: 4,
-
- // Typography
- fontBase: '"Roboto", sans-serif',
- fontCode: 'monospace',
+ appBorderRadius: 4,
// Text colors
textColor: '#333333',
diff --git a/.storybook/main.js b/.storybook/main.js
index d31c78a4..26608b83 100644
--- a/.storybook/main.js
+++ b/.storybook/main.js
@@ -1,7 +1,6 @@
module.exports = {
stories: ["../src/**/*.stories.tsx"],
addons: [
- "@storybook/preset-create-react-app",
"@storybook/addon-actions",
"@storybook/addon-links",
"@storybook/addon-docs",
diff --git a/.storybook/preview.js b/.storybook/preview.js
index 221af33b..c4b605e4 100644
--- a/.storybook/preview.js
+++ b/.storybook/preview.js
@@ -6,15 +6,15 @@ import { ThemeProvider } from 'styled-components';
import theme from '../src/theme';
import GlobalStyles from '../src/global';
-addDecorator(storyFn => (
-
+addDecorator((storyFn) => (
+ <>
- {storyFn()}
-
+ {storyFn()}
+ >
));
addParameters({
options: {
- showRoots: false
- }
+ showRoots: false,
+ },
});
diff --git a/.storybook/webpack.config.js b/.storybook/webpack.config.js
index cc490772..ebcefdd1 100644
--- a/.storybook/webpack.config.js
+++ b/.storybook/webpack.config.js
@@ -11,6 +11,18 @@ module.exports = ({ config }) => {
]
});
+ // There was a problem with the fonts not being loaded
+ // I took the fix from here: https://github.com/storybookjs/storybook/issues/5936#issuecomment-532902187
+ config.module.rules = config.module.rules.map(rule => {
+ if (rule.test && rule.test.toString().includes('woff')) {
+ return {
+ ...rule,
+ test: /\.(svg|ico|jpg|jpeg|png|gif|webp|cur|ani|pdf)(\?.*)?$/
+ }
+ }
+ return rule
+ })
+
config.module.rules.push({
test: /\.(woff|woff2|eot|ttf)$/,
use: [
diff --git a/.travis.yml b/.travis.yml
index 7e7f6456..07e024d9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,12 +1,14 @@
if: (branch = master) OR (branch = development) OR (type = pull_request) OR (tag IS present)
+os: linux
+dist: bionic
language: node_js
node_js: '12'
+cache:
+ yarn: true
+
before_install:
- - yarn install
# Needed to deploy pull request and releases
- pip install awscli --upgrade --user
-cache:
- yarn: true
script: |
echo "Skip tests" # no test cases for the project
@@ -49,7 +51,7 @@ deploy:
secret_access_key: $AWS_SECRET_ACCESS_KEY
skip_cleanup: true
local_dir: storybook-static
- upload-dir: current
+ upload_dir: current
region: eu-central-1
on:
branch: master
@@ -61,7 +63,7 @@ deploy:
secret_access_key: $AWS_SECRET_ACCESS_KEY
skip_cleanup: true
local_dir: storybook-static
- upload-dir: releases/$TRAVIS_TAG/website
+ upload_dir: releases/$TRAVIS_TAG/website
region: eu-central-1
on:
tags: true
@@ -73,7 +75,7 @@ deploy:
secret_access_key: $AWS_SECRET_ACCESS_KEY
skip_cleanup: true
local_dir: dist
- upload-dir: releases/$TRAVIS_TAG/npmlib
+ upload_dir: releases/$TRAVIS_TAG/npmlib
region: eu-central-1
on:
tags: true
diff --git a/package.json b/package.json
index be151190..b3799d4c 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@gnosis.pm/safe-react-components",
- "version": "0.4.0",
+ "version": "0.5.0",
"description": "Gnosis UI components",
"main": "dist/index.min.js",
"typings": "dist/index.d.ts",
@@ -14,8 +14,8 @@
"types": "yarn tsc",
"start": "rimraf dist && webpack --mode production --watch",
"build": "rimraf dist && webpack --mode production",
- "build-storybook": "build-storybook -s public --docs",
- "storybook": "start-storybook -p 9009 -s public --docs",
+ "build-storybook": "build-storybook --docs",
+ "storybook": "start-storybook -p 9009 --docs",
"lint:check": "eslint './src/**/*.{js,jsx,ts,tsx}'",
"prepare": "yarn build"
},
@@ -23,58 +23,57 @@
"license": "MIT",
"dependencies": {
"classnames": "^2.2.6",
- "polished": "3.6.5",
- "react-docgen-typescript-loader": "^3.7.2",
- "react-media": "^1.10.0",
- "url-loader": "^4.1.0"
+ "react-media": "^1.10.0"
},
"devDependencies": {
- "@material-ui/core": "4.10.2",
- "@storybook/addon-actions": "5.3.19",
- "@storybook/addon-docs": "5.3.19",
- "@storybook/addon-links": "5.3.19",
- "@storybook/addons": "5.3.19",
- "@storybook/preset-create-react-app": "2.1.2",
- "@storybook/react": "5.3.19",
- "@testing-library/jest-dom": "5.11.2",
- "@testing-library/react": "10.4.7",
- "@testing-library/user-event": "12.0.17",
- "@types/big.js": "^4.0.5",
- "@types/classnames": "^2.2.10",
- "@types/jest": "26.0.7",
- "@types/material-ui": "^0.21.7",
- "@types/node": "14.0.27",
- "@types/react": "16.9.43",
- "@types/react-dom": "16.9.8",
- "@types/styled-components": "5.1.1",
- "@types/yup": "0.29.3",
- "@typescript-eslint/eslint-plugin": "^3.7.1",
- "@typescript-eslint/parser": "^3.7.1",
+ "@material-ui/core": "^4.11.2",
+ "@storybook/addon-actions": "^6.1.0",
+ "@storybook/addon-docs": "^6.1.0",
+ "@storybook/addon-links": "^6.1.0",
+ "@storybook/addons": "^6.1.0",
+ "@storybook/react": "^6.1.0",
+ "@testing-library/jest-dom": "^5.11.5",
+ "@testing-library/react": "^11.1.0",
+ "@testing-library/user-event": "^12.2.0",
+ "@types/classnames": "^2.2.11",
+ "@types/jest": "^26.0.0",
+ "@types/material-ui": "^0.21.8",
+ "@types/node": "^14.14.0",
+ "@types/react": "^16.9.55",
+ "@types/react-dom": "^16.9.0",
+ "@types/styled-components": "^5.1.0",
+ "@typescript-eslint/eslint-plugin": "^4.6.1",
+ "@typescript-eslint/parser": "^4.6.1",
"awesome-typescript-loader": "^5.2.1",
"babel-eslint": "^10.0.3",
- "babel-loader": "8.1.0",
- "copy-webpack-plugin": "^5.1.1",
- "eslint": "7.5.0",
- "eslint-config-prettier": "6.11.0",
- "eslint-plugin-prettier": "3.1.4",
- "eslint-plugin-react": "7.20.5",
- "eslint-plugin-react-hooks": "4.0.8",
+ "babel-loader": "^8.1.0",
+ "copy-webpack-plugin": "^6.3.0",
+ "eslint": "^7.12.0",
+ "eslint-config-prettier": "^6.15.0",
+ "eslint-plugin-prettier": "^3.1.0",
+ "eslint-plugin-react": "^7.21.5",
+ "eslint-plugin-react-hooks": "^4.2.0",
"ethereum-blockies-base64": "^1.0.2",
- "file-loader": "^6.0.0",
- "prettier": "2.0.5",
- "react": "16.13.1",
- "react-dom": "16.13.1",
+ "file-loader": "^6.2.0",
+ "prettier": "^2.1.0",
+ "react": "^16.13.0",
+ "react-docgen-typescript-loader": "^3.7.2",
+ "react-dom": "^16.13.0",
"rimraf": "^3.0.2",
- "styled-components": "5.1.1",
- "typescript": "3.9.7",
+ "styled-components": "^5.2.1",
+ "typescript": "^4.0.5",
+ "url-loader": "^4.1.1",
"webpack": "4.43.0",
"webpack-cli": "^3.3.10",
- "webpack-node-externals": "^1.7.2"
+ "webpack-node-externals": "^2.5.2"
+ },
+ "resolutions": {
+ "@babel/core": "^7.12.0"
},
"peerDependencies": {
"@material-ui/core": "4.X.X",
- "react": "16.x.x",
- "react-dom": "16.x.x",
+ "react": "16.x.x || 17.x.x",
+ "react-dom": "16.x.x || 17.x.x",
"styled-components": "5.x.x"
},
"eslintConfig": {
diff --git a/src/colors.stories.tsx b/src/colors.stories.tsx
index dfb97db6..e9ac1e34 100644
--- a/src/colors.stories.tsx
+++ b/src/colors.stories.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import styled from 'styled-components';
-import { parseToHsl } from 'polished';
+import { getLuminance } from '@material-ui/core/styles/colorManipulator';
import { Text, theme } from './index';
@@ -26,7 +26,7 @@ const ColorDisplay = styled.div<{ color: string }>`
`;
export default {
- title: 'Colors',
+ title: 'Utils/Colors',
};
export const ColorsSample = (): React.ReactElement => {
@@ -44,7 +44,7 @@ export const ColorsSample = (): React.ReactElement => {
}, [])
.sort(
({ code: colorA }, { code: colorB }) =>
- parseToHsl(colorA).lightness - parseToHsl(colorB).lightness
+ getLuminance(colorA) - getLuminance(colorB)
);
return (
diff --git a/src/dataDisplay/Accordion/accordion.stories.tsx b/src/dataDisplay/Accordion/accordion.stories.tsx
new file mode 100644
index 00000000..d4b69ce7
--- /dev/null
+++ b/src/dataDisplay/Accordion/accordion.stories.tsx
@@ -0,0 +1,125 @@
+import React from 'react';
+
+import { Accordion, AccordionSummary, AccordionDetails } from './index';
+import { Card, Text, IconText } from '../../index';
+
+export default {
+ title: 'Data Display/Accordion',
+ component: Accordion,
+ parameters: {
+ componentSubtitle: 'Expansion panels with Summary and Detail content.',
+ },
+};
+
+export const SimpleAccordion = (): React.ReactElement => (
+
+
+
+
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse
+ malesuada lacus ex, sit amet blandit leo lobortis eget.
+
+
+
+
+
+
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse
+ malesuada lacus ex, sit amet blandit leo lobortis eget.
+
+
+
+
+
+
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse
+ malesuada lacus ex, sit amet blandit leo lobortis eget.
+
+
+
+
+);
+
+export const CompactAccordion = (): React.ReactElement => (
+
+
+
+
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse
+ malesuada lacus ex, sit amet blandit leo lobortis eget.
+
+
+
+
+
+
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse
+ malesuada lacus ex, sit amet blandit leo lobortis eget.
+
+
+
+
+
+
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse
+ malesuada lacus ex, sit amet blandit leo lobortis eget.
+
+
+
+
+);
diff --git a/src/dataDisplay/Accordion/index.tsx b/src/dataDisplay/Accordion/index.tsx
new file mode 100644
index 00000000..8dc64ec2
--- /dev/null
+++ b/src/dataDisplay/Accordion/index.tsx
@@ -0,0 +1,93 @@
+import React, { ReactElement } from 'react';
+import AccordionMUI, {
+ AccordionProps as AccordionMUIProps,
+} from '@material-ui/core/Accordion';
+import AccordionSummaryMUI, {
+ AccordionSummaryProps as AccordionSummaryMUIProps,
+} from '@material-ui/core/AccordionSummary';
+import styled from 'styled-components';
+
+import FixedIcon from '../FixedIcon';
+
+type StyledAccordionProps = AccordionMUIProps & {
+ compact?: boolean;
+};
+
+const StyledAccordion = styled(AccordionMUI)`
+ &.MuiAccordion-root {
+ border-radius: ${({ compact }) => (compact ? '8px' : '0')};
+ border: ${({ compact, theme }) =>
+ compact ? '2px solid ' + theme.colors.separator : 'none'};
+ border-bottom: 2px solid ${({ theme }) => theme.colors.separator};
+ margin-bottom: ${({ compact }) => (compact ? '16px' : '0')};
+ overflow: hidden;
+
+ &:before {
+ height: 0;
+ }
+
+ &:first-child {
+ border-top: 2px solid ${({ theme }) => theme.colors.separator};
+ }
+
+ &.Mui-expanded {
+ margin: ${({ compact }) => (compact ? '0 0 16px 0' : '0')};
+ }
+
+ .MuiAccordionDetails-root {
+ padding: 16px;
+ }
+ }
+`;
+
+const StyledAccordionSummary = styled(AccordionSummaryMUI)`
+ &.MuiAccordionSummary-root {
+ &.Mui-expanded {
+ min-height: 48px;
+ border-bottom: 2px solid ${({ theme }) => theme.colors.separator};
+ background-color: ${({ theme }) => theme.colors.background};
+ }
+
+ &:hover {
+ background-color: ${({ theme }) => theme.colors.background};
+ }
+
+ .MuiAccordionSummary-content {
+ &.Mui-expanded {
+ margin: 0;
+ }
+ }
+ .MuiIconButton-root {
+ font-size: 0;
+ padding: 16px;
+ }
+ }
+`;
+
+export const Accordion = ({
+ compact,
+ children,
+ ...props
+}: StyledAccordionProps): ReactElement => {
+ return (
+
+ {children}
+
+ );
+};
+
+export const AccordionSummary = ({
+ children,
+ ...props
+}: AccordionSummaryMUIProps): ReactElement => {
+ return (
+ }
+ {...props}>
+ {children}
+
+ );
+};
+
+export { default as AccordionActions } from '@material-ui/core/AccordionActions';
+export { default as AccordionDetails } from '@material-ui/core/AccordionDetails';
diff --git a/src/dataDisplay/Card/card.stories.tsx b/src/dataDisplay/Card/card.stories.tsx
index 7fcb6c88..a2a65a39 100644
--- a/src/dataDisplay/Card/card.stories.tsx
+++ b/src/dataDisplay/Card/card.stories.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import Card from './index';
-import { Title } from '../../index';
+import { Button, Dot, Title, Text } from '../../index';
export default {
title: 'Data Display/Card',
@@ -13,6 +13,42 @@ export default {
export const SimpleCard = (): React.ReactElement => (
+
+
+ 1
+
+
Some text
+
+
+);
+
+export const CardDisabled = (): React.ReactElement => (
+
+
+
+ 1
+
+
+ Some text
+
);
diff --git a/src/dataDisplay/Card/index.tsx b/src/dataDisplay/Card/index.tsx
index 7640ad2c..de5b40e1 100644
--- a/src/dataDisplay/Card/index.tsx
+++ b/src/dataDisplay/Card/index.tsx
@@ -1,22 +1,42 @@
import React from 'react';
import styled from 'styled-components';
-import { rgba } from 'polished';
+import { fade } from '@material-ui/core/styles/colorManipulator';
const StyledCard = styled.div`
box-shadow: 1px 2px 10px 0
- ${({ theme }) => rgba(theme.colors.shadow.color, 0.08)};
+ ${({ theme }) => fade(theme.colors.shadow.color, 0.18)};
border-radius: 8px;
padding: 24px;
background-color: ${({ theme }) => theme.colors.white};
+ position: relative;
+`;
+
+const Disabled = styled.div`
+ opacity: 0.5;
+ position: absolute;
+ height: 100%;
+ width: 100%;
+ background-color: ${({ theme }) => theme.colors.white};
+ z-index: 1;
+ top: 0;
+ left: 0;
`;
type Props = {
className?: string;
- children: React.ReactNode;
-};
+ disabled?: boolean;
+} & React.HTMLAttributes;
-const Card = ({ className, children }: Props): React.ReactElement => (
- {children}
+const Card: React.FC = ({
+ className,
+ children,
+ disabled,
+ ...rest
+}): React.ReactElement => (
+
+ {disabled && }
+ {children}
+
);
export default Card;
diff --git a/src/dataDisplay/Divider/divider.stories.tsx b/src/dataDisplay/Divider/divider.stories.tsx
index f446ebf0..311e9e84 100644
--- a/src/dataDisplay/Divider/divider.stories.tsx
+++ b/src/dataDisplay/Divider/divider.stories.tsx
@@ -19,7 +19,13 @@ export const Horizontal = (): React.ReactElement => (
);
export const Vertical = (): React.ReactElement => (
-
+
Some content
Some content2
diff --git a/src/dataDisplay/Dot/dot.stories.tsx b/src/dataDisplay/Dot/dot.stories.tsx
new file mode 100644
index 00000000..637dadd9
--- /dev/null
+++ b/src/dataDisplay/Dot/dot.stories.tsx
@@ -0,0 +1,25 @@
+import React from 'react';
+
+import { Dot, Text, Icon } from '../../index';
+
+export default {
+ title: 'Data Display/Dot',
+ component: Dot,
+ parameters: {
+ componentSubtitle: 'Generic Dot container for text or icons.',
+ },
+};
+
+export const DotWithText = (): React.ReactElement => (
+
+
+ 1
+
+
+);
+
+export const DotWithIcon = (): React.ReactElement => (
+
+
+
+);
diff --git a/src/dataDisplay/Dot/index.tsx b/src/dataDisplay/Dot/index.tsx
new file mode 100644
index 00000000..637beb26
--- /dev/null
+++ b/src/dataDisplay/Dot/index.tsx
@@ -0,0 +1,24 @@
+import React from 'react';
+import styled from 'styled-components';
+import { ThemeColors } from '../../theme';
+
+type Props = {
+ className?: string;
+ color: ThemeColors;
+};
+
+const StyledDot = styled.div
`
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: 50%;
+ height: 36px;
+ width: 36px;
+ background-color: ${({ theme, color }) => theme.colors[color]};
+`;
+
+const Dot: React.FC = ({ children, ...rest }): React.ReactElement => (
+ {children}
+);
+
+export default Dot;
diff --git a/src/dataDisplay/FixedDialog/index.tsx b/src/dataDisplay/FixedDialog/index.tsx
index 37be1fd7..e341b8f6 100644
--- a/src/dataDisplay/FixedDialog/index.tsx
+++ b/src/dataDisplay/FixedDialog/index.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import styled from 'styled-components';
-import { rgba } from 'polished';
+import { fade } from '@material-ui/core/styles/colorManipulator';
import { Title, ModalFooterConfirmation } from '../../index';
@@ -9,7 +9,7 @@ const Container = styled.div`
display: flex;
align-items: center;
justify-content: center;
- background-color: ${({ theme }) => rgba(theme.colors.overlay.color, 0.8)};
+ background-color: ${({ theme }) => fade(theme.colors.overlay.color, 0.8)};
`;
const Wrapper = styled.div`
diff --git a/src/dataDisplay/FixedIcon/fixedIcon.stories.tsx b/src/dataDisplay/FixedIcon/fixedIcon.stories.tsx
index 58d1a489..f67b6e8c 100644
--- a/src/dataDisplay/FixedIcon/fixedIcon.stories.tsx
+++ b/src/dataDisplay/FixedIcon/fixedIcon.stories.tsx
@@ -50,6 +50,7 @@ export const Icons = (): React.ReactElement => {
'creatingInProgress',
'notOwner',
'notConnected',
+ 'networkError',
];
return (
diff --git a/src/dataDisplay/FixedIcon/images/networkError.tsx b/src/dataDisplay/FixedIcon/images/networkError.tsx
new file mode 100644
index 00000000..a0be7611
--- /dev/null
+++ b/src/dataDisplay/FixedIcon/images/networkError.tsx
@@ -0,0 +1,34 @@
+import React from 'react';
+
+const icon = (
+
+);
+
+export default icon;
diff --git a/src/dataDisplay/FixedIcon/index.tsx b/src/dataDisplay/FixedIcon/index.tsx
index ac3248d8..0430bdc2 100644
--- a/src/dataDisplay/FixedIcon/index.tsx
+++ b/src/dataDisplay/FixedIcon/index.tsx
@@ -20,6 +20,7 @@ import settingsChange from './images/settingsChange';
import creatingInProgress from './images/creatingInProgress';
import notOwner from './images/notOwner';
import notConnected from './images/notConnected';
+import networkError from './images/networkError';
const icons = {
arrowSort,
@@ -42,6 +43,7 @@ const icons = {
creatingInProgress,
notOwner,
notConnected,
+ networkError,
};
export type IconType = typeof icons;
diff --git a/src/dataDisplay/Icon/icon.stories.tsx b/src/dataDisplay/Icon/icon.stories.tsx
index 4a66c7aa..4955b360 100644
--- a/src/dataDisplay/Icon/icon.stories.tsx
+++ b/src/dataDisplay/Icon/icon.stories.tsx
@@ -28,7 +28,7 @@ export const Icons = (): React.ReactElement => {
width: 140px;
height: 140px;
border: 1px solid ${({ theme }) => theme.colors.background};
- font-family: 'Averta', sans-serif;
+ font-family: ${({ theme }) => theme.fonts.fontFamily};
font-size: 14px;
`;
@@ -88,6 +88,7 @@ export const Icons = (): React.ReactElement => {
'resync',
'rocket',
'scan',
+ 'safe',
'search',
'sendAgain',
'sent',
diff --git a/src/dataDisplay/Icon/images/safe.tsx b/src/dataDisplay/Icon/images/safe.tsx
new file mode 100644
index 00000000..c4bea6eb
--- /dev/null
+++ b/src/dataDisplay/Icon/images/safe.tsx
@@ -0,0 +1,47 @@
+import React from 'react';
+
+export default {
+ sm: (
+
+ ),
+ md: (
+
+ ),
+};
diff --git a/src/dataDisplay/Icon/index.tsx b/src/dataDisplay/Icon/index.tsx
index 923eebbf..5a98b7f9 100644
--- a/src/dataDisplay/Icon/index.tsx
+++ b/src/dataDisplay/Icon/index.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import styled from 'styled-components';
-import Tooltip from '@material-ui/core/Tooltip';
-import { withStyles } from '@material-ui/core/styles';
+
+import { Tooltip } from '../..';
import add from './images/add';
import addressBook from './images/addressBook';
@@ -57,6 +57,7 @@ import requiredConfirmations from './images/requiredConfirmations';
import restricted from './images/restricted';
import resync from './images/resync';
import rocket from './images/rocket';
+import safe from './images/safe';
import scan from './images/scan';
import search from './images/search';
import sendAgain from './images/sendAgain';
@@ -71,9 +72,8 @@ import transactionsInactive from './images/transactionsInactive';
import unlocked from './images/unlocked';
import userEdit from './images/userEdit';
import wallet from './images/wallet';
-import { rgba } from 'polished';
-import theme, { ThemeColors, ThemeIconSize } from '../../theme';
+import { ThemeColors, ThemeIconSize } from '../../theme';
const StyledIcon = styled.span<{ color?: ThemeColors }>`
display: inline-flex;
@@ -84,18 +84,6 @@ const StyledIcon = styled.span<{ color?: ThemeColors }>`
}
`;
-const StyledTooltip = withStyles(() => ({
- popper: {
- zIndex: 2001,
- },
- tooltip: {
- backgroundColor: theme.colors.overlay.color,
- border: `1px solid ${theme.colors.icon}`,
- boxShadow: `1px 2px 4px ${rgba(theme.colors.shadow.color, 0.08)}`,
- color: theme.colors.text,
- },
-}))(Tooltip);
-
const icons = {
add,
addressBook,
@@ -151,6 +139,7 @@ const icons = {
restricted,
resync,
rocket,
+ safe,
scan,
search,
sendAgain,
@@ -170,7 +159,7 @@ const icons = {
export type IconType = typeof icons;
export type IconTypes = keyof IconType;
-type Props = {
+export type Props = {
type: IconTypes;
size: ThemeIconSize;
color?: ThemeColors;
@@ -197,8 +186,8 @@ export const Icon = ({
return tooltip === undefined ? (
IconElement
) : (
-
+
{IconElement}
-
+
);
};
diff --git a/src/dataDisplay/Text/index.tsx b/src/dataDisplay/Text/index.tsx
index 2c170977..bc83efcd 100644
--- a/src/dataDisplay/Text/index.tsx
+++ b/src/dataDisplay/Text/index.tsx
@@ -2,7 +2,7 @@ import React from 'react';
import styled from 'styled-components';
import Tooltip from '@material-ui/core/Tooltip';
import { withStyles } from '@material-ui/core/styles';
-import { rgba } from 'polished';
+import { fade } from '@material-ui/core/styles/colorManipulator';
import theme, { ThemeTextSize, ThemeColors } from '../../theme';
@@ -32,11 +32,11 @@ const StyledTooltip = withStyles(() => ({
tooltip: {
backgroundColor: theme.colors.white,
color: theme.colors.text,
- boxShadow: `0px 0px 10px ${rgba(theme.colors.shadow.color, 0.2)}`,
+ boxShadow: `0px 0px 10px ${fade(theme.colors.shadow.color, 0.2)}`,
},
arrow: {
color: theme.colors.white,
- boxShadow: `0px 0px 10px ${rgba(theme.colors.shadow.color, 0.2)}`,
+ boxShadow: 'transparent',
},
}))(Tooltip);
diff --git a/src/dataDisplay/Title/index.tsx b/src/dataDisplay/Title/index.tsx
index bffd8d4a..ba899bed 100644
--- a/src/dataDisplay/Title/index.tsx
+++ b/src/dataDisplay/Title/index.tsx
@@ -7,89 +7,65 @@ type Props = {
children: string | React.ReactNode;
size: ThemeTitleSize;
withoutMargin?: boolean;
+ strong?: boolean;
};
-const StyledH1 = styled.h1<{ withoutMargin?: boolean }>`
- font-family: 'Averta';
+const StyledH1 = styled.h1<{ withoutMargin?: boolean; strong?: boolean }>`
+ font-family: ${({ theme }) => theme.fonts.fontFamily};
font-size: ${({ theme }) => theme.title.size.xl.fontSize};
line-height: ${({ theme }) => theme.title.size.xl.lineHeight};
- font-weight: normal;
+ font-weight: ${({ strong }) => (strong ? 'bold' : 'normal')};
margin: ${({ withoutMargin }) => (withoutMargin ? 0 : '30px')} 0;
`;
-const StyledH2 = styled.h2<{ withoutMargin?: boolean }>`
- font-family: 'Averta';
+const StyledH2 = styled.h2<{ withoutMargin?: boolean; strong?: boolean }>`
+ font-family: ${({ theme }) => theme.fonts.fontFamily};
font-size: ${({ theme }) => theme.title.size.lg.fontSize};
line-height: ${({ theme }) => theme.title.size.lg.lineHeight};
- font-weight: normal;
+ font-weight: ${({ strong }) => (strong ? 'bold' : 'normal')};
margin: ${({ withoutMargin }) => (withoutMargin ? 0 : '28px')} 0;
`;
-const StyledH3 = styled.h3<{ withoutMargin?: boolean }>`
- font-family: 'Averta';
+const StyledH3 = styled.h3<{ withoutMargin?: boolean; strong?: boolean }>`
+ font-family: ${({ theme }) => theme.fonts.fontFamily};
font-size: ${({ theme }) => theme.title.size.md.fontSize};
line-height: ${({ theme }) => theme.title.size.md.lineHeight};
- font-weight: normal;
+ font-weight: ${({ strong }) => (strong ? 'bold' : 'normal')};
margin: ${({ withoutMargin }) => (withoutMargin ? 0 : '26px')} 0;
`;
-const StyledH4 = styled.h4<{ withoutMargin?: boolean }>`
- font-family: 'Averta';
+const StyledH4 = styled.h4<{ withoutMargin?: boolean; strong?: boolean }>`
+ font-family: ${({ theme }) => theme.fonts.fontFamily};
font-size: ${({ theme }) => theme.title.size.sm.fontSize};
line-height: ${({ theme }) => theme.title.size.sm.lineHeight};
- font-weight: normal;
+ font-weight: ${({ strong }) => (strong ? 'bold' : 'normal')};
margin: ${({ withoutMargin }) => (withoutMargin ? 0 : '22px')} 0;
`;
-const StyledH5 = styled.h5<{ withoutMargin?: boolean }>`
- font-family: 'Averta';
+const StyledH5 = styled.h5<{ withoutMargin?: boolean; strong?: boolean }>`
+ font-family: ${({ theme }) => theme.fonts.fontFamily};
font-size: ${({ theme }) => theme.title.size.xs.fontSize};
line-height: ${({ theme }) => theme.title.size.xs.lineHeight};
- font-weight: normal;
+ font-weight: ${({ strong }) => (strong ? 'bold' : 'normal')};
margin: ${({ withoutMargin }) => (withoutMargin ? 0 : '18px')} 0;
`;
-const Title = ({
- children,
- size,
- withoutMargin,
- ...rest
-}: Props): React.ReactElement => {
+const Title = ({ children, size, ...rest }: Props): React.ReactElement => {
switch (size) {
case 'xl': {
- return (
-
- {children}
-
- );
+ return {children};
}
case 'lg': {
- return (
-
- {children}
-
- );
+ return {children};
}
case 'md': {
- return (
-
- {children}
-
- );
+ return {children};
}
case 'sm': {
- return (
-
- {children}
-
- );
+ return {children};
}
case 'xs': {
- return (
-
- {children}
-
- );
+ return {children};
}
}
};
diff --git a/src/dataDisplay/Title/title.stories.tsx b/src/dataDisplay/Title/title.stories.tsx
index aabd4b3e..d8460d30 100644
--- a/src/dataDisplay/Title/title.stories.tsx
+++ b/src/dataDisplay/Title/title.stories.tsx
@@ -25,3 +25,14 @@ export const WithSizes = (): React.ReactElement => {
>
);
};
+
+export const Bold = (): React.ReactElement => (
+ <>
+
+ Title LG
+
+
+ Title MD
+
+ >
+);
diff --git a/src/dataDisplay/Tooltip/index.stories.tsx b/src/dataDisplay/Tooltip/index.stories.tsx
new file mode 100644
index 00000000..42ee4920
--- /dev/null
+++ b/src/dataDisplay/Tooltip/index.stories.tsx
@@ -0,0 +1,43 @@
+import React from 'react';
+
+import { Tooltip } from './index';
+
+export default {
+ title: 'Data Display/Tooltip',
+ component: Tooltip,
+ parameters: {
+ componentSubtitle: 'Add a tooltip to any ReactElement passed as a child.',
+ },
+};
+
+export const Basic = (): React.ReactElement => {
+ return (
+
+ hover me
+
+ );
+};
+
+export const CustomColor = (): React.ReactElement => {
+ return (
+
+ hover me
+
+ );
+};
+
+export const CustomColorAndArrow = (): React.ReactElement => {
+ return (
+
+ hover me
+
+ );
+};
+
+export const CustomSize = (): React.ReactElement => {
+ return (
+
+ hover me
+
+ );
+};
diff --git a/src/dataDisplay/Tooltip/index.tsx b/src/dataDisplay/Tooltip/index.tsx
new file mode 100644
index 00000000..cf623ad0
--- /dev/null
+++ b/src/dataDisplay/Tooltip/index.tsx
@@ -0,0 +1,110 @@
+import React, { ReactElement } from 'react';
+import MUITooltip, {
+ TooltipProps as TooltipPropsMui,
+} from '@material-ui/core/Tooltip';
+import { withStyles } from '@material-ui/core/styles';
+import { fade } from '@material-ui/core/styles/colorManipulator';
+
+import theme, { ThemeColors, ThemeTooltipSize } from '../../theme';
+
+type TooltipProps = {
+ size?: ThemeTooltipSize;
+ backgroundColor?: ThemeColors;
+ textColor?: ThemeColors;
+ padding?: string;
+ border?: string;
+};
+
+const getPaddingBySize = (size: ThemeTooltipSize): string => {
+ switch (size) {
+ case 'lg':
+ return '8px 16px';
+ default:
+ return '4px 8px';
+ }
+};
+
+const getBorderBySize = (size: ThemeTooltipSize): string => {
+ switch (size) {
+ case 'lg':
+ return 'none';
+ default:
+ return `1px solid ${theme.colors.separator}`;
+ }
+};
+
+const getFontInfoBySize = (
+ size: ThemeTooltipSize
+): {
+ fontSize: string;
+ lineHeight: string;
+} => {
+ switch (size) {
+ case 'lg':
+ return theme.text.size.lg;
+ default:
+ return theme.text.size.md;
+ }
+};
+
+const customTooltip = ({
+ backgroundColor,
+ textColor,
+ size = 'md',
+}: TooltipProps) =>
+ withStyles(() => ({
+ popper: {
+ zIndex: 2001,
+ },
+ tooltip: {
+ backgroundColor: backgroundColor
+ ? (theme.colors[backgroundColor] as string)
+ : theme.colors.overlay.color,
+ boxShadow: `1px 2px 10px ${fade(theme.colors.shadow.color, 0.18)}`,
+ border: getBorderBySize(size),
+ color: textColor
+ ? (theme.colors[textColor] as string)
+ : theme.colors.text,
+ borderRadius: '4px',
+ fontFamily: theme.fonts.fontFamily,
+ padding: getPaddingBySize(size),
+ fontSize: getFontInfoBySize(size).fontSize,
+ lineHeight: getFontInfoBySize(size).lineHeight,
+ },
+ arrow: {
+ color: backgroundColor
+ ? (theme.colors[backgroundColor] as string)
+ : theme.colors.overlay.color,
+ border: 'none',
+
+ '&::before': {
+ boxShadow: `1px 2px 10px ${fade(theme.colors.shadow.color, 0.18)}`,
+ },
+ },
+ }))(MUITooltip);
+
+type Props = {
+ title: string;
+ children: ReactElement;
+} & TooltipProps;
+
+export const Tooltip = ({
+ title,
+ backgroundColor,
+ textColor,
+ children,
+ size,
+ ...rest
+}: Props & TooltipPropsMui): ReactElement => {
+ const StyledTooltip = customTooltip({
+ backgroundColor,
+ textColor,
+ size,
+ });
+
+ return (
+
+ {children}
+
+ );
+};
diff --git a/src/dataDisplay/index.ts b/src/dataDisplay/index.ts
index d5c82a96..c97ae5c9 100644
--- a/src/dataDisplay/index.ts
+++ b/src/dataDisplay/index.ts
@@ -1,11 +1,14 @@
export { default as Card } from './Card';
+export * from './Accordion';
export { default as Divider } from './Divider';
+export { default as Dot } from './Dot';
export { default as FixedIcon } from './FixedIcon';
export { default as FixedDialog } from './FixedDialog';
export * from './Icon';
export { default as IconText } from './IconText';
export { default as Layout } from './Layout';
export * from './Table';
+export * from './Tooltip';
export { default as Text } from './Text';
export { default as Title } from './Title';
export { default as Section } from './Section';
diff --git a/src/inputs/Button/button.stories.tsx b/src/inputs/Button/button.stories.tsx
index 1a157c83..84120048 100644
--- a/src/inputs/Button/button.stories.tsx
+++ b/src/inputs/Button/button.stories.tsx
@@ -1,6 +1,7 @@
import React from 'react';
+import styled from 'styled-components';
-import Button from './index';
+import { Button } from './index';
export default {
title: 'Inputs/Button',
@@ -10,62 +11,170 @@ export default {
},
};
+const Wrapper = styled.div`
+ > * {
+ margin-right: 5px;
+ }
+`;
+
export const SimpleButton = (): React.ReactElement => (
<>
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
>
);
-export const Sizes = (): React.ReactElement => (
+export const DisabledButton = (): React.ReactElement => (
<>
-