diff --git a/.gitignore b/.gitignore
index b7dab5e..e48f9b2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
node_modules
-build
\ No newline at end of file
+storybook-static
+build
+lib
\ No newline at end of file
diff --git a/.storybook/config.js b/.storybook/config.js
index 217f6a1..8083da9 100644
--- a/.storybook/config.js
+++ b/.storybook/config.js
@@ -1,13 +1,22 @@
+import React from 'react';
+import { ThemeProvider } from 'styled-components'
import { configure } from '@storybook/react';
import { setAddon, addDecorator } from '@storybook/react';
import JSXAddon from 'storybook-addon-jsx';
import { withInfo } from '@storybook/addon-info';
+import { Theme } from "../theme/index";
+
setAddon(JSXAddon);
addDecorator(withInfo);
+addDecorator(story => (
+
+ {story()}
+
+))
// automatically import all files ending in *.stories.js
-const req = require.context('../src', true, /.stories.js$/);
+const req = require.context('../src', true, /\.stories\.tsx$/);
function loadStories() {
req.keys().forEach(req);
}
diff --git a/.storybook/webpack.config.js b/.storybook/webpack.config.js
index 78e8a39..ffff379 100644
--- a/.storybook/webpack.config.js
+++ b/.storybook/webpack.config.js
@@ -5,8 +5,8 @@ const styledComponentsTransformer = createStyledComponentsTransformer();
module.exports = ({ config, mode }) => {
config.module.rules.push({
- test: /\.tsx?$/,
- include: path.resolve(__dirname, "../src"),
+ test: /\.(ts|tsx)$/,
+ include: [path.resolve(__dirname, "../src"), path.resolve(__dirname, "../theme")],
use: [
{
loader: require.resolve("awesome-typescript-loader"),
diff --git a/package-lock.json b/package-lock.json
index ce74ca8..7bbd4bb 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13,6 +13,123 @@
"@babel/highlight": "^7.0.0"
}
},
+ "@babel/core": {
+ "version": "7.4.3",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.4.3.tgz",
+ "integrity": "sha512-oDpASqKFlbspQfzAE7yaeTmdljSH2ADIvBlb0RwbStltTuWa0+7CCI1fYVINNv9saHPa1W7oaKeuNuKj+RQCvA==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.0.0",
+ "@babel/generator": "^7.4.0",
+ "@babel/helpers": "^7.4.3",
+ "@babel/parser": "^7.4.3",
+ "@babel/template": "^7.4.0",
+ "@babel/traverse": "^7.4.3",
+ "@babel/types": "^7.4.0",
+ "convert-source-map": "^1.1.0",
+ "debug": "^4.1.0",
+ "json5": "^2.1.0",
+ "lodash": "^4.17.11",
+ "resolve": "^1.3.2",
+ "semver": "^5.4.1",
+ "source-map": "^0.5.0"
+ },
+ "dependencies": {
+ "@babel/generator": {
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.0.tgz",
+ "integrity": "sha512-/v5I+a1jhGSKLgZDcmAUZ4K/VePi43eRkUs3yePW1HB1iANOD5tqJXwGSG4BZhSksP8J9ejSlwGeTiiOFZOrXQ==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.4.0",
+ "jsesc": "^2.5.1",
+ "lodash": "^4.17.11",
+ "source-map": "^0.5.0",
+ "trim-right": "^1.0.1"
+ }
+ },
+ "@babel/helper-split-export-declaration": {
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.0.tgz",
+ "integrity": "sha512-7Cuc6JZiYShaZnybDmfwhY4UYHzI6rlqhWjaIqbsJGsIqPimEYy5uh3akSRLMg65LSdSEnJ8a8/bWQN6u2oMGw==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.4.0"
+ }
+ },
+ "@babel/helpers": {
+ "version": "7.4.3",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.4.3.tgz",
+ "integrity": "sha512-BMh7X0oZqb36CfyhvtbSmcWc3GXocfxv3yNsAEuM0l+fAqSO22rQrUpijr3oE/10jCTrB6/0b9kzmG4VetCj8Q==",
+ "dev": true,
+ "requires": {
+ "@babel/template": "^7.4.0",
+ "@babel/traverse": "^7.4.3",
+ "@babel/types": "^7.4.0"
+ }
+ },
+ "@babel/parser": {
+ "version": "7.4.3",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.3.tgz",
+ "integrity": "sha512-gxpEUhTS1sGA63EGQGuA+WESPR/6tz6ng7tSHFCmaTJK/cGK8y37cBTspX+U2xCAue2IQVvF6Z0oigmjwD8YGQ==",
+ "dev": true
+ },
+ "@babel/template": {
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.0.tgz",
+ "integrity": "sha512-SOWwxxClTTh5NdbbYZ0BmaBVzxzTh2tO/TeLTbF6MO6EzVhHTnff8CdBXx3mEtazFBoysmEM6GU/wF+SuSx4Fw==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.0.0",
+ "@babel/parser": "^7.4.0",
+ "@babel/types": "^7.4.0"
+ }
+ },
+ "@babel/traverse": {
+ "version": "7.4.3",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.3.tgz",
+ "integrity": "sha512-HmA01qrtaCwwJWpSKpA948cBvU5BrmviAief/b3AVw936DtcdsTexlbyzNuDnthwhOQ37xshn7hvQaEQk7ISYQ==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.0.0",
+ "@babel/generator": "^7.4.0",
+ "@babel/helper-function-name": "^7.1.0",
+ "@babel/helper-split-export-declaration": "^7.4.0",
+ "@babel/parser": "^7.4.3",
+ "@babel/types": "^7.4.0",
+ "debug": "^4.1.0",
+ "globals": "^11.1.0",
+ "lodash": "^4.17.11"
+ }
+ },
+ "@babel/types": {
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.0.tgz",
+ "integrity": "sha512-aPvkXyU2SPOnztlgo8n9cEiXW755mgyvueUPcpStqdzoSPm0fjO0vQBjLkt3JKJW7ufikfcnMTTPsN1xaTsBPA==",
+ "dev": true,
+ "requires": {
+ "esutils": "^2.0.2",
+ "lodash": "^4.17.11",
+ "to-fast-properties": "^2.0.0"
+ }
+ },
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true
+ }
+ }
+ },
"@babel/generator": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.2.0.tgz",
@@ -2532,6 +2649,17 @@
"@types/react": "*"
}
},
+ "@types/rebass": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/rebass/-/rebass-3.0.3.tgz",
+ "integrity": "sha512-2/zZV9W7QVjEnJnrwy3TArzdSTVVhNFylWLcricMj5RfmglbM08etPgwelPP/I/UTHUEDjRAEkUYp7YzJt1vhQ==",
+ "dev": true,
+ "requires": {
+ "@types/react": "*",
+ "@types/styled-components": "*",
+ "@types/styled-system": "*"
+ }
+ },
"@types/storybook__react": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@types/storybook__react/-/storybook__react-4.0.1.tgz",
@@ -2553,6 +2681,15 @@
"csstype": "^2.2.0"
}
},
+ "@types/styled-system": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/@types/styled-system/-/styled-system-4.1.0.tgz",
+ "integrity": "sha512-3TSDL7LbpfGsCv7VZoqnKtHwYJZ/REVT6cfsw5e5vUyB+zymRgrOiJg78XOpXJgd722WrmONi+PYfnyJAMMhdw==",
+ "dev": true,
+ "requires": {
+ "csstype": "^2.2.0"
+ }
+ },
"@types/unist": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz",
@@ -12691,6 +12828,14 @@
"util.promisify": "^1.0.0"
}
},
+ "rebass": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/rebass/-/rebass-3.1.0.tgz",
+ "integrity": "sha512-FtmBb0bDT8q8HaGT4uAiJAQKZOdMsdonx6vp/cjnPc23FdMoo74ClTm0vJAwkWY1KzA0LCvmPbyGvWE0FFMR8w==",
+ "requires": {
+ "styled-system": "^4.0.8"
+ }
+ },
"recast": {
"version": "0.14.7",
"resolved": "https://registry.npmjs.org/recast/-/recast-0.14.7.tgz",
@@ -14200,6 +14345,45 @@
"supports-color": "^5.5.0"
}
},
+ "styled-system": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/styled-system/-/styled-system-4.1.0.tgz",
+ "integrity": "sha512-ioIAJ029tRr6eJhiUrE3VZeahN+GBuJHv/jmckkfikY4ej8BaxvIKAaavmjFoqzNsIzr+x5HCpry1ybQYpchtQ==",
+ "requires": {
+ "@babel/runtime": "^7.4.2",
+ "prop-types": "^15.7.2"
+ },
+ "dependencies": {
+ "@babel/runtime": {
+ "version": "7.4.3",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.3.tgz",
+ "integrity": "sha512-9lsJwJLxDh/T3Q3SZszfWOTkk3pHbkmH+3KY+zwIDmsNlxsumuhS2TH3NIpktU4kNvfzy+k3eLT7aTJSPTo0OA==",
+ "requires": {
+ "regenerator-runtime": "^0.13.2"
+ }
+ },
+ "prop-types": {
+ "version": "15.7.2",
+ "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
+ "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
+ "requires": {
+ "loose-envify": "^1.4.0",
+ "object-assign": "^4.1.1",
+ "react-is": "^16.8.1"
+ }
+ },
+ "react-is": {
+ "version": "16.8.6",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz",
+ "integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA=="
+ },
+ "regenerator-runtime": {
+ "version": "0.13.2",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz",
+ "integrity": "sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA=="
+ }
+ }
+ },
"stylis": {
"version": "3.5.4",
"resolved": "https://registry.npmjs.org/stylis/-/stylis-3.5.4.tgz",
diff --git a/package.json b/package.json
index 21636d1..64c1abc 100644
--- a/package.json
+++ b/package.json
@@ -4,6 +4,7 @@
"main": "index.js",
"license": "MIT",
"devDependencies": {
+ "@babel/core": "^7.4.3",
"@storybook/addon-actions": "^5.0.10",
"@storybook/addon-info": "^5.0.10",
"@storybook/addon-links": "^5.0.10",
@@ -11,6 +12,7 @@
"@storybook/react": "^5.0.10",
"@types/jest": "^23.3.10",
"@types/react-test-renderer": "^16.0.3",
+ "@types/rebass": "^3.0.3",
"@types/storybook__react": "^4.0.1",
"@types/styled-components": "^4.1.2",
"awesome-typescript-loader": "^5.2.1",
@@ -28,12 +30,13 @@
"dependencies": {
"react": "^16.6.3",
"react-dom": "^16.6.3",
+ "rebass": "^3.1.0",
"styled-components": "^4.1.2"
},
"scripts": {
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook",
- "check-types": "tsc",
+ "compile": "tsc",
"test": "jest"
}
-}
+}
\ No newline at end of file
diff --git a/src/button/__tests__/button.test.tsx b/src/button/__tests__/button.test.tsx
index 90476a1..a647c26 100644
--- a/src/button/__tests__/button.test.tsx
+++ b/src/button/__tests__/button.test.tsx
@@ -5,7 +5,9 @@ import { Button } from "../index";
describe("Button test suite", () => {
test("Snapshot test", () => {
- const tree = renderer.create().toJSON();
+ const tree = renderer
+ .create()
+ .toJSON();
expect(tree).toMatchSnapshot();
});
diff --git a/src/button/button.stories.js b/src/button/button.stories.js
deleted file mode 100644
index a972b77..0000000
--- a/src/button/button.stories.js
+++ /dev/null
@@ -1,18 +0,0 @@
-import * as React from "react";
-import { storiesOf } from "@storybook/react";
-
-import { Button } from "./index";
-
-const stories = storiesOf("Button", module);
-
-stories
- .add("with text", () => , {
- info: { inline: true }
- })
- .add(
- "with text disabled",
- () => ,
- {
- info: { inline: true }
- }
- );
diff --git a/src/button/button.stories.tsx b/src/button/button.stories.tsx
new file mode 100644
index 0000000..5f575b3
--- /dev/null
+++ b/src/button/button.stories.tsx
@@ -0,0 +1,29 @@
+import * as React from "react";
+import { storiesOf } from "@storybook/react";
+
+import { Button } from "./index";
+
+const stories = storiesOf("Button", module);
+
+stories
+ .add("Primary", () => , {
+ info: { inline: true }
+ })
+ .add(
+ "Secondary",
+ () => ,
+ {
+ info: { inline: true }
+ }
+ )
+ .add(
+ "Disabled",
+ () => (
+
+ ),
+ {
+ info: { inline: true }
+ }
+ );
diff --git a/src/button/index.tsx b/src/button/index.tsx
index 7fb12af..389b905 100644
--- a/src/button/index.tsx
+++ b/src/button/index.tsx
@@ -1,10 +1,5 @@
import * as React from "react";
-import styled from "styled-components";
-
-const StyledButton = styled.button`
- background-color: blue;
- font-size: 20px;
-`;
+import { Button as BaseButton } from "rebass";
export interface Props {
/** Children to be rendered. */
@@ -15,16 +10,25 @@ export interface Props {
* @default false
*/
isDisabled?: boolean;
+ /**
+ * Type of display that the button should be shown.
+ *
+ * @default primary
+ */
+ variant: string;
}
function Button(props: Props) {
return (
- {props.children}
+
+ {props.children}
+
);
}
Button.defaultProps = {
- isDisabled: false
+ isDisabled: false,
+ variant: "primary"
};
export { Button };
diff --git a/src/core/palette.stories.tsx b/src/core/palette.stories.tsx
new file mode 100644
index 0000000..8b1f429
--- /dev/null
+++ b/src/core/palette.stories.tsx
@@ -0,0 +1,61 @@
+import * as React from "react";
+import { Box, Flex, Text } from "rebass";
+import { storiesOf } from "@storybook/react";
+import styled from "styled-components";
+
+import { palette } from "../../theme/index";
+
+interface ItemProps {
+ bg: string;
+}
+
+const List = styled.ol`
+ list-style: none;
+ padding: 0;
+ margin: 0;
+`;
+
+const Item = styled.li`
+ display: inline-block;
+ margin: 10px;
+ border-radius: ${({ theme }) => `${theme.radii[0]}px`};
+ box-shadow: ${({ theme }) => theme.shadows.default};
+ overflow: hidden;
+
+ &:hover {
+ box-shadow: ${({ theme }) => theme.shadows.hover};
+ }
+`;
+
+const Color = styled.div`
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background-color: ${(props: ItemProps) => props.bg};
+ height: 175px;
+ width: 175px;
+`;
+
+function Palette() {
+ return (
+
+
+ {Object.keys(palette).map((key, index) => (
+ -
+
+
+ {palette[key]}
+ {key}
+
+
+ ))}
+
+
+ );
+}
+
+const stories = storiesOf("Core", module);
+
+stories.add("Palette", () => , {
+ info: { inline: true }
+});
diff --git a/theme/colors.ts b/theme/colors.ts
new file mode 100644
index 0000000..e5fb53a
--- /dev/null
+++ b/theme/colors.ts
@@ -0,0 +1,70 @@
+import { States, Variants } from "./constants";
+import { palette } from "./palette";
+
+interface ColorPalette {
+ [States.default]: string;
+ [States.hover]: string;
+ [States.pressed]: string;
+}
+
+interface BackgroundPalette {
+ [States.default]: string;
+ [States.hover]: string;
+ [States.disabled]: string;
+}
+
+interface TextPalette {
+ [Variants.primary]: string;
+ [Variants.secondary]: string;
+ [States.disabled]: string;
+ [States.pressed]: string;
+}
+
+interface Colors {
+ brand: string;
+ [Variants.primary]: ColorPalette;
+ [Variants.secondary]: ColorPalette;
+ success: string;
+ warning: string;
+ danger: string;
+ stroke: string;
+ background: BackgroundPalette;
+ text: TextPalette;
+ common: {
+ white: string;
+ };
+}
+
+const colors: Colors = {
+ brand: palette.BRAND_COLOR,
+ primary: {
+ default: palette.PRIMARY_COLOR,
+ hover: palette.PRIMARY_COLOR_HOVER,
+ pressed: palette.PRIMARY_COLOR_PRESSED
+ },
+ secondary: {
+ default: palette.SECONDARY_COLOR,
+ hover: palette.SECONDARY_COLOR_HOVER,
+ pressed: palette.SECONDARY_COLOR_PRESSED
+ },
+ success: palette.SUCCESS_COLOR,
+ warning: palette.WARNING_COLOR,
+ danger: palette.DANGER_COLOR,
+ stroke: palette.STROKE_LINE_COLOR,
+ background: {
+ default: palette.BACKGROUND_COLOR,
+ hover: palette.BACKGROUND_COLOR_HOVER,
+ disabled: palette.BACKGROUND_COLOR_DISABLED
+ },
+ text: {
+ primary: palette.PRIMARY_TEXT_COLOR,
+ secondary: palette.SECODARY_TEXT_COLOR,
+ disabled: palette.DISABLED_TEXT_COLOR,
+ pressed: palette.PRESSED_TEXT_COLOR
+ },
+ common: {
+ white: "#FFFFFF"
+ }
+};
+
+export { Colors, colors };
diff --git a/theme/constants.ts b/theme/constants.ts
new file mode 100644
index 0000000..a39bdd0
--- /dev/null
+++ b/theme/constants.ts
@@ -0,0 +1,29 @@
+enum States {
+ default = "default",
+ hover = "hover",
+ pressed = "pressed",
+ disabled = "disabled"
+}
+
+enum Sizes {
+ xs = "xs",
+ sm = "sm",
+ rg = "rg",
+ md = "md",
+ lg = "lg",
+ xl = "xl"
+}
+
+enum Headers {
+ subheader2 = "subheader2",
+ subheader = "subheader",
+ header = "header"
+}
+
+enum Variants {
+ primary = "primary",
+ secondary = "secondary",
+ inverse = "inverse"
+}
+
+export { States, Sizes, Headers, Variants };
diff --git a/theme/index.ts b/theme/index.ts
new file mode 100644
index 0000000..085eba3
--- /dev/null
+++ b/theme/index.ts
@@ -0,0 +1,5 @@
+import { States, Sizes, Variants, Headers } from "./constants";
+import { palette } from "./palette";
+import { Theme } from "./theme";
+
+export { Theme, States, Sizes, Variants, Headers, palette };
diff --git a/theme/palette.ts b/theme/palette.ts
new file mode 100644
index 0000000..f0fd3f2
--- /dev/null
+++ b/theme/palette.ts
@@ -0,0 +1,22 @@
+enum palette {
+ BRAND_COLOR = "#f73d56",
+ PRIMARY_COLOR = "#9c4fba",
+ PRIMARY_COLOR_HOVER = "#753085",
+ PRIMARY_COLOR_PRESSED = "#51215c",
+ SECONDARY_COLOR = "#36038c",
+ SECONDARY_COLOR_HOVER = "#2b0065",
+ SECONDARY_COLOR_PRESSED = "#1c0046",
+ BACKGROUND_COLOR = "#f3f5f8",
+ BACKGROUND_COLOR_HOVER = "#ebebff",
+ BACKGROUND_COLOR_DISABLED = "#cecece",
+ SUCCESS_COLOR = "#16d4af",
+ WARNING_COLOR = "#f0c241",
+ DANGER_COLOR = "#d0021b",
+ STROKE_LINE_COLOR = "#dadfe6",
+ PRIMARY_TEXT_COLOR = "#2a3037",
+ SECODARY_TEXT_COLOR = "#697280",
+ PRESSED_TEXT_COLOR = "#b2b2b2",
+ DISABLED_TEXT_COLOR = "#666666"
+}
+
+export { palette };
diff --git a/theme/shadows.ts b/theme/shadows.ts
new file mode 100644
index 0000000..0bfdb07
--- /dev/null
+++ b/theme/shadows.ts
@@ -0,0 +1,16 @@
+import { States } from "./constants";
+
+interface Shadows {
+ [States.default]: string;
+ [States.hover]: string;
+}
+
+const SHADOW_DEFAULT = "0px 1px 3px rgba(0, 0, 0, 0.07)";
+const SHADOW_HOVER = "0px 5px 10px rgba(0, 0, 0, 0.1)";
+
+const shadows: Shadows = {
+ default: SHADOW_DEFAULT,
+ hover: SHADOW_HOVER
+};
+
+export { Shadows, shadows };
diff --git a/theme/theme.ts b/theme/theme.ts
new file mode 100644
index 0000000..32abe53
--- /dev/null
+++ b/theme/theme.ts
@@ -0,0 +1,35 @@
+import { Colors, colors } from "./colors";
+import { Shadows, shadows } from "./shadows";
+import { space, radii } from "./units";
+import {
+ TypographyElement,
+ fontSizes,
+ lineHeights,
+ FontWeights,
+ fontWeights
+} from "./typography";
+import { Variant, buttons } from "./variants";
+
+interface BaseTheme {
+ colors: Colors;
+ shadows: Shadows;
+ fontSizes: TypographyElement;
+ fontWeights: FontWeights;
+ lineHeights: TypographyElement;
+ buttons: Variant;
+ space: number[];
+ radii: number[];
+}
+
+const Theme: BaseTheme = {
+ colors,
+ shadows,
+ fontSizes,
+ fontWeights,
+ lineHeights,
+ buttons,
+ space,
+ radii
+};
+
+export { Theme };
diff --git a/theme/typography.ts b/theme/typography.ts
new file mode 100644
index 0000000..ee21f2a
--- /dev/null
+++ b/theme/typography.ts
@@ -0,0 +1,56 @@
+import { Sizes, Headers } from "./constants";
+
+interface TypographyElement {
+ [Sizes.xs]: number;
+ [Sizes.sm]: number;
+ [Sizes.rg]: number;
+ [Sizes.md]: number;
+ [Sizes.lg]: number;
+ [Sizes.xl]: number;
+ [Headers.subheader2]?: number;
+ [Headers.subheader]?: number;
+ [Headers.header]?: number;
+}
+
+interface FontWeights {
+ lite: number;
+ normal: number;
+ bold: number;
+}
+
+// Line height scale
+const LINE_HEIGHTS_SCALE = [19, 23, 26, 32, 39, 49];
+
+// Line height scale object
+const lineHeights: TypographyElement = {
+ [Sizes.xs]: LINE_HEIGHTS_SCALE[0],
+ [Sizes.sm]: LINE_HEIGHTS_SCALE[1],
+ [Sizes.rg]: LINE_HEIGHTS_SCALE[2],
+ [Sizes.md]: LINE_HEIGHTS_SCALE[3],
+ [Sizes.lg]: LINE_HEIGHTS_SCALE[4],
+ [Sizes.xl]: LINE_HEIGHTS_SCALE[5]
+};
+
+// Font size scale
+const FONT_SIZES_SCALE = [12, 14, 16, 20, 24, 30, 36, 48, 60];
+
+// Font size scale object
+const fontSizes: TypographyElement = {
+ [Sizes.xs]: FONT_SIZES_SCALE[0],
+ [Sizes.sm]: FONT_SIZES_SCALE[1],
+ [Sizes.rg]: FONT_SIZES_SCALE[2],
+ [Sizes.md]: FONT_SIZES_SCALE[3],
+ [Sizes.lg]: FONT_SIZES_SCALE[4],
+ [Sizes.xl]: FONT_SIZES_SCALE[5],
+ [Headers.subheader2]: FONT_SIZES_SCALE[6],
+ [Headers.subheader]: FONT_SIZES_SCALE[7],
+ [Headers.header]: FONT_SIZES_SCALE[8]
+};
+
+const fontWeights: FontWeights = {
+ lite: 300,
+ normal: 400,
+ bold: 600
+};
+
+export { TypographyElement, fontSizes, lineHeights, FontWeights, fontWeights };
diff --git a/theme/units.ts b/theme/units.ts
new file mode 100644
index 0000000..6dc3149
--- /dev/null
+++ b/theme/units.ts
@@ -0,0 +1,4 @@
+const space = [5, 10, 15, 20, 25, 30, 40, 50, 60, 70, 80, 90, 100];
+const radii = [6];
+
+export { space, radii };
diff --git a/theme/variants.ts b/theme/variants.ts
new file mode 100644
index 0000000..70b978c
--- /dev/null
+++ b/theme/variants.ts
@@ -0,0 +1,72 @@
+import { Variants } from "./constants";
+import { colors } from "./colors";
+import { radii } from "./units";
+
+interface BaseButton {
+ backgroundColor: string;
+ color?: string;
+ borderColor?: string;
+}
+
+interface Button extends BaseButton {
+ borderRadius: number;
+ borderStyle: string;
+ borderWidth: number;
+ cursor?: string;
+ "&:disabled": BaseButton;
+ "&:hover"?: BaseButton;
+ "&:focus"?: BaseButton;
+ "&:active"?: BaseButton;
+}
+
+interface Variant {
+ [Variants.primary]: Button;
+ [Variants.secondary]: Button;
+}
+
+const { primary, secondary, background, text, common } = colors;
+const borderStyle: {
+ borderWidth: number;
+ borderStyle: string;
+} = {
+ borderWidth: 1,
+ borderStyle: "solid"
+};
+function getButtonStyle({ bg, color }: { bg: string; color: string }) {
+ return {
+ backgroundColor: bg,
+ borderColor: bg,
+ color: color
+ };
+}
+
+const disabled = {
+ ...getButtonStyle({ bg: background.disabled, color: text.disabled }),
+ ...borderStyle,
+ borderRadius: radii[0],
+ cursor: "not-allowed",
+ "&:hover": getButtonStyle({ bg: background.disabled, color: text.disabled })
+};
+
+const buttons: Variant = {
+ [Variants.primary]: {
+ ...getButtonStyle({ bg: primary.default, color: common.white }),
+ ...borderStyle,
+ borderRadius: radii[0],
+ "&:disabled": disabled,
+ "&:hover": getButtonStyle({ bg: primary.hover, color: common.white }),
+ "&:focus": getButtonStyle({ bg: primary.hover, color: common.white }),
+ "&:active": getButtonStyle({ bg: primary.pressed, color: text.pressed })
+ },
+ [Variants.secondary]: {
+ ...getButtonStyle({ bg: secondary.default, color: common.white }),
+ ...borderStyle,
+ borderRadius: radii[0],
+ "&:disabled": disabled,
+ "&:hover": getButtonStyle({ bg: secondary.hover, color: common.white }),
+ "&:focus": getButtonStyle({ bg: secondary.hover, color: common.white }),
+ "&:active": getButtonStyle({ bg: secondary.pressed, color: text.pressed })
+ }
+};
+
+export { Variant, buttons };
diff --git a/tsconfig.json b/tsconfig.json
index 46c52c2..0a79cc1 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,15 +1,14 @@
{
"compilerOptions": {
- "outDir": "build/lib",
+ "outDir": "lib",
"module": "commonjs",
"target": "es5",
"lib": ["es5", "es6", "es7", "es2017", "dom"],
"sourceMap": true,
"allowJs": false,
- "alwaysStrict": true,
"jsx": "react",
"moduleResolution": "node",
- "rootDir": "src",
+ "rootDirs": ["src", "theme"],
"baseUrl": "src",
"forceConsistentCasingInFileNames": true,
"noImplicitReturns": true,
@@ -23,6 +22,6 @@
"experimentalDecorators": true,
"emitDecoratorMetadata": true
},
- "include": ["src/**/*"],
+ "include": ["src/**/*", "theme"],
"exclude": ["node_modules", "build", "scripts"]
}
\ No newline at end of file