feat: add tooltips for icon buttons
This commit is contained in:
@@ -5,16 +5,26 @@
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Button, Popup as SemanticUIPopup } from 'semantic-ui-react';
|
||||
import Tooltip from '../Tooltip';
|
||||
|
||||
import styles from './PopupHeader.module.css';
|
||||
|
||||
const PopupHeader = React.memo(({ children, onBack }) => (
|
||||
<SemanticUIPopup.Header className={styles.wrapper}>
|
||||
{onBack && <Button icon="angle left" onClick={onBack} className={styles.backButton} />}
|
||||
<div className={styles.content}>{children}</div>
|
||||
</SemanticUIPopup.Header>
|
||||
));
|
||||
const PopupHeader = React.memo(({ children, onBack }) => {
|
||||
const [t] = useTranslation();
|
||||
|
||||
return (
|
||||
<SemanticUIPopup.Header className={styles.wrapper}>
|
||||
{onBack && (
|
||||
<Tooltip content={t('action.goBack')}>
|
||||
<Button icon="angle left" onClick={onBack} className={styles.backButton} />
|
||||
</Tooltip>
|
||||
)}
|
||||
<div className={styles.content}>{children}</div>
|
||||
</SemanticUIPopup.Header>
|
||||
);
|
||||
});
|
||||
|
||||
PopupHeader.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*!
|
||||
* Copyright (c) 2024 PLANKA Software GmbH
|
||||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
import React, { useMemo } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Popup as SemanticUIPopup } from 'semantic-ui-react';
|
||||
|
||||
import styles from './Tooltip.module.css';
|
||||
|
||||
const callAll =
|
||||
(...callbacks) =>
|
||||
(...args) => {
|
||||
callbacks.forEach((callback) => {
|
||||
if (callback) {
|
||||
callback(...args);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const Tooltip = React.forwardRef(
|
||||
({ children, content, disabled, position, 'aria-label': ariaLabel, onClick, ...props }, ref) => {
|
||||
const trigger = useMemo(() => {
|
||||
const contentAriaLabel = typeof content === 'string' ? content : undefined;
|
||||
|
||||
return React.cloneElement(children, {
|
||||
...props,
|
||||
ref,
|
||||
'aria-label': children.props['aria-label'] || ariaLabel || contentAriaLabel,
|
||||
onClick: callAll(children.props.onClick, onClick),
|
||||
});
|
||||
}, [children, content, props, ref, ariaLabel, onClick]);
|
||||
|
||||
if (disabled || !content) {
|
||||
return trigger;
|
||||
}
|
||||
|
||||
return (
|
||||
<SemanticUIPopup
|
||||
basic
|
||||
inverted
|
||||
trigger={trigger}
|
||||
content={content}
|
||||
on={['hover', 'focus']}
|
||||
position={position}
|
||||
className={styles.wrapper}
|
||||
/>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
Tooltip.propTypes = {
|
||||
children: PropTypes.element.isRequired,
|
||||
content: PropTypes.node.isRequired,
|
||||
disabled: PropTypes.bool,
|
||||
'aria-label': PropTypes.string,
|
||||
onClick: PropTypes.func,
|
||||
position: PropTypes.string,
|
||||
};
|
||||
|
||||
Tooltip.defaultProps = {
|
||||
disabled: false,
|
||||
'aria-label': undefined,
|
||||
onClick: undefined,
|
||||
position: 'top center',
|
||||
};
|
||||
|
||||
export default React.memo(Tooltip);
|
||||
@@ -0,0 +1,12 @@
|
||||
/*!
|
||||
* Copyright (c) 2024 PLANKA Software GmbH
|
||||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
:global(#app) .wrapper {
|
||||
border-radius: 3px;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
line-height: 16px;
|
||||
padding: 6px 8px;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
/*!
|
||||
* Copyright (c) 2024 PLANKA Software GmbH
|
||||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
import Tooltip from './Tooltip';
|
||||
|
||||
export default Tooltip;
|
||||
@@ -7,5 +7,6 @@ import Input from './components/Input';
|
||||
import Popup from './components/Popup';
|
||||
import Masonry from './components/Masonry';
|
||||
import FilePicker from './components/FilePicker';
|
||||
import Tooltip from './components/Tooltip';
|
||||
|
||||
export { Input, Popup, Masonry, FilePicker };
|
||||
export { Input, Popup, Masonry, FilePicker, Tooltip };
|
||||
|
||||
Reference in New Issue
Block a user