-
Notifications
You must be signed in to change notification settings - Fork 333
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #179 from unix/button
feat(button): support to display icons in button
- Loading branch information
Showing
11 changed files
with
432 additions
and
30 deletions.
There are no files selected for viewing
189 changes: 189 additions & 0 deletions
189
components/button/__tests__/__snapshots__/icon.test.tsx.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`ButtonIcon should render correctly 1`] = ` | ||
"<button class=\\"btn \\"><span class=\\"icon \\"><svg></svg><style> | ||
.icon { | ||
position: absolute; | ||
left: var(--zeit-ui-button-padding); | ||
right: auto; | ||
top: 50%; | ||
transform: translateY(-50%); | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
color: var(--zeit-ui-button-color); | ||
z-index: 1; | ||
} | ||
.right { | ||
right: var(--zeit-ui-button-padding); | ||
left: auto; | ||
} | ||
.icon :global(svg) { | ||
background: transparent; | ||
height: calc(var(--zeit-ui-button-height) / 2.35); | ||
width: calc(var(--zeit-ui-button-height) / 2.35); | ||
} | ||
</style></span><div class=\\"text left\\">action<style> | ||
.left { | ||
padding-left: 0; | ||
} | ||
.right { | ||
padding-right: 0; | ||
} | ||
</style></div><style> | ||
.btn { | ||
box-sizing: border-box; | ||
display: inline-block; | ||
padding: 0 1.375rem; | ||
height: 2.5rem; | ||
line-height: 2.5rem; | ||
min-width: 12.5rem; | ||
width: auto; | ||
border-radius: 5px; | ||
font-weight: 400; | ||
font-size: .875rem; | ||
user-select: none; | ||
outline: none; | ||
text-transform: capitalize; | ||
justify-content: center; | ||
text-align: center; | ||
white-space: nowrap; | ||
transition: all 0.2s ease 0s; | ||
position: relative; | ||
overflow: hidden; | ||
color: #666; | ||
background-color: #fff; | ||
border: 1px solid #eaeaea; | ||
cursor: pointer; | ||
pointer-events: auto; | ||
box-shadow: none; | ||
--zeit-ui-button-padding: 1.375rem; | ||
--zeit-ui-button-height: 2.5rem; | ||
--zeit-ui-button-color: #666; | ||
} | ||
.btn:hover { | ||
color: #000; | ||
--zeit-ui-button-color: #000; | ||
background-color: #fff; | ||
border-color: #000; | ||
cursor: pointer; | ||
pointer-events: auto; | ||
box-shadow: none; | ||
transform: translate3d(0px, 0px, 0px); | ||
} | ||
.btn :global(.text) { | ||
position: relative; | ||
z-index: 1; | ||
display: inline-flex; | ||
justify-content: center; | ||
align-items: center; | ||
text-align: center; | ||
line-height: inherit; | ||
top: -1px; | ||
} | ||
.btn :global(.text p), | ||
.btn :global(.text pre), | ||
.btn :global(.text div) { | ||
margin: 0; | ||
} | ||
</style></button>" | ||
`; | ||
exports[`ButtonIcon should work with right 1`] = ` | ||
"<button class=\\"btn \\"><span class=\\"icon right \\"><svg></svg><style> | ||
.icon { | ||
position: absolute; | ||
left: var(--zeit-ui-button-padding); | ||
right: auto; | ||
top: 50%; | ||
transform: translateY(-50%); | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
color: var(--zeit-ui-button-color); | ||
z-index: 1; | ||
} | ||
.right { | ||
right: var(--zeit-ui-button-padding); | ||
left: auto; | ||
} | ||
.icon :global(svg) { | ||
background: transparent; | ||
height: calc(var(--zeit-ui-button-height) / 2.35); | ||
width: calc(var(--zeit-ui-button-height) / 2.35); | ||
} | ||
</style></span><div class=\\"text right\\">action<style> | ||
.left { | ||
padding-left: 0; | ||
} | ||
.right { | ||
padding-right: 0; | ||
} | ||
</style></div><style> | ||
.btn { | ||
box-sizing: border-box; | ||
display: inline-block; | ||
padding: 0 1.375rem; | ||
height: 2.5rem; | ||
line-height: 2.5rem; | ||
min-width: 12.5rem; | ||
width: auto; | ||
border-radius: 5px; | ||
font-weight: 400; | ||
font-size: .875rem; | ||
user-select: none; | ||
outline: none; | ||
text-transform: capitalize; | ||
justify-content: center; | ||
text-align: center; | ||
white-space: nowrap; | ||
transition: all 0.2s ease 0s; | ||
position: relative; | ||
overflow: hidden; | ||
color: #666; | ||
background-color: #fff; | ||
border: 1px solid #eaeaea; | ||
cursor: pointer; | ||
pointer-events: auto; | ||
box-shadow: none; | ||
--zeit-ui-button-padding: 1.375rem; | ||
--zeit-ui-button-height: 2.5rem; | ||
--zeit-ui-button-color: #666; | ||
} | ||
.btn:hover { | ||
color: #000; | ||
--zeit-ui-button-color: #000; | ||
background-color: #fff; | ||
border-color: #000; | ||
cursor: pointer; | ||
pointer-events: auto; | ||
box-shadow: none; | ||
transform: translate3d(0px, 0px, 0px); | ||
} | ||
.btn :global(.text) { | ||
position: relative; | ||
z-index: 1; | ||
display: inline-flex; | ||
justify-content: center; | ||
align-items: center; | ||
text-align: center; | ||
line-height: inherit; | ||
top: -1px; | ||
} | ||
.btn :global(.text p), | ||
.btn :global(.text pre), | ||
.btn :global(.text div) { | ||
margin: 0; | ||
} | ||
</style></button>" | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import React from 'react' | ||
import { mount } from 'enzyme' | ||
import { Button } from 'components' | ||
const Icon: React.FC<any> = () => <svg /> | ||
|
||
describe('ButtonIcon', () => { | ||
it('should render correctly', () => { | ||
const wrapper = mount(<Button icon={<Icon />}>action</Button>) | ||
expect(wrapper.html()).toMatchSnapshot() | ||
expect(() => wrapper.unmount()).not.toThrow() | ||
}) | ||
|
||
it('should work with right', () => { | ||
const wrapper = mount(<Button iconRight={<Icon />}>action</Button>) | ||
expect(wrapper.html()).toMatchSnapshot() | ||
expect(() => wrapper.unmount()).not.toThrow() | ||
}) | ||
|
||
it('the width of the text should be filled', () => { | ||
const autoWrapper = mount( | ||
<Button auto icon={<Icon />}> | ||
action | ||
</Button>, | ||
) | ||
const wrapper = mount(<Button icon={<Icon />}>action</Button>) | ||
|
||
const autoHtml = autoWrapper.find('.text').html() | ||
const html = wrapper.find('.text').html() | ||
expect(html).not.toEqual(autoHtml) | ||
|
||
const mini = mount(<Button size="mini">action</Button>) | ||
const miniIcon = mount( | ||
<Button size="mini" icon={<Icon />}> | ||
action | ||
</Button>, | ||
) | ||
const miniHtml = mini.find('.text').html() | ||
const miniIconHtml = miniIcon.find('.text').html() | ||
expect(miniHtml).not.toEqual(miniIconHtml) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import React from 'react' | ||
import withDefaults from '../utils/with-defaults' | ||
|
||
interface Props { | ||
isRight?: boolean | ||
className?: string | ||
} | ||
|
||
const defaultProps = { | ||
isRight: false, | ||
className: '', | ||
} | ||
|
||
type NativeAttrs = Omit<React.HTMLAttributes<any>, keyof Props> | ||
export type ButtonIconProps = Props & typeof defaultProps & NativeAttrs | ||
|
||
const ButtonIcon: React.FC<React.PropsWithChildren<ButtonIconProps>> = ({ | ||
isRight, | ||
children, | ||
className, | ||
...props | ||
}) => { | ||
return ( | ||
<span className={`icon ${isRight ? 'right' : ''} ${className}`} {...props}> | ||
{children} | ||
<style jsx>{` | ||
.icon { | ||
position: absolute; | ||
left: var(--zeit-ui-button-padding); | ||
right: auto; | ||
top: 50%; | ||
transform: translateY(-50%); | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
color: var(--zeit-ui-button-color); | ||
z-index: 1; | ||
} | ||
.right { | ||
right: var(--zeit-ui-button-padding); | ||
left: auto; | ||
} | ||
.icon :global(svg) { | ||
background: transparent; | ||
height: calc(var(--zeit-ui-button-height) / 2.35); | ||
width: calc(var(--zeit-ui-button-height) / 2.35); | ||
} | ||
`}</style> | ||
</span> | ||
) | ||
} | ||
|
||
const MemoButtonIcon = React.memo(ButtonIcon) | ||
|
||
export default withDefaults(MemoButtonIcon, defaultProps) |
Oops, something went wrong.