* feat(button): center the icon if the button is empty

* test(button): add testcase for icon only

* docs(button): add example for icon only
This commit is contained in:
witt
2020-07-05 14:29:33 +08:00
committed by unix
parent 076e19a48c
commit a24933d2f9
6 changed files with 132 additions and 5 deletions

View File

@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ButtonIcon should render correctly 1`] = `
"<button type=\\"button\\" class=\\"btn \\"><span class=\\"icon \\"><svg></svg><style>
"<button type=\\"button\\" class=\\"btn \\"><span class=\\"icon \\"><svg></svg><style>
.icon {
position: absolute;
left: var(--zeit-ui-button-padding);
@@ -25,6 +25,11 @@ exports[`ButtonIcon should render correctly 1`] = `
height: calc(var(--zeit-ui-button-height) / 2.35);
width: calc(var(--zeit-ui-button-height) / 2.35);
}
.single {
position: static;
transform: none;
}
</style></span><div class=\\"text left\\">action<style>
.left {
padding-left: 0;
@@ -97,7 +102,7 @@ exports[`ButtonIcon should render correctly 1`] = `
`;
exports[`ButtonIcon should work with right 1`] = `
"<button type=\\"button\\" class=\\"btn \\"><span class=\\"icon right \\"><svg></svg><style>
"<button type=\\"button\\" class=\\"btn \\"><span class=\\"icon right \\"><svg></svg><style>
.icon {
position: absolute;
left: var(--zeit-ui-button-padding);
@@ -121,6 +126,11 @@ exports[`ButtonIcon should work with right 1`] = `
height: calc(var(--zeit-ui-button-height) / 2.35);
width: calc(var(--zeit-ui-button-height) / 2.35);
}
.single {
position: static;
transform: none;
}
</style></span><div class=\\"text right\\">action<style>
.left {
padding-left: 0;
@@ -191,3 +201,97 @@ exports[`ButtonIcon should work with right 1`] = `
}
</style></button>"
`;
exports[`ButtonIcon should work without text 1`] = `
"<button type=\\"button\\" class=\\"btn \\"><span class=\\"icon right single \\"><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);
}
.single {
position: static;
transform: none;
}
</style></span><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: background-color 200ms ease 0ms, box-shadow 200ms ease 0ms,
border 200ms ease 0ms, color 200ms ease 0ms;
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;
--zeit-ui-button-bg: #fff;
}
.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>"
`;

View File

@@ -16,6 +16,13 @@ describe('ButtonIcon', () => {
expect(() => wrapper.unmount()).not.toThrow()
})
it('should work without text', () => {
const wrapper = mount(<Button iconRight={<Icon />} />)
const text = wrapper.find('.text')
expect(wrapper.html()).toMatchSnapshot()
expect(text.length).toBe(0)
})
it('the width of the text should be filled', () => {
const autoWrapper = mount(
<Button auto icon={<Icon />}>

View File

@@ -3,6 +3,7 @@ import withDefaults from '../utils/with-defaults'
interface Props {
isRight?: boolean
isSingle?: boolean
className?: string
}
@@ -16,12 +17,15 @@ export type ButtonIconProps = Props & typeof defaultProps & NativeAttrs
const ButtonIcon: React.FC<React.PropsWithChildren<ButtonIconProps>> = ({
isRight,
isSingle,
children,
className,
...props
}) => {
return (
<span className={`icon ${isRight ? 'right' : ''} ${className}`} {...props}>
<span
className={`icon ${isRight ? 'right' : ''} ${isSingle ? 'single' : ''} ${className}`}
{...props}>
{children}
<style jsx>{`
.icon {
@@ -47,6 +51,11 @@ const ButtonIcon: React.FC<React.PropsWithChildren<ButtonIconProps>> = ({
height: calc(var(--zeit-ui-button-height) / 2.35);
width: calc(var(--zeit-ui-button-height) / 2.35);
}
.single {
position: static;
transform: none;
}
`}</style>
</span>
)

View File

@@ -21,6 +21,13 @@ export const getButtonChildrenWithIcon = (
? `calc(var(--zeit-ui-button-height) / 2 + var(--zeit-ui-button-padding) * .5)`
: 0
if (!hasIcon) return <div className="text">{children}</div>
if (React.Children.count(children) === 0) {
return (
<ButtonIcon isRight={isRight} isSingle>
{hasIcon}
</ButtonIcon>
)
}
return (
<>
<ButtonIcon isRight={isRight}>{hasIcon}</ButtonIcon>

View File

@@ -110,7 +110,7 @@ Used to trigger an operation.
scope={{ Button, Spacer, Settings, UserX, Power }}
code={`
<>
<Button iconRight={<Power />} auto size="small">shut off</Button>
<Button iconRight={<Power />} auto size="small" />
<Spacer y={.5} />
<Button icon={<Settings />} auto>Action</Button>
<Spacer y={.5} />

View File

@@ -109,7 +109,7 @@ export const meta = {
scope={{ Button, Spacer, Settings, UserX, Power }}
code={`
<>
<Button iconRight={<Power />} auto size="small">关闭</Button>
<Button iconRight={<Power />} auto size="small" />
<Spacer y={.5} />
<Button icon={<Settings />} auto>按钮</Button>
<Spacer y={.5} />