Skip to content

Commit

Permalink
fix: add tooltip to button
Browse files Browse the repository at this point in the history
  • Loading branch information
richardmichel committed May 29, 2023
1 parent 26a9fa5 commit 7699b96
Show file tree
Hide file tree
Showing 9 changed files with 1,257 additions and 41 deletions.
14 changes: 14 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"prop-types": "^15.8.1",
"prop-types-extra": "^1.1.0",
"react-full-screen": "^1.1.1",
"react-popper": "^2.3.0",
"react-select": "^5.7.0",
"react-spinners": "^0.13.8",
"react-transition-group": "^4.4.2",
Expand Down
111 changes: 71 additions & 40 deletions src/components/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { useBootstrapPrefix } from './ThemeProvider';
import { BsPrefixProps, BsPrefixRefForwardingComponent } from './helpers';
import { ButtonVariant } from './types';
import OverlayTrigger from './OverlayTrigger';
import Tooltip from './Tooltip';
import { Tooltip2 } from './Tooltip2';
import { v4 as uuid } from 'uuid';

const faAsterisk = {
Expand Down Expand Up @@ -126,6 +126,26 @@ const defaultProps = {
animateIconClass: false,
};

const useTooltip = (tooltip: any) => {
if (!tooltip) {
return {
tooltipOpen: null,
setTooltipOpen: null,
toggle: null,
tooltipId: null,
};
}
const [tooltipOpen, setTooltipOpen] = React.useState(false);
const toggle = () => setTooltipOpen(!tooltipOpen);
const [tooltipId] = React.useState(`button-tooltip-${uuid()}`);

return {
tooltipOpen,
setTooltipOpen,
toggle,
tooltipId,
};
};
export const Button: BsPrefixRefForwardingComponent<'button', ButtonProps> =
React.forwardRef<HTMLButtonElement, ButtonProps>(
(
Expand All @@ -150,6 +170,9 @@ export const Button: BsPrefixRefForwardingComponent<'button', ButtonProps> =
},
ref
) => {
const { tooltipOpen, setTooltipOpen, toggle, tooltipId } =
useTooltip(tooltip);

const prefix = useBootstrapPrefix(bsPrefix, 'btn');
const [buttonProps, { tagName }] = useButtonProps({
tagName: as,
Expand Down Expand Up @@ -205,47 +228,55 @@ export const Button: BsPrefixRefForwardingComponent<'button', ButtonProps> =
);
};

const renderTooltip = () => (
<Tooltip id={`button-tooltip-${uuid()}`}>{tooltip}</Tooltip>
);
return (
<React.Fragment>
<Component
{...buttonProps}
{...props}
ref={ref}
className={classNames(
className,
prefix,
active && 'active',
variant && `${prefix}-${variant}`,
size && `${prefix}-${size}`,
props.href && props.disabled && 'disabled',
loading && 'disabled',
fullWidth && 'w-100'
)}
{...{
...(tooltip &&
tooltipId && {
id: tooltipId,
}),
}}
>
{iconRight && (
<React.Fragment>
{label ? label : children}{' '}
{icon && getIcon(icon)}
</React.Fragment>
)}
{!iconRight && (
<React.Fragment>
{icon && getIcon(icon)}{' '}
{label ? label : children}
</React.Fragment>
)}
</Component>

const RenderButton = () => (
<Component
{...buttonProps}
{...props}
ref={ref}
className={classNames(
className,
prefix,
active && 'active',
variant && `${prefix}-${variant}`,
size && `${prefix}-${size}`,
props.href && props.disabled && 'disabled',
loading && 'disabled',
fullWidth && 'w-100'
)}
>
{iconRight && (
<React.Fragment>
{label ? label : children} {icon && getIcon(icon)}
</React.Fragment>
)}
{!iconRight && (
<React.Fragment>
{icon && getIcon(icon)} {label ? label : children}
</React.Fragment>
{tooltip && tooltipId && (
// @ts-ignore
<Tooltip2
placement={'top'}
isOpen={tooltipOpen}
target={tooltipId}
toggle={toggle}
>
<p>{tooltip}</p>
</Tooltip2>
)}
</Component>
);

if (!tooltip) {
return <RenderButton />;
}

return (
<OverlayTrigger placement="top" overlay={renderTooltip}>
<RenderButton />
</OverlayTrigger>
</React.Fragment>
);
}
);
Expand Down
82 changes: 82 additions & 0 deletions src/components/Fade.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import React, { useRef } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { Transition } from 'react-transition-group';
import {
mapToCssModules,
omit,
pick,
TransitionPropTypeKeys,
TransitionTimeouts,
tagPropType,
} from './utils';

const propTypes = {
...Transition.propTypes,
children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.node),
PropTypes.node,
]),
tag: tagPropType,
baseClass: PropTypes.string,
baseClassActive: PropTypes.string,
className: PropTypes.string,
cssModule: PropTypes.object,
innerRef: PropTypes.oneOfType([
PropTypes.object,
PropTypes.string,
PropTypes.func,
]),
};

const defaultProps = {
...Transition.defaultProps,
tag: 'div',
baseClass: 'fade',
baseClassActive: 'show',
timeout: TransitionTimeouts.Fade,
appear: true,
enter: true,
exit: true,
in: true,
};

function Fade(props) {
const ref = useRef(null);

const {
tag: Tag,
baseClass,
baseClassActive,
className,
cssModule,
children,
innerRef = ref,
...otherProps
} = props;

const transitionProps = pick(otherProps, TransitionPropTypeKeys);
const childProps = omit(otherProps, TransitionPropTypeKeys);

return (
<Transition nodeRef={innerRef} {...transitionProps}>
{(status) => {
const isActive = status === 'entered';
const classes = mapToCssModules(
classNames(className, baseClass, isActive && baseClassActive),
cssModule,
);
return (
<Tag className={classes} {...childProps} ref={innerRef}>
{children}
</Tag>
);
}}
</Transition>
);
}

Fade.propTypes = propTypes;
Fade.defaultProps = defaultProps;

export default Fade;

0 comments on commit 7699b96

Please sign in to comment.