diff --git a/src/DTableModalHeader/index.js b/src/DTableModalHeader/index.js index 7af79786..f66ad64b 100644 --- a/src/DTableModalHeader/index.js +++ b/src/DTableModalHeader/index.js @@ -1,13 +1,14 @@ import React from 'react'; import { ModalHeader } from 'reactstrap'; import IconButton from '../IconButton'; +import { getLocale } from '../lang'; import './index.css'; const DTableModalHeader = ({ children, ...props }) => { const customCloseBtn = ( ); return ( diff --git a/src/DTableToolTip/index.css b/src/DTableToolTip/index.css new file mode 100644 index 00000000..f6d53d1d --- /dev/null +++ b/src/DTableToolTip/index.css @@ -0,0 +1,45 @@ +.dtable-tooltip { + position: absolute; + z-index: 99999; +} + +.dtable-tooltip .tooltip { + max-width: 242px; + min-width: max-content; + opacity: 1; +} + +.dtable-tooltip .tooltip .tooltip-inner { + font-size: 14px; + text-align: start; + background-color: var(--bs-body-color); + color: var(--bs-body-bg); + border-radius: 4px; + padding: 4px 8px; + line-height: 20px; + font-weight: normal; +} + +.dtable-tooltip-shortcut-inner { + display: flex; + align-items: center; + justify-content: space-between; + gap: 4px; + line-height: 20px; +} + +.dtable-tooltip-shortcut-keys { + display: inline-flex; + align-items: center; + gap: 4px; + flex-shrink: 0; +} + +.dtable-tooltip-shortcut-key { + display: inline-block; + padding: 2px 8px; + border: 1px solid #999; + border-radius: 4px; + white-space: nowrap; + line-height: 14px; +} diff --git a/src/DTableToolTip/index.js b/src/DTableToolTip/index.js new file mode 100644 index 00000000..87090d60 --- /dev/null +++ b/src/DTableToolTip/index.js @@ -0,0 +1,69 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { UncontrolledTooltip } from 'reactstrap'; + +import './index.css'; + +const DTableToolTip = ({ target, placement = 'bottom', className, children, shortcut }) => { + + const hasShortcut = Boolean(shortcut); + + const renderContent = () => { + if (hasShortcut) { + return ( +
+ {children} + + {shortcut.map((key, index) => ( + + {key} + + ))} + +
+ ); + } + + return children; + }; + + const tooltipProps = { + target, + placement, + className: `dtable-tooltip ${className ? className : ''}`, + innerClassName: hasShortcut ? 'dtable-tooltip-shortcut-inner' : '', + delay: { show: 0, hide: 0 }, + hideArrow: true, + autohide: false, + modifiers: [ + { + name: 'offset', + options: { + offset: [0, -2.5], + }, + }, + { + name: 'preventOverflow', + options: { + boundariesElement: 'window', + }, + } + ], + }; + + return ( + + {renderContent()} + + ); +}; + +DTableToolTip.propTypes = { + target: PropTypes.oneOfType([PropTypes.string, PropTypes.object, PropTypes.instanceOf(Element)]), + placement: PropTypes.oneOf(['top', 'bottom', 'left', 'right']), + className: PropTypes.string, + children: PropTypes.node, + shortcut: PropTypes.arrayOf(PropTypes.string), +}; + +export default DTableToolTip; diff --git a/src/IconButton/index.js b/src/IconButton/index.js index 6398c75d..0e8c3165 100644 --- a/src/IconButton/index.js +++ b/src/IconButton/index.js @@ -1,24 +1,54 @@ -import React from 'react'; +import React, { useState, useMemo, useEffect } from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; +import DTableToolTip from '../DTableToolTip'; +import { generatorBase64Code } from 'dtable-utils'; + +import '../css/icon-button-styles.css'; + +const IconButton = ({ disabled, className, icon, color, children, title, tooltipPlacement, outline, noBackground, ...otherProperties }) => { + const buttonId = useMemo(() => `dtable-icon-button-${generatorBase64Code(8)}`, []); + const [mounted, setMounted] = useState(false); + + useEffect(() => { + setMounted(true); + }, []); -const IconButton = ({ disabled, className, icon, children, ...otherProperties }) => { return ( -
- {icon && ()} - {children} -
+ <> +
+ {icon && } + {children} +
+ {title && mounted && ( + + {title} + + )} + ); }; IconButton.propTypes = { disabled: PropTypes.bool, - classnames: PropTypes.string, + className: PropTypes.string, icon: PropTypes.string, + color: PropTypes.string, children: PropTypes.any, + title: PropTypes.string, + tooltipPlacement: PropTypes.string, + outline: PropTypes.bool, + noBackground: PropTypes.bool, + ariaLabel: PropTypes.string, }; export default IconButton; diff --git a/src/NotificationPopover/index.js b/src/NotificationPopover/index.js index 0095647c..55efa0fd 100644 --- a/src/NotificationPopover/index.js +++ b/src/NotificationPopover/index.js @@ -2,6 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Popover } from 'reactstrap'; import IconButton from '../IconButton'; +import { getLocale } from '../lang'; import './index.css'; @@ -74,7 +75,7 @@ export default class NotificationPopover extends React.Component {
this.notificationContainerRef = ref}>
{headerText} - +
{this.props.enableWeixin && diff --git a/src/css/icon-button-styles.css b/src/css/icon-button-styles.css new file mode 100644 index 00000000..9b390796 --- /dev/null +++ b/src/css/icon-button-styles.css @@ -0,0 +1,141 @@ +.dtable-icon-btn { + display: inline-flex !important; + align-items: center !important; + justify-content: center !important; + padding: 0 !important; + border: none !important; + background-color: transparent !important; + color: #666666 !important; + cursor: pointer; + transition: all 0.2s ease !important; + outline: none !important; + border-radius: 3px !important; + min-width: 24px; + min-height: 24px; +} + +.dtable-icon-btn:focus { + outline: none !important; + box-shadow: none !important; +} + +.dtable-icon-btn:active:focus { + box-shadow: none !important; +} + +.dtable-icon-btn.btn-lg, +.dtable-icon-btn.size-lg { + min-width: 40px !important; + min-height: 40px !important; +} + +.dtable-icon-btn.btn-lg .dtable-icon-btn__icon, +.dtable-icon-btn.size-lg .dtable-icon-btn__icon { + font-size: 20px !important; +} + +.dtable-icon-btn .dtable-icon-btn__icon { + font-size: 16px !important; +} + +.dtable-icon-btn.btn-sm, +.dtable-icon-btn.size-sm { + min-width: 24px !important; + min-height: 24px !important; +} + +.dtable-icon-btn.btn-sm .dtable-icon-btn__icon, +.dtable-icon-btn.size-sm .dtable-icon-btn__icon { + font-size: 14px !important; +} + +.dtable-icon-btn.size-xs { + min-width: 20px !important; + min-height: 20px !important; +} + +.dtable-icon-btn.size-xs .dtable-icon-btn__icon { + font-size: 12px !important; +} + +.dtable-icon-btn:hover:not(:disabled) { + background-color: rgba(0, 0, 0, 0.04) !important; +} + +.dtable-icon-btn:active:not(:disabled) { + background-color: rgba(0, 0, 0, 0.08) !important; +} + +.dtable-icon-btn.outline, +.dtable-icon-btn.outlined { + background-color: #FFFFFF !important; + border: 1px solid rgba(0, 40, 100, 0.12) !important; + color: #666666 !important; +} + +.dtable-icon-btn.outline:hover:not(:disabled), +.dtable-icon-btn.outlined:hover:not(:disabled) { + background-color: rgba(0, 0, 0, 0.04) !important; + border-color: rgba(0, 40, 100, 0.12) !important; +} + +.dtable-icon-btn.outline:active:not(:disabled), +.dtable-icon-btn.outlined:active:not(:disabled) { + background-color: rgba(0, 0, 0, 0.08) !important; + border-color: rgba(0, 40, 100, 0.12) !important; +} + +.dtable-icon-btn.no-background, +.dtable-icon-btn.no-display-bac { + background-color: transparent !important; +} + +.dtable-icon-btn.no-background:hover:not(:disabled), +.dtable-icon-btn.no-display-bac:hover:not(:disabled) { + background-color: transparent !important; +} + +.dtable-icon-btn.no-background:active:not(:disabled), +.dtable-icon-btn.no-display-bac:active:not(:disabled) { + background-color: transparent !important; +} + +.dtable-icon-btn:disabled, +.dtable-icon-btn.disabled { + opacity: 0.65 !important; + cursor: not-allowed !important; +} + +.dtable-icon-btn__icon { + display: inline-block; + line-height: 1; + margin: 0; + font-weight: normal; +} + +.dtable-icon-btn.btn-primary, +.dtable-icon-btn.color-primary { + color: #FF8000 !important; +} + +.dtable-icon-btn.btn-primary:hover:not(:disabled), +.dtable-icon-btn.color-primary:hover:not(:disabled) { + color: #ED7109 !important; + background-color: rgba(255, 128, 0, 0.1) !important; +} + +.dtable-icon-btn.btn-secondary, +.dtable-icon-btn.color-secondary { + color: #212529 !important; +} + +.dtable-icon-btn.btn-danger, +.dtable-icon-btn.color-danger { + color: #dc3545 !important; +} + +.dtable-icon-btn.btn-danger:hover:not(:disabled), +.dtable-icon-btn.color-danger:hover:not(:disabled) { + color: #c82333 !important; + background-color: rgba(220, 53, 69, 0.1) !important; +} diff --git a/src/index.js b/src/index.js index 8570ec2b..7d1542d6 100644 --- a/src/index.js +++ b/src/index.js @@ -36,6 +36,7 @@ export { default as FileItemFormatter } from './FileItemFormatter'; export { default as DigitalSignFormatter } from './DigitalSignFormatter'; export { default as DepartmentSingleSelectFormatter } from './DepartmentSingleSelectFormatter'; export { default as SimpleLongTextFormatter } from './SimpleLongTextFormatter'; +export { default as DTableToolTip } from './DTableToolTip'; // row expand export { default as RowExpandFormatter } from './RowExpandFormatter';