├── _redirects ├── __mocks__ └── fileMock.js ├── src ├── components │ ├── Typography │ │ ├── Text │ │ │ ├── index.js │ │ │ └── styles.module.css │ │ ├── P.jsx │ │ ├── H1.jsx │ │ ├── H2.jsx │ │ ├── H3.jsx │ │ ├── H4.jsx │ │ ├── H5.jsx │ │ ├── H6.jsx │ │ ├── tests │ │ │ ├── __snapshots__ │ │ │ │ └── typography.test.js.snap │ │ │ └── typography.test.js │ │ └── styles.module.css │ ├── DarkLightToggle │ │ ├── styles.module.css │ │ └── tests │ │ │ └── darkLightToggle.test.js │ ├── NumberInput │ │ ├── styles.module.css │ │ ├── tests │ │ │ ├── __snapshots__ │ │ │ │ └── numberInput.test.js.snap │ │ │ └── numberInput.test.js │ │ └── NumberInput.jsx │ ├── Link │ │ ├── Link.test.js │ │ ├── test │ │ │ ├── __snapshots__ │ │ │ │ └── Link.test.js.snap │ │ │ └── Link.test.js │ │ ├── styles.module.css │ │ └── Link.jsx │ ├── Table │ │ ├── Table.test.js │ │ ├── TableHeader.jsx │ │ ├── TableBody.jsx │ │ ├── styles.module.css │ │ ├── tests │ │ │ ├── __snapshots__ │ │ │ │ └── table.test.js.snap │ │ │ └── table.test.js │ │ └── Table.jsx │ ├── Message │ │ ├── Message.test.js │ │ ├── test │ │ │ ├── message.test.js │ │ │ └── __snapshots__ │ │ │ │ └── message.test.js.snap │ │ ├── Message.jsx │ │ └── styles.module.css │ ├── Checkbox │ │ ├── Checkbox.test.js │ │ ├── tests │ │ │ ├── checkbox.test.js │ │ │ └── __snapshots__ │ │ │ │ └── checkbox.test.js.snap │ │ ├── Checkbox.jsx │ │ └── styles.module.css │ ├── StatusBar │ │ ├── StatusBar.test.js │ │ └── test │ │ │ └── statusBar.test.js │ ├── TextHighlighted │ │ ├── styles.module.css │ │ ├── tests │ │ │ ├── __snapshots__ │ │ │ │ └── texthighlighted.test.js.snap │ │ │ └── texthighlighted.test.js │ │ └── TextHighlighted.jsx │ ├── Description │ │ ├── styles.module.css │ │ └── Description.jsx │ ├── Card │ │ ├── tests │ │ │ ├── __snapshots__ │ │ │ │ └── card.test.js.snap │ │ │ └── card.test.js │ │ ├── styles.module.css │ │ └── Card.jsx │ ├── CopyableText │ │ ├── helpers.js │ │ ├── styles.module.css │ │ ├── tests │ │ │ ├── copyableText.test.js │ │ │ └── __snapshots__ │ │ │ │ └── copyableText.test.js.snap │ │ └── CopyableText.jsx │ ├── Button │ │ ├── tests │ │ │ ├── __snapshots__ │ │ │ │ └── button.test.js.snap │ │ │ └── button.test.js │ │ ├── Button.jsx │ │ └── styles.module.css │ ├── Spinner │ │ ├── test │ │ │ ├── __snapshots__ │ │ │ │ └── spinner.test.js.snap │ │ │ └── spinner.test.js │ │ ├── Spinner.jsx │ │ └── styles.module.css │ ├── Tooltip │ │ ├── test │ │ │ ├── __snapshots__ │ │ │ │ └── tooltip.test.js.snap │ │ │ └── tooltip.test.js │ │ ├── styles.module.css │ │ └── Tooltip.jsx │ ├── StatusTag │ │ ├── negative.svg │ │ ├── negative_blue.svg │ │ ├── test │ │ │ ├── __snapshots__ │ │ │ │ └── statusTag.test.js.snap │ │ │ └── statusTag.test.js │ │ ├── waiting.svg │ │ ├── green_check.svg │ │ ├── time_yellow.svg │ │ ├── styles.module.css │ │ ├── negative_circle.svg │ │ └── StatusTag.jsx │ ├── Toggle │ │ ├── tests │ │ │ ├── __snapshots__ │ │ │ │ └── toggle.test.js.snap │ │ │ └── toggle.test.js │ │ ├── Toggle.jsx │ │ └── styles.module.css │ ├── Layout │ │ ├── StaticContainer.jsx │ │ ├── Row.jsx │ │ ├── Sidebar.jsx │ │ ├── Header.jsx │ │ ├── TopBanner.jsx │ │ ├── PageDetails.jsx │ │ ├── Main.jsx │ │ ├── Column.jsx │ │ └── Container.jsx │ ├── TextInput │ │ └── test │ │ │ ├── __snapshots__ │ │ │ └── textInput.test.js.snap │ │ │ └── textInput.test.js │ ├── Badge │ │ ├── tests │ │ │ ├── __snapshots__ │ │ │ │ └── badge.test.js.snap │ │ │ └── badge.test.js │ │ ├── styles.module.css │ │ └── Badge.jsx │ ├── Select │ │ ├── styles.module.css │ │ └── test │ │ │ ├── select.test.js │ │ │ └── __snapshots__ │ │ │ └── select.test.js.snap │ ├── Modal │ │ ├── tests │ │ │ └── modal.test.js │ │ ├── ModalWrapper.jsx │ │ └── styles.module.css │ ├── Dropdown │ │ ├── tests │ │ │ ├── __snapshots__ │ │ │ │ └── dropdown.test.js.snap │ │ │ └── dropdown.test.js │ │ ├── DropdownItem.jsx │ │ └── styles.module.css │ ├── TextArea │ │ ├── test │ │ │ ├── textArea.test.js │ │ │ └── __snapshots__ │ │ │ │ └── textArea.test.js.snap │ │ ├── styles.module.css │ │ └── TextArea.jsx │ ├── Slider │ │ ├── helpers.js │ │ ├── tests │ │ │ ├── slider.test.js │ │ │ └── __snapshots__ │ │ │ │ └── slider.test.js.snap │ │ ├── styles.module.css │ │ └── SliderHandle.jsx │ ├── Paginator │ │ └── styles.module.css │ ├── Datepicker │ │ ├── DatepickerPad.module.css │ │ └── test │ │ │ ├── __snapshots__ │ │ │ └── datepicker.test.js.snap │ │ │ └── datepicker.test.js │ ├── ButtonIcon │ │ └── styles.module.css │ ├── BoxTextInput │ │ ├── styles.module.css │ │ └── tests │ │ │ ├── boxTextInput.test.js │ │ │ └── __snapshots__ │ │ │ └── boxTextInput.test.js.snap │ ├── Tabs │ │ ├── tests │ │ │ ├── __snapshots__ │ │ │ │ └── tabs.test.js.snap │ │ │ └── tabs.test.js │ │ └── styles.module.css │ └── RadioButtonGroup │ │ ├── tests │ │ └── radiobuttongroup.test.js │ │ └── styles.module.css ├── assets │ └── fonts │ │ └── source-sans-pro │ │ ├── SourceSansPro-Light.ttf │ │ ├── SourceSansPro-Regular.ttf │ │ └── SourceSansPro-SemiBold.ttf ├── stories │ ├── buttonicon.module.css │ ├── page.css │ ├── Description.stories.jsx │ ├── Badge.stories.jsx │ ├── Checkbox.stories.jsx │ ├── Spinner.stories.jsx │ ├── NumberInput.stories.jsx │ ├── Toggle.stories.jsx │ ├── DarkLightToggle.stories.jsx │ ├── TextArea.stories.jsx │ ├── Icon.stories.jsx │ ├── Paginator.stories.jsx │ ├── Dropdown.stories.jsx │ ├── CopyableText.stories.jsx │ ├── DatePickerV2.stories.jsx │ ├── Card.stories.jsx │ ├── Link.stories.jsx │ ├── Message.stories.jsx │ ├── DatePicker.stories.jsx │ ├── Tooltip.stories.jsx │ ├── StatusTag.stories.jsx │ ├── assets │ │ ├── direction.svg │ │ ├── flow.svg │ │ ├── code-brackets.svg │ │ ├── comments.svg │ │ ├── repo.svg │ │ ├── plugin.svg │ │ └── stackalt.svg │ ├── BoxTextInput.stories.jsx │ ├── Button.stories.jsx │ ├── TextInput.stories.jsx │ ├── RadioButton.stories.jsx │ ├── Select.stories.jsx │ ├── ButtonIcon.stories.jsx │ ├── Introduction.stories.mdx │ ├── StatusBar.stories.jsx │ └── Typography.stories.jsx ├── theme │ ├── index.js │ ├── constants.js │ ├── defaultTheme.js │ ├── helpers.js │ └── ThemeProvider.js ├── hooks │ ├── usePrevious.js │ ├── index.js │ ├── useMountEffect.js │ ├── useClickOutside.js │ ├── useLockBodyScrollOnTrue.js │ ├── useKeyPress.js │ ├── useHover.js │ └── useTruncate.js ├── css │ └── exports.css ├── utils.js └── utils.test.js ├── .eslintrc ├── .prettierrc ├── postcss.config.js ├── babel.config.js ├── .gitignore ├── jest.setup.js ├── .storybook ├── themeDecorator.js ├── main.js ├── preview.js └── providerFn.js ├── .github └── workflows │ ├── deploy.yml │ └── nodejs.yml ├── .stylelintrc ├── rollup.config.js └── jest.config.js /_redirects: -------------------------------------------------------------------------------- 1 | /* /index.html 200 -------------------------------------------------------------------------------- /__mocks__/fileMock.js: -------------------------------------------------------------------------------- 1 | export default ""; 2 | -------------------------------------------------------------------------------- /src/components/Typography/Text/index.js: -------------------------------------------------------------------------------- 1 | export { default } from "./Text.jsx"; 2 | -------------------------------------------------------------------------------- /src/components/DarkLightToggle/styles.module.css: -------------------------------------------------------------------------------- 1 | .darkLightToggle { 2 | cursor: pointer; 3 | } 4 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["react-app", "react-app/jest", "prettier"], 3 | "rules": { 4 | "eqeqeq": 0 5 | } 6 | } -------------------------------------------------------------------------------- /src/assets/fonts/source-sans-pro/SourceSansPro-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decred/pi-ui/HEAD/src/assets/fonts/source-sans-pro/SourceSansPro-Light.ttf -------------------------------------------------------------------------------- /src/assets/fonts/source-sans-pro/SourceSansPro-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decred/pi-ui/HEAD/src/assets/fonts/source-sans-pro/SourceSansPro-Regular.ttf -------------------------------------------------------------------------------- /src/assets/fonts/source-sans-pro/SourceSansPro-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/decred/pi-ui/HEAD/src/assets/fonts/source-sans-pro/SourceSansPro-SemiBold.ttf -------------------------------------------------------------------------------- /src/components/NumberInput/styles.module.css: -------------------------------------------------------------------------------- 1 | .numberInputWrapper { 2 | width: 4rem; 3 | display: inline-block; 4 | } 5 | 6 | .numberInput { 7 | text-align: center; 8 | } 9 | -------------------------------------------------------------------------------- /src/components/Link/Link.test.js: -------------------------------------------------------------------------------- 1 | import Link from "./Link.jsx"; 2 | 3 | describe("Link Component", () => { 4 | it("is truthy", () => { 5 | expect(Link).toBeTruthy(); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /src/components/Table/Table.test.js: -------------------------------------------------------------------------------- 1 | import Table from "./Table.jsx"; 2 | 3 | describe("Table Component", () => { 4 | it("is truthy", () => { 5 | expect(Table).toBeTruthy(); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /src/components/Message/Message.test.js: -------------------------------------------------------------------------------- 1 | import Message from "./Message.jsx"; 2 | 3 | describe("Message Component", () => { 4 | it("is truthy", () => { 5 | expect(Message).toBeTruthy(); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /src/stories/buttonicon.module.css: -------------------------------------------------------------------------------- 1 | .blueButtonIcon { 2 | background: var(--color-primary) !important; 3 | } 4 | 5 | .darkBlueButtonIcon { 6 | background: var(--paginator-button-color) !important; 7 | } 8 | -------------------------------------------------------------------------------- /src/components/Checkbox/Checkbox.test.js: -------------------------------------------------------------------------------- 1 | import Checkbox from "./Checkbox.jsx"; 2 | 3 | describe("Checkbox Component", () => { 4 | it("is truthy", () => { 5 | expect(Checkbox).toBeTruthy(); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /src/components/StatusBar/StatusBar.test.js: -------------------------------------------------------------------------------- 1 | import StatusBar from "./StatusBar.jsx"; 2 | 3 | describe("StatusBar Component", () => { 4 | it("is truthy", () => { 5 | expect(StatusBar).toBeTruthy(); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /src/components/TextHighlighted/styles.module.css: -------------------------------------------------------------------------------- 1 | .contentWrapper { 2 | padding: 0.3rem 1rem; 3 | word-break: break-all; 4 | background-color: var(--copyable-text-background-color); 5 | border-radius: 0.4rem; 6 | } 7 | -------------------------------------------------------------------------------- /src/components/Description/styles.module.css: -------------------------------------------------------------------------------- 1 | .description { 2 | margin-left: 2.5rem; 3 | margin-top: 0.5rem; 4 | color: var(--text-secondary-color); 5 | font-size: var(--font-size-small); 6 | font-style: italic; 7 | } 8 | -------------------------------------------------------------------------------- /src/components/Link/test/__snapshots__/Link.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Link component Matches the snapshot 1`] = ` 4 | 7 | test 8 | 9 | `; 10 | -------------------------------------------------------------------------------- /src/stories/page.css: -------------------------------------------------------------------------------- 1 | body.sb-show-main { 2 | background: transparent !important; 3 | } 4 | 5 | #story--design-system-components-tabs--slide-animation { 6 | position: relative; 7 | overflow-x: hidden; 8 | height: 5rem; 9 | } 10 | -------------------------------------------------------------------------------- /src/theme/index.js: -------------------------------------------------------------------------------- 1 | export { default as defaultDarkTheme } from "./darkTheme"; 2 | export { default as defaultLightTheme } from "./lightTheme"; 3 | export * from "./ThemeProvider"; 4 | export * from "./helpers"; 5 | export * from "./constants"; 6 | -------------------------------------------------------------------------------- /src/components/Card/tests/__snapshots__/card.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Card component Matches the snapshot 1`] = ` 4 |
7 | test 8 |
9 | `; 10 | -------------------------------------------------------------------------------- /src/theme/constants.js: -------------------------------------------------------------------------------- 1 | /* 2 | * The following constants are used throughout the application to determine 3 | * if the current active theme is default light or dark theme 4 | */ 5 | export const DEFAULT_LIGHT_THEME_NAME = "light"; 6 | export const DEFAULT_DARK_THEME_NAME = "dark"; 7 | -------------------------------------------------------------------------------- /src/hooks/usePrevious.js: -------------------------------------------------------------------------------- 1 | import { useRef, useEffect } from "react"; 2 | 3 | function usePrevious(value) { 4 | const ref = useRef(); 5 | useEffect(() => { 6 | ref.current = value; 7 | }, [value]); 8 | return ref.current; 9 | } 10 | 11 | export default usePrevious; 12 | -------------------------------------------------------------------------------- /src/components/CopyableText/helpers.js: -------------------------------------------------------------------------------- 1 | export const copyToClipboard = (str) => { 2 | const el = document.createElement("textarea"); 3 | el.value = str; 4 | document.body.appendChild(el); 5 | el.select(); 6 | document.execCommand("copy"); 7 | document.body.removeChild(el); 8 | }; 9 | -------------------------------------------------------------------------------- /src/theme/defaultTheme.js: -------------------------------------------------------------------------------- 1 | import lightTheme from "./lightTheme"; 2 | 3 | function applyDefaultTheme() { 4 | Object.keys(lightTheme).forEach((key) => { 5 | document.documentElement.style.setProperty(`--${key}`, lightTheme[key]); 6 | }); 7 | } 8 | 9 | applyDefaultTheme(); 10 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 80, 3 | "tabWidth": 2, 4 | "useTabs": false, 5 | "semi": true, 6 | "singleQuote": false, 7 | "trailingComma": "es5", 8 | "bracketSpacing": true, 9 | "bracketSameLine": true, 10 | "arrowParens": "always", 11 | "endOfLine": "auto" 12 | } 13 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | const postcssPresetEnv = require("postcss-preset-env"); 2 | 3 | module.exports = { 4 | plugins: [ 5 | postcssPresetEnv({ 6 | importFrom: "src/css/exports.css", 7 | features: { 8 | "nesting-rules": true, 9 | }, 10 | }), 11 | ], 12 | }; 13 | -------------------------------------------------------------------------------- /src/components/Button/tests/__snapshots__/button.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Button component Matches the snapshot 1`] = ` 4 | 11 | `; 12 | -------------------------------------------------------------------------------- /src/components/CopyableText/styles.module.css: -------------------------------------------------------------------------------- 1 | .copyableWrapper { 2 | display: flex; 3 | align-items: center; 4 | flex-wrap: nowrap; 5 | max-width: 100%; 6 | } 7 | 8 | .copyToClipboard { 9 | width: 1.4rem; 10 | height: 1.4rem; 11 | cursor: pointer; 12 | margin-left: 5px; 13 | user-select: none; 14 | } 15 | -------------------------------------------------------------------------------- /src/components/Spinner/test/__snapshots__/spinner.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Spinner component Matches the snapshot 1`] = ` 4 |
13 | `; 14 | -------------------------------------------------------------------------------- /src/components/Link/test/Link.test.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Link from "../Link"; 3 | import { create } from "react-test-renderer"; 4 | 5 | describe("Link component", () => { 6 | test("Matches the snapshot", () => { 7 | const link = create(test); 8 | expect(link.toJSON()).toMatchSnapshot(); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /src/components/TextHighlighted/tests/__snapshots__/texthighlighted.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`TextHighlighted component Matches snapshot 1`] = ` 4 | 8 | test 9 | 10 | `; 11 | -------------------------------------------------------------------------------- /src/components/Tooltip/test/__snapshots__/tooltip.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Tooltip component Matches the snapshot 1`] = ` 4 |
8 |
11 | content 12 |
13 |
14 | `; 15 | -------------------------------------------------------------------------------- /src/components/Card/tests/card.test.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Card from "../Card"; 3 | import { create } from "react-test-renderer"; 4 | 5 | describe("Card component", () => { 6 | test("Matches the snapshot", () => { 7 | const card = create(test); 8 | expect(card.toJSON()).toMatchSnapshot(); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /src/components/StatusTag/negative.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/StatusTag/negative_blue.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/Spinner/test/spinner.test.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Spinner from "../Spinner"; 3 | import { create } from "react-test-renderer"; 4 | 5 | describe("Spinner component", () => { 6 | test("Matches the snapshot", () => { 7 | const spinner = create(); 8 | expect(spinner.toJSON()).toMatchSnapshot(); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /src/components/Tooltip/test/tooltip.test.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Tooltip from "../Tooltip"; 3 | import { create } from "react-test-renderer"; 4 | 5 | describe("Tooltip component", () => { 6 | test("Matches the snapshot", () => { 7 | const tooltip = create(); 8 | expect(tooltip.toJSON()).toMatchSnapshot(); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /src/components/Toggle/tests/__snapshots__/toggle.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Toggle Component Matches snapshot 1`] = ` 4 |
7 |
11 |
14 |
15 |
16 | `; 17 | -------------------------------------------------------------------------------- /src/components/StatusTag/test/__snapshots__/statusTag.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`StatusTag component Matches the snapshot 1`] = ` 4 | 7 | grayNegative 11 | 12 | grayNegative 13 | 14 | 15 | `; 16 | -------------------------------------------------------------------------------- /src/components/StatusTag/test/statusTag.test.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import StatusTag from "../StatusTag"; 3 | import { create } from "react-test-renderer"; 4 | 5 | describe("StatusTag component", () => { 6 | test("Matches the snapshot", () => { 7 | const statusTag = create(); 8 | expect(statusTag.toJSON()).toMatchSnapshot(); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /src/components/StatusTag/waiting.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/Checkbox/tests/checkbox.test.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Checkbox from "../Checkbox"; 3 | import { create } from "react-test-renderer"; 4 | 5 | describe("Checkbox component", () => { 6 | test("Matches the snapshot", () => { 7 | const checkbox = create(); 8 | expect(checkbox.toJSON()).toMatchSnapshot(); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /src/components/Layout/StaticContainer.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { classNames } from "../../utils"; 3 | import styles from "./styles.module.css"; 4 | 5 | const StaticContainer = ({ children, className, style }) => ( 6 |
7 | {children} 8 |
9 | ); 10 | 11 | export default StaticContainer; 12 | -------------------------------------------------------------------------------- /src/components/StatusTag/green_check.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/Checkbox/tests/__snapshots__/checkbox.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Checkbox component Matches the snapshot 1`] = ` 4 | 19 | `; 20 | -------------------------------------------------------------------------------- /src/components/TextInput/test/__snapshots__/textInput.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`TextInput component Matches the snapshot 1`] = ` 4 |
7 | 13 |
14 |

17 |

18 | `; 19 | -------------------------------------------------------------------------------- /src/components/Badge/tests/__snapshots__/badge.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Badge component Matches the snapshot 1`] = ` 4 |
7 | 14 |
17 | test 18 |
19 | `; 20 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ["@babel/preset-env", "@babel/preset-react"], 3 | plugins: [ 4 | ["@babel/plugin-proposal-class-properties", { "loose": true }], 5 | ["@babel/plugin-proposal-private-methods", { "loose": true }], 6 | ["@babel/plugin-proposal-private-property-in-object", { "loose": true }] 7 | ], 8 | env: { 9 | test: { 10 | plugins: ["@babel/plugin-transform-runtime"], 11 | }, 12 | }, 13 | }; 14 | -------------------------------------------------------------------------------- /src/hooks/index.js: -------------------------------------------------------------------------------- 1 | export { default as useTruncate } from "./useTruncate"; 2 | export { default as useMediaQuery } from "./useMediaQuery"; 3 | export { default as useHover } from "./useHover"; 4 | export { default as useClickOutside } from "./useClickOutside"; 5 | export { default as useLockBodyScrollOnTrue } from "./useLockBodyScrollOnTrue"; 6 | export { default as useMountEffect } from "./useMountEffect"; 7 | export { default as usePrevious } from "./usePrevious"; 8 | -------------------------------------------------------------------------------- /src/stories/Description.stories.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Description } from ".."; 3 | import "./page.css"; 4 | 5 | const DescriptionObj = { 6 | title: "Design System/Components/Description", 7 | component: Description, 8 | }; 9 | 10 | export default DescriptionObj; 11 | 12 | const Template = ({ ...args }) => ; 13 | 14 | export const Basic = Template.bind({}); 15 | Basic.args = { 16 | body: "Test Description", 17 | }; 18 | -------------------------------------------------------------------------------- /src/stories/Badge.stories.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Badge } from ".."; 3 | import "./page.css"; 4 | 5 | const BadgeObj = { 6 | title: "Design System/Components/Badge", 7 | component: Badge, 8 | }; 9 | 10 | export default BadgeObj; 11 | 12 | const Template = ({ children, ...args }) => {children}; 13 | 14 | export const Basic = Template.bind({}); 15 | Basic.args = { 16 | children: "Test Badge", 17 | show: true, 18 | }; 19 | -------------------------------------------------------------------------------- /src/components/NumberInput/tests/__snapshots__/numberInput.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`NumberInput component Matches the snapshot 1`] = ` 4 |
7 | 13 | 14 |
15 |

18 |

19 | `; 20 | -------------------------------------------------------------------------------- /src/stories/Checkbox.stories.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Checkbox } from ".."; 3 | import "./page.css"; 4 | 5 | const CheckboxObj = { 6 | title: "Design System/Components/Checkbox", 7 | component: Checkbox, 8 | }; 9 | 10 | export default CheckboxObj; 11 | 12 | const Template = ({ children, ...args }) => ; 13 | 14 | export const Basic = Template.bind({}); 15 | Basic.args = { 16 | id: "test-checkbox", 17 | label: "test", 18 | description: "yoyo!", 19 | }; 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # See https://help.github.com/ignore-files/ for more about ignoring files. 3 | 4 | # IDEs 5 | .idea 6 | 7 | # dependencies 8 | node_modules 9 | 10 | # builds 11 | build 12 | dist 13 | .rpt2_cache 14 | 15 | # misc 16 | .DS_Store 17 | .env 18 | .env.local 19 | .env.development.local 20 | .env.test.local 21 | .env.production.local 22 | 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | #storybook 28 | storybook-static 29 | 30 | #docz 31 | .docz 32 | 33 | #bundle stats 34 | stats.html -------------------------------------------------------------------------------- /src/components/Link/styles.module.css: -------------------------------------------------------------------------------- 1 | .link { 2 | color: var(--link-color); 3 | font-weight: var(--font-weight-regular); 4 | } 5 | 6 | .gray { 7 | color: var(--color-gray); 8 | } 9 | 10 | .dark { 11 | color: var(--color-primary-dark); 12 | } 13 | 14 | .link:hover { 15 | text-decoration: underline; 16 | } 17 | 18 | .noHover:hover { 19 | text-decoration: none; 20 | } 21 | 22 | .truncate { 23 | display: block; 24 | white-space: nowrap; 25 | overflow: hidden; 26 | text-overflow: ellipsis; 27 | } 28 | -------------------------------------------------------------------------------- /src/stories/Spinner.stories.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Spinner } from ".."; 3 | import "./page.css"; 4 | 5 | const SpinnerObj = { 6 | title: "Design System/Components/Spinner", 7 | component: Spinner, 8 | }; 9 | 10 | export default SpinnerObj; 11 | 12 | const Template = ({ children, ...args }) => ; 13 | 14 | export const Basic = Template.bind({}); 15 | Basic.args = {}; 16 | 17 | export const Inverted = Template.bind({}); 18 | Inverted.args = { 19 | invert: true, 20 | }; 21 | -------------------------------------------------------------------------------- /jest.setup.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | 3 | /** 4 | * This code silences the warnings about the forwardRef update inside a test. TODO: improve tests and get rid of the warnings 5 | */ 6 | const consoleError = console.error; 7 | beforeAll(() => { 8 | jest.spyOn(console, "error").mockImplementation((...args) => { 9 | if ( 10 | !args[0].includes( 11 | "Warning: An update to %s inside a test was not wrapped in act" 12 | ) 13 | ) { 14 | consoleError(...args); 15 | } 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /src/components/Spinner/Spinner.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import styles from "./styles.module.css"; 3 | import PropTypes from "prop-types"; 4 | 5 | const Spinner = ({ invert, width, height }) => { 6 | return ( 7 |
11 | ); 12 | }; 13 | 14 | Spinner.propTypes = { 15 | width: PropTypes.string, 16 | height: PropTypes.string, 17 | invert: PropTypes.bool, 18 | }; 19 | 20 | export default Spinner; 21 | -------------------------------------------------------------------------------- /src/components/Card/styles.module.css: -------------------------------------------------------------------------------- 1 | .card { 2 | background: var(--card-background); 3 | position: relative; 4 | } 5 | 6 | .padding-small { 7 | padding: 2rem 4rem; 8 | } 9 | 10 | .padding-medium { 11 | padding: 4rem 6rem; 12 | } 13 | 14 | .padding-large { 15 | padding: 6rem 9rem; 16 | } 17 | 18 | .marker { 19 | border-left: 1.2rem solid; 20 | border-top: 1.2rem solid; 21 | border-right: 1.2rem solid transparent; 22 | border-bottom: 1.2rem solid transparent; 23 | position: absolute; 24 | top: 0; 25 | left: 0; 26 | } 27 | -------------------------------------------------------------------------------- /src/components/Select/styles.module.css: -------------------------------------------------------------------------------- 1 | .arrowAnchor { 2 | position: relative; 3 | height: 100%; 4 | width: 2rem; 5 | } 6 | 7 | .arrowAnchor:after { 8 | content: ""; 9 | width: 0; 10 | height: 0; 11 | 12 | border: 0.5rem solid transparent; 13 | border-color: var(--select-anchor-color) transparent transparent transparent; 14 | position: absolute; 15 | top: -0.3rem; 16 | right: 0.3rem; 17 | } 18 | 19 | .arrowAnchorOpen:after { 20 | top: -0.9rem; 21 | border-color: transparent transparent var(--color-primary) transparent; 22 | } 23 | -------------------------------------------------------------------------------- /src/theme/helpers.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Returns the final value of a given theme key 3 | * @param {Object} theme 4 | * @param {String} key 5 | */ 6 | export const getThemeProperty = (theme, key) => { 7 | if (!theme[key]) { 8 | return new Error("Please, provide a valid color key!"); 9 | } 10 | const value = theme[key]; 11 | const regex = /^var\(--(.*)\)/gm; 12 | const match = regex.exec(value); 13 | 14 | const isVariable = match && match.length > 0; 15 | if (isVariable) { 16 | return getThemeProperty(theme, match[1]); 17 | } 18 | 19 | return value; 20 | }; 21 | -------------------------------------------------------------------------------- /src/components/Layout/Row.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import PropTypes from "prop-types"; 3 | import styles from "./styles.module.css"; 4 | import { classNames } from "../../utils"; 5 | 6 | function Row({ className, style, children, ...props }) { 7 | return ( 8 |
9 | {children} 10 |
11 | ); 12 | } 13 | 14 | Row.propTypes = { 15 | children: PropTypes.node.isRequired, 16 | style: PropTypes.object, 17 | className: PropTypes.string, 18 | }; 19 | 20 | export default Row; 21 | -------------------------------------------------------------------------------- /src/components/Description/Description.jsx: -------------------------------------------------------------------------------- 1 | import { PropTypes } from "prop-types"; 2 | import React from "react"; 3 | import styles from "./styles.module.css"; 4 | import { classNames } from "../../utils"; 5 | 6 | const Description = ({ body, style, className }) => 7 | body ? ( 8 |
9 | {body} 10 |
11 | ) : null; 12 | 13 | Description.propTypes = { 14 | body: PropTypes.node, 15 | style: PropTypes.object, 16 | className: PropTypes.string, 17 | }; 18 | 19 | export default Description; 20 | -------------------------------------------------------------------------------- /.storybook/themeDecorator.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | ThemeProvider, 4 | DEFAULT_DARK_THEME_NAME, 5 | DEFAULT_LIGHT_THEME_NAME, 6 | defaultDarkTheme, 7 | defaultLightTheme, 8 | } from "../src/theme"; 9 | 10 | const themes = { 11 | [DEFAULT_DARK_THEME_NAME]: defaultDarkTheme, 12 | [DEFAULT_LIGHT_THEME_NAME]: defaultLightTheme, 13 | }; 14 | 15 | const ThemeDecorator = (storyFn) => ( 16 | 17 | {storyFn()} 18 | 19 | ); 20 | 21 | export default ThemeDecorator; 22 | -------------------------------------------------------------------------------- /src/components/Modal/tests/modal.test.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { render, fireEvent, screen } from "@testing-library/react"; 3 | import Modal from "../Modal"; 4 | 5 | describe("Modal Component", () => { 6 | test("Open and close", () => { 7 | const mockOnClose = jest.fn(); 8 | render( 9 | 10 | test 11 | 12 | ); 13 | expect(screen.queryByText(/test/i)).toBeTruthy(); 14 | 15 | fireEvent.click(screen.getByTestId("close")); 16 | 17 | expect(mockOnClose).toBeCalled(); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /src/css/exports.css: -------------------------------------------------------------------------------- 1 | @custom-media --xs-viewport screen and (max-width: 560px); 2 | @custom-media --sm-viewport screen and (max-width: 768px); 3 | @custom-media --md-viewport screen and (max-width: 1000px); 4 | @custom-media --bg-viewport screen and (max-width: 1180px); 5 | @custom-media --lg-viewport screen and (max-width: 1400px); 6 | @custom-media --xl-viewport screen and (min-width: 1401px); 7 | @custom-media --bigger-than-xs-viewport screen and (min-width: 561px); 8 | @custom-media --bigger-than-sm-viewport screen and (min-width: 769px); 9 | @custom-media --bigger-than-md-viewport screen and (min-width: 1001px); 10 | -------------------------------------------------------------------------------- /src/components/Layout/Sidebar.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import PropTypes from "prop-types"; 3 | import styles from "./styles.module.css"; 4 | import { classNames } from "../../utils"; 5 | 6 | const Sidebar = ({ children, style, className, ...props }) => { 7 | return ( 8 |
12 | {children} 13 |
14 | ); 15 | }; 16 | 17 | Sidebar.propTypes = { 18 | children: PropTypes.node, 19 | style: PropTypes.object, 20 | className: PropTypes.string, 21 | }; 22 | 23 | export default Sidebar; 24 | -------------------------------------------------------------------------------- /src/stories/NumberInput.stories.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { NumberInput } from ".."; 3 | import "./page.css"; 4 | 5 | const NumberInputObj = { 6 | title: "Design System/Components/NumberInput", 7 | component: NumberInput, 8 | }; 9 | 10 | export default NumberInputObj; 11 | 12 | const Template = ({ children, ...args }) => ; 13 | 14 | export const Basic = Template.bind({}); 15 | Basic.args = { 16 | id: "test-number-input", 17 | }; 18 | export const Error = Template.bind({}); 19 | Error.args = { 20 | id: "test-number-input2", 21 | error: "Value must be lass than 20", 22 | }; 23 | -------------------------------------------------------------------------------- /src/components/Dropdown/tests/__snapshots__/dropdown.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Dropdown component Matches snapshot 1`] = ` 4 |
12 |
17 | 20 | test 21 | 22 |
26 |
27 |
28 | `; 29 | -------------------------------------------------------------------------------- /src/components/Layout/Header.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import PropTypes from "prop-types"; 3 | import styles from "./styles.module.css"; 4 | import { classNames } from "../../utils"; 5 | 6 | const Header = ({ children, style, className, ...props }) => { 7 | return ( 8 |
12 | {children} 13 |
14 | ); 15 | }; 16 | 17 | Header.propTypes = { 18 | children: PropTypes.node.isRequired, 19 | style: PropTypes.object, 20 | className: PropTypes.string, 21 | }; 22 | 23 | export default Header; 24 | -------------------------------------------------------------------------------- /src/components/Layout/TopBanner.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import PropTypes from "prop-types"; 3 | import styles from "./styles.module.css"; 4 | import { classNames } from "../../utils"; 5 | 6 | const TopBanner = ({ children, style, className, ...props }) => { 7 | return ( 8 |
12 | {children} 13 |
14 | ); 15 | }; 16 | 17 | TopBanner.propTypes = { 18 | children: PropTypes.node, 19 | style: PropTypes.object, 20 | className: PropTypes.string, 21 | }; 22 | 23 | export default TopBanner; 24 | -------------------------------------------------------------------------------- /src/components/Layout/PageDetails.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import PropTypes from "prop-types"; 3 | import styles from "./styles.module.css"; 4 | import { classNames } from "../../utils"; 5 | 6 | const PageDetails = ({ children, style, className, ...props }) => { 7 | return ( 8 |
12 | {children} 13 |
14 | ); 15 | }; 16 | 17 | PageDetails.propTypes = { 18 | children: PropTypes.node, 19 | style: PropTypes.object, 20 | className: PropTypes.string, 21 | }; 22 | 23 | export default PageDetails; 24 | -------------------------------------------------------------------------------- /src/stories/Toggle.stories.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Toggle } from ".."; 3 | import "./page.css"; 4 | 5 | const ToggleObj = { 6 | title: "Design System/Components/Toggle", 7 | component: Toggle, 8 | }; 9 | 10 | export default ToggleObj; 11 | 12 | const Template = ({ children, ...args }) => ; 13 | 14 | export const Basic = Template.bind({}); 15 | Basic.args = { 16 | toggled: false, 17 | }; 18 | 19 | export const Toggled = Template.bind({}); 20 | Toggled.args = { 21 | toggled: true, 22 | }; 23 | 24 | export const Disabled = Template.bind({}); 25 | Disabled.args = { 26 | disabled: true, 27 | }; 28 | -------------------------------------------------------------------------------- /src/components/NumberInput/NumberInput.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import PropTypes from "prop-types"; 3 | import TextInput from "../TextInput/TextInput.jsx"; 4 | import styles from "./styles.module.css"; 5 | 6 | const NumberInput = ({ ...props }) => { 7 | return ( 8 | 15 | ); 16 | }; 17 | 18 | NumberInput.propTypes = { 19 | min: PropTypes.number, 20 | max: PropTypes.number, 21 | style: PropTypes.object, 22 | }; 23 | 24 | export default NumberInput; 25 | -------------------------------------------------------------------------------- /src/components/Layout/Main.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import PropTypes from "prop-types"; 3 | import styles from "./styles.module.css"; 4 | import { classNames } from "../../utils"; 5 | 6 | const Main = ({ children, style, className, fill, ...props }) => { 7 | return ( 8 |
12 | {children} 13 |
14 | ); 15 | }; 16 | 17 | Main.propTypes = { 18 | children: PropTypes.node, 19 | style: PropTypes.object, 20 | fill: PropTypes.bool, 21 | className: PropTypes.string, 22 | }; 23 | 24 | export default Main; 25 | -------------------------------------------------------------------------------- /src/components/Message/test/message.test.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Message from "../Message"; 3 | import { create } from "react-test-renderer"; 4 | import { 5 | defaultLightTheme, 6 | ThemeProvider, 7 | DEFAULT_LIGHT_THEME_NAME, 8 | } from "../../../theme"; 9 | 10 | describe("Message component", () => { 11 | test("Matches the snapshot", () => { 12 | const message = create( 13 | 16 | test 17 | 18 | ); 19 | expect(message.toJSON()).toMatchSnapshot(); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /src/components/StatusTag/time_yellow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/components/TextArea/test/textArea.test.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import TextArea from "../TextArea"; 3 | import { create } from "react-test-renderer"; 4 | import { 5 | defaultLightTheme, 6 | ThemeProvider, 7 | DEFAULT_LIGHT_THEME_NAME, 8 | } from "../../../theme"; 9 | 10 | describe("TextArea component", () => { 11 | test("Matches the snapshot", () => { 12 | const textArea = create( 13 | 16 |