├── .babelrc ├── .flowconfig ├── .gitignore ├── .npmignore ├── .prettierignore ├── .prettierrc.json ├── .storybook ├── addons.ts ├── config.ts └── webpack.config.js ├── LICENSE ├── README.md ├── now.json ├── package.json ├── src ├── __storybook__ │ ├── BaseStylesDecorator.tsx │ └── TextStylesDecorator.tsx ├── base.ts ├── components │ ├── button │ │ ├── Button.ts │ │ ├── PrimaryButton.ts │ │ ├── PrimaryDestructiveButton.ts │ │ ├── SecondaryButton.ts │ │ ├── SecondaryDestructiveButton.ts │ │ └── __storybook__ │ │ │ └── Button.stories.tsx │ ├── checkbox │ │ ├── Checkbox.tsx │ │ └── __storybook__ │ │ │ └── Checkbox.stories.tsx │ ├── disclosure │ │ ├── Disclosure.ts │ │ ├── DisclosureItem.tsx │ │ └── __storybook__ │ │ │ └── Disclosure.stories.tsx │ ├── divider │ │ ├── Divider.ts │ │ └── __storybook__ │ │ │ └── Divider.stories.tsx │ ├── icon │ │ ├── Icon.ts │ │ └── __storybook__ │ │ │ └── Icon.stories.tsx │ ├── input │ │ ├── Input.ts │ │ ├── InputWithIcon.tsx │ │ └── __storybook__ │ │ │ └── Input.stories.tsx │ ├── label │ │ ├── Label.ts │ │ └── __storybook__ │ │ │ └── Label.stories.tsx │ ├── onboarding-tip │ │ ├── OnboardingTip.tsx │ │ └── __storybook__ │ │ │ └── OnboardingTip.stories.tsx │ ├── section-title │ │ ├── SectionTitle.ts │ │ └── __storybook__ │ │ │ └── SectionTitle.stories.tsx │ ├── select-menu │ │ ├── Divider.ts │ │ ├── SelectMenu.tsx │ │ ├── SelectMenuItem.tsx │ │ └── __storybook__ │ │ │ └── SelectMenu.stories.tsx │ ├── switch │ │ ├── Switch.tsx │ │ └── __storybook__ │ │ │ └── Switch.stories.tsx │ ├── textarea │ │ ├── Textarea.ts │ │ └── __storybook__ │ │ │ └── Textarea.stories.tsx │ ├── type │ │ ├── Type.ts │ │ └── __storybook__ │ │ │ └── Type.stories.tsx │ └── visual-bell │ │ ├── VisualBell.tsx │ │ └── __storybook__ │ │ └── VisualBell.stories.tsx ├── index.ts ├── mixins.ts ├── typography.ts └── variables.ts ├── tsconfig.json └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env", "@babel/preset-react", "@babel/preset-flow"], 3 | } 4 | -------------------------------------------------------------------------------- /.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | 3 | [include] 4 | 5 | [libs] 6 | ./flow-typed 7 | 8 | [lints] 9 | 10 | [options] 11 | module.file_ext=.js 12 | module.file_ext=.jsx 13 | 14 | [strict] 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | npm-debug.log 3 | 4 | .cache/ 5 | dist/ 6 | node_modules/ 7 | .idea/ 8 | .vscode/ 9 | *.sketchplugin/ 10 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | *.log 2 | npm-debug.log* 3 | 4 | # Coverage directory used by tools like istanbul 5 | coverage 6 | .nyc_output 7 | 8 | # Dependency directories 9 | node_modules 10 | 11 | # npm package lock 12 | package-lock.json 13 | yarn.lock 14 | 15 | # project files 16 | src 17 | test 18 | examples 19 | .travis.yml 20 | .babelrc 21 | .gitignore 22 | .flowconfig 23 | .prettierignore 24 | .prettierrc.json 25 | .idea 26 | .storybook 27 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .cache/ 2 | dist/ 3 | node_modules/ 4 | flow-typed/ 5 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 4, 3 | "printWidth": 120, 4 | "jsxBracketSameLine": true 5 | } -------------------------------------------------------------------------------- /.storybook/addons.ts: -------------------------------------------------------------------------------- 1 | import "@storybook/addon-knobs/register"; 2 | -------------------------------------------------------------------------------- /.storybook/config.ts: -------------------------------------------------------------------------------- 1 | import { configure } from "@storybook/react"; 2 | // automatically import all files ending in *.stories.tsx 3 | const req = require.context("../src/components", true, /.stories.tsx$/); 4 | 5 | function loadStories() { 6 | req.keys().forEach(req); 7 | } 8 | 9 | configure(loadStories, module); 10 | -------------------------------------------------------------------------------- /.storybook/webpack.config.js: -------------------------------------------------------------------------------- 1 | module.exports = ({ config }) => { 2 | config.module.rules.push({ 3 | test: /\.(ts|tsx)$/, 4 | use: [ 5 | { 6 | loader: require.resolve('ts-loader'), 7 | } 8 | ], 9 | }); 10 | config.resolve.extensions.push('.ts', '.tsx'); 11 | return config; 12 | }; 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Lessmess 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # figma-ui-components 2 | 3 | [![npm version](https://img.shields.io/npm/v/figma-ui-components.svg)](https://www.npmjs.com/package/figma-ui-components) 4 | 5 | An unofficial set of Figma UI components for creating plugins and other purposes. 6 | Based on [Tom Lowry's Figma UI JS/CSS files](https://www.dropbox.com/s/iar45s6h22nupom/figma-plugin-ui-css-0.5.zip?dl=0). 7 | 8 | * Uses React ⚛️, styled-components 💅, TypeScript. 9 | * Stateful components, fully controlled outside. 10 | * All components showed at [Storybook](https://figma-ui.lessmess.dev/). 11 | 12 | ## Installation 13 | 14 | Install it with yarn: 15 | 16 | ``` 17 | yarn add figma-ui-components 18 | ``` 19 | 20 | Or with npm: 21 | 22 | ``` 23 | npm i figma-ui-components --save 24 | ``` 25 | 26 | ## Usage 27 | 28 | ### Global styles 29 | 30 | ```javascript 31 | import * as React from 'react' 32 | import {TypographyStyles, BaseStyles} from "figma-ui-components" 33 | 34 | const App = () => { 35 | return <> 36 | 37 | 38 | ... 39 | 40 | }; 41 | ``` 42 | 43 | ### Components 44 | 45 | ```javascript 46 | import * as React from 'react' 47 | import {PrimaryButton, SecondaryButton} from "figma-ui-components" 48 | 49 | export const Component = () => { 50 | return <> 51 | Create 52 | Cancel 53 | 54 | }; 55 | ``` 56 | 57 | ## Sponsored 58 | 59 | 60 | Sponsored by Lessmess 62 | 63 | 64 | -------------------------------------------------------------------------------- /now.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 2, 3 | "name": "figma-ui", 4 | "builds": [ 5 | { "src": "package.json", "use": "@now/static-build", "config": { "distDir": ".out" } } 6 | ], 7 | "env": { 8 | "NODE_ENV": "production" 9 | }, 10 | "routes": [ 11 | { "src": "^/(.*)", "dest": "/$1" } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "figma-ui-components", 3 | "version": "0.0.8", 4 | "description": "Unofficial set of Figma UI components", 5 | "main": "./dist/index.js", 6 | "scripts": { 7 | "tsc": "tsc -p tsconfig.json", 8 | "storybook": "start-storybook -p 6006", 9 | "build-storybook": "build-storybook -c .storybook -o .out", 10 | "test": "jest", 11 | "prettier": "prettier \"*/**/*.tsx\" \"*/**/*.ts\" --ignore-path ./.prettierignore --write && git add . && git status", 12 | "build": "npm run build:clean && npm run build:lib", 13 | "build:clean": "rimraf dist", 14 | "build:lib": "cross-env BABEL_ENV=production tsc -p tsconfig.json", 15 | "prepublish": "npm run build", 16 | "now-build": "npm run build-storybook", 17 | "deploy": "now" 18 | }, 19 | "pre-commit": [ 20 | "prettier" 21 | ], 22 | "repository": { 23 | "type": "git", 24 | "url": "git+ssh://git@github.com/lessmess-dev/figma-ui-components.git" 25 | }, 26 | "keywords": [ 27 | "figma", 28 | "react", 29 | "ui-kit" 30 | ], 31 | "author": "Ilya Lesik ", 32 | "license": "MIT", 33 | "devDependencies": { 34 | "@babel/cli": "^7.5.5", 35 | "@babel/core": "7.4.3", 36 | "@babel/preset-env": "7.4.3", 37 | "@babel/preset-flow": "^7.0.0", 38 | "@babel/preset-react": "7.0.0", 39 | "@storybook/addon-actions": "5.0.10", 40 | "@storybook/addon-info": "5.0.10", 41 | "@storybook/addon-knobs": "5.0.10", 42 | "@storybook/react": "5.0.10", 43 | "@types/jest": "^24.0.16", 44 | "@types/storybook__react": "^4.0.2", 45 | "@types/styled-components": "^4.1.18", 46 | "awesome-typescript-loader": "^5.2.1", 47 | "babel-loader": "8.0.5", 48 | "cross-env": "^5.2.0", 49 | "flow-bin": "^0.101.1", 50 | "gen-flow-files": "^0.4.6", 51 | "jest": "^24.8.0", 52 | "pre-commit": "^1.2.2", 53 | "prettier": "^1.17.0", 54 | "react-docgen-typescript-loader": "^3.1.0", 55 | "rimraf": "^2.6.3", 56 | "ts-jest": "^24.0.2", 57 | "ts-loader": "^6.0.4", 58 | "typescript": "^3.5.3" 59 | }, 60 | "dependencies": { 61 | "prop-types": "^15.7.2", 62 | "react": "^16.8.6", 63 | "react-dom": "^16.8.6", 64 | "react-primitives": "^0.8.0", 65 | "react-test-renderer": "^16.8.6", 66 | "styled-components": "^4.3.2" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/__storybook__/BaseStylesDecorator.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { BaseStyles } from "../base"; 3 | 4 | export const BaseStyleDecorator = (story: () => any) => ( 5 | <> 6 | 7 | {story()} 8 | 9 | ); 10 | -------------------------------------------------------------------------------- /src/__storybook__/TextStylesDecorator.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { TypographyStyles } from "../typography"; 3 | 4 | export const TextStyleDecorator = (story: () => any) => ( 5 | <> 6 | 7 | {story()} 8 | 9 | ); 10 | -------------------------------------------------------------------------------- /src/base.ts: -------------------------------------------------------------------------------- 1 | // @flow 2 | import { createGlobalStyle } from "styled-components"; 3 | 4 | export const BaseStyles = createGlobalStyle` 5 | * { 6 | box-sizing: border-box; 7 | } 8 | `; 9 | -------------------------------------------------------------------------------- /src/components/button/Button.ts: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import { border_radius_large } from "../../variables"; 3 | 4 | export const Button = styled.button` 5 | display: inline-block; 6 | flex-shrink: 0; 7 | 8 | margin: 1px 0 1px 0; 9 | padding: 5px 16px 5px 16px; 10 | 11 | border: 2px solid transparent; 12 | border-radius: ${border_radius_large}; 13 | outline: none; 14 | `; 15 | -------------------------------------------------------------------------------- /src/components/button/PrimaryButton.ts: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import { Button } from "./Button"; 3 | import { figma_black_3, figma_blue, figma_white } from "../../variables"; 4 | import { fontUINeg } from "../../mixins"; 5 | 6 | export const PrimaryButton = styled(Button)` 7 | color: ${figma_white}; 8 | background-color: ${figma_blue}; 9 | 10 | ${fontUINeg("small", "medium")}; 11 | 12 | &:active, 13 | &:focus { 14 | border: 2px solid ${figma_black_3}; 15 | } 16 | 17 | &:disabled { 18 | background-color: ${figma_black_3}; 19 | } 20 | `; 21 | -------------------------------------------------------------------------------- /src/components/button/PrimaryDestructiveButton.ts: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import { Button } from "./Button"; 3 | import { figma_black_3, figma_red, figma_white } from "../../variables"; 4 | import { fontUINeg } from "../../mixins"; 5 | 6 | export const PrimaryDestructiveButton = styled(Button)` 7 | color: ${figma_white}; 8 | background-color: ${figma_red}; 9 | 10 | ${fontUINeg("small", "medium")}; 11 | 12 | &:active, 13 | &:focus { 14 | border: 2px solid ${figma_black_3}; 15 | } 16 | 17 | &:disabled { 18 | opacity: 0.4; 19 | } 20 | `; 21 | -------------------------------------------------------------------------------- /src/components/button/SecondaryButton.ts: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import { Button } from "./Button"; 3 | import { figma_black_3, figma_black_8, figma_blue, figma_white } from "../../variables"; 4 | import { fontUIPos } from "../../mixins"; 5 | 6 | export const SecondaryButton = styled(Button)` 7 | color: ${figma_black_8}; 8 | border: 1px solid ${figma_black_8}; 9 | background-color: ${figma_white}; 10 | 11 | ${fontUIPos("small", "medium")}; 12 | 13 | &:active, 14 | &:focus { 15 | padding: 4px 15px 4px 15px; 16 | 17 | border: 2px solid ${figma_blue}; 18 | } 19 | 20 | &:disabled { 21 | color: ${figma_black_3}; 22 | border: 1px solid ${figma_black_3}; 23 | } 24 | `; 25 | -------------------------------------------------------------------------------- /src/components/button/SecondaryDestructiveButton.ts: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import { Button } from "./Button"; 3 | import { figma_red, figma_white } from "../../variables"; 4 | import { fontUIPos } from "../../mixins"; 5 | 6 | export const SecondaryDestructiveButton = styled(Button)` 7 | color: ${figma_red}; 8 | border: 1px solid ${figma_red}; 9 | background-color: ${figma_white}; 10 | 11 | ${fontUIPos("small", "medium")}; 12 | 13 | &:active, 14 | &:focus { 15 | padding: 4px 15px 4px 15px; 16 | 17 | border: 2px solid ${figma_red}; 18 | } 19 | 20 | &:disabled { 21 | opacity: 0.4; 22 | } 23 | `; 24 | -------------------------------------------------------------------------------- /src/components/button/__storybook__/Button.stories.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { storiesOf } from "@storybook/react"; 3 | import { PrimaryButton } from "../PrimaryButton"; 4 | import { TextStyleDecorator } from "../../../__storybook__/TextStylesDecorator"; 5 | import { boolean, withKnobs } from "@storybook/addon-knobs"; 6 | import { PrimaryDestructiveButton } from "../PrimaryDestructiveButton"; 7 | import { SecondaryButton } from "../SecondaryButton"; 8 | import { SecondaryDestructiveButton } from "../SecondaryDestructiveButton"; 9 | 10 | storiesOf("Button", module) 11 | .addDecorator(TextStyleDecorator) 12 | .addDecorator(withKnobs) 13 | .add("PrimaryButton", () => Label) 14 | .add("PrimaryDestructiveButton", () => ( 15 | Label 16 | )) 17 | .add("SecondaryButton", () => Label) 18 | .add("SecondaryDestructiveButton", () => ( 19 | Label 20 | )); 21 | -------------------------------------------------------------------------------- /src/components/checkbox/Checkbox.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import styled from "styled-components"; 3 | import { fontUIPos } from "../../mixins"; 4 | import { border_radius_small, figma_black, figma_blue, figma_white } from "../../variables"; 5 | 6 | const Root = styled.label` 7 | display: flex; 8 | flex-direction: row; 9 | 10 | height: 28px; 11 | 12 | cursor: default; 13 | `; 14 | 15 | const Container = styled.div` 16 | position: relative; 17 | 18 | width: 32px; 19 | height: 32px; 20 | `; 21 | 22 | const Mark = styled.span` 23 | position: absolute; 24 | top: 10px; 25 | left: 10px; 26 | 27 | width: 12px; 28 | height: 12px; 29 | 30 | border: 1px solid ${figma_black}; 31 | border-radius: ${border_radius_small}; 32 | background-color: ${figma_white}; 33 | 34 | &:after { 35 | position: absolute; 36 | 37 | width: 12px; 38 | height: 12px; 39 | 40 | content: ""; 41 | 42 | background-image: url("data:image/svg+xml;utf8,%3Csvg%20fill%3D%22none%22%20height%3D%227%22%20viewBox%3D%220%200%208%207%22%20width%3D%228%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20clip-rule%3D%22evenodd%22%20d%3D%22m1.17647%201.88236%201.88235%201.88236%203.76471-3.76472%201.17647%201.17648-4.94118%204.9412-3.05882-3.05884z%22%20fill%3D%22%23fff%22%20fill-rule%3D%22evenodd%22%2F%3E%3C%2Fsvg%3E"); 43 | background-repeat: no-repeat; 44 | background-position: 1px 2px; 45 | } 46 | `; 47 | 48 | const Box = styled.input` 49 | position: absolute; 50 | 51 | width: 0; 52 | height: 0; 53 | 54 | opacity: 0; 55 | 56 | &:checked ~ ${Mark} { 57 | border: 1px solid ${figma_blue}; 58 | background-color: ${figma_blue}; 59 | } 60 | 61 | &:checked ~ ${Mark}:after { 62 | display: block; 63 | } 64 | `; 65 | 66 | const Label = styled.label` 67 | display: flex; 68 | align-items: center; 69 | 70 | padding-top: 4px; 71 | 72 | ${fontUIPos("small", "normal")}; 73 | `; 74 | 75 | export const CheckboxComponents = { 76 | Root, 77 | Container, 78 | Box, 79 | Mark, 80 | Label 81 | }; 82 | 83 | export const Checkbox = (props: { checked?: boolean; name?: React.ReactNode; onChange?: (value: boolean) => void }) => { 84 | const { checked, name, onChange, ...otherProps } = props; 85 | return ( 86 | 87 | 88 | onChange && onChange(!!e.target.value)} /> 89 | 90 | 91 | 92 | 93 | ); 94 | }; 95 | -------------------------------------------------------------------------------- /src/components/checkbox/__storybook__/Checkbox.stories.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { storiesOf } from "@storybook/react"; 3 | import { TextStyleDecorator } from "../../../__storybook__/TextStylesDecorator"; 4 | import { boolean, text, withKnobs } from "@storybook/addon-knobs"; 5 | import { Checkbox } from "../Checkbox"; 6 | import { BaseStyleDecorator } from "../../../__storybook__/BaseStylesDecorator"; 7 | 8 | storiesOf("Checkbox", module) 9 | .addDecorator(BaseStyleDecorator) 10 | .addDecorator(TextStyleDecorator) 11 | .addDecorator(withKnobs) 12 | .add("Checkbox", () => ); 13 | -------------------------------------------------------------------------------- /src/components/disclosure/Disclosure.ts: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | 3 | export const Disclosure = styled.ul` 4 | position: relative; 5 | 6 | display: block; 7 | 8 | width: 100%; 9 | margin: 0; 10 | padding: 0; 11 | 12 | list-style-type: none; 13 | `; 14 | -------------------------------------------------------------------------------- /src/components/disclosure/DisclosureItem.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import styled, { css, StyledComponent } from "styled-components"; 3 | import { fontUIPos } from "../../mixins"; 4 | import { figma_black_8, figma_silver, figma_white } from "../../variables"; 5 | 6 | const Item = styled.li` 7 | display: flex; 8 | flex-direction: column; 9 | 10 | border-bottom: 1px solid ${figma_silver}; 11 | background-color: ${figma_white}; 12 | 13 | ${fontUIPos("small", "normal")}; 14 | 15 | &:last-child { 16 | border-bottom: 1px solid transparent; 17 | } 18 | `; 19 | 20 | const Label: StyledComponent<"div", any, { isSection?: boolean; isExpanded?: boolean }> = styled.div` 21 | position: relative; 22 | 23 | display: flex; 24 | align-items: center; 25 | 26 | height: 32px; 27 | padding: 0 8px 0 24px; 28 | 29 | cursor: default; 30 | 31 | color: ${figma_black_8}; 32 | 33 | ${(props: { isSection?: boolean }) => fontUIPos("small", props.isSection ? "bold" : "normal")} 34 | 35 | &:before { 36 | position: absolute; 37 | top: 8px; 38 | left: 4px; 39 | 40 | display: block; 41 | 42 | width: 16px; 43 | height: 16px; 44 | 45 | content: ""; 46 | 47 | opacity: 0.3; 48 | background-image: url("data:image/svg+xml;utf8,%3Csvg%20fill%3D%22none%22%20height%3D%2216%22%20viewBox%3D%220%200%2016%2016%22%20width%3D%2216%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22m11%208-4-3v6z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E"); 49 | background-repeat: no-repeat; 50 | background-position: center center; 51 | 52 | ${(props: any) => 53 | props.isExpanded && 54 | css` 55 | opacity: 0.8; 56 | background-image: url("data:image/svg+xml;utf8,%3Csvg%20fill%3D%22none%22%20height%3D%2216%22%20viewBox%3D%220%200%2016%2016%22%20width%3D%2216%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22m9%2010%203-4h-6z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E"); 57 | `} 58 | } 59 | 60 | &:hover { 61 | &:before { 62 | opacity: 0.8; 63 | } 64 | } 65 | `; 66 | 67 | const Content: StyledComponent<"div", any, { isExpanded?: boolean }> = styled.div` 68 | display: ${(props: any) => (props.isExpanded ? "block" : "none")}; 69 | 70 | padding: 8px 8px 8px 24px; 71 | 72 | color: ${figma_black_8}; 73 | 74 | ${fontUIPos("small", "normal")}; 75 | `; 76 | 77 | export const DisclosureItemComponents = { 78 | Item, 79 | Label, 80 | Content 81 | }; 82 | 83 | export const DisclosureItem = (props: { 84 | isExpanded?: boolean; 85 | isSection?: boolean; 86 | label: React.ReactNode; 87 | content?: React.ReactNode; 88 | onClick?: () => void; 89 | }) => { 90 | const { isExpanded, isSection, label, content, onClick, ...otherProps } = props; 91 | return ( 92 | 93 | 96 | {content} 97 | 98 | ); 99 | }; 100 | -------------------------------------------------------------------------------- /src/components/disclosure/__storybook__/Disclosure.stories.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { storiesOf } from "@storybook/react"; 3 | import { TextStyleDecorator } from "../../../__storybook__/TextStylesDecorator"; 4 | import { withKnobs } from "@storybook/addon-knobs"; 5 | import { Disclosure } from "../Disclosure"; 6 | import { DisclosureItem } from "../DisclosureItem"; 7 | 8 | storiesOf("Disclosure", module) 9 | .addDecorator(TextStyleDecorator) 10 | .addDecorator(withKnobs) 11 | .add("Disclosure", () => ( 12 | 13 | 14 | 15 | 16 | 17 | 18 | )); 19 | -------------------------------------------------------------------------------- /src/components/divider/Divider.ts: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import { figma_silver } from "../../variables"; 3 | 4 | export const Divider = styled.div` 5 | display: block; 6 | 7 | width: 100%; 8 | height: 1px; 9 | margin: 8px 0 8px 0; 10 | padding: 0; 11 | 12 | background-color: ${figma_silver}; 13 | `; 14 | -------------------------------------------------------------------------------- /src/components/divider/__storybook__/Divider.stories.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { Divider } from "../Divider"; 3 | import { storiesOf } from "@storybook/react"; 4 | 5 | storiesOf("Divider", module) 6 | .addDecorator(story => ( 7 | <> 8 | some text 9 | {story()} 10 | some text 11 | 12 | )) 13 | .add("Divider", () => ); 14 | -------------------------------------------------------------------------------- /src/components/icon/Icon.ts: -------------------------------------------------------------------------------- 1 | import styled, { StyledComponent, css } from "styled-components"; 2 | import { 3 | border_radius_small, 4 | figma_black, 5 | figma_black_3, 6 | figma_blue, 7 | figma_hover_fill, 8 | font_size_small, 9 | font_stack 10 | } from "../../variables"; 11 | 12 | type TIcon = StyledComponent< 13 | "div", 14 | any, 15 | { isBlue?: boolean; isBlack3?: boolean; isButton?: boolean; isText?: boolean } 16 | >; 17 | 18 | const Icon = styled.div` 19 | width: 32px; 20 | height: 32px; 21 | 22 | cursor: default; 23 | 24 | color: ${figma_black}; 25 | background-repeat: no-repeat; 26 | background-position: 0 0; 27 | 28 | ${(props: any) => 29 | props.isBlue && 30 | css` 31 | color: ${figma_blue}; 32 | background-position: 0 -64px; 33 | `} 34 | 35 | ${(props: any) => 36 | props.isBlack3 && 37 | css` 38 | color: ${figma_black_3}; 39 | background-position: 0 -32px; 40 | `} 41 | 42 | ${(props: any) => 43 | props.isButton && 44 | css` 45 | border: 2px solid transparent; 46 | border-radius: ${border_radius_small}; 47 | outline: none; 48 | background-position: -2px -2px; 49 | 50 | &:hover { 51 | background-color: ${figma_hover_fill}; 52 | } 53 | 54 | &:active { 55 | border: 2px solid ${figma_blue}; 56 | background-color: ${figma_hover_fill}; 57 | } 58 | 59 | &:active { 60 | } 61 | 62 | &:disabled { 63 | opacity: 0.37; 64 | } 65 | `} 66 | 67 | ${(props: any) => 68 | props.isText && 69 | css` 70 | display: flex; 71 | align-items: center; 72 | justify-content: center; 73 | 74 | font-family: ${font_stack}; 75 | font-size: ${font_size_small}; 76 | `} 77 | `; 78 | 79 | export const AdjustIcon: TIcon = styled(Icon)` 80 | background-image: url("data:image/svg+xml;utf8,%3Csvg%20fill%3D%22none%22%20height%3D%2296%22%20viewBox%3D%220%200%2032%2096%22%20width%3D%2232%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cg%20clip-rule%3D%22evenodd%22%20fill-rule%3D%22evenodd%22%3E%3Cpath%20d%3D%22m12%2016.05v-7.05h1v7.05c1.1411.2316%202%201.2405%202%202.45s-.8589%202.2184-2%202.45v2.05h-1v-2.05c-1.1411-.2316-2-1.2405-2-2.45s.8589-2.2184%202-2.45zm2%202.45c0%20.8284-.6716%201.5-1.5%201.5s-1.5-.6716-1.5-1.5.6716-1.5%201.5-1.5%201.5.6716%201.5%201.5zm5%204.5h1v-7.05c1.1411-.2316%202-1.2405%202-2.45s-.8589-2.2184-2-2.45v-2.05h-1v2.05c-1.1411.2316-2%201.2405-2%202.45s.8589%202.2184%202%202.45zm2-9.5c0-.8284-.6716-1.5-1.5-1.5s-1.5.6716-1.5%201.5.6716%201.5%201.5%201.5%201.5-.6716%201.5-1.5z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.8%22%2F%3E%3Cpath%20d%3D%22m12%2048.05v-7.05h1v7.05c1.1411.2316%202%201.2405%202%202.45s-.8589%202.2184-2%202.45v2.05h-1v-2.05c-1.1411-.2316-2-1.2405-2-2.45s.8589-2.2184%202-2.45zm2%202.45c0%20.8284-.6716%201.5-1.5%201.5s-1.5-.6716-1.5-1.5.6716-1.5%201.5-1.5%201.5.6716%201.5%201.5zm5%204.5h1v-7.05c1.1411-.2316%202-1.2405%202-2.45s-.8589-2.2184-2-2.45v-2.05h-1v2.05c-1.1411.2316-2%201.2405-2%202.45s.8589%202.2184%202%202.45zm2-9.5c0-.8284-.6716-1.5-1.5-1.5s-1.5.6716-1.5%201.5.6716%201.5%201.5%201.5%201.5-.6716%201.5-1.5z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.3%22%2F%3E%3Cpath%20d%3D%22m12%2080.05v-7.05h1v7.05c1.1411.2316%202%201.2405%202%202.45s-.8589%202.2184-2%202.45v2.05h-1v-2.05c-1.1411-.2316-2-1.2405-2-2.45s.8589-2.2184%202-2.45zm2%202.45c0%20.8284-.6716%201.5-1.5%201.5s-1.5-.6716-1.5-1.5.6716-1.5%201.5-1.5%201.5.6716%201.5%201.5zm5%204.5h1v-7.05c1.1411-.2316%202-1.2405%202-2.45s-.8589-2.2184-2-2.45v-2.05h-1v2.05c-1.1411.2316-2%201.2405-2%202.45s.8589%202.2184%202%202.45zm2-9.5c0-.8284-.6716-1.5-1.5-1.5s-1.5.6716-1.5%201.5.6716%201.5%201.5%201.5%201.5-.6716%201.5-1.5z%22%20fill%3D%22%2318a0fb%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"); 81 | `; 82 | 83 | export const AngleIcon: TIcon = styled(Icon)` 84 | background-image: url("data:image/svg+xml;utf8,%3Csvg%20fill%3D%22none%22%20height%3D%2296%22%20viewBox%3D%220%200%2032%2096%22%20width%3D%2232%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cg%20clip-rule%3D%22evenodd%22%20fill-rule%3D%22evenodd%22%3E%3Cpath%20d%3D%22m12%2012v7.5.5h.5%207.5v-1h-3c0-2.2091-1.7909-4-4-4v-3zm1%204v3h3c0-1.6569-1.3431-3-3-3z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.8%22%2F%3E%3Cpath%20d%3D%22m12%2044v7.5.5h.5%207.5v-1h-3c0-2.2091-1.7909-4-4-4v-3zm1%204v3h3c0-1.6569-1.3431-3-3-3z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.3%22%2F%3E%3Cpath%20d%3D%22m12%2076v7.5.5h.5%207.5v-1h-3c0-2.2091-1.7909-4-4-4v-3zm1%204v3h3c0-1.6569-1.3431-3-3-3z%22%20fill%3D%22%2318a0fb%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"); 85 | `; 86 | 87 | export const BreakIcon: TIcon = styled(Icon)` 88 | background-image: url("data:image/svg+xml;utf8,%3Csvg%20fill%3D%22none%22%20height%3D%2296%22%20viewBox%3D%220%200%2032%2096%22%20width%3D%2232%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cg%20clip-rule%3D%22evenodd%22%20fill-rule%3D%22evenodd%22%3E%3Cpath%20d%3D%22m13.0002%209v3h1v-3zm9.1031.89644c-1.1617-1.16176-3.0453-1.16176-4.2071.00002l-2.7499%202.74994.7071.7071%202.7499-2.7499c.7712-.77128%202.0217-.77129%202.7929%200%20.7712.7712.7713%202.0216%200%202.7928l-2.7499%202.75.7071.7071%202.7499-2.75c1.1618-1.1617%201.1618-3.0453%200-4.20706zm-12.20691%2012.20706c-1.16176-1.1617-1.16177-3.0453-.00001-4.2071l2.75002-2.75.7071.7071-2.75%202.75c-.77124.7713-.77124%202.0217%200%202.7929.7712.7713%202.0216.7713%202.7929%200l2.75-2.75.7071.7071-2.75%202.75c-1.1618%201.1618-3.0454%201.1618-4.20711%200zm13.10341-3.1035h-3v-1h3zm-3.9994%201v3h-1v-3zm-7.0006-7h-3.00004v1h3.00004z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.8%22%20opacity%3D%22.9%22%2F%3E%3Cpath%20d%3D%22m13.0002%2041v3h1v-3zm9.1031.8964c-1.1617-1.1617-3.0453-1.1617-4.2071.0001l-2.7499%202.7499.7071.7071%202.7499-2.7499c.7712-.7713%202.0217-.7713%202.7929%200%20.7712.7712.7713%202.0216%200%202.7928l-2.7499%202.75.7071.7071%202.7499-2.75c1.1618-1.1617%201.1618-3.0453%200-4.2071zm-12.20691%2012.2071c-1.16176-1.1617-1.16177-3.0453-.00001-4.2071l2.75002-2.75.7071.7071-2.75%202.75c-.77124.7713-.77124%202.0217%200%202.7929.7712.7713%202.0216.7713%202.7929%200l2.75-2.75.7071.7071-2.75%202.75c-1.1618%201.1618-3.0454%201.1618-4.20711%200zm13.10341-3.1035h-3v-1h3zm-3.9994%201v3h-1v-3zm-7.0006-7h-3.00004v1h3.00004z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.3%22%20opacity%3D%22.9%22%2F%3E%3Cpath%20d%3D%22m13.0002%2073v3h1v-3zm9.1031.8965c-1.1617-1.1618-3.0453-1.1618-4.2071%200l-2.7499%202.7499.7071.7071%202.7499-2.7499c.7712-.7713%202.0217-.7713%202.7929%200%20.7712.7712.7713%202.0216%200%202.7928l-2.7499%202.75.7071.7071%202.7499-2.7499c1.1618-1.1618%201.1618-3.0454%200-4.2071zm-12.20691%2012.207c-1.16176-1.1617-1.16177-3.0453-.00001-4.2071l2.75002-2.75.7071.7071-2.75%202.75c-.77124.7713-.77124%202.0217%200%202.7929.7712.7713%202.0216.7713%202.7929%200l2.75-2.75.7071.7071-2.75%202.75c-1.1618%201.1618-3.0454%201.1618-4.20711%200zm13.10341-3.1035h-3v-1h3zm-3.9994%201v3h-1v-3zm-7.0006-7h-3.00004v1h3.00004z%22%20fill%3D%22%2318a0fb%22%20opacity%3D%22.9%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"); 89 | `; 90 | 91 | export const CloseIcon: TIcon = styled(Icon)` 92 | background-image: url("data:image/svg+xml;utf8,%3Csvg%20fill%3D%22none%22%20height%3D%2296%22%20viewBox%3D%220%200%2032%2096%22%20width%3D%2232%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cg%20clip-rule%3D%22evenodd%22%20fill-rule%3D%22evenodd%22%3E%3Cpath%20d%3D%22m16%2015.293%204.6465-4.6464.7071.7071-4.6465%204.6464%204.6465%204.6465-.7071.7071-4.6465-4.6464-4.6464%204.6464-.7071-.7071%204.6464-4.6465-4.6464-4.6463.7071-.7071z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.8%22%2F%3E%3Cpath%20d%3D%22m16%2047.293%204.6465-4.6464.7071.7071-4.6465%204.6464%204.6465%204.6465-.7071.7071-4.6465-4.6464-4.6464%204.6464-.7071-.7071%204.6464-4.6465-4.6464-4.6463.7071-.7071z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.3%22%2F%3E%3Cpath%20d%3D%22m16%2079.293%204.6465-4.6464.7071.7071-4.6465%204.6464%204.6465%204.6465-.7071.7071-4.6465-4.6464-4.6464%204.6464-.7071-.7071%204.6464-4.6465-4.6464-4.6463.7071-.7071z%22%20fill%3D%22%2318a0fb%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"); 93 | `; 94 | 95 | export const EllipsesIcon: TIcon = styled(Icon)` 96 | background-image: url("data:image/svg+xml;utf8,%3Csvg%20fill%3D%22none%22%20height%3D%2296%22%20viewBox%3D%220%200%2032%2096%22%20width%3D%2232%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cg%20clip-rule%3D%22evenodd%22%20fill-rule%3D%22evenodd%22%3E%3Cpath%20d%3D%22m11.5%2016c0%20.8284-.6716%201.5-1.5%201.5-.82843%200-1.5-.6716-1.5-1.5s.67157-1.5%201.5-1.5c.8284%200%201.5.6716%201.5%201.5zm6%200c0%20.8284-.6716%201.5-1.5%201.5s-1.5-.6716-1.5-1.5.6716-1.5%201.5-1.5%201.5.6716%201.5%201.5zm4.5%201.5c.8284%200%201.5-.6716%201.5-1.5s-.6716-1.5-1.5-1.5-1.5.6716-1.5%201.5.6716%201.5%201.5%201.5z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.8%22%2F%3E%3Cpath%20d%3D%22m11.5%2048c0%20.8284-.6716%201.5-1.5%201.5-.82843%200-1.5-.6716-1.5-1.5s.67157-1.5%201.5-1.5c.8284%200%201.5.6716%201.5%201.5zm6%200c0%20.8284-.6716%201.5-1.5%201.5s-1.5-.6716-1.5-1.5.6716-1.5%201.5-1.5%201.5.6716%201.5%201.5zm4.5%201.5c.8284%200%201.5-.6716%201.5-1.5s-.6716-1.5-1.5-1.5-1.5.6716-1.5%201.5.6716%201.5%201.5%201.5z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.3%22%2F%3E%3Cpath%20d%3D%22m11.5%2080c0%20.8284-.6716%201.5-1.5%201.5-.82843%200-1.5-.6716-1.5-1.5s.67157-1.5%201.5-1.5c.8284%200%201.5.6716%201.5%201.5zm6%200c0%20.8284-.6716%201.5-1.5%201.5s-1.5-.6716-1.5-1.5.6716-1.5%201.5-1.5%201.5.6716%201.5%201.5zm4.5%201.5c.8284%200%201.5-.6716%201.5-1.5s-.6716-1.5-1.5-1.5-1.5.6716-1.5%201.5.6716%201.5%201.5%201.5z%22%20fill%3D%22%2318a0fb%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"); 97 | `; 98 | 99 | export const EyedropperIcon: TIcon = styled(Icon)` 100 | background-image: url("data:image/svg+xml;utf8,%3Csvg%20fill%3D%22none%22%20height%3D%2296%22%20viewBox%3D%220%200%2032%2096%22%20width%3D%2232%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22m22.4473%209.6c-.8-.8-2-.8-2.8%200l-2.8001%202.8-.8-.7c-.4-.4-1-.4-1.4%200s-.4%201%200%201.4l.7.7-5.79995%205.8c-.4.4-1%201.9%200%202.9.99995%201%202.49995.4%202.89995%200l5.8-5.8.7001.7c.4.4%201%20.4%201.4%200s.4-1%200-1.4l-.7-.7%202.8-2.8c.8-.9.8-2.1%200-2.9zm-10.9001%2011.9h-1v-1l5.8-5.8%201%201c-.1%200-5.8%205.8-5.8%205.8z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.8%22%2F%3E%3Cpath%20d%3D%22m22.4473%2041.6c-.8-.8-2-.8-2.8%200l-2.8001%202.8-.8-.7c-.4-.4-1-.4-1.4%200s-.4%201%200%201.4l.7.7-5.79995%205.8c-.4.4-1%201.9%200%202.9.99995%201%202.49995.4%202.89995%200l5.8-5.8.7001.7c.4.4%201%20.4%201.4%200s.4-1%200-1.4l-.7-.7%202.8-2.8c.8-.9.8-2.1%200-2.9zm-10.9001%2011.9h-1v-1l5.8-5.8%201%201c-.1%200-5.8%205.8-5.8%205.8z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.3%22%2F%3E%3Cpath%20d%3D%22m22.4473%2073.6c-.8-.8-2-.8-2.8%200l-2.8001%202.8-.8-.7c-.4-.4-1-.4-1.4%200s-.4%201%200%201.4l.7.7-5.79995%205.8c-.4.4-1%201.9%200%202.9.99995%201%202.49995.4%202.89995%200l5.8-5.8.7001.7c.4.4%201%20.4%201.4%200s.4-1%200-1.4l-.7-.7%202.8-2.8c.8-.9.8-2.1%200-2.9zm-10.9001%2011.9h-1v-1l5.8-5.8%201%201c-.1%200-5.8%205.8-5.8%205.8z%22%20fill%3D%22%2318a0fb%22%2F%3E%3C%2Fsvg%3E"); 101 | `; 102 | 103 | export const HiddenIcon: TIcon = styled(Icon)` 104 | background-image: url("data:image/svg+xml;utf8,%3Csvg%20fill%3D%22none%22%20height%3D%2296%22%20viewBox%3D%220%200%2032%2096%22%20width%3D%2232%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cg%20clip-rule%3D%22evenodd%22%20fill-rule%3D%22evenodd%22%3E%3Cpath%20d%3D%22m21.5085%2015.8012c.5554-.5276%201.0351-1.134%201.421-1.8012h-1.1842c-1.2655%201.8142-3.3673%203-5.7454%203-2.3782%200-4.48-1.1858-5.7454-3h-1.18428c.38597.6673.86567%201.2737%201.42108%201.8013l-1.59482%201.5949.70712.7071%201.6573-1.6574c.7108.5234%201.5112.9321%202.3742%201.1988l-.6171%202.2213.9636.2676.6262-2.2543c.452.0793.9172.1207%201.3921.1207.4748%200%20.9399-.0414%201.392-.1207l.6261%202.2543.9636-.2676-.617-2.2213c.863-.2666%201.6635-.6754%202.3743-1.1989l1.6576%201.6575.7071-.7071z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.8%22%2F%3E%3Cpath%20d%3D%22m21.5085%2047.8012c.5554-.5276%201.0351-1.134%201.421-1.8012h-1.1842c-1.2655%201.8142-3.3673%203-5.7454%203-2.3782%200-4.48-1.1858-5.7454-3h-1.18428c.38597.6673.86567%201.2737%201.42108%201.8013l-1.59482%201.5949.70712.7071%201.6573-1.6574c.7108.5234%201.5112.9321%202.3742%201.1988l-.6171%202.2213.9636.2676.6262-2.2543c.452.0793.9172.1207%201.3921.1207.4748%200%20.9399-.0414%201.392-.1207l.6261%202.2543.9636-.2676-.617-2.2213c.863-.2666%201.6635-.6754%202.3743-1.1989l1.6576%201.6575.7071-.7071z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.3%22%2F%3E%3Cpath%20d%3D%22m21.5085%2079.8012c.5554-.5276%201.0351-1.134%201.421-1.8012h-1.1842c-1.2655%201.8142-3.3673%203-5.7454%203-2.3782%200-4.48-1.1858-5.7454-3h-1.18428c.38597.6673.86567%201.2737%201.42108%201.8013l-1.59482%201.5949.70712.7071%201.6573-1.6574c.7108.5234%201.5112.9321%202.3742%201.1988l-.6171%202.2213.9636.2676.6262-2.2543c.452.0793.9172.1207%201.3921.1207.4748%200%20.9399-.0414%201.392-.1207l.6261%202.2543.9636-.2676-.617-2.2213c.863-.2666%201.6635-.6754%202.3743-1.1989l1.6576%201.6575.7071-.7071z%22%20fill%3D%22%2318a0fb%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"); 105 | `; 106 | 107 | export const HyperlinkIcon: TIcon = styled(Icon)` 108 | background-image: url("data:image/svg+xml;utf8,%3Csvg%20fill%3D%22none%22%20height%3D%2296%22%20viewBox%3D%220%200%2032%2096%22%20width%3D%2232%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cg%20clip-rule%3D%22evenodd%22%20fill-rule%3D%22evenodd%22%3E%3Cpath%20d%3D%22m13.5%2018c1.9593%200%203.6262-1.2522%204.2439-3h1.0491c-.653%202.3085-2.7754%204-5.293%204-3.0376%200-5.5-2.4624-5.5-5.5s2.4624-5.5%205.5-5.5c2.5176%200%204.64%201.6915%205.293%204h-1.0491c-.6177-1.7478-2.2846-3-4.2439-3-2.4853%200-4.5%202.0147-4.5%204.5s2.0147%204.5%204.5%204.5zm5%205c2.4853%200%204.5-2.0147%204.5-4.5s-2.0147-4.5-4.5-4.5c-1.9593%200-3.6262%201.2522-4.2439%203h-1.0491c.653-2.3085%202.7754-4%205.293-4%203.0376%200%205.5%202.4624%205.5%205.5s-2.4624%205.5-5.5%205.5c-2.5176%200-4.64-1.6915-5.293-4h1.0491c.6177%201.7478%202.2846%203%204.2439%203z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.8%22%2F%3E%3Cpath%20d%3D%22m13.5%2050c1.9593%200%203.6262-1.2522%204.2439-3h1.0491c-.653%202.3085-2.7754%204-5.293%204-3.0376%200-5.5-2.4624-5.5-5.5s2.4624-5.5%205.5-5.5c2.5176%200%204.64%201.6915%205.293%204h-1.0491c-.6177-1.7478-2.2846-3-4.2439-3-2.4853%200-4.5%202.0147-4.5%204.5s2.0147%204.5%204.5%204.5zm5%205c2.4853%200%204.5-2.0147%204.5-4.5s-2.0147-4.5-4.5-4.5c-1.9593%200-3.6262%201.2522-4.2439%203h-1.0491c.653-2.3085%202.7754-4%205.293-4%203.0376%200%205.5%202.4624%205.5%205.5s-2.4624%205.5-5.5%205.5c-2.5176%200-4.64-1.6915-5.293-4h1.0491c.6177%201.7478%202.2846%203%204.2439%203z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.3%22%2F%3E%3Cpath%20d%3D%22m13.5%2082c1.9593%200%203.6262-1.2522%204.2439-3h1.0491c-.653%202.3085-2.7754%204-5.293%204-3.0376%200-5.5-2.4624-5.5-5.5s2.4624-5.5%205.5-5.5c2.5176%200%204.64%201.6915%205.293%204h-1.0491c-.6177-1.7478-2.2846-3-4.2439-3-2.4853%200-4.5%202.0147-4.5%204.5s2.0147%204.5%204.5%204.5zm5%205c2.4853%200%204.5-2.0147%204.5-4.5s-2.0147-4.5-4.5-4.5c-1.9593%200-3.6262%201.2522-4.2439%203h-1.0491c.653-2.3085%202.7754-4%205.293-4%203.0376%200%205.5%202.4624%205.5%205.5s-2.4624%205.5-5.5%205.5c-2.5176%200-4.64-1.6915-5.293-4h1.0491c.6177%201.7478%202.2846%203%204.2439%203z%22%20fill%3D%22%2318a0fb%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"); 109 | `; 110 | 111 | export const LinkBrokenIcon: TIcon = styled(Icon)` 112 | background-image: url("data:image/svg+xml;utf8,%3Csvg%20fill%3D%22none%22%20height%3D%2296%22%20viewBox%3D%220%200%2032%2096%22%20width%3D%2232%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cg%20clip-rule%3D%22evenodd%22%20fill-rule%3D%22evenodd%22%3E%3Cpath%20d%3D%22m18%2014v-2c0-1.1046-.8954-2-2-2s-2%20.8954-2%202v2h-1v-2c0-1.6569%201.3431-3%203-3s3%201.3431%203%203v2zm1%204h-1v2c0%201.1046-.8954%202-2%202s-2-.8954-2-2v-2h-1v2c0%201.6569%201.3431%203%203%203s3-1.3431%203-3z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.8%22%2F%3E%3Cpath%20d%3D%22m18%2046v-2c0-1.1046-.8954-2-2-2s-2%20.8954-2%202v2h-1v-2c0-1.6569%201.3431-3%203-3s3%201.3431%203%203v2zm1%204h-1v2c0%201.1046-.8954%202-2%202s-2-.8954-2-2v-2h-1v2c0%201.6569%201.3431%203%203%203s3-1.3431%203-3z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.3%22%2F%3E%3Cpath%20d%3D%22m18%2078v-2c0-1.1046-.8954-2-2-2s-2%20.8954-2%202v2h-1v-2c0-1.6569%201.3431-3%203-3s3%201.3431%203%203v2zm1%204h-1v2c0%201.1046-.8954%202-2%202s-2-.8954-2-2v-2h-1v2c0%201.6569%201.3431%203%203%203s3-1.3431%203-3z%22%20fill%3D%22%2318a0fb%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"); 113 | `; 114 | 115 | export const LinkIcon: TIcon = styled(Icon)` 116 | background-image: url("data:image/svg+xml;utf8,%3Csvg%20fill%3D%22none%22%20height%3D%2296%22%20viewBox%3D%220%200%2032%2096%22%20width%3D%2232%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cg%20clip-rule%3D%22evenodd%22%20fill-rule%3D%22evenodd%22%3E%3Cpath%20d%3D%22m16%2010c1.1046%200%202%20.8954%202%202v2h1v-2c0-1.6569-1.3431-3-3-3s-3%201.3431-3%203v2h1v-2c0-1.1046.8954-2%202-2zm2%208h1v2c0%201.6569-1.3431%203-3%203s-3-1.3431-3-3v-2h1v2c0%201.1046.8954%202%202%202s2-.8954%202-2zm-2.5-5v6h1v-6z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.8%22%2F%3E%3Cpath%20d%3D%22m16%2042c1.1046%200%202%20.8954%202%202v2h1v-2c0-1.6569-1.3431-3-3-3s-3%201.3431-3%203v2h1v-2c0-1.1046.8954-2%202-2zm2%208h1v2c0%201.6569-1.3431%203-3%203s-3-1.3431-3-3v-2h1v2c0%201.1046.8954%202%202%202s2-.8954%202-2zm-2.5-5v6h1v-6z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.3%22%2F%3E%3Cpath%20d%3D%22m16%2074c1.1046%200%202%20.8954%202%202v2h1v-2c0-1.6569-1.3431-3-3-3s-3%201.3431-3%203v2h1v-2c0-1.1046.8954-2%202-2zm2%208h1v2c0%201.6569-1.3431%203-3%203s-3-1.3431-3-3v-2h1v2c0%201.1046.8954%202%202%202s2-.8954%202-2zm-2.5-5v6h1v-6z%22%20fill%3D%22%2318a0fb%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"); 117 | `; 118 | 119 | export const LockIcon: TIcon = styled(Icon)` 120 | background-image: url("data:image/svg+xml;utf8,%3Csvg%20fill%3D%22none%22%20height%3D%2296%22%20viewBox%3D%220%200%2032%2096%22%20width%3D%2232%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cg%20clip-rule%3D%22evenodd%22%20fill-rule%3D%22evenodd%22%3E%3Cpath%20d%3D%22m17.5%2013.5v1.5h-3v-1.5c0-.8284.6716-1.5%201.5-1.5s1.5.6716%201.5%201.5zm-4%201.5v-1.5c0-1.3807%201.1193-2.5%202.5-2.5s2.5%201.1193%202.5%202.5v1.5h.5c.2761%200%20.5.2239.5.5v5c0%20.2761-.2239.5-.5.5h-6c-.2761%200-.5-.2239-.5-.5v-5c0-.2761.2239-.5.5-.5z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.8%22%2F%3E%3Cpath%20d%3D%22m17.5%2045.5v1.5h-3v-1.5c0-.8284.6716-1.5%201.5-1.5s1.5.6716%201.5%201.5zm-4%201.5v-1.5c0-1.3807%201.1193-2.5%202.5-2.5s2.5%201.1193%202.5%202.5v1.5h.5c.2761%200%20.5.2239.5.5v5c0%20.2761-.2239.5-.5.5h-6c-.2761%200-.5-.2239-.5-.5v-5c0-.2761.2239-.5.5-.5z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.3%22%2F%3E%3Cpath%20d%3D%22m17.5%2077.5v1.5h-3v-1.5c0-.8284.6716-1.5%201.5-1.5s1.5.6716%201.5%201.5zm-4%201.5v-1.5c0-1.3807%201.1193-2.5%202.5-2.5s2.5%201.1193%202.5%202.5v1.5h.5c.2761%200%20.5.2239.5.5v5c0%20.2761-.2239.5-.5.5h-6c-.2761%200-.5-.2239-.5-.5v-5c0-.2761.2239-.5.5-.5z%22%20fill%3D%22%2318a0fb%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"); 121 | `; 122 | 123 | export const MinusIcon: TIcon = styled(Icon)` 124 | background-image: url("data:image/svg+xml;utf8,%3Csvg%20fill%3D%22none%22%20height%3D%2296%22%20viewBox%3D%220%200%2032%2096%22%20width%3D%2232%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cg%20clip-rule%3D%22evenodd%22%20fill-rule%3D%22evenodd%22%3E%3Cpath%20d%3D%22m21.5%2016.5h-11v-1h11z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.8%22%2F%3E%3Cpath%20d%3D%22m21.5%2048.5h-11v-1h11z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.3%22%2F%3E%3Cpath%20d%3D%22m21.5%2080.5h-11v-1h11z%22%20fill%3D%22%2318a0fb%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"); 125 | `; 126 | 127 | export const PlayIcon: TIcon = styled(Icon)` 128 | background-image: url("data:image/svg+xml;utf8,%3Csvg%20fill%3D%22none%22%20height%3D%2296%22%20viewBox%3D%220%200%2032%2096%22%20width%3D%2232%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cg%20clip-rule%3D%22evenodd%22%20fill-rule%3D%22evenodd%22%3E%3Cpath%20d%3D%22m13%2010.0979.765.4781%208%205%20.6784.424-.6784.424-8%205-.765.4781v-.9021-10zm1%201.8042v8.1958l6.5566-4.0979z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.8%22%2F%3E%3Cpath%20d%3D%22m13%2042.0979.765.4781%208%205%20.6784.424-.6784.424-8%205-.765.4781v-.9021-10zm1%201.8042v8.1958l6.5566-4.0979z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.3%22%2F%3E%3Cpath%20d%3D%22m13%2074.0979.765.4781%208%205%20.6784.424-.6784.424-8%205-.765.4781v-.9021-10zm1%201.8042v8.1958l6.5566-4.0979z%22%20fill%3D%22%2318a0fb%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"); 129 | `; 130 | 131 | export const PlusIcon: TIcon = styled(Icon)` 132 | background-image: url("data:image/svg+xml;utf8,%3Csvg%20fill%3D%22none%22%20height%3D%2296%22%20viewBox%3D%220%200%2032%2096%22%20width%3D%2232%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cg%20clip-rule%3D%22evenodd%22%20fill-rule%3D%22evenodd%22%3E%3Cpath%20d%3D%22m15.5%2015.5v-5h1v5h5v1h-5v5h-1v-5h-5v-1z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.8%22%2F%3E%3Cpath%20d%3D%22m15.5%2047.5v-5h1v5h5v1h-5v5h-1v-5h-5v-1z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.3%22%2F%3E%3Cpath%20d%3D%22m15.5%2079.5v-5h1v5h5v1h-5v5h-1v-5h-5v-1z%22%20fill%3D%22%2318a0fb%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"); 133 | `; 134 | 135 | export const RecentIcon: TIcon = styled(Icon)` 136 | background-image: url("data:image/svg+xml;utf8,%3Csvg%20fill%3D%22none%22%20height%3D%2296%22%20viewBox%3D%220%200%2032%2096%22%20width%3D%2232%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cg%20clip-rule%3D%22evenodd%22%20fill-rule%3D%22evenodd%22%3E%3Cpath%20d%3D%22m16%2023.9999c4.4183%200%208-3.5817%208-8s-3.5817-8.00002-8-8.00002-8%203.58172-8%208.00002%203.5817%208%208%208zm-.0889-5.1346%204-4.4999-.8222-.7308-3.6125%204.0639-2.5875-2.5874-.7778.7778%203%202.9999.4125.4124z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.8%22%2F%3E%3Cpath%20d%3D%22m16%2055.9999c4.4183%200%208-3.5817%208-8s-3.5817-8-8-8-8%203.5817-8%208%203.5817%208%208%208zm-.0889-5.1346%204-4.4999-.8222-.7308-3.6125%204.0639-2.5875-2.5874-.7778.7778%203%202.9999.4125.4124z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.3%22%2F%3E%3Cpath%20d%3D%22m16%2087.9999c4.4183%200%208-3.5817%208-8s-3.5817-8-8-8-8%203.5817-8%208%203.5817%208%208%208zm-.0889-5.1346%204-4.4999-.8222-.7308-3.6125%204.0639-2.5875-2.5874-.7778.7778%203%202.9999.4125.4124z%22%20fill%3D%22%2318a0fb%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"); 137 | `; 138 | 139 | export const ResolveFilledIcon: TIcon = styled(Icon)` 140 | background-image: url("data:image/svg+xml;utf8,%3Csvg%20fill%3D%22none%22%20height%3D%2296%22%20viewBox%3D%220%200%2032%2096%22%20width%3D%2232%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cg%20clip-rule%3D%22evenodd%22%20fill-rule%3D%22evenodd%22%3E%3Cpath%20d%3D%22m16%2023.9999c4.4183%200%208-3.5817%208-8s-3.5817-8.00002-8-8.00002-8%203.58172-8%208.00002%203.5817%208%208%208zm-.0889-5.1346%204-4.4999-.8222-.7308-3.6125%204.0639-2.5875-2.5874-.7778.7778%203%202.9999.4125.4124z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.8%22%2F%3E%3Cpath%20d%3D%22m16%2055.9999c4.4183%200%208-3.5817%208-8s-3.5817-8-8-8-8%203.5817-8%208%203.5817%208%208%208zm-.0889-5.1346%204-4.4999-.8222-.7308-3.6125%204.0639-2.5875-2.5874-.7778.7778%203%202.9999.4125.4124z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.3%22%2F%3E%3Cpath%20d%3D%22m16%2087.9999c4.4183%200%208-3.5817%208-8s-3.5817-8-8-8-8%203.5817-8%208%203.5817%208%208%208zm-.0889-5.1346%204-4.4999-.8222-.7308-3.6125%204.0639-2.5875-2.5874-.7778.7778%203%202.9999.4125.4124z%22%20fill%3D%22%2318a0fb%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"); 141 | `; 142 | 143 | export const ResolveIcon: TIcon = styled(Icon)` 144 | background-image: url("data:image/svg+xml;utf8,%3Csvg%20fill%3D%22none%22%20height%3D%2296%22%20viewBox%3D%220%200%2032%2096%22%20width%3D%2232%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cg%20clip-rule%3D%22evenodd%22%20fill-rule%3D%22evenodd%22%3E%3Cpath%20d%3D%22m23%2015.9999c0%203.866-3.134%207-7%207s-7-3.134-7-7%203.134-7.00002%207-7.00002%207%203.13402%207%207.00002zm1%200c0%204.4183-3.5817%208-8%208s-8-3.5817-8-8%203.5817-8.00002%208-8.00002%208%203.58172%208%208.00002zm-8.0889%202.8654%204-4.4999-.8222-.7308-3.6125%204.0639-2.5875-2.5874-.7778.7778%203%202.9999.4125.4124z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.8%22%2F%3E%3Cpath%20d%3D%22m23%2047.9999c0%203.866-3.134%207-7%207s-7-3.134-7-7%203.134-7%207-7%207%203.134%207%207zm1%200c0%204.4183-3.5817%208-8%208s-8-3.5817-8-8%203.5817-8%208-8%208%203.5817%208%208zm-8.0889%202.8654%204-4.4999-.8222-.7308-3.6125%204.0639-2.5875-2.5874-.7778.7778%203%202.9999.4125.4124z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.3%22%2F%3E%3Cpath%20d%3D%22m23%2079.9999c0%203.866-3.134%207-7%207s-7-3.134-7-7%203.134-7%207-7%207%203.134%207%207zm1%200c0%204.4183-3.5817%208-8%208s-8-3.5817-8-8%203.5817-8%208-8%208%203.5817%208%208zm-8.0889%202.8654%204-4.4999-.8222-.7308-3.6125%204.0639-2.5875-2.5874-.7778.7778%203%202.9999.4125.4124z%22%20fill%3D%22%2318a0fb%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"); 145 | `; 146 | 147 | export const SearchIcon: TIcon = styled(Icon)` 148 | background-image: url("data:image/svg+xml;utf8,%3Csvg%20fill%3D%22none%22%20height%3D%2296%22%20viewBox%3D%220%200%2032%2096%22%20width%3D%2232%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cg%20clip-rule%3D%22evenodd%22%20fill-rule%3D%22evenodd%22%3E%3Cpath%20d%3D%22m20%2015c0%202.7614-2.2386%205-5%205s-5-2.2386-5-5%202.2386-5%205-5%205%202.2386%205%205zm-1.1256%204.5815c-1.0453.8849-2.3975%201.4185-3.8744%201.4185-3.3137%200-6-2.6863-6-6s2.6863-6%206-6%206%202.6863%206%206c0%201.4769-.5336%202.8291-1.4185%203.8744l4.2721%204.272-.7072.7072z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.8%22%2F%3E%3Cpath%20d%3D%22m20%2047c0%202.7614-2.2386%205-5%205s-5-2.2386-5-5%202.2386-5%205-5%205%202.2386%205%205zm-1.1256%204.5815c-1.0453.8849-2.3975%201.4185-3.8744%201.4185-3.3137%200-6-2.6863-6-6s2.6863-6%206-6%206%202.6863%206%206c0%201.4769-.5336%202.8291-1.4185%203.8744l4.2721%204.272-.7072.7072z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.3%22%2F%3E%3Cpath%20d%3D%22m20%2079c0%202.7614-2.2386%205-5%205s-5-2.2386-5-5%202.2386-5%205-5%205%202.2386%205%205zm-1.1256%204.5815c-1.0453.8849-2.3975%201.4185-3.8744%201.4185-3.3137%200-6-2.6863-6-6s2.6863-6%206-6%206%202.6863%206%206c0%201.4769-.5336%202.8291-1.4185%203.8744l4.2721%204.272-.7072.7072z%22%20fill%3D%22%2318a0fb%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"); 149 | `; 150 | 151 | export const TrashIcon: TIcon = styled(Icon)` 152 | background-image: url("data:image/svg+xml;utf8,%3Csvg%20fill%3D%22none%22%20height%3D%2296%22%20viewBox%3D%220%200%2032%2096%22%20width%3D%2232%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cg%20clip-rule%3D%22evenodd%22%20fill-rule%3D%22evenodd%22%3E%3Cpath%20d%3D%22m15%209.5c-.5523%200-1%20.44772-1%201h4c0-.55228-.4477-1-1-1zm4%201c0-1.10457-.8954-2-2-2h-2c-1.1046%200-2%20.89543-2%202h-1.5-1.5v1h1v10c0%201.1046.8954%202%202%202h6c1.1046%200%202-.8954%202-2v-10h1v-1h-1.5zm1%201h-1.5-5-1.5v10c0%20.5523.4477%201%201%201h6c.5523%200%201-.4477%201-1zm-6%207v-4h1v4zm3%200v-4h1v4z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.8%22%2F%3E%3Cpath%20d%3D%22m15%2041.5c-.5523%200-1%20.4477-1%201h4c0-.5523-.4477-1-1-1zm4%201c0-1.1046-.8954-2-2-2h-2c-1.1046%200-2%20.8954-2%202h-1.5-1.5v1h1v10c0%201.1046.8954%202%202%202h6c1.1046%200%202-.8954%202-2v-10h1v-1h-1.5zm1%201h-1.5-5-1.5v10c0%20.5523.4477%201%201%201h6c.5523%200%201-.4477%201-1zm-6%207v-4h1v4zm3%200v-4h1v4z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.3%22%2F%3E%3Cpath%20d%3D%22m15%2073.5c-.5523%200-1%20.4477-1%201h4c0-.5523-.4477-1-1-1zm4%201c0-1.1046-.8954-2-2-2h-2c-1.1046%200-2%20.8954-2%202h-1.5-1.5v1h1v10c0%201.1046.8954%202%202%202h6c1.1046%200%202-.8954%202-2v-10h1v-1h-1.5zm1%201h-1.5-5-1.5v10c0%20.5523.4477%201%201%201h6c.5523%200%201-.4477%201-1zm-6%207v-4h1v4zm3%200v-4h1v4z%22%20fill%3D%22%2318a0fb%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"); 153 | `; 154 | 155 | export const UnlockIcon: TIcon = styled(Icon)` 156 | background-image: url("data:image/svg+xml;utf8,%3Csvg%20fill%3D%22none%22%20height%3D%2296%22%20viewBox%3D%220%200%2032%2096%22%20width%3D%2232%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cg%20clip-rule%3D%22evenodd%22%20fill-rule%3D%22evenodd%22%3E%3Cpath%20d%3D%22m18%2014v1h.5c.2761%200%20.5.2239.5.5v5c0%20.2761-.2239.5-.5.5h-6c-.2761%200-.5-.2239-.5-.5v-5c0-.2761.2239-.5.5-.5h4.5v-2.5c0-1.3807%201.1193-2.5%202.5-2.5s2.5%201.1193%202.5%202.5v1.5h-1v-1.5c0-.8284-.6716-1.5-1.5-1.5s-1.5.6716-1.5%201.5z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.8%22%2F%3E%3Cpath%20d%3D%22m18%2046v1h.5c.2761%200%20.5.2239.5.5v5c0%20.2761-.2239.5-.5.5h-6c-.2761%200-.5-.2239-.5-.5v-5c0-.2761.2239-.5.5-.5h4.5v-2.5c0-1.3807%201.1193-2.5%202.5-2.5s2.5%201.1193%202.5%202.5v1.5h-1v-1.5c0-.8284-.6716-1.5-1.5-1.5s-1.5.6716-1.5%201.5z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.3%22%2F%3E%3Cpath%20d%3D%22m18%2078v1h.5c.2761%200%20.5.2239.5.5v5c0%20.2761-.2239.5-.5.5h-6c-.2761%200-.5-.2239-.5-.5v-5c0-.2761.2239-.5.5-.5h4.5v-2.5c0-1.3807%201.1193-2.5%202.5-2.5s2.5%201.1193%202.5%202.5v1.5h-1v-1.5c0-.8284-.6716-1.5-1.5-1.5s-1.5.6716-1.5%201.5z%22%20fill%3D%22%2318a0fb%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"); 157 | `; 158 | 159 | export const VisibleIcon: TIcon = styled(Icon)` 160 | background-image: url("data:image/svg+xml;utf8,%3Csvg%20fill%3D%22none%22%20height%3D%2296%22%20viewBox%3D%220%200%2032%2096%22%20width%3D%2232%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cg%20clip-rule%3D%22evenodd%22%20fill-rule%3D%22evenodd%22%3E%3Cpath%20d%3D%22m16.0001%2019c-2.2999%200-4.3222-1.1942-5.4784-3%201.1562-1.8058%203.1785-3%205.4784-3%202.2998%200%204.3221%201.1942%205.4783%203-1.1562%201.8058-3.1785%203-5.4783%203zm0-7c2.878%200%205.3774%201.6211%206.6349%204-1.2575%202.3789-3.7569%204-6.6349%204-2.8781%200-5.3775-1.6211-6.63499-4%201.25749-2.3789%203.75689-4%206.63499-4zm.0003%206c1.1045%200%202-.8954%202-2s-.8955-2-2-2c-1.1046%200-2%20.8954-2%202s.8954%202%202%202z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.8%22%2F%3E%3Cpath%20d%3D%22m16.0001%2051c-2.2999%200-4.3222-1.1942-5.4784-3%201.1562-1.8058%203.1785-3%205.4784-3%202.2998%200%204.3221%201.1942%205.4783%203-1.1562%201.8058-3.1785%203-5.4783%203zm0-7c2.878%200%205.3774%201.6211%206.6349%204-1.2575%202.3789-3.7569%204-6.6349%204-2.8781%200-5.3775-1.6211-6.63499-4%201.25749-2.3789%203.75689-4%206.63499-4zm.0003%206c1.1045%200%202-.8954%202-2s-.8955-2-2-2c-1.1046%200-2%20.8954-2%202s.8954%202%202%202z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.3%22%2F%3E%3Cpath%20d%3D%22m16.0001%2083c-2.2999%200-4.3222-1.1942-5.4784-3%201.1562-1.8058%203.1785-3%205.4784-3%202.2998%200%204.3221%201.1942%205.4783%203-1.1562%201.8058-3.1785%203-5.4783%203zm0-7c2.878%200%205.3774%201.6211%206.6349%204-1.2575%202.3789-3.7569%204-6.6349%204-2.8781%200-5.3775-1.6211-6.63499-4%201.25749-2.3789%203.75689-4%206.63499-4zm.0003%206c1.1045%200%202-.8954%202-2s-.8955-2-2-2c-1.1046%200-2%20.8954-2%202s.8954%202%202%202z%22%20fill%3D%22%2318a0fb%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"); 161 | `; 162 | -------------------------------------------------------------------------------- /src/components/icon/__storybook__/Icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import * as icons from "../Icon"; 3 | import { storiesOf } from "@storybook/react"; 4 | import { BaseStyleDecorator } from "../../../__storybook__/BaseStylesDecorator"; 5 | import { boolean, withKnobs } from "@storybook/addon-knobs"; 6 | 7 | Object.keys(icons).map(iconKey => { 8 | const Icon = icons[iconKey]; 9 | storiesOf("Icon", module) 10 | .addDecorator(BaseStyleDecorator) 11 | .addDecorator(withKnobs) 12 | .add(iconKey, () => ( 13 | 19 | )); 20 | }); 21 | -------------------------------------------------------------------------------- /src/components/input/Input.ts: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import { fontUIPos } from "../../mixins"; 3 | import { 4 | border_radius_small, 5 | figma_black, 6 | figma_black_1, 7 | figma_black_3, 8 | figma_black_8, 9 | figma_blue, 10 | figma_blue_3, 11 | figma_white 12 | } from "../../variables"; 13 | 14 | export const Input = styled.input` 15 | ${fontUIPos("small", "normal")}; 16 | 17 | position: relative; 18 | display: flex; 19 | overflow: visible; 20 | align-items: center; 21 | width: 100%; 22 | height: 30px; 23 | margin: 1px 0 1px 0; 24 | padding: 8px 4px 8px 7px; 25 | 26 | color: ${figma_black_8}; 27 | border: 1px solid transparent; 28 | border-radius: ${border_radius_small}; 29 | outline: none; 30 | background-color: ${figma_white}; 31 | 32 | &:hover { 33 | color: ${figma_black_8}; 34 | border: 1px solid ${figma_black_1}; 35 | } 36 | 37 | &:active, 38 | &:focus { 39 | padding: 8px 4px 8px 6px; 40 | 41 | color: ${figma_black}; 42 | border: 2px solid ${figma_blue}; 43 | border-radius: ${border_radius_small}; 44 | } 45 | 46 | &::selection { 47 | color: ${figma_black}; 48 | background-color: ${figma_blue_3}; 49 | } 50 | 51 | &::placeholder { 52 | color: ${figma_black_3}; 53 | } 54 | 55 | &:not(:disabled):not(:hover):placeholder-shown { 56 | background: linear-gradient(90deg, transparent 6px, rgba(0, 0, 0, 0.1) 0); 57 | background-repeat: repeat-x; 58 | background-position: left bottom -1px; 59 | background-size: calc(100% - 6px) 1px; 60 | } 61 | 62 | &:disabled { 63 | color: ${figma_black_3}; 64 | } 65 | 66 | &:disabled:hover { 67 | border: 1px solid transparent; 68 | } 69 | `; 70 | -------------------------------------------------------------------------------- /src/components/input/InputWithIcon.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import styled from "styled-components"; 3 | import { Input } from "./Input"; 4 | 5 | const Root = styled.div` 6 | position: relative; 7 | width: 100%; 8 | 9 | & ${Input} { 10 | position: static; 11 | overflow: auto; 12 | padding: 8px 4px 8px 0; 13 | text-indent: 32px; 14 | 15 | &:active, 16 | &:focus { 17 | margin-left: -1px; 18 | padding: 8px 4px 8px 0; 19 | } 20 | } 21 | `; 22 | 23 | const Icon = styled.div` 24 | position: absolute; 25 | top: -1px; 26 | left: 0; 27 | width: 32px; 28 | height: 32px; 29 | `; 30 | 31 | export const InputWithIconComponents = { 32 | Root, 33 | Icon 34 | }; 35 | 36 | export const InputWithIcon = (props: { icon: React.ReactNode; input: React.ReactNode }) => { 37 | const { icon, input } = props; 38 | return ( 39 | 40 | {icon} 41 | {input} 42 | 43 | ); 44 | }; 45 | -------------------------------------------------------------------------------- /src/components/input/__storybook__/Input.stories.tsx: -------------------------------------------------------------------------------- 1 | import { storiesOf } from "@storybook/react"; 2 | import { BaseStyleDecorator } from "../../../__storybook__/BaseStylesDecorator"; 3 | import { select, text, withKnobs } from "@storybook/addon-knobs"; 4 | import * as React from "react"; 5 | import { TextStyleDecorator } from "../../../__storybook__/TextStylesDecorator"; 6 | import { Input } from "../Input"; 7 | import { InputWithIcon } from "../InputWithIcon"; 8 | import { AngleIcon } from "../../.."; 9 | 10 | storiesOf("Input", module) 11 | .addDecorator(BaseStyleDecorator) 12 | .addDecorator(TextStyleDecorator) 13 | .addDecorator(withKnobs) 14 | .add("Input", () => ( 15 | 20 | )) 21 | .add("InputWithIcon", () => { 22 | return ( 23 | } 25 | input={ 26 | 31 | } 32 | /> 33 | ); 34 | }); 35 | -------------------------------------------------------------------------------- /src/components/label/Label.ts: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import { figma_black_3, figma_white } from "../../variables"; 3 | import { fontUIPos } from "../../mixins"; 4 | 5 | export const Label = styled.div` 6 | display: flex; 7 | align-items: center; 8 | 9 | height: 32px; 10 | padding: 8px 4px 8px 8px; 11 | 12 | color: ${figma_black_3}; 13 | background-color: ${figma_white}; 14 | 15 | ${fontUIPos("small", "normal")}; 16 | `; 17 | -------------------------------------------------------------------------------- /src/components/label/__storybook__/Label.stories.tsx: -------------------------------------------------------------------------------- 1 | import { storiesOf } from "@storybook/react"; 2 | import { BaseStyleDecorator } from "../../../__storybook__/BaseStylesDecorator"; 3 | import { text, withKnobs } from "@storybook/addon-knobs"; 4 | import * as React from "react"; 5 | import { Label } from "../Label"; 6 | import { TextStyleDecorator } from "../../../__storybook__/TextStylesDecorator"; 7 | 8 | storiesOf("Label", module) 9 | .addDecorator(BaseStyleDecorator) 10 | .addDecorator(TextStyleDecorator) 11 | .addDecorator(withKnobs) 12 | .add("Label", () => ); 13 | -------------------------------------------------------------------------------- /src/components/onboarding-tip/OnboardingTip.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import styled, { css, StyledComponent } from "styled-components"; 3 | import { figma_black_3, figma_black_8, figma_blue } from "../../variables"; 4 | import { fontUIPos } from "../../mixins"; 5 | import { VisibleIcon } from "../.."; 6 | 7 | const Root: StyledComponent<"div", any, { isHidden?: boolean; isLight?: boolean; isPt5?: boolean }> = styled.div` 8 | display: flex; 9 | align-items: top; 10 | flex-direction: row; 11 | 12 | padding: 0 16px 0 0; 13 | 14 | 15 | ${(props: any) => 16 | props.isHidden && 17 | css` 18 | display: none; 19 | `} 20 | 21 | ${(props: any) => 22 | props.isLight && 23 | css` 24 | color: ${figma_black_3}; 25 | `} 26 | 27 | ${(props: any) => 28 | props.isPt5 && 29 | css` 30 | padding-top: 8px; 31 | `} 32 | 33 | 34 | `; 35 | 36 | const Icon = styled.div` 37 | width: 32px; 38 | height: 32px; 39 | margin-right: 8px; 40 | `; 41 | 42 | const Msg = styled.div` 43 | padding: 8px 0 8px 0; 44 | 45 | color: ${figma_black_8}; 46 | 47 | ${fontUIPos("small", "normal")}; 48 | 49 | a:link, 50 | a:hover, 51 | a:active, 52 | a:visited { 53 | text-decoration: none; 54 | 55 | color: ${figma_blue}; 56 | } 57 | `; 58 | 59 | export const OnboardingTipComponents = { 60 | Root, 61 | Icon, 62 | Msg 63 | }; 64 | 65 | export const OnboardingTip = (props: { 66 | isHidden?: boolean; 67 | isLight?: boolean; 68 | isPt5?: boolean; 69 | children: React.ReactNode; 70 | }) => { 71 | const { children, ...otherProps } = props; 72 | return ( 73 | 74 | 75 | 76 | 77 | {children} 78 | 79 | ); 80 | }; 81 | -------------------------------------------------------------------------------- /src/components/onboarding-tip/__storybook__/OnboardingTip.stories.tsx: -------------------------------------------------------------------------------- 1 | import { storiesOf } from "@storybook/react"; 2 | import { BaseStyleDecorator } from "../../../__storybook__/BaseStylesDecorator"; 3 | import { boolean, text, withKnobs } from "@storybook/addon-knobs"; 4 | import * as React from "react"; 5 | import { TextStyleDecorator } from "../../../__storybook__/TextStylesDecorator"; 6 | import { OnboardingTip } from "../OnboardingTip"; 7 | 8 | storiesOf("OnboardingTip", module) 9 | .addDecorator(BaseStyleDecorator) 10 | .addDecorator(TextStyleDecorator) 11 | .addDecorator(withKnobs) 12 | .add("OnboardingTip", () => ( 13 | 17 | {text("children", "Your onboarding tip goes here.")} 18 | 19 | )); 20 | -------------------------------------------------------------------------------- /src/components/section-title/SectionTitle.ts: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | import { figma_black_8, figma_white } from "../../variables"; 3 | import { fontUIPos } from "../../mixins"; 4 | 5 | export const SectionTitle = styled.div` 6 | display: flex; 7 | align-items: center; 8 | 9 | height: 32px; 10 | padding: 8px 4px 8px 8px; 11 | 12 | color: ${figma_black_8}; 13 | background-color: ${figma_white}; 14 | 15 | ${fontUIPos("small", "bold")}; 16 | `; 17 | -------------------------------------------------------------------------------- /src/components/section-title/__storybook__/SectionTitle.stories.tsx: -------------------------------------------------------------------------------- 1 | import { storiesOf } from "@storybook/react"; 2 | import { BaseStyleDecorator } from "../../../__storybook__/BaseStylesDecorator"; 3 | import { text, withKnobs } from "@storybook/addon-knobs"; 4 | import * as React from "react"; 5 | import { TextStyleDecorator } from "../../../__storybook__/TextStylesDecorator"; 6 | import { SectionTitle } from "../SectionTitle"; 7 | 8 | storiesOf("SectionTitle", module) 9 | .addDecorator(BaseStyleDecorator) 10 | .addDecorator(TextStyleDecorator) 11 | .addDecorator(withKnobs) 12 | .add("SectionTitle", () => {text("children", "Section title")}); 13 | -------------------------------------------------------------------------------- /src/components/select-menu/Divider.ts: -------------------------------------------------------------------------------- 1 | import styled, { css, StyledComponent } from "styled-components"; 2 | import { figma_white_2, figma_white_4 } from "../../variables"; 3 | import { fontUINeg } from "../../mixins"; 4 | 5 | export const Divider = styled.div` 6 | margin: 0; 7 | `; 8 | 9 | export const DividerLine = styled.div` 10 | display: block; 11 | 12 | height: 1px; 13 | margin: 8px 0 7px; 14 | 15 | background-color: ${figma_white_2}; 16 | `; 17 | 18 | export const DividerLabel: StyledComponent<"div", any, { isFirst?: boolean }> = styled.div` 19 | display: flex; 20 | align-items: center; 21 | 22 | height: 32px; 23 | margin-top: 8px; 24 | padding: 8px 8px 0 32px; 25 | 26 | color: ${figma_white_4}; 27 | border-top: 1px solid ${figma_white_2}; 28 | 29 | ${fontUINeg("medium", "normal")}; 30 | 31 | ${(props: any) => 32 | props.isFirst && 33 | css` 34 | height: 24px; 35 | margin-top: 0; 36 | padding: 0 8px 0 32px; 37 | 38 | border-top: none; 39 | `} 40 | `; 41 | 42 | export const SelectMenuDivider = { 43 | Divider, 44 | DividerLine, 45 | DividerLabel 46 | }; 47 | -------------------------------------------------------------------------------- /src/components/select-menu/SelectMenu.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import styled, { css, StyledComponent } from "styled-components"; 3 | import { 4 | border_radius_small, 5 | figma_black_1, 6 | figma_black_8, 7 | figma_blue, 8 | figma_hud, 9 | figma_white, 10 | shadow_hud 11 | } from "../../variables"; 12 | import { fontUIPos } from "../../mixins"; 13 | 14 | const Root = styled.div` 15 | position: relative; 16 | 17 | box-sizing: border-box; 18 | width: 100%; 19 | 20 | cursor: default; 21 | `; 22 | 23 | const Icon = styled.div` 24 | position: absolute; 25 | top: 0; 26 | right: 0; 27 | 28 | width: 30px; 29 | height: 30px; 30 | 31 | opacity: 0; 32 | background-image: url("data:image/svg+xml;utf8,%3Csvg%20fill%3D%22none%22%20height%3D%2230%22%20viewBox%3D%220%200%2030%2030%22%20width%3D%2230%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20clip-rule%3D%22evenodd%22%20d%3D%22m15%2016.7071-3-3%20.7071-.7071%202.6465%202.6464%202.6464-2.6464.7071.7071-3%203-.3535.3536z%22%20fill%3D%22%23000%22%20fill-rule%3D%22evenodd%22%2F%3E%3C%2Fsvg%3E"); 33 | background-repeat: no-repeat; 34 | background-position: center center; 35 | `; 36 | 37 | const Button: StyledComponent<"button", any, { isActive: boolean }> = styled.button` 38 | position: relative; 39 | 40 | display: flex; 41 | justify-content: space-between; 42 | 43 | width: 100%; 44 | height: 30px; 45 | margin: 1px 0 1px 0; 46 | padding: 6px 0 6px 8px; 47 | 48 | cursor: default; 49 | 50 | color: ${figma_black_8}; 51 | border: 1px solid transparent; 52 | border-radius: ${border_radius_small}; 53 | background-color: ${figma_white}; 54 | 55 | ${fontUIPos("small", "normal")}; 56 | 57 | &:hover { 58 | border: 1px solid ${figma_black_1}; 59 | 60 | span:after { 61 | opacity: 0; 62 | } 63 | 64 | ${Icon} { 65 | opacity: 1; 66 | } 67 | } 68 | 69 | &:focus, 70 | &:active { 71 | width: 100%; 72 | padding: 5px 0 5px 7px; 73 | 74 | border: 2px solid ${figma_blue}; 75 | outline: none; 76 | 77 | span:after { 78 | opacity: 0; 79 | } 80 | 81 | ${Icon} { 82 | opacity: 1; 83 | } 84 | } 85 | 86 | ${(props: any) => 87 | props.isActive && 88 | css` 89 | &:hover { 90 | width: 100%; 91 | padding: 5px 0 5px 7px; 92 | 93 | border: 2px solid ${figma_blue}; 94 | outline: none; 95 | } 96 | `} 97 | `; 98 | 99 | const Label = styled.div` 100 | display: inline-block; 101 | 102 | text-align: left; 103 | 104 | &:after { 105 | display: inline-block; 106 | 107 | width: 7px; 108 | height: 5px; 109 | margin-top: 6px; 110 | margin-left: 6px; 111 | 112 | content: ""; 113 | 114 | background-color: transparent; 115 | background-image: url("data:image/svg+xml;utf8,%3Csvg%20fill%3D%22none%22%20height%3D%225%22%20viewBox%3D%220%200%207%205%22%20width%3D%227%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20clip-rule%3D%22evenodd%22%20d%3D%22m3%203.70711-3-3.000003.707107-.707107%202.646443%202.64645%202.64645-2.64645.70711.707107-3%203.000003-.35356.35355z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.3%22%20fill-rule%3D%22evenodd%22%2F%3E%3C%2Fsvg%3E"); 116 | } 117 | `; 118 | 119 | const List: StyledComponent<"ul", any, { isActive: boolean }> = styled.ul` 120 | position: absolute; 121 | z-index: 2; 122 | 123 | display: none; 124 | flex-direction: column; 125 | 126 | width: 100%; 127 | margin: 0; 128 | padding: 8px 0 8px 0; 129 | 130 | border-radius: ${border_radius_small}; 131 | background-color: ${figma_hud}; 132 | box-shadow: ${shadow_hud}; 133 | 134 | ${(props: any) => 135 | props.isActive && 136 | css` 137 | display: flex; 138 | `} 139 | `; 140 | 141 | export const SelectMenuComponents = { 142 | Root, 143 | Icon, 144 | Button, 145 | Label, 146 | List 147 | }; 148 | 149 | export const SelectMenu = (props: { isActive?: boolean; label?: string; children?: React.ReactNode }) => { 150 | const { isActive, label, children } = props; 151 | return ( 152 | 153 | 157 | {children} 158 | 159 | ); 160 | }; 161 | -------------------------------------------------------------------------------- /src/components/select-menu/SelectMenuItem.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import styled, { css, StyledComponent } from "styled-components"; 3 | import { figma_blue, figma_white } from "../../variables"; 4 | import { fontUINeg } from "../../mixins"; 5 | 6 | const Icon = styled.div` 7 | display: block; 8 | flex-shrink: 0; 9 | 10 | width: 24px; 11 | height: 24px; 12 | 13 | opacity: 0; 14 | background-image: url("data:image/svg+xml;utf8,%3Csvg%20fill%3D%22none%22%20height%3D%2216%22%20viewBox%3D%220%200%2016%2016%22%20width%3D%2216%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20clip-rule%3D%22evenodd%22%20d%3D%22m13.2069%205.20724-5.50002%205.49996-.70711.7072-.70711-.7072-3-2.99996%201.41422-1.41421%202.29289%202.29289%204.79293-4.79289z%22%20fill%3D%22%23fff%22%20fill-rule%3D%22evenodd%22%2F%3E%3C%2Fsvg%3E"); 15 | background-repeat: no-repeat; 16 | background-position: center center; 17 | `; 18 | 19 | const Root: StyledComponent<"li", any, { isActive: boolean }> = styled.li` 20 | display: flex; 21 | align-items: center; 22 | 23 | width: 100%; 24 | height: 24px; 25 | padding: 0 8px 0 4px; 26 | 27 | color: ${figma_white}; 28 | 29 | ${fontUINeg("medium", "normal")}; 30 | 31 | ${(props: any) => 32 | props.isActive && 33 | css` 34 | & ${Icon} { 35 | opacity: 1 !important; 36 | } 37 | `} 38 | 39 | &:hover { 40 | background-color: ${figma_blue}; 41 | } 42 | `; 43 | 44 | const Text = styled.span` 45 | display: flex; 46 | align-items: center; 47 | 48 | width: 100%; 49 | height: 100%; 50 | padding: 0 0 0 4px; 51 | `; 52 | 53 | export const SelectMenuItemComponents = { 54 | Root, 55 | Icon, 56 | Text 57 | }; 58 | 59 | export const SelectMenuItem = (props: { isActive?: boolean; text?: string }) => { 60 | const { isActive, text, ...otherProps } = props; 61 | return ( 62 | 63 | 64 | {text} 65 | 66 | ); 67 | }; 68 | -------------------------------------------------------------------------------- /src/components/select-menu/__storybook__/SelectMenu.stories.tsx: -------------------------------------------------------------------------------- 1 | import { storiesOf } from "@storybook/react"; 2 | import { BaseStyleDecorator } from "../../../__storybook__/BaseStylesDecorator"; 3 | import { boolean, text, withKnobs } from "@storybook/addon-knobs"; 4 | import * as React from "react"; 5 | import { TextStyleDecorator } from "../../../__storybook__/TextStylesDecorator"; 6 | import { SelectMenu } from "../SelectMenu"; 7 | import { SelectMenuItem } from "../SelectMenuItem"; 8 | import { Divider, DividerLabel, DividerLine } from "../Divider"; 9 | 10 | storiesOf("SelectMenu", module) 11 | .addDecorator(BaseStyleDecorator) 12 | .addDecorator(TextStyleDecorator) 13 | .addDecorator(withKnobs) 14 | .add("SelectMenu", () => ( 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | )) 25 | .add("SelectMenu with groups", () => ( 26 | 27 | 28 | Group A 29 | 30 | 31 | 32 | 33 | Group B 34 | 35 | 36 | 37 | 38 | )); 39 | -------------------------------------------------------------------------------- /src/components/switch/Switch.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import styled from "styled-components"; 3 | import { fontUIPos } from "../../mixins"; 4 | import { figma_black, figma_white } from "../../variables"; 5 | 6 | const Root = styled.label` 7 | position: relative; 8 | 9 | display: flex; 10 | align-items: center; 11 | align-self: 1; 12 | flex-direction: row; 13 | 14 | cursor: default; 15 | `; 16 | 17 | const Container = styled.div` 18 | position: relative; 19 | 20 | width: 24px; 21 | height: 12px; 22 | margin: 10px 16px 10px 8px; 23 | `; 24 | 25 | const Label = styled.div` 26 | ${fontUIPos("small", "normal")} 27 | `; 28 | 29 | const Slider = styled.div` 30 | position: absolute; 31 | top: 0; 32 | right: 0; 33 | bottom: 0; 34 | left: 0; 35 | 36 | transition: transform 0.2s; 37 | transition: background-color 0 0.2s; 38 | 39 | border: 1px solid ${figma_black}; 40 | border-radius: 12px; 41 | background-color: ${figma_white}; 42 | 43 | &::before { 44 | position: absolute; 45 | top: -1px; 46 | left: -1px; 47 | 48 | width: 10px; 49 | height: 10px; 50 | 51 | content: ""; 52 | 53 | transition: transform 0.2s; 54 | transition: background-color 0 0.2s; 55 | 56 | border: 1px solid ${figma_black}; 57 | border-radius: 50%; 58 | background-color: white; 59 | } 60 | `; 61 | 62 | const Checkbox = styled.input` 63 | width: 0; 64 | height: 0; 65 | 66 | opacity: 0; 67 | 68 | &:checked + ${Slider} { 69 | background-color: ${figma_black}; 70 | } 71 | 72 | &:focus + ${Slider} { 73 | outline: none; 74 | box-shadow: 0 0 1px #2196f3; 75 | } 76 | 77 | &:checked + ${Slider}:before { 78 | transform: translateX(12px); 79 | } 80 | `; 81 | 82 | export const SwitchComponents = { 83 | Root, 84 | Container, 85 | Checkbox, 86 | Slider, 87 | Label 88 | }; 89 | 90 | export const Switch = (props: { checked?: boolean; name?: React.ReactNode; onChange?: (value: boolean) => void }) => { 91 | const { checked, name, onChange, ...otherProps } = props; 92 | return ( 93 | 94 | 95 | onChange && onChange(!!e.target.value)} /> 96 | 97 | 98 | 99 | 100 | ); 101 | }; 102 | -------------------------------------------------------------------------------- /src/components/switch/__storybook__/Switch.stories.tsx: -------------------------------------------------------------------------------- 1 | import { storiesOf } from "@storybook/react"; 2 | import { BaseStyleDecorator } from "../../../__storybook__/BaseStylesDecorator"; 3 | import { boolean, text, withKnobs } from "@storybook/addon-knobs"; 4 | import * as React from "react"; 5 | import { TextStyleDecorator } from "../../../__storybook__/TextStylesDecorator"; 6 | import { Switch } from "../Switch"; 7 | 8 | storiesOf("Switch", module) 9 | .addDecorator(BaseStyleDecorator) 10 | .addDecorator(TextStyleDecorator) 11 | .addDecorator(withKnobs) 12 | .add("Switch", () => ); 13 | -------------------------------------------------------------------------------- /src/components/textarea/Textarea.ts: -------------------------------------------------------------------------------- 1 | import styled, { StyledComponent } from "styled-components"; 2 | import { fontUIPos } from "../../mixins"; 3 | import { 4 | border_radius_small, 5 | figma_black, 6 | figma_black_1, 7 | figma_black_3, 8 | figma_black_8, 9 | figma_blue, 10 | figma_blue_3, 11 | figma_white 12 | } from "../../variables"; 13 | 14 | export const Textarea: StyledComponent<"textarea", any, any> = styled.textarea` 15 | ${fontUIPos("small", "normal")}; 16 | 17 | display: flex; 18 | overflow: hidden; 19 | align-items: center; 20 | width: calc(100% - 16px); 21 | min-height: 62px; 22 | margin: 1px 8px 1px 8px; 23 | padding: 7px 4px 7px 7px; 24 | 25 | resize: none; 26 | 27 | color: ${figma_black_8}; 28 | border: 1px solid ${figma_black_1}; 29 | border-radius: ${border_radius_small}; 30 | outline: none; 31 | background-color: ${figma_white}; 32 | 33 | &:active, 34 | &:focus { 35 | padding: 6px 4px 6px 6px; 36 | 37 | color: ${figma_black}; 38 | border: 2px solid ${figma_blue}; 39 | border-radius: ${border_radius_small}; 40 | } 41 | 42 | &::selection { 43 | color: ${figma_black}; 44 | background-color: ${figma_blue_3}; 45 | } 46 | 47 | &::placeholder { 48 | color: ${figma_black_3}; 49 | } 50 | 51 | &:disabled { 52 | color: ${figma_black_3}; 53 | 54 | &:focus { 55 | border: 1px solid ${figma_black_1}; 56 | } 57 | } 58 | `; 59 | -------------------------------------------------------------------------------- /src/components/textarea/__storybook__/Textarea.stories.tsx: -------------------------------------------------------------------------------- 1 | import { storiesOf } from "@storybook/react"; 2 | import { BaseStyleDecorator } from "../../../__storybook__/BaseStylesDecorator"; 3 | import { text, withKnobs } from "@storybook/addon-knobs"; 4 | import * as React from "react"; 5 | import { TextStyleDecorator } from "../../../__storybook__/TextStylesDecorator"; 6 | import { Textarea } from "../Textarea"; 7 | 8 | storiesOf("Textarea", module) 9 | .addDecorator(BaseStyleDecorator) 10 | .addDecorator(TextStyleDecorator) 11 | .addDecorator(withKnobs) 12 | .add("Textarea", () =>