ghost-portal/packages/react-components/src/Button/Button.tsx
Ewa Kowalska ad8226a5c3
Account sidebar - single button for editing name and tags (#6049)
* WIP - merge edition of account name and tags

* [WIP] - tests

* Apply test improvements

* Improve tests

* Improve tests and use useCallback

* WIP - add cancel button

* Outside click

* Add more tests

* Apply styling

* Add opacity on not editable elements

* Remove unnecessary code and fix type of sidebar ref

* Disable eslint rule

* Place edit button within account menu buttons

* Adjust test setup

* Ato-lint fixes

* Update styles

* Apply review suggestions

* Remove unused styles and change type of sidebar ref

* Remove onCancel from useAccountInfo hook

* Fix issue with edit button

* Apply review suggestions, remove tests

* Adjust tests

* Simplify tests

* Apply lint fixes

* Change layout of buttons

Co-authored-by: MiZiet <michalzietalak@o2.pl>
Co-authored-by: Jaco Greeff <jacogr@gmail.com>
2021-09-09 19:40:09 +02:00

155 lines
3.4 KiB
TypeScript

// Copyright 2017-2021 @polkadot/react-components authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { ButtonProps } from './types';
import React, { useCallback, useEffect } from 'react';
import styled from 'styled-components';
import Icon from '../Icon';
import Spinner from '../Spinner';
function Button ({ activeOnEnter, children, className = '', dataTestId = '', icon, isBasic, isBusy, isCircular, isDisabled, isFull, isIcon, isSelected, isToplevel, label, onClick, isReadOnly = !onClick, onMouseEnter, onMouseLeave, tabIndex, withoutLink }: ButtonProps): React.ReactElement<ButtonProps> {
const _onClick = useCallback(
() => !(isBusy || isDisabled) && onClick && onClick(),
[isBusy, isDisabled, onClick]
);
const listenKeyboard = useCallback((event: KeyboardEvent) => {
if (!isBusy && !isDisabled && event.key === 'Enter') {
onClick && onClick();
}
}, [isBusy, isDisabled, onClick]);
useEffect(() => {
if (activeOnEnter) {
window.addEventListener('keydown', listenKeyboard, true);
}
return () => {
if (activeOnEnter) {
window.removeEventListener('keydown', listenKeyboard, true);
}
};
}, [activeOnEnter, listenKeyboard]);
return (
<button
className={`ui--Button${label ? ' hasLabel' : ''}${isBasic ? ' isBasic' : ''}${isCircular ? ' isCircular' : ''}${isFull ? ' isFull' : ''}${isIcon ? ' isIcon' : ''}${(isBusy || isDisabled) ? ' isDisabled' : ''}${isBusy ? ' isBusy' : ''}${isReadOnly ? ' isReadOnly' : ''}${isSelected ? ' isSelected' : ''}${isToplevel ? ' isToplevel' : ''}${withoutLink ? ' withoutLink' : ''} ${className}`}
data-testid={dataTestId}
onClick={_onClick}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
tabIndex={tabIndex}
>
{icon && <Icon icon={icon} />}
{label}
{children}
<Spinner
className='ui--Button-spinner'
variant='cover'
/>
</button>
);
}
const ICON_PADDING = 0.5;
export default React.memo(styled(Button)`
background: transparent;
border: none;
color: inherit;
cursor: pointer;
line-height: 1;
margin: 0;
outline: none;
position: relative;
vertical-align: middle;
text-align: center;
&:not(.hasLabel) {
padding: 0.7em;
.ui--Icon {
padding: 0.6rem;
margin: -0.6rem;
}
}
&:not(.isCircular) {
border-radius: 0.25rem;
}
&:focus {
outline:0;
}
&.hasLabel {
padding: 0.7rem 1.1rem 0.7rem ${1.1 - ICON_PADDING}rem;
.ui--Icon {
margin-right: 0.425rem !important;
}
}
&.isBasic {
background: var(--bg-table);
}
&.isCircular {
border-radius: 10rem;
}
&.isDisabled, &.isReadOnly {
background: none;
box-shadow: none;
cursor: not-allowed;
}
&.isBusy {
cursor: wait;
}
&.isFull {
display: block;
width: 100%;
}
&.isIcon {
background: transparent;
}
.ui--Button-spinner {
visibility: hidden;
}
.ui--Button-overlay {
background: rgba(253, 252, 251, 0.75);
bottom: 0;
left: 0;
position: absolute;
right: 0;
top: 0;
visibility: hidden;
}
.ui--Icon {
border-radius: 50%;
box-sizing: content-box;
height: 1rem;
margin: -${ICON_PADDING}rem 0;
padding: ${ICON_PADDING}rem;
width: 1rem;
}
&.isBusy {
.ui--Button-spinner {
visibility: visible;
}
}
&.isDisabled {
color: #bcbbba;
}
`);