Skip to content

Commit

Permalink
feat(elements): add Button (#86)
Browse files Browse the repository at this point in the history
  • Loading branch information
ivangabriele committed Dec 1, 2022
1 parent 8d92d2d commit 00b2e10
Show file tree
Hide file tree
Showing 25 changed files with 738 additions and 10 deletions.
10 changes: 6 additions & 4 deletions .storybook/preview.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import { StrictMode } from 'react'
import { createGlobalStyle, ThemeProvider } from 'styled-components'

import { THEME } from '../src/theme'
import { GlobalStyle, THEME } from '../src'

import type { ComponentStory } from '@storybook/react'
// import type { ComponentAnnotations } from '@storybook/csf'

import 'rsuite/dist/rsuite.min.css'
import '../src/assets/rsuite-override.css'
import '../src/assets/stylesheets/rsuite-override.css'

const UntypedGlobalStyle = GlobalStyle as any
const UntypedThemeProvider = ThemeProvider as any

const GlobalStyle: any = createGlobalStyle<{
const CustomGlobalStyle: any = createGlobalStyle<{
isFullWidth: boolean | undefined
}>`
p {
Expand All @@ -30,7 +31,8 @@ export const decorators = [
return (
<StrictMode>
<UntypedThemeProvider theme={THEME}>
<GlobalStyle isFullWidth={isFullWidth} />
<UntypedGlobalStyle />
<CustomGlobalStyle isFullWidth={isFullWidth} />

<Story />
</UntypedThemeProvider>
Expand Down
Binary file not shown.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"@rollup/plugin-node-resolve": "15.0.0",
"@rollup/plugin-replace": "5.0.1",
"@rollup/plugin-typescript": "10.0.1",
"@rollup/plugin-url": "8.0.1",
"@semantic-release/changelog": "6.0.2",
"@semantic-release/commit-analyzer": "9.0.2",
"@semantic-release/exec": "6.0.3",
Expand Down Expand Up @@ -105,6 +106,7 @@
"react-dom": "18.2.0",
"react-is": "18.2.0",
"rollup": "2.79.1",
"rollup-plugin-bundle-size": "1.0.3",
"rollup-plugin-peer-deps-external": "2.2.4",
"rollup-plugin-postcss": "4.0.2",
"rollup-plugin-sizes": "1.0.4",
Expand Down
8 changes: 7 additions & 1 deletion rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import commonjs from '@rollup/plugin-commonjs'
import { nodeResolve } from '@rollup/plugin-node-resolve'
import typescript from '@rollup/plugin-typescript'
import peerDepsExternal from 'rollup-plugin-peer-deps-external'
import url from '@rollup/plugin-url'

module.exports = {
external: [],
Expand All @@ -19,8 +20,13 @@ module.exports = {

plugins: [
peerDepsExternal(),
url({
destDir: './dist/assets/fonts',
include: ['**/*.woff2'],
limit: 0
}),
nodeResolve({
extensions: ['css', '.js', 'json', '.jsx', '.ts', '.tson', '.tsx', 'woff', 'woff2'],
extensions: ['css', '.js', 'json', '.jsx', '.ts', '.tson', '.tsx'],
ignoreSideEffectsForRoot: true
}),
// Convert CommonJS to ES6:
Expand Down
2 changes: 1 addition & 1 deletion scripts/build/copyPublicFiles.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/bash

cp -R ./src/assets ./dist
cp -R ./src/assets/stylesheets ./dist/assets

cp ./CHANGELOG.md ./dist/CHANGELOG.md
cp ./LICENSE ./dist/LICENSE
Expand Down
78 changes: 78 additions & 0 deletions src/GlobalStyle.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { createGlobalStyle } from 'styled-components'

// @ts-ignore
import MarianneBold from './assets/fonts/Marianne-Bold.woff2'
// @ts-ignore
import MarianneBoldItalic from './assets/fonts/Marianne-Bold_Italic.woff2'
// @ts-ignore
import MarianneLight from './assets/fonts/Marianne-Light.woff2'
// @ts-ignore
import MarianneLightItalic from './assets/fonts/Marianne-Light_Italic.woff2'
// @ts-ignore
import MarianneMedium from './assets/fonts/Marianne-Medium.woff2'
// @ts-ignore
import MarianneMediumItalic from './assets/fonts/Marianne-Medium_Italic.woff2'
// @ts-ignore
import MarianneRegular from './assets/fonts/Marianne-Regular.woff2'
// @ts-ignore
import MarianneItalic from './assets/fonts/Marianne-Regular_Italic.woff2'

export const GlobalStyle = createGlobalStyle`
@font-face {
font-family: Marianne;
src: local('Marianne'), local('Marianne-Regular'), url(${MarianneRegular}) format('woff2');
font-weight: normal;
}
@font-face {
font-family: Marianne;
src: local('Marianne-Thin'), url(${MarianneLight}) format('woff2');
font-weight: 300;
}
@font-face {
font-family: Marianne;
src:local('Marianne-Medium'), url(${MarianneMedium}) format('woff2');
font-weight: 500;
}
@font-face {
font-family: Marianne;
src: local('Marianne-Medium_Italic'), url(${MarianneMediumItalic}) format('woff2');
font-weight: 500;
font-style: italic;
}
@font-face {
font-family: Marianne;
src: local('Marianne-Thin_Italic'), url(${MarianneLightItalic}) format('woff2');
font-weight: lighter;
font-style: italic;
}
@font-face {
font-family: Marianne;
src:local('Marianne-Regular_Italic'), url(${MarianneItalic}) format('woff2');
font-weight: normal;
font-style: italic;
}
@font-face {
font-family: Marianne;
src: local('Marianne-Bold'), url(${MarianneBold}) format('woff2');
font-weight: 700;
}
@font-face {
font-family: Marianne;
src: local('Marianne-Bold_Italic'), url(${MarianneBoldItalic}) format('woff2');
font-style: italic;
font-weight: 700;
}
body {
font-family: Marianne, sans-serif;
font-size: 16px;
line-height: 1.4;
}
`
Binary file added src/assets/fonts/Marianne-Bold.woff2
Binary file not shown.
Binary file added src/assets/fonts/Marianne-Bold_Italic.woff2
Binary file not shown.
Binary file added src/assets/fonts/Marianne-Light.woff2
Binary file not shown.
Binary file added src/assets/fonts/Marianne-Light_Italic.woff2
Binary file not shown.
Binary file added src/assets/fonts/Marianne-Medium.woff2
Binary file not shown.
Binary file added src/assets/fonts/Marianne-Medium_Italic.woff2
Binary file not shown.
Binary file added src/assets/fonts/Marianne-Regular.woff2
Binary file not shown.
Binary file added src/assets/fonts/Marianne-Regular_Italic.woff2
Binary file not shown.
File renamed without changes.
11 changes: 11 additions & 0 deletions src/contants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export enum Accent {
PRIMARY = 'PRIMARY',
SECONDARY = 'SECONDARY',
TERTIARY = 'TERTIARY'
}

export enum Size {
LARGE = 'LARGE',
NORMAL = 'NORMAL',
SMALL = 'SMALL'
}
170 changes: 170 additions & 0 deletions src/elements/Button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
import { useMemo } from 'react'
import styled from 'styled-components'

import { Accent, Size } from '../contants'

import type { IconProps } from '../types'
import type { ButtonHTMLAttributes, FunctionComponent } from 'react'

const ICON_SIZE: Record<Size, number> = {
[Size.LARGE]: 1.25,
[Size.NORMAL]: 1.25,
[Size.SMALL]: 0.75
}

export type ButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
Icon?: FunctionComponent<IconProps>
accent?: Accent
isFullWidth?: boolean
size?: Size
}
export function Button({
accent = Accent.PRIMARY,
children,
Icon,
isFullWidth = false,
size = Size.NORMAL,
type = 'button',
...nativeProps
}: ButtonProps) {
const commonChildren = useMemo(
() => (
<>
{Icon && <Icon size={ICON_SIZE[size]} />}
{children}
</>
),
[children, Icon, size]
)
const commonProps = useMemo(
() => ({
children: commonChildren,
isFullWidth,
size,
type,
...nativeProps
}),
[commonChildren, isFullWidth, nativeProps, size, type]
)

switch (accent) {
case Accent.SECONDARY:
return <SecondaryButton {...commonProps} />

case Accent.TERTIARY:
return <TertiaryButton {...commonProps} />

default:
return <PrimaryButton {...commonProps} />
}
}

const FONT_SIZE: Record<Size, string> = {
[Size.LARGE]: '13px',
[Size.NORMAL]: '13px',
[Size.SMALL]: '11px'
}
const PADDING: Record<Size, string> = {
[Size.LARGE]: '6px 12px',
[Size.NORMAL]: '6px 12px',
[Size.SMALL]: '5px 8px 4px'
}

const StyledButton = styled.button<{
isFullWidth: boolean
size: Size
}>`
align-items: center;
display: flex;
font-size: ${p => FONT_SIZE[p.size]};
justify-content: center;
padding: ${p => PADDING[p.size]};
white-space: nowrap;
width: ${p => (p.isFullWidth ? '100%' : 'auto')};
/* SVG Icon Components are wrapped within a <div /> */
> div {
margin-right: 5px;
}
`

const PrimaryButton = styled(StyledButton)`
background-color: ${p => p.theme.color.charcoal};
border: 1px solid ${p => p.theme.color.charcoal};
color: ${p => p.theme.color.gainsboro};
:hover,
&._hover {
background-color: ${p => p.theme.color.blueYonder['100']};
border: 1px solid ${p => p.theme.color.blueYonder['100']};
color: ${p => p.theme.color.white};
}
:active,
&._active {
background-color: ${p => p.theme.color.blueGray['100']};
border: 1px solid ${p => p.theme.color.blueGray['100']};
color: ${p => p.theme.color.white};
}
:disabled,
&._disabled {
background-color: ${p => p.theme.color.lightGray};
border: 1px solid ${p => p.theme.color.lightGray};
color: ${p => p.theme.color.cultured};
}
`

const SecondaryButton = styled(StyledButton)`
background-color: ${p => p.theme.color.white};
border: 1px solid ${p => p.theme.color.charcoal};
color: ${p => p.theme.color.charcoal};
:hover,
&._hover {
background-color: ${p => p.theme.color.blueYonder['25']};
border: 1px solid ${p => p.theme.color.blueYonder['100']};
color: ${p => p.theme.color.blueYonder['100']};
}
:active,
&._active {
background-color: ${p => p.theme.color.blueGray['25']};
border: 1px solid ${p => p.theme.color.blueGray['100']};
color: ${p => p.theme.color.blueGray['100']};
}
:disabled,
&._disabled {
background-color: ${p => p.theme.color.white};
border: 1px solid ${p => p.theme.color.lightGray};
color: ${p => p.theme.color.lightGray};
}
`

const TertiaryButton = styled(StyledButton)`
background-color: ${p => p.theme.color.white};
border: 1px solid ${p => p.theme.color.white};
color: ${p => p.theme.color.gainsboro};
:hover,
&._hover {
background-color: ${p => p.theme.color.blueYonder['25']};
border: 1px solid ${p => p.theme.color.blueYonder['25']};
color: ${p => p.theme.color.blueYonder['100']};
}
:active,
&._active {
background-color: ${p => p.theme.color.blueGray['25']};
border: 1px solid ${p => p.theme.color.blueGray['100']};
color: ${p => p.theme.color.blueGray['100']};
}
:disabled,
&._disabled {
background-color: ${p => p.theme.color.white};
border: 1px solid ${p => p.theme.color.lightGray};
color: ${p => p.theme.color.lightGray};
}
`
1 change: 1 addition & 0 deletions src/elements/IconBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export const IconBox = styled.div<IconBoxProps>`
color: ${p => p.color ?? 'inherit'};
> svg {
display: block;
height: ${p => p.size ?? 1}rem;
width: ${p => p.size ?? 1}rem;
}
Expand Down
10 changes: 7 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
export { GlobalStyle } from './GlobalStyle'
export { THEME } from './theme'
export { ThemeProvider } from './ThemeProvider'

export * as Icon from './icons'

export { Button } from './elements/Button'
export { Field } from './elements/Field'
export { Fieldset } from './elements/Fieldset'
export { Label } from './elements/Label'
Expand All @@ -28,12 +29,15 @@ export { FormikSelect } from './formiks/FormikSelect'
export { FormikTextarea } from './formiks/FormikTextarea'
export { FormikTextInput } from './formiks/FormikTextInput'

export { ThemeProvider } from './ThemeProvider'
export * as Icon from './icons'

export { Accent, Size } from './contants'

export type { DateRange, IconProps, Option } from './types'

export type { PartialTheme, Theme } from './theme'

export type { ButtonProps } from './elements/Button'
export type { FieldProps } from './elements/Field'
export type { FieldsetProps } from './elements/Fieldset'
export type { LabelProps } from './elements/Label'
Expand Down
9 changes: 9 additions & 0 deletions stories/_components/Showcase/Subtitle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import styled from 'styled-components'

export const Subtitle = styled.h3`
color: ${p => p.theme.color.gunMetal};
font-size: 13px;
font-weight: bold;
margin: 0;
text-transform: uppercase;
`
Loading

0 comments on commit 00b2e10

Please sign in to comment.