Skip to content

Commit

Permalink
feat:#2616 elements v3 buttons (#3842)
Browse files Browse the repository at this point in the history
* WIP: buttons

* WIP: more updates to button component

* move getIntentClassname to helper file; rename intent from `cta` to `critical`

* add additional stories; use PT sans font explicitly

* add mdx story, fix test

* add loading state to button; add more states to the docs

* move v3 components to the bottom of the sidebar list
  • Loading branch information
jblok authored Mar 26, 2021
1 parent 3657f72 commit d330224
Show file tree
Hide file tree
Showing 14 changed files with 486 additions and 224 deletions.
34 changes: 9 additions & 25 deletions packages/elements/.storybook/main.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,9 @@
module.exports =
process.env.NODE_ENV === 'production'
? {
stories: [
'../src/components/**/*.stories.mdx',
'../src/components/**/*.stories.@(js|jsx|ts|tsx)',
'../src/utils/**/*.stories.mdx',
'../src/utils/**/*.stories.@(js|jsx|ts|tsx)',
],
addons: [
'@storybook/addon-links',
'@whitespace/storybook-addon-html',
'@storybook/addon-essentials',
'@storybook/addon-storysource/register',
],
}
: {
stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
addons: [
'@storybook/addon-links',
'@whitespace/storybook-addon-html',
'@storybook/addon-essentials',
'@storybook/addon-storysource/register',
],
}
module.exports = {
stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
addons: [
'@storybook/addon-links',
'@whitespace/storybook-addon-html',
'@storybook/addon-essentials',
'@storybook/addon-storysource/register',
],
}
3 changes: 3 additions & 0 deletions packages/elements/.storybook/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,7 @@ import '../src/styles-v3/base/variables.ts'

export const parameters = {
actions: { argTypesRegex: '^on[A-Z].*' },
options: {
storySort: { method: 'alphabetical' },
},
}
51 changes: 0 additions & 51 deletions packages/elements/src/components-v3/Button/__styles__/index.ts

This file was deleted.

218 changes: 218 additions & 0 deletions packages/elements/src/components-v3/Button/__styles__/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
import { css } from 'linaria'
import { styled } from 'linaria/react'
import {
elIntentPrimary,
elIntentSecondary,
elIntentCritical,
elIntentSuccess,
elIntentDanger,
} from '../../../styles-v3/base/intent'
import { elIsLoading } from '../../../styles-v3/base/states'
import {
intentPrimary,
intentSecondary,
intentCritical,
intentSuccess,
intentDanger,
} from '../../../styles-v3/base/variables'

const buttonXPadding = 1
const chevronLeft = (fill: string) =>
`data:image/svg+xml;utf8,<svg width="18" height="40" viewBox="0 0 18 40" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M24 0L9.79882 0C8.09608 0 6.57999 1.07793 6.02073 2.6862L0.456861 18.6862C0.160976 19.5371 0.160976 20.4629 0.456861 21.3138L6.02073 37.3138C6.57999 38.9221 8.09608 40 9.79882 40H24V0Z" fill="${encodeURIComponent(
fill,
)}"/></svg>`
const chevronRight = (fill: string) =>
`data:image/svg+xml;utf8,<svg width="18" height="40" viewBox="0 0 18 40" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0 0L8.8012 0C10.5501 0 13.0962 2.1362 12.6186 2.80527L17.6261 18.8053C17.8695 19.5832 17.8695 20.4168 17.6261 21.1947L12.6186 37.1947C12.0962 38.8638 10.5501 40 8.8012 40H0V0Z" fill="${encodeURIComponent(
fill,
)}"/></svg>`

export const ElButton = styled.button`
display: inline-block;
position: relative;
height: auto;
padding: 0.75rem ${buttonXPadding}rem;
justify-content: center;
text-align: center;
white-space: nowrap;
cursor: pointer;
border-radius: var(--default-border-radius);
border: none;
font-size: 1rem;
font-family: var(--font-sans-serif);
font-weight: bold;
color: var(--color-black-light, #363636);
background-color: unset;
background-image: linear-gradient(to right, var(--color-white), var(--color-white));
background-repeat: no-repeat;
&${elIntentPrimary} {
background-image: linear-gradient(to right, var(--intent-primary), var(--intent-primary));
color: var(--intent-primary-text);
}
&${elIntentSecondary} {
background-image: linear-gradient(to right, var(--intent-secondary), var(--intent-secondary));
color: var(--intent-secondary-text);
}
&${elIntentCritical} {
background-image: linear-gradient(to right, var(--intent-critical), var(--intent-critical));
color: var(--intent-critical-text);
}
&${elIntentSuccess} {
background-image: linear-gradient(to right, var(--intent-success), var(--intent-success));
color: var(--intent-success-text);
}
&${elIntentDanger} {
background-image: linear-gradient(to right, var(--intent-danger), var(--intent-danger));
color: var(--intent-danger-text);
}
&[disabled] {
opacity: 0.5;
}
&${elIsLoading} {
@keyframes spinAround {
from {
transform: rotate(0deg);
}
to {
transform: rotate(359deg);
}
}
color: transparent !important;
pointer-events: none;
&::after {
left: calc(50% - (1em / 2));
top: calc(50% - (1em / 2));
position: absolute;
animation: spinAround 500ms infinite linear;
border: 2px solid #dbdbdb;
border-radius: 290486px;
border-color: transparent transparent rgba(0, 0, 0, 0.7) rgba(0, 0, 0, 0.7);
content: '';
display: block;
height: 1rem;
width: 1rem;
}
&${elIntentPrimary}, &${elIntentSecondary}, &${elIntentCritical}, &${elIntentSuccess}, &${elIntentDanger} {
&::after {
border-color: transparent transparent #fff #fff;
}
}
}
`

export const elButtonHasLeftChevron = css`
background-size: calc(100% - 1rem);
background-position-x: right;
padding-left: ${buttonXPadding + 0.5}rem
&::before {
content: '';
position: absolute;
height: 100%;
width: 100%;
top: 0;
left: 0;
background-image: url('${chevronLeft('black')}');
background-size: contain;
background-repeat: no-repeat;
background-position: left;
}
&${elIntentPrimary} {
&::before {
background-image: url('${chevronLeft(intentPrimary)}');
}
}
&${elIntentSecondary} {
&::before {
background-image: url('${chevronLeft(intentSecondary)}');
}
}
&${elIntentCritical} {
&::before {
background-image: url('${chevronLeft(intentCritical)}');
}
}
&${elIntentSuccess} {
&::before {
background-image: url('${chevronLeft(intentSuccess)}');
}
}
&${elIntentDanger} {
&::before {
background-image: url('${chevronLeft(intentDanger)}');
}
}
`

export const elButtonHasRightChevron = css`
background-size: calc(100% - 1rem);
background-position-x: left;
padding-right: ${buttonXPadding + 0.5}rem;
&.${elButtonHasLeftChevron} {
background-size: calc(100% - 2rem);
background-position-x: center;
}
&::after {
content: '';
position: absolute;
height: 100%;
width: 100%;
top: 0;
right: 0;
background-image: url('${chevronRight('black')}');
background-size: contain;
background-repeat: no-repeat;
background-position: right;
}
&${elIntentPrimary} {
&::after {
background-image: url('${chevronRight(intentPrimary)}');
}
}
&${elIntentSecondary} {
&::after {
background-image: url('${chevronRight(intentSecondary)}');
}
}
&${elIntentCritical} {
&::after {
background-image: url('${chevronRight(intentCritical)}');
}
}
&${elIntentSuccess} {
&::after {
background-image: url('${chevronRight(intentSuccess)}');
}
}
&${elIntentDanger} {
&::after {
background-image: url('${chevronRight(intentDanger)}');
}
}
`
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Button should match a snapshot 1`] = `
<button
className="el-button el-intent-primary"
data-test="some-selector"
<ElButton
className="el-intent-primary"
disabled={false}
onClick={[MockFunction]}
type="submit"
>
button text
</button>
</ElButton>
`;
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import * as React from 'react'
import { shallow } from 'enzyme'
import { Button, ButtonProps } from '../index'
import { Button, IButton } from '../index'
import toJson from 'enzyme-to-json'

const props: ButtonProps = {
const props: IButton = {
type: 'submit',
intent: 'primary',
disabled: false,
loading: false,
fullWidth: false,
dataTest: 'some-selector',
onClick: jest.fn(),
}

Expand All @@ -20,8 +18,7 @@ describe('Button', () => {

it('should fire a click event correctly', () => {
const wrapper = shallow(<Button {...props}>button text</Button>)
wrapper.find('button').first().simulate('click')

wrapper.simulate('click')
expect(props.onClick).toHaveBeenCalledTimes(1)
})

Expand Down
Loading

0 comments on commit d330224

Please sign in to comment.