feat: tooltip support color (#3603)

* feat: tooltip support color

* update
pull/3610/head
ajuner 2021-01-27 23:21:48 +08:00 committed by GitHub
parent 10a5fb28cb
commit d221171e53
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 58 additions and 25 deletions

View File

@ -2,9 +2,7 @@
exports[`Popconfirm should show overlay when trigger is clicked 1`] = ` exports[`Popconfirm should show overlay when trigger is clicked 1`] = `
<div class="ant-popover-content"> <div class="ant-popover-content">
<div class="ant-popover-arrow"> <div class="ant-popover-arrow"><span class="ant-popover-arrow-content"></span></div>
<!---->
</div>
<div class="ant-popover-inner" role="tooltip"> <div class="ant-popover-inner" role="tooltip">
<div class="ant-popover-inner-content"> <div class="ant-popover-inner-content">
<div class="ant-popover-message"><span role="img" aria-label="exclamation-circle" class="anticon anticon-exclamation-circle"><svg class="" data-icon="exclamation-circle" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896" focusable="false"><path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm-32 232c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v272c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V296zm32 440a48.01 48.01 0 010-96 48.01 48.01 0 010 96z"></path></svg></span> <div class="ant-popover-message"><span role="img" aria-label="exclamation-circle" class="anticon anticon-exclamation-circle"><svg class="" data-icon="exclamation-circle" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896" focusable="false"><path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm-32 232c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v272c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V296zm32 440a48.01 48.01 0 010-96 48.01 48.01 0 010 96z"></path></svg></span>

View File

@ -2,9 +2,7 @@
exports[`Popover should show overlay when trigger is clicked 1`] = ` exports[`Popover should show overlay when trigger is clicked 1`] = `
<div class="ant-popover-content"> <div class="ant-popover-content">
<div class="ant-popover-arrow"> <div class="ant-popover-arrow"><span class="ant-popover-arrow-content"></span></div>
<!---->
</div>
<div class="ant-popover-inner" role="tooltip"> <div class="ant-popover-inner" role="tooltip">
<div> <div>
<div class="ant-popover-title">code</div> <div class="ant-popover-title">code</div>
@ -16,9 +14,7 @@ exports[`Popover should show overlay when trigger is clicked 1`] = `
exports[`Popover should show overlay when trigger is clicked 2`] = ` exports[`Popover should show overlay when trigger is clicked 2`] = `
<div class="ant-popover-content"> <div class="ant-popover-content">
<div class="ant-popover-arrow"> <div class="ant-popover-arrow"><span class="ant-popover-arrow-content"></span></div>
<!---->
</div>
<div class="ant-popover-inner" role="tooltip"> <div class="ant-popover-inner" role="tooltip">
<div> <div>
<div class="ant-popover-title">code</div> <div class="ant-popover-title">code</div>

View File

@ -18,9 +18,7 @@ exports[`Slider should show tooltip when hovering slider handler 1`] = `
<!----> <!---->
<div class="ant-tooltip ant-slider-tooltip ant-tooltip-placement-top"> <div class="ant-tooltip ant-slider-tooltip ant-tooltip-placement-top">
<div class="ant-tooltip-content"> <div class="ant-tooltip-content">
<div class="ant-tooltip-arrow"> <div class="ant-tooltip-arrow"><span class="ant-tooltip-arrow-content"></span></div>
<!---->
</div>
<div class="ant-tooltip-inner" role="tooltip">30</div> <div class="ant-tooltip-inner" role="tooltip">30</div>
</div> </div>
</div> </div>
@ -46,9 +44,7 @@ exports[`Slider should show tooltip when hovering slider handler 2`] = `
<!----> <!---->
<div class="ant-tooltip ant-slider-tooltip ant-tooltip-placement-top" style="display: none;"> <div class="ant-tooltip ant-slider-tooltip ant-tooltip-placement-top" style="display: none;">
<div class="ant-tooltip-content"> <div class="ant-tooltip-content">
<div class="ant-tooltip-arrow"> <div class="ant-tooltip-arrow"><span class="ant-tooltip-arrow-content"></span></div>
<!---->
</div>
<div class="ant-tooltip-inner" role="tooltip">30</div> <div class="ant-tooltip-inner" role="tooltip">30</div>
</div> </div>
</div> </div>

View File

@ -1,8 +1,9 @@
import { defineComponent, ExtractPropTypes, inject } from 'vue'; import { defineComponent, ExtractPropTypes, inject, CSSProperties } from 'vue';
import VcTooltip from '../vc-tooltip'; import VcTooltip from '../vc-tooltip';
import classNames from '../_util/classNames'; import classNames from '../_util/classNames';
import getPlacements from './placements'; import getPlacements from './placements';
import PropTypes from '../_util/vue-types'; import PropTypes from '../_util/vue-types';
import { PresetColorTypes } from '../_util/colors';
import { import {
hasProp, hasProp,
getComponent, getComponent,
@ -28,6 +29,8 @@ const splitObject = (obj: any, keys: string[]) => {
}; };
const props = abstractTooltipProps(); const props = abstractTooltipProps();
const PresetColorRegex = new RegExp(`^(${PresetColorTypes.join('|')})(-inverse)?$`);
const tooltipProps = { const tooltipProps = {
...props, ...props,
title: PropTypes.VNodeChild, title: PropTypes.VNodeChild,
@ -176,7 +179,13 @@ export default defineComponent({
render() { render() {
const { $props, $data, $attrs } = this; const { $props, $data, $attrs } = this;
const { prefixCls: customizePrefixCls, openClassName, getPopupContainer } = $props; const {
prefixCls: customizePrefixCls,
openClassName,
getPopupContainer,
color,
overlayClassName,
} = $props;
const { getPopupContainer: getContextPopupContainer } = this.configProvider; const { getPopupContainer: getContextPopupContainer } = this.configProvider;
const getPrefixCls = this.configProvider.getPrefixCls; const getPrefixCls = this.configProvider.getPrefixCls;
const prefixCls = getPrefixCls('tooltip', customizePrefixCls); const prefixCls = getPrefixCls('tooltip', customizePrefixCls);
@ -197,6 +206,16 @@ export default defineComponent({
[openClassName || `${prefixCls}-open`]: sVisible, [openClassName || `${prefixCls}-open`]: sVisible,
[child.props && child.props.class]: child.props && child.props.class, [child.props && child.props.class]: child.props && child.props.class,
}); });
const customOverlayClassName = classNames(overlayClassName, {
[`${prefixCls}-${color}`]: color && PresetColorRegex.test(color),
});
let formattedOverlayInnerStyle: CSSProperties;
let arrowContentStyle: CSSProperties;
if (color && !PresetColorRegex.test(color)) {
formattedOverlayInnerStyle = { backgroundColor: color };
arrowContentStyle = { backgroundColor: color };
}
const vcTooltipProps = { const vcTooltipProps = {
...$attrs, ...$attrs,
...$props, ...$props,
@ -206,6 +225,9 @@ export default defineComponent({
overlay: this.getOverlay(), overlay: this.getOverlay(),
visible: sVisible, visible: sVisible,
ref: 'tooltip', ref: 'tooltip',
overlayClassName: customOverlayClassName,
overlayInnerStyle: formattedOverlayInnerStyle,
arrowContent: <span class={`${prefixCls}-arrow-content`} style={arrowContentStyle}></span>,
onVisibleChange: this.handleVisibleChange, onVisibleChange: this.handleVisibleChange,
onPopupAlign: this.onPopupAlign, onPopupAlign: this.onPopupAlign,
}; };

View File

@ -22,6 +22,7 @@ export default () => ({
'rightBottom', 'rightBottom',
), ),
).def('top'), ).def('top'),
color: PropTypes.string,
transitionName: PropTypes.string.def('zoom-big-fast'), transitionName: PropTypes.string.def('zoom-big-fast'),
overlayStyle: PropTypes.object.def(() => ({})), overlayStyle: PropTypes.object.def(() => ({})),
overlayClassName: PropTypes.string, overlayClassName: PropTypes.string,

View File

@ -73,7 +73,7 @@
background: transparent; background: transparent;
pointer-events: none; pointer-events: none;
&::before { &-content {
position: absolute; position: absolute;
top: 0; top: 0;
right: 0; right: 0;
@ -94,7 +94,7 @@
&-placement-topRight &-arrow { &-placement-topRight &-arrow {
bottom: @tooltip-distance - @tooltip-arrow-rotate-width; bottom: @tooltip-distance - @tooltip-arrow-rotate-width;
&::before { &-content {
box-shadow: @tooltip-arrow-shadow-width @tooltip-arrow-shadow-width 7px fade(@black, 7%); box-shadow: @tooltip-arrow-shadow-width @tooltip-arrow-shadow-width 7px fade(@black, 7%);
transform: translateY((-@tooltip-arrow-rotate-width / 2)) rotate(45deg); transform: translateY((-@tooltip-arrow-rotate-width / 2)) rotate(45deg);
} }
@ -118,7 +118,7 @@
&-placement-rightBottom &-arrow { &-placement-rightBottom &-arrow {
left: @tooltip-distance - @tooltip-arrow-rotate-width; left: @tooltip-distance - @tooltip-arrow-rotate-width;
&::before { &-content {
box-shadow: -@tooltip-arrow-shadow-width @tooltip-arrow-shadow-width 7px fade(@black, 7%); box-shadow: -@tooltip-arrow-shadow-width @tooltip-arrow-shadow-width 7px fade(@black, 7%);
transform: translateX((@tooltip-arrow-rotate-width / 2)) rotate(45deg); transform: translateX((@tooltip-arrow-rotate-width / 2)) rotate(45deg);
} }
@ -142,7 +142,7 @@
&-placement-leftBottom &-arrow { &-placement-leftBottom &-arrow {
right: @tooltip-distance - @tooltip-arrow-rotate-width; right: @tooltip-distance - @tooltip-arrow-rotate-width;
&::before { &-content {
box-shadow: @tooltip-arrow-shadow-width -@tooltip-arrow-shadow-width 7px fade(@black, 7%); box-shadow: @tooltip-arrow-shadow-width -@tooltip-arrow-shadow-width 7px fade(@black, 7%);
transform: translateX((-@tooltip-arrow-rotate-width / 2)) rotate(45deg); transform: translateX((-@tooltip-arrow-rotate-width / 2)) rotate(45deg);
} }
@ -166,7 +166,7 @@
&-placement-bottomRight &-arrow { &-placement-bottomRight &-arrow {
top: @tooltip-distance - @tooltip-arrow-rotate-width; top: @tooltip-distance - @tooltip-arrow-rotate-width;
&::before { &-content {
box-shadow: -@tooltip-arrow-shadow-width -@tooltip-arrow-shadow-width 7px fade(@black, 7%); box-shadow: -@tooltip-arrow-shadow-width -@tooltip-arrow-shadow-width 7px fade(@black, 7%);
transform: translateY((@tooltip-arrow-rotate-width / 2)) rotate(45deg); transform: translateY((@tooltip-arrow-rotate-width / 2)) rotate(45deg);
} }
@ -185,3 +185,20 @@
right: @tooltip-arrow-offset-horizontal; right: @tooltip-arrow-offset-horizontal;
} }
} }
.generator-tooltip-preset-color(@i: length(@preset-colors)) when (@i > 0) {
.generator-tooltip-preset-color(@i - 1);
@color: extract(@preset-colors, @i);
@lightColor: '@{color}-6';
.@{tooltip-prefix-cls}-@{color} {
.@{tooltip-prefix-cls}-inner {
background-color: @@lightColor;
}
.@{tooltip-prefix-cls}-arrow {
&-content {
background-color: @@lightColor;
}
}
}
}
.generator-tooltip-preset-color();

View File

@ -6,6 +6,7 @@ export default {
prefixCls: PropTypes.string, prefixCls: PropTypes.string,
overlay: PropTypes.any, overlay: PropTypes.any,
trigger: PropTypes.any, trigger: PropTypes.any,
overlayInnerStyle: PropTypes.any,
}, },
updated() { updated() {
const { trigger } = this; const { trigger } = this;
@ -14,9 +15,9 @@ export default {
} }
}, },
render() { render() {
const { overlay, prefixCls } = this; const { overlay, prefixCls, overlayInnerStyle } = this;
return ( return (
<div class={`${prefixCls}-inner`} role="tooltip"> <div class={`${prefixCls}-inner`} role="tooltip" style={overlayInnerStyle}>
{typeof overlay === 'function' ? overlay() : overlay} {typeof overlay === 'function' ? overlay() : overlay}
</div> </div>
); );

View File

@ -28,10 +28,11 @@ export default defineComponent({
arrowContent: PropTypes.any.def(null), arrowContent: PropTypes.any.def(null),
tipId: PropTypes.string, tipId: PropTypes.string,
builtinPlacements: PropTypes.object, builtinPlacements: PropTypes.object,
overlayInnerStyle: PropTypes.style,
}, },
methods: { methods: {
getPopupElement() { getPopupElement() {
const { prefixCls, tipId } = this.$props; const { prefixCls, tipId, overlayInnerStyle } = this.$props;
return [ return [
<div class={`${prefixCls}-arrow`} key="arrow"> <div class={`${prefixCls}-arrow`} key="arrow">
{getComponent(this, 'arrowContent')} {getComponent(this, 'arrowContent')}
@ -42,6 +43,7 @@ export default defineComponent({
prefixCls={prefixCls} prefixCls={prefixCls}
id={tipId} id={tipId}
overlay={getComponent(this, 'overlay')} overlay={getComponent(this, 'overlay')}
overlayInnerStyle={overlayInnerStyle}
/>, />,
]; ];
}, },