= (args) => {
+ args = {
+ ...defaultArgs,
+ ...args
+ } as ButtonProps
+
+ const colors: string[] = ['main0', 'main1', 'main2']
+ const kinds: ButtonKind[] = ['neon', 'flat']
+ const sizes: ButtonSize[] = ['big', 'regular']
+ const variants: ButtonVariant[] = ['primary', 'secondary', 'tertiary', 'text-only']
+
+ const col1 = (kinds.length * sizes.length * variants.length) - sizes.length
+ const col2 = (sizes.length * variants.length)
+ const col3 = (variants.length)
+
+ function Cell({ children, gc, gr, bg = false }: any) {
+ return ({children}
)
+ }
+
+
+ return (
+
+
+ |
+ Default |
+ Focus |
+ Active |
+ Hover |
+ Disable |
+
+ {colors.map((color) => {
+ return (
+ <>
+ {color} |
+ {kinds.map(kind => {
+ const isFlat = kind === 'flat'
+ const removeCols = isFlat ? sizes.length : 0
+
+ return (
+ <>
+ {kind} |
+ {sizes.map(size => {
+ const removeCols = isFlat ? 1 : 0
+
+ return (
+ <>
+ {size} |
+ {variants.map(variant => {
+ if (variant === 'tertiary' && isFlat) return null
+ const extraArgs = { ...args, kind, size, variant, color }
+ return (
+ <>
+ {variant} |
+ |
+ |
+ |
+ |
+ |
+ >
+ )
+ })}
+ >
+ )
+ })}
+ >
+ )
+ })}
+ >
+ )
+ })}
+
+
+ )
+};
+
+export const Catalog = CatalogTemplate.bind({})
+Catalog.args = {
+ ...defaultArgs
+};
+Catalog.parameters = {
+ ...defaultParams,
+ controls: { include: [], hideNoControlsWarning: true }
+}
\ No newline at end of file
diff --git a/src/components/Button/cmp.tsx b/src/components/Button/cmp.tsx
new file mode 100644
index 00000000..f026f5bc
--- /dev/null
+++ b/src/components/Button/cmp.tsx
@@ -0,0 +1,40 @@
+import React, { useMemo } from "react";
+import { StyledButton } from "./styles";
+import { ButtonProps } from "./types";
+
+export const Button = ({
+ variant = 'primary',
+ kind = 'flat',
+ size = 'regular',
+ color = 'main2',
+ label,
+ hover,
+ active,
+ focus,
+ disabled,
+}: ButtonProps) => {
+ // @note: Storybook testing purposes
+ const classes = useMemo(() => {
+ return [
+ hover ? '_hover' : '',
+ active ? '_active' : '',
+ focus ? '_focus' : ''
+ ].join(' ')
+ }, [hover, active, focus])
+
+ return (
+
+ {label}
+
+ );
+};
+
+export default Button;
diff --git a/src/components/Button/index.ts b/src/components/Button/index.ts
new file mode 100644
index 00000000..9954bcf1
--- /dev/null
+++ b/src/components/Button/index.ts
@@ -0,0 +1,2 @@
+export { default } from "./cmp";
+export { ButtonProps } from "./types";
\ No newline at end of file
diff --git a/src/components/Button/styles.tsx b/src/components/Button/styles.tsx
new file mode 100644
index 00000000..7f7fc77b
--- /dev/null
+++ b/src/components/Button/styles.tsx
@@ -0,0 +1,241 @@
+import styled, { css, DefaultTheme, FlattenSimpleInterpolation } from "styled-components"
+import { StyledButtonProps } from "./types"
+
+const colorGradient = (color: string) => `linear-gradient(0deg, ${color}, ${color})`
+
+const defaultVariants = (props: StyledButtonProps & { theme: DefaultTheme }) => {
+ const { theme, color, size, variant, kind } = props
+ const mainColor = theme.color[color] || color
+ const [g0, g1] = theme.gradient[color]?.colors || [color, color]
+ const glowMin = theme.effect.glow.min[color]
+
+ if (kind === 'flat') {
+ switch (variant) {
+ case 'primary': {
+ return css`
+ color: ${theme.color.background};
+ background-color: ${mainColor};
+
+ &::after {
+ display: none;
+ }
+ `
+ }
+ case 'secondary': {
+ return css`
+ &::after {
+ display: block;
+ }
+ `
+ }
+ case 'text-only': {
+ return css`
+ /* TRANSFORM BORDER INTO UNDERSCORE */
+ &::after {
+ display: block;
+ mask: none;
+ height: 1px;
+ padding: 0 22px;
+ background-clip: content-box;
+ top: 100%;
+ margin-top: -8px;
+ }
+ `
+ }
+ }
+ } else {
+ switch (variant) {
+ case 'primary': {
+ return css`
+ color: ${theme.color.background};
+ background-image: linear-gradient(90deg, ${g0} 0%, ${g1} 100%);
+
+ ${glowMin}
+
+ &::after {
+ display: none;
+ }
+ `
+ }
+ case 'secondary': {
+ return css`
+ &::after {
+ display: block;
+ background-image: linear-gradient(90deg, ${g0} 0%, ${g1} 100%);
+ }
+ `
+ }
+ case 'tertiary': {
+ return css`
+ background-image: linear-gradient(90deg, ${g0}1f 0%, ${g1}1f 100%);
+
+ &::after {
+ display: block;
+ background-image: linear-gradient(90deg, ${g0} 0%, ${g1} 100%);
+ }
+ `
+ }
+ case 'text-only': {
+ return css`
+ color: ${theme.color.text};
+ background-color: transparent;
+
+ /* TRANSFORM BORDER INTO UNDERSCORE */
+ &::after {
+ display: block;
+ mask: none;
+ height: 1px;
+ padding: 0 22px;
+ background-clip: content-box;
+ top: 100%;
+ margin-top: -8px;
+ }
+ `
+ }
+ }
+ }
+}
+
+const focusVariants = (props: StyledButtonProps & { theme: DefaultTheme }) => {
+ const { theme, variant } = props
+
+ return css`
+ &::after {
+ display: block;
+ background-image: none;
+ background-color: ${theme.color.text};
+ ${variant === 'text-only' ? 'height: 2px;' : 'padding: 2px;'}
+ }
+ `
+}
+
+const hoverVariants = (props: StyledButtonProps & { theme: DefaultTheme }) => {
+ return css`
+ `
+}
+
+const activeVariants = (props: StyledButtonProps & { theme: DefaultTheme }, defaultVariantsCss?: FlattenSimpleInterpolation) => {
+ const { variant } = props
+
+ return css`
+ ${defaultVariantsCss}
+ ${(variant === 'tertiary') ? `background-image: none;` : ''}
+ box-shadow: none;
+ backdrop-filter: none;
+ `
+}
+
+const disableVariants = (props: StyledButtonProps & { theme: DefaultTheme }) => {
+ const { theme } = props
+
+ return css`
+ cursor: not-allowed;
+ opacity: 0.4;
+ color: ${theme.color.text};
+ background-color: transparent;
+ background-image: none;
+ box-shadow: none;
+ backdrop-filter: none;
+
+ &::after {
+ background-color: ${theme.color.text};
+ background-image: none;
+ }
+ `
+}
+
+export const StyledButton = styled.button`
+ ${(props) => {
+ const { theme, color, size, variant, kind } = props
+ const mainColor = theme.color[color] || color
+
+ const defaultVariantsCss = defaultVariants(props)
+ const focusVariantsCss = focusVariants(props)
+ const hoverVariantsCss = hoverVariants(props)
+ const activeVariantsCss = activeVariants(props, defaultVariantsCss)
+ const disableVariantsCss = disableVariants(props)
+
+ return css`
+ position: relative;
+ cursor: pointer;
+ box-sizing: border-box;
+ /* display: inline-flex; inline-flex doesnt work with text-overflow */
+ display: inline-flex;
+ justify-content: center;
+ align-items: center;
+ text-align: center;
+ font-weight: 700;
+ margin: 0;
+ padding: 8px 22px;
+ width: auto;
+ min-width: 0;
+ max-width: 100%;
+ min-height: 1rem;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ border: none;
+ border-radius: 30px;
+ line-height: 1em;
+ background-color: transparent;
+ outline: 0;
+ color: ${theme.color.text};
+ transform: transale3d(0,0,0);
+
+ /* BORDER */
+ &::after {
+ display: none;
+ content: '';
+ position: absolute;
+ top: 0;
+ height: 100%;
+ width: 100%;
+ box-sizing: border-box;
+ background-color: ${mainColor};
+ z-index: 1;
+ padding: 1px;
+ border-radius: 30px;
+ mask:
+ linear-gradient(#fff 0 0) content-box,
+ linear-gradient(#fff 0 0);
+ mask-composite: exclude;
+ -webkit-mask-composite: xor;
+ }
+
+ /* DEFAULT VARIANT STYLES FOR EACH KIND */
+ ${defaultVariantsCss}
+
+ &:focus, &._focus {
+ ${focusVariantsCss}
+ }
+
+ &:hover, &._hover {
+ ${hoverVariantsCss}
+ }
+
+ &:active, &._active {
+ ${activeVariantsCss}
+ }
+
+ &[disabled] {
+ ${disableVariantsCss}
+ }
+
+ /* Size */
+ ${() => {
+ switch (size) {
+ case 'regular': {
+ return css`
+ font-size: ${theme.button.size.regular - (variant !== 'text-only' ? 0 : 0.25)}rem;
+ `
+ }
+ case 'big': {
+ return css`
+ font-size: ${theme.button.size.big - (variant !== 'text-only' ? 0 : 0.375)}rem;
+ `
+ }
+ }
+ }}
+ `
+ }}
+`
diff --git a/src/components/Button/types.ts b/src/components/Button/types.ts
new file mode 100644
index 00000000..9dc2147e
--- /dev/null
+++ b/src/components/Button/types.ts
@@ -0,0 +1,25 @@
+export type ButtonVariant = 'primary' | 'secondary' | 'tertiary' | 'text-only'
+export type ButtonKind = 'neon' | 'flat'
+export type ButtonSize = 'regular' | 'big'
+
+export type ButtonProps = {
+ label: string
+ variant: ButtonVariant
+ kind: ButtonKind
+ size: ButtonSize
+ color: string
+
+ // Force states
+ hover?: boolean
+ active?: boolean
+ focus?: boolean
+ disabled?: boolean
+}
+
+export type StyledButtonProps = {
+ variant: ButtonVariant
+ kind: ButtonKind
+ size: ButtonSize
+ color: string
+}
+
diff --git a/src/components/Icon/cmp.stories.tsx b/src/components/Icon/cmp.stories.tsx
new file mode 100644
index 00000000..216d4ec4
--- /dev/null
+++ b/src/components/Icon/cmp.stories.tsx
@@ -0,0 +1,44 @@
+import React from "react";
+import { ComponentStory, ComponentMeta } from "@storybook/react";
+import { withDesign } from 'storybook-addon-designs'
+import Icon from "./cmp";
+import { IconProps } from "./types";
+
+export default {
+ title: "Components/UI/Icon",
+ component: Icon,
+ decorators: [withDesign],
+ argTypes: {
+ size: {
+ options: ['xs', 'sm', 'md', 'lg', 'xl'],
+ control: { type: 'inline-radio' },
+ },
+ },
+
+} as ComponentMeta;
+
+const defaultArgs: Partial = {
+ name: 'bitcoin',
+ prefix: 'fab',
+ color: '#f7931a',
+ size: 'lg'
+}
+
+const defaultParams = {
+ design: {
+ type: 'figma',
+ url: 'https://www.figma.com/file/OXq1C8cPtY3JtmwmGfD23I/ALEPH-rebranding-UIKIT?t=RLzn6arl4QiCt5YB-0',
+ },
+}
+
+// ---
+
+const Template: ComponentStory = (args) => ;
+
+export const Default = Template.bind({});
+Default.args = {
+ ...defaultArgs,
+};
+Default.parameters = {
+ ...defaultParams,
+}
diff --git a/src/components/Icon/cmp.tsx b/src/components/Icon/cmp.tsx
new file mode 100644
index 00000000..49186dfc
--- /dev/null
+++ b/src/components/Icon/cmp.tsx
@@ -0,0 +1,32 @@
+import React from 'react';
+import { library, findIconDefinition, SizeProp } from '@fortawesome/fontawesome-svg-core'
+import { fas } from '@fortawesome/pro-solid-svg-icons'
+import { far } from '@fortawesome/pro-regular-svg-icons'
+import { fab } from '@fortawesome/free-brands-svg-icons'
+
+import { IconProps } from './types';
+import { StyledIcon } from './styles';
+
+// @todo: Think about it as we are including all the icons on the final bundle
+library.add(far, fas, fab)
+
+export const Icon = ({
+ name,
+ prefix = 'fas',
+ size = 'md',
+ ...rest
+}: IconProps) => {
+ let icon = findIconDefinition({ iconName: name, prefix })
+ icon = (!icon && prefix !== 'fab') ? findIconDefinition({ iconName: name, prefix: 'fab' }) : icon
+
+ return (
+
+ );
+};
+
+export default Icon;
diff --git a/src/components/Icon/index.ts b/src/components/Icon/index.ts
new file mode 100644
index 00000000..2dfc276c
--- /dev/null
+++ b/src/components/Icon/index.ts
@@ -0,0 +1,2 @@
+export { default } from "./cmp";
+export { IconProps } from "./types";
diff --git a/src/components/Icon/styles.tsx b/src/components/Icon/styles.tsx
new file mode 100644
index 00000000..d31bd7ca
--- /dev/null
+++ b/src/components/Icon/styles.tsx
@@ -0,0 +1,40 @@
+import styled, { css } from "styled-components"
+import { FontAwesomeIcon, FontAwesomeIconProps } from "@fortawesome/react-fontawesome"
+import { IconSize } from "./types"
+
+
+export interface StyledIconProps extends FontAwesomeIconProps {
+ $iconSize: IconSize
+}
+
+export const StyledIcon = styled(FontAwesomeIcon) `
+ ${({ $iconSize, theme }) => {
+ switch ($iconSize) {
+ case 'xs': {
+ return css`
+ font-size: ${theme.icon.size.xs}rem;
+ `
+ }
+ case 'sm': {
+ return css`
+ font-size: ${theme.icon.size.sm}rem;
+ `
+ }
+ case 'md': {
+ return css`
+ font-size: ${theme.icon.size.md}rem;
+ `
+ }
+ case 'lg': {
+ return css`
+ font-size: ${theme.icon.size.lg}rem;
+ `
+ }
+ case 'xl': {
+ return css`
+ font-size: ${theme.icon.size.xl}rem;
+ `
+ }
+ }
+ }}
+`
\ No newline at end of file
diff --git a/src/components/Icon/types.ts b/src/components/Icon/types.ts
new file mode 100644
index 00000000..f495c80d
--- /dev/null
+++ b/src/components/Icon/types.ts
@@ -0,0 +1,11 @@
+import { IconName } from '@fortawesome/fontawesome-svg-core'
+import { FontAwesomeIconProps } from '@fortawesome/react-fontawesome';
+
+export type IconPrefix = 'fas' | 'far' | 'fab'
+export type IconSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl'
+
+export interface IconProps extends Omit {
+ name: IconName
+ size?: IconSize
+ prefix?: IconPrefix
+}
diff --git a/src/components/index.ts b/src/components/index.ts
new file mode 100644
index 00000000..1fdf4382
--- /dev/null
+++ b/src/components/index.ts
@@ -0,0 +1 @@
+export { default as Button } from "./Button";
diff --git a/src/index.ts b/src/index.ts
new file mode 100644
index 00000000..1b18b5e5
--- /dev/null
+++ b/src/index.ts
@@ -0,0 +1,2 @@
+export * from './themes';
+export * from './components';
diff --git a/src/styles/global.ts b/src/styles/global.ts
new file mode 100644
index 00000000..a624524f
--- /dev/null
+++ b/src/styles/global.ts
@@ -0,0 +1,15 @@
+import { createGlobalStyle, css } from "styled-components";
+
+export const GlobalStyle = createGlobalStyle`
+ ${({ theme }) => {
+ return css`
+ @import "${theme.font.url}";
+
+ body {
+ font-family: ${theme.font.family.body};
+ color: ${theme.color.text};
+ }
+ `
+ }}
+`
+export default GlobalStyle
\ No newline at end of file
diff --git a/src/styles/index.ts b/src/styles/index.ts
new file mode 100644
index 00000000..aa59cacc
--- /dev/null
+++ b/src/styles/index.ts
@@ -0,0 +1 @@
+export * from './global'
\ No newline at end of file
diff --git a/src/styles/typo.ts b/src/styles/typo.ts
new file mode 100644
index 00000000..306baceb
--- /dev/null
+++ b/src/styles/typo.ts
@@ -0,0 +1,5 @@
+import { css } from "styled-components";
+
+export default css`
+ color: red
+`
\ No newline at end of file
diff --git a/src/themes/alephDark.ts b/src/themes/alephDark.ts
new file mode 100644
index 00000000..7cbae8a2
--- /dev/null
+++ b/src/themes/alephDark.ts
@@ -0,0 +1,20 @@
+import { DefaultTheme } from 'styled-components'
+import { default as base } from './base'
+
+export default {
+ ...base,
+
+ name: 'alephDark',
+
+ color: {
+ ...base.color,
+
+ primary: '#0054ff',
+ secondary: '#71c9fa',
+
+ background: '#172025',
+ contentBackground: '#1d2a31',
+ foreground: '#2e363b',
+ text: base.color.base2,
+ },
+} as DefaultTheme
\ No newline at end of file
diff --git a/src/themes/alephLight.ts b/src/themes/alephLight.ts
new file mode 100644
index 00000000..dde06f67
--- /dev/null
+++ b/src/themes/alephLight.ts
@@ -0,0 +1,20 @@
+import { DefaultTheme } from 'styled-components'
+import { default as base } from './base'
+
+export default {
+ ...base,
+
+ name: 'alephLight',
+
+ color: {
+ ...base.color,
+
+ primary: '#0054ff',
+ secondary: '#71c9fa',
+
+ background: '#ffffff',
+ contentBackground: '#f8f8f8',
+ foreground: '#ffffff',
+ text: base.color.base0,
+ },
+} as DefaultTheme
\ No newline at end of file
diff --git a/src/themes/base.ts b/src/themes/base.ts
new file mode 100644
index 00000000..8372ed93
--- /dev/null
+++ b/src/themes/base.ts
@@ -0,0 +1,246 @@
+import { css, DefaultTheme } from "styled-components"
+import { ThemeButton, ThemeColor, ThemeFont, ThemeGradient, ThemeIcon, ThemeTypo } from "./styles"
+
+const round = (n: number, precission: number) => {
+ const m = 10 ** precission
+ return Math.round((n * m) + Number.EPSILON) / m
+}
+
+const pxToRem = (px: number, base: number = 16) => {
+ return round(Number(px / base), 3)
+}
+
+const color: ThemeColor = {
+ base0: '#FFFFFF',
+ base1: '#141327',
+ base2: '#000000',
+
+ main0: '#029AFF',
+ main1: '#5CFFB1',
+ main2: '#FECD17',
+
+ success: '#7CFF79',
+ warn: '#FFD179',
+ error: '#D92446',
+
+ background: '#141327',
+ contentBackground: '#141327',
+ foreground: '#141327',
+ text: '#FFFFFF'
+}
+
+const gradient: ThemeGradient = {
+ main0: {
+ colors: ['#00D1FF', '#0054FF'],
+ stops: [0, 100],
+ deg: 90,
+ fn: 'linear-gradient(90deg, #00D1FF 0%, #0054FF 100%)'
+ },
+ main1: {
+ colors: ['#EEFF9C', '#00FFBD'],
+ stops: [0, 100],
+ deg: 90,
+ fn: 'linear-gradient(90deg, #EEFF9C 0%, #00FFBD 100%)'
+ },
+ main2: {
+ colors: ['#FFE814', '#FBAE18'],
+ stops: [0, 100],
+ deg: 90,
+ fn: 'linear-gradient(90deg, #FFE814 0%, #FBAE18 100%)'
+ },
+ extra0: {
+ colors: ['#9B41FF', '#0054FF'],
+ stops: [0, 100],
+ deg: 90,
+ fn: 'linear-gradient(90deg, #9B41FF 0%, #0054FF 100%)'
+ },
+ extra1: {
+ colors: ['#F17E4C', '#98203D'],
+ stops: [0, 100],
+ deg: 90,
+ fn: 'linear-gradient(90deg, #F17E4C 0%, #98203D 90.62%)'
+ }
+}
+
+// width: 192px;
+// height: 192px;
+/* box-shadow:
+ inset 0px -82px 68px -64px #4462904D,
+ inset 0px 7px 11px -4px #FFFFFFB2,
+ inset 0px 1px 40px 0px #DEEFFF33,
+ inset 0px 4px 18px 0px #92D2D24D,
+ 0px -18px 70px 26px #0054FF1C,
+ 24px 40px 92px 44px #0066FF4D; */
+
+// @note: Divided each px size by 192 to calculate factors
+function glowBoxShadow({ w, h, c }: { w: number, h: number, c: string[] }) {
+ const r = Math.max(w, h)
+ const s = Math.min(w, h)
+
+ return css`
+ box-shadow:
+ inset 0px -82px 68px -64px #4462904D,
+ inset 0px 7px 11px -4px #FFFFFFB2,
+ inset 0px 1px 40px 0px #DEEFFF33,
+ inset 0px 4px 18px 0px #92D2D24D,
+ 0 ${h * -0.09375}px ${r * 0.36458}px ${s * 0.13541}px ${c[0]},
+ ${w * 0.125}px ${h * 0.20833}px ${r * 0.47916}px ${s * 0.22916}px ${c[1]};
+ `
+}
+
+const effect = {
+ glow: {
+ min: {
+ main0: css`
+ ${glowBoxShadow({ w: 97, h: 44, c: ['#0054FF1C', '#0066FF4D'] })}
+ /* box-shadow:
+ inset 0px -82px 68px -64px #4462904D,
+ inset 0px 7px 11px -4px #FFFFFFB2,
+ inset 0px 1px 40px 0px #DEEFFF33,
+ inset 0px 4px 18px 0px #92D2D24D,
+ 0px -18px 70px 26px #0054FF1C,
+ 24px 40px 92px 44px #0066FF4D; */
+ `,
+ main1: css`
+ ${glowBoxShadow({ w: 97, h: 44, c: ['#00FFBD2E', '#00FFBD2E'] })}
+ /* box-shadow:
+ inset 0px -82px 68px -64px #4462904D,
+ inset 0px 7px 11px -4px #FFFFFF,
+ inset 0px 4px 18px 0px #92D2AF4D,
+ inset 0px 98px 100px -48px #00FFBD1A,
+ 0px -18px 50px 26px #00FFBD2E,
+ 34px 60px 102px 44px #00FFBD2E; */
+ `,
+ main2: css`
+ ${glowBoxShadow({ w: 97, h: 44, c: ['#FFC7002E', '#FF99002E'] })}
+ /* box-shadow:
+ inset 0px -82px 68px -64px #FFCC4933,
+ inset 0px 7px 11px -4px #FFFFFF,
+ inset 0px 1px 40px 0px #FFEEDE33,
+ inset 0px 4px 18px 0px #D2C4924D,
+ inset 0px 38px 70px -48px #FFF50014,
+ 0px -18px 60px 26px #FFC7002E,
+ 34px 60px 122px 44px #FF99002E; */
+ `
+ }
+ }
+}
+
+const font: ThemeFont = {
+ url: 'https://fonts.googleapis.com/css2?family=Public+Sans:ital,wght@0,400;1,400;1,700&family=Source+Code+Pro:wght@400;700&family=Rubik:ital,wght@0,500;1,800&display=swap',
+ family: {
+ head: '\'Rubik\', sans-serif',
+ body: '\'Public Sans\', sans-serif',
+ code: '\'Source Code Pro\', monospace',
+ },
+ size: {
+ // ---------
+ xl: pxToRem(28),
+ lg: pxToRem(24),
+ md: pxToRem(18),
+ sm: pxToRem(16),
+ xs: pxToRem(10),
+ // ---------
+ }
+}
+
+const commonHeaderFont = {
+ family: font.family.head,
+ style: 'italic',
+ weight: 800
+}
+
+const typo: ThemeTypo = {
+ h1: {
+ ...commonHeaderFont,
+ size: pxToRem(72),
+ },
+ h2: {
+ ...commonHeaderFont,
+ size: pxToRem(64),
+ },
+ h3: {
+ ...commonHeaderFont,
+ size: pxToRem(48),
+ },
+ h4: {
+ ...commonHeaderFont,
+ size: pxToRem(40),
+ },
+ h5: {
+ ...commonHeaderFont,
+ size: pxToRem(36),
+ },
+ h6: {
+ ...commonHeaderFont,
+ size: pxToRem(32),
+ },
+ h7: {
+ ...commonHeaderFont,
+ size: pxToRem(24),
+ },
+ header: {
+ ...commonHeaderFont,
+ size: pxToRem(128),
+ },
+ body: {
+ family: font.family.body,
+ style: 'normal',
+ weight: 400,
+ size: font.size.sm,
+ },
+ body2: {
+ family: font.family.body,
+ style: 'italic',
+ weight: 400,
+ size: font.size.sm,
+ },
+ body3: {
+ family: font.family.body,
+ style: 'italic',
+ weight: 700,
+ size: font.size.sm,
+ },
+ code: {
+ family: font.family.code,
+ style: 'normal',
+ weight: 400,
+ size: font.size.sm,
+ },
+ code2: {
+ family: font.family.code,
+ style: 'normal',
+ weight: 700,
+ size: font.size.sm,
+ },
+}
+
+const icon: ThemeIcon = {
+ size: {
+ xl: pxToRem(24),
+ lg: pxToRem(16),
+ md: pxToRem(14),
+ sm: pxToRem(12),
+ xs: pxToRem(8),
+ }
+}
+
+const button: ThemeButton = {
+ size: {
+ regular: pxToRem(18),
+ big: pxToRem(24),
+ }
+}
+
+const theme: DefaultTheme = {
+ name: 'Base',
+ color,
+ font,
+ typo,
+ icon,
+ button,
+ gradient,
+ effect
+}
+
+export default theme
diff --git a/src/themes/dark.ts b/src/themes/dark.ts
new file mode 100644
index 00000000..04e80d1d
--- /dev/null
+++ b/src/themes/dark.ts
@@ -0,0 +1,14 @@
+import { DefaultTheme } from 'styled-components'
+import { default as base } from './base'
+
+export default {
+ ...base,
+ name: 'dark',
+ color: {
+ ...base.color,
+ background: base.color.base1,
+ contentBackground: base.color.base1,
+ foreground: base.color.base1,
+ text: base.color.base0,
+ },
+} as DefaultTheme
\ No newline at end of file
diff --git a/src/themes/index.ts b/src/themes/index.ts
new file mode 100644
index 00000000..391ac114
--- /dev/null
+++ b/src/themes/index.ts
@@ -0,0 +1,21 @@
+import { default as light } from './light'
+import { default as dark } from './dark'
+import { default as alephLight } from './alephLight'
+import { default as alephDark } from './alephDark'
+
+export const themes = {
+ dark,
+ light,
+ alephDark,
+ alephLight,
+}
+
+// @note: sorted list for storybook UI
+export const themeList = [
+ dark,
+ light,
+ alephDark,
+ alephLight,
+]
+
+export { CoreTheme } from './styles'
\ No newline at end of file
diff --git a/src/themes/light.ts b/src/themes/light.ts
new file mode 100644
index 00000000..a7f80d28
--- /dev/null
+++ b/src/themes/light.ts
@@ -0,0 +1,14 @@
+import { DefaultTheme } from 'styled-components'
+import { default as base } from './base'
+
+export default {
+ ...base,
+ name: 'light',
+ color: {
+ ...base.color,
+ background: base.color.base0,
+ contentBackground: base.color.base0,
+ foreground: base.color.base0,
+ text: base.color.base1,
+ },
+} as DefaultTheme
\ No newline at end of file
diff --git a/src/themes/styled.d.ts b/src/themes/styled.d.ts
new file mode 100644
index 00000000..0c52ee56
--- /dev/null
+++ b/src/themes/styled.d.ts
@@ -0,0 +1,6 @@
+import 'styled-components';
+import { CoreTheme } from './styles'
+
+declare module 'styled-components' {
+ export interface DefaultTheme extends CoreTheme {}
+}
\ No newline at end of file
diff --git a/src/themes/styles.ts b/src/themes/styles.ts
new file mode 100644
index 00000000..db868230
--- /dev/null
+++ b/src/themes/styles.ts
@@ -0,0 +1,95 @@
+export type TypoSizeKind = 'xs' | 'sm' | 'md' | 'lg' | 'xl'
+export type TypoSize = Record
+
+export type TypoKind = 'header' | 'body' | 'body2' | 'body3' | 'code' | 'code2' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'h7'
+export type Typo = {
+ size: number,
+ family: string
+ weight: number
+ style: string
+}
+export type ThemeTypo = Record
+
+export type Gradient = {
+ colors: string[]
+ stops: number[]
+ deg: number
+ fn: string
+}
+export type ThemeGradient = {
+ [k: string]: Gradient
+
+ main0: Gradient
+ main1: Gradient
+ main2: Gradient
+
+ extra0: Gradient
+ extra1: Gradient
+}
+
+export type ThemeColor = {
+ [k: string]: string
+
+ base0: string
+ base1: string
+ base2: string
+
+ main0: string
+ main1: string
+ main2: string
+
+ success: string
+ warn: string
+ error: string
+
+ background: string
+ contentBackground: string
+ foreground: string
+ text: string
+}
+
+export type ThemeFont = {
+ url: string
+ size: {
+ xl: number
+ lg: number
+ md: number
+ sm: number
+ xs: number
+ }
+ family: {
+ head: string
+ body: string
+ code: string
+ }
+}
+
+export type ThemeButton = {
+ size: {
+ regular: number
+ big: number
+ }
+}
+
+export type ThemeIcon = {
+ size: {
+ xl: number
+ lg: number
+ md: number
+ sm: number
+ xs: number
+ }
+}
+
+export interface CoreTheme {
+ name: string
+ // palette: Record
+ font: ThemeFont
+ color: ThemeColor,
+ typo: ThemeTypo
+ icon: ThemeIcon
+ button: ThemeButton
+ gradient: ThemeGradient
+ effect: any
+}
+
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 00000000..c9a814b5
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,95 @@
+{
+ "compilerOptions": {
+ /* Visit https://aka.ms/tsconfig to read more about this file */
+ /* Projects */
+ // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
+ // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
+ // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
+ // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
+ // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
+ // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
+ /* Language and Environment */
+ "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
+ // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
+ "jsx": "react", /* Specify what JSX code is generated. */
+ // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
+ // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
+ // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
+ // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
+ // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
+ // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
+ // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
+ // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
+ // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
+ /* Modules */
+ "module": "ESNext", /* Specify what module code is generated. */
+ // "rootDir": "./", /* Specify the root folder within your source files. */
+ "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
+ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
+ // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
+ // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
+ // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
+ // "types": [], /* Specify type package names to be included without being referenced in a source file. */
+ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
+ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
+ // "resolveJsonModule": true, /* Enable importing .json files. */
+ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */
+ /* JavaScript Support */
+ // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
+ // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
+ // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
+ /* Emit */
+ "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
+ // "declarationMap": true, /* Create sourcemaps for d.ts files. */
+ "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
+ "sourceMap": true, /* Create source map files for emitted JavaScript files. */
+ // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
+ "outDir": "dist", /* Specify an output folder for all emitted files. */
+ // "removeComments": true, /* Disable emitting comments. */
+ // "noEmit": true, /* Disable emitting files from a compilation. */
+ // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
+ // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
+ // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
+ // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
+ // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
+ // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
+ // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
+ // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
+ // "newLine": "crlf", /* Set the newline character for emitting files. */
+ // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
+ // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
+ // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
+ // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
+ "declarationDir": "types", /* Specify the output directory for generated declaration files. */
+ // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
+ /* Interop Constraints */
+ // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
+ "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
+ "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
+ // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
+ "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
+ /* Type Checking */
+ "strict": true, /* Enable all strict type-checking options. */
+ // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
+ // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
+ // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
+ // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
+ // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
+ // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
+ // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
+ // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
+ // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
+ // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
+ // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
+ // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
+ // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
+ // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
+ // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
+ // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
+ // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
+ // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
+ /* Completeness */
+ // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
+ "skipLibCheck": true /* Skip type checking all .d.ts files. */
+ }
+}
\ No newline at end of file