refactor: popover
parent
783fb2c8a9
commit
f71a72208b
|
@ -4,10 +4,8 @@ exports[`Popover should show overlay when trigger is clicked 1`] = `
|
|||
<div class="ant-popover-content">
|
||||
<div class="ant-popover-arrow"><span class="ant-popover-arrow-content"></span></div>
|
||||
<div class="ant-popover-inner" role="tooltip">
|
||||
<div>
|
||||
<div class="ant-popover-title">code</div>
|
||||
<div class="ant-popover-inner-content">console.log('hello world')</div>
|
||||
</div>
|
||||
<div class="ant-popover-title">code</div>
|
||||
<div class="ant-popover-inner-content">console.log('hello world')</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
@ -16,10 +14,8 @@ exports[`Popover should show overlay when trigger is clicked 2`] = `
|
|||
<div class="ant-popover-content">
|
||||
<div class="ant-popover-arrow"><span class="ant-popover-arrow-content"></span></div>
|
||||
<div class="ant-popover-inner" role="tooltip">
|
||||
<div>
|
||||
<div class="ant-popover-title">code</div>
|
||||
<div class="ant-popover-inner-content">console.log('hello world')</div>
|
||||
</div>
|
||||
<div class="ant-popover-title">code</div>
|
||||
<div class="ant-popover-inner-content">console.log('hello world')</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
|
|
@ -1,54 +1,60 @@
|
|||
import { defineComponent, inject } from 'vue';
|
||||
import { computed, defineComponent, ExtractPropTypes, ref } from 'vue';
|
||||
import Tooltip from '../tooltip';
|
||||
import abstractTooltipProps from '../tooltip/abstractTooltipProps';
|
||||
import PropTypes from '../_util/vue-types';
|
||||
import { getOptionProps, getComponent, getSlot } from '../_util/props-util';
|
||||
import { defaultConfigProvider } from '../config-provider';
|
||||
import { initDefaultProps } from '../_util/props-util';
|
||||
import { withInstall } from '../_util/type';
|
||||
import useConfigInject from '../_util/hooks/useConfigInject';
|
||||
import omit from '../_util/omit';
|
||||
import { getTransitionName } from '../_util/transition';
|
||||
|
||||
export const popoverProps = () => ({
|
||||
...abstractTooltipProps(),
|
||||
content: PropTypes.any,
|
||||
title: PropTypes.any,
|
||||
});
|
||||
|
||||
export type PopoverProps = Partial<ExtractPropTypes<ReturnType<typeof popoverProps>>>;
|
||||
|
||||
const props = abstractTooltipProps();
|
||||
const Popover = defineComponent({
|
||||
name: 'APopover',
|
||||
props: {
|
||||
...props,
|
||||
prefixCls: PropTypes.string,
|
||||
transitionName: PropTypes.string.def('zoom-big'),
|
||||
content: PropTypes.any,
|
||||
title: PropTypes.any,
|
||||
},
|
||||
setup() {
|
||||
return {
|
||||
configProvider: inject('configProvider', defaultConfigProvider),
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
getPopupDomNode() {
|
||||
return (this.$refs.tooltip as any).getPopupDomNode();
|
||||
},
|
||||
},
|
||||
props: initDefaultProps(popoverProps(), {
|
||||
trigger: 'hover',
|
||||
transitionName: 'zoom-big',
|
||||
placement: 'top',
|
||||
mouseEnterDelay: 0.1,
|
||||
mouseLeaveDelay: 0.1,
|
||||
}),
|
||||
setup(props, { expose, slots }) {
|
||||
const tooltipRef = ref();
|
||||
|
||||
render() {
|
||||
const { title, prefixCls: customizePrefixCls, $slots } = this;
|
||||
const { getPrefixCls } = this.configProvider;
|
||||
const prefixCls = getPrefixCls('popover', customizePrefixCls);
|
||||
|
||||
const props = getOptionProps(this);
|
||||
delete props.title;
|
||||
delete props.content;
|
||||
const tooltipProps = {
|
||||
...props,
|
||||
prefixCls,
|
||||
ref: 'tooltip',
|
||||
title: (
|
||||
<div>
|
||||
{(title || $slots.title) && (
|
||||
<div class={`${prefixCls}-title`}>{getComponent(this, 'title')}</div>
|
||||
)}
|
||||
<div class={`${prefixCls}-inner-content`}>{getComponent(this, 'content')}</div>
|
||||
</div>
|
||||
),
|
||||
expose({
|
||||
getPopupDomNode: () => {
|
||||
return tooltipRef.value?.getPopupDomNode?.();
|
||||
},
|
||||
});
|
||||
const { prefixCls, configProvider } = useConfigInject('popover', props);
|
||||
const rootPrefixCls = computed(() => configProvider.getPrefixCls());
|
||||
const getOverlay = () => {
|
||||
const { title = slots.title?.(), content = slots.content?.() } = props;
|
||||
return (
|
||||
<>
|
||||
{title && <div class={`${prefixCls.value}-title`}>{title}</div>}
|
||||
<div class={`${prefixCls.value}-inner-content`}>{content}</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
return () => {
|
||||
return (
|
||||
<Tooltip
|
||||
{...omit(props, ['title', 'content'])}
|
||||
prefixCls={prefixCls.value}
|
||||
ref={tooltipRef}
|
||||
v-slots={{ title: getOverlay, default: slots.default }}
|
||||
transitionName={getTransitionName(rootPrefixCls.value, 'zoom-big', props.transitionName)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
return <Tooltip {...tooltipProps}>{getSlot(this)}</Tooltip>;
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
@import './index.less';
|
||||
|
||||
.popover-customize-bg(@popover-prefix-cls, @popover-background);
|
|
@ -3,6 +3,11 @@
|
|||
|
||||
@popover-prefix-cls: ~'@{ant-prefix}-popover';
|
||||
|
||||
@popover-arrow-rotate-width: sqrt(@popover-arrow-width * @popover-arrow-width * 2);
|
||||
|
||||
@popover-arrow-offset-vertical: 12px;
|
||||
@popover-arrow-offset-horizontal: 16px;
|
||||
|
||||
.@{popover-prefix-cls} {
|
||||
.reset-component();
|
||||
|
||||
|
@ -68,16 +73,16 @@
|
|||
|
||||
&-title {
|
||||
min-width: @popover-min-width;
|
||||
min-height: 32px;
|
||||
min-height: @popover-min-height;
|
||||
margin: 0; // reset heading margin
|
||||
padding: 5px @padding-md 4px;
|
||||
padding: 5px @popover-padding-horizontal 4px;
|
||||
color: @heading-color;
|
||||
font-weight: 500;
|
||||
border-bottom: 1px solid @border-color-split;
|
||||
}
|
||||
|
||||
&-inner-content {
|
||||
padding: 12px @padding-md;
|
||||
padding: @padding-sm @popover-padding-horizontal;
|
||||
color: @popover-color;
|
||||
}
|
||||
|
||||
|
@ -88,7 +93,9 @@
|
|||
font-size: @font-size-base;
|
||||
> .@{iconfont-css-prefix} {
|
||||
position: absolute;
|
||||
top: 8px; // 4px for padding-top, 4px for vertical middle;
|
||||
top: (
|
||||
4px + ((@line-height-base * @font-size-base - @font-size-base) / 2)
|
||||
); // 4px for padding-top, 4px for vertical middle
|
||||
color: @warning-color;
|
||||
font-size: @font-size-base;
|
||||
}
|
||||
|
@ -100,106 +107,146 @@
|
|||
&-buttons {
|
||||
margin-bottom: 4px;
|
||||
text-align: right;
|
||||
|
||||
button {
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
// Arrows
|
||||
// .popover-arrow is outer, .popover-arrow:after is inner
|
||||
|
||||
&-arrow {
|
||||
position: absolute;
|
||||
display: block;
|
||||
width: sqrt(@popover-arrow-width * @popover-arrow-width * 2);
|
||||
height: sqrt(@popover-arrow-width * @popover-arrow-width * 2);
|
||||
width: @popover-arrow-rotate-width;
|
||||
height: @popover-arrow-rotate-width;
|
||||
overflow: hidden;
|
||||
background: transparent;
|
||||
border-style: solid;
|
||||
border-width: (sqrt(@popover-arrow-width * @popover-arrow-width * 2) / 2);
|
||||
transform: rotate(45deg);
|
||||
pointer-events: none;
|
||||
|
||||
&-content {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
display: block;
|
||||
width: @popover-arrow-width;
|
||||
height: @popover-arrow-width;
|
||||
margin: auto;
|
||||
background-color: @popover-bg;
|
||||
content: '';
|
||||
pointer-events: auto;
|
||||
}
|
||||
}
|
||||
|
||||
&-placement-top > &-content > &-arrow,
|
||||
&-placement-topLeft > &-content > &-arrow,
|
||||
&-placement-topRight > &-content > &-arrow {
|
||||
bottom: @popover-distance - @popover-arrow-width + 2.2px;
|
||||
border-top-color: transparent;
|
||||
border-right-color: @popover-bg;
|
||||
border-bottom-color: @popover-bg;
|
||||
border-left-color: transparent;
|
||||
box-shadow: 3px 3px 7px fade(@black, 7%);
|
||||
&-placement-top &-arrow,
|
||||
&-placement-topLeft &-arrow,
|
||||
&-placement-topRight &-arrow {
|
||||
bottom: @popover-distance - @popover-arrow-rotate-width;
|
||||
|
||||
&-content {
|
||||
box-shadow: 3px 3px 7px fade(@black, 7%);
|
||||
transform: translateY((-@popover-arrow-rotate-width / 2)) rotate(45deg);
|
||||
}
|
||||
}
|
||||
&-placement-top > &-content > &-arrow {
|
||||
&-placement-top &-arrow {
|
||||
left: 50%;
|
||||
transform: translateX(-50%) rotate(45deg);
|
||||
}
|
||||
&-placement-topLeft > &-content > &-arrow {
|
||||
left: 16px;
|
||||
}
|
||||
&-placement-topRight > &-content > &-arrow {
|
||||
right: 16px;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
&-placement-right > &-content > &-arrow,
|
||||
&-placement-rightTop > &-content > &-arrow,
|
||||
&-placement-rightBottom > &-content > &-arrow {
|
||||
left: @popover-distance - @popover-arrow-width + 2px;
|
||||
border-top-color: transparent;
|
||||
border-right-color: transparent;
|
||||
border-bottom-color: @popover-bg;
|
||||
border-left-color: @popover-bg;
|
||||
box-shadow: -3px 3px 7px fade(@black, 7%);
|
||||
&-placement-topLeft &-arrow {
|
||||
left: @popover-arrow-offset-horizontal;
|
||||
}
|
||||
&-placement-right > &-content > &-arrow {
|
||||
|
||||
&-placement-topRight &-arrow {
|
||||
right: @popover-arrow-offset-horizontal;
|
||||
}
|
||||
|
||||
&-placement-right &-arrow,
|
||||
&-placement-rightTop &-arrow,
|
||||
&-placement-rightBottom &-arrow {
|
||||
left: @popover-distance - @popover-arrow-rotate-width;
|
||||
|
||||
&-content {
|
||||
box-shadow: -3px 3px 7px fade(@black, 7%);
|
||||
transform: translateX((@popover-arrow-rotate-width / 2)) rotate(45deg);
|
||||
}
|
||||
}
|
||||
&-placement-right &-arrow {
|
||||
top: 50%;
|
||||
transform: translateY(-50%) rotate(45deg);
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
&-placement-rightTop > &-content > &-arrow {
|
||||
top: 12px;
|
||||
&-placement-rightTop &-arrow {
|
||||
top: @popover-arrow-offset-vertical;
|
||||
}
|
||||
&-placement-rightBottom > &-content > &-arrow {
|
||||
bottom: 12px;
|
||||
&-placement-rightBottom &-arrow {
|
||||
bottom: @popover-arrow-offset-vertical;
|
||||
}
|
||||
|
||||
&-placement-bottom > &-content > &-arrow,
|
||||
&-placement-bottomLeft > &-content > &-arrow,
|
||||
&-placement-bottomRight > &-content > &-arrow {
|
||||
top: @popover-distance - @popover-arrow-width + 2px;
|
||||
border-top-color: @popover-bg;
|
||||
border-right-color: transparent;
|
||||
border-bottom-color: transparent;
|
||||
border-left-color: @popover-bg;
|
||||
box-shadow: -2px -2px 5px fade(@black, 6%);
|
||||
&-placement-bottom &-arrow,
|
||||
&-placement-bottomLeft &-arrow,
|
||||
&-placement-bottomRight &-arrow {
|
||||
top: @popover-distance - @popover-arrow-rotate-width;
|
||||
|
||||
&-content {
|
||||
box-shadow: -2px -2px 5px fade(@black, 6%);
|
||||
transform: translateY((@popover-arrow-rotate-width / 2)) rotate(45deg);
|
||||
}
|
||||
}
|
||||
&-placement-bottom > &-content > &-arrow {
|
||||
|
||||
&-placement-bottom &-arrow {
|
||||
left: 50%;
|
||||
transform: translateX(-50%) rotate(45deg);
|
||||
}
|
||||
&-placement-bottomLeft > &-content > &-arrow {
|
||||
left: 16px;
|
||||
}
|
||||
&-placement-bottomRight > &-content > &-arrow {
|
||||
right: 16px;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
&-placement-left > &-content > &-arrow,
|
||||
&-placement-leftTop > &-content > &-arrow,
|
||||
&-placement-leftBottom > &-content > &-arrow {
|
||||
right: @popover-distance - @popover-arrow-width + 2px;
|
||||
border-top-color: @popover-bg;
|
||||
border-right-color: @popover-bg;
|
||||
border-bottom-color: transparent;
|
||||
border-left-color: transparent;
|
||||
box-shadow: 3px -3px 7px fade(@black, 7%);
|
||||
&-placement-bottomLeft &-arrow {
|
||||
left: @popover-arrow-offset-horizontal;
|
||||
}
|
||||
&-placement-left > &-content > &-arrow {
|
||||
|
||||
&-placement-bottomRight &-arrow {
|
||||
right: @popover-arrow-offset-horizontal;
|
||||
}
|
||||
|
||||
&-placement-left &-arrow,
|
||||
&-placement-leftTop &-arrow,
|
||||
&-placement-leftBottom &-arrow {
|
||||
right: @popover-distance - @popover-arrow-rotate-width;
|
||||
|
||||
&-content {
|
||||
box-shadow: 3px -3px 7px fade(@black, 7%);
|
||||
transform: translateX((-@popover-arrow-rotate-width / 2)) rotate(45deg);
|
||||
}
|
||||
}
|
||||
|
||||
&-placement-left &-arrow {
|
||||
top: 50%;
|
||||
transform: translateY(-50%) rotate(45deg);
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
&-placement-leftTop > &-content > &-arrow {
|
||||
top: 12px;
|
||||
|
||||
&-placement-leftTop &-arrow {
|
||||
top: @popover-arrow-offset-vertical;
|
||||
}
|
||||
&-placement-leftBottom > &-content > &-arrow {
|
||||
bottom: 12px;
|
||||
|
||||
&-placement-leftBottom &-arrow {
|
||||
bottom: @popover-arrow-offset-vertical;
|
||||
}
|
||||
}
|
||||
|
||||
.generator-popover-preset-color(@i: length(@preset-colors)) when (@i > 0) {
|
||||
.generator-popover-preset-color(@i - 1);
|
||||
@color: extract(@preset-colors, @i);
|
||||
@lightColor: '@{color}-6';
|
||||
.@{popover-prefix-cls}-@{color} {
|
||||
.@{popover-prefix-cls}-inner {
|
||||
background-color: @@lightColor;
|
||||
}
|
||||
.@{popover-prefix-cls}-arrow {
|
||||
&-content {
|
||||
background-color: @@lightColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.generator-popover-preset-color();
|
||||
|
||||
@import './rtl';
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
@import '../../style/themes/index';
|
||||
@import '../../style/mixins/index';
|
||||
|
||||
@popover-prefix-cls: ~'@{ant-prefix}-popover';
|
||||
|
||||
.@{popover-prefix-cls} {
|
||||
&-rtl {
|
||||
direction: rtl;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
&-message {
|
||||
&-title {
|
||||
.@{popover-prefix-cls}-rtl & {
|
||||
padding-right: @font-size-base + 8px;
|
||||
padding-left: @padding-md;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-buttons {
|
||||
.@{popover-prefix-cls}-rtl & {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
button {
|
||||
.@{popover-prefix-cls}-rtl & {
|
||||
margin-right: 8px;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -472,6 +472,7 @@
|
|||
@popover-color: @text-color;
|
||||
// Popover maximum width
|
||||
@popover-min-width: 177px;
|
||||
@popover-min-height: 32px;
|
||||
// Popover arrow width
|
||||
@popover-arrow-width: 6px;
|
||||
// Popover arrow color
|
||||
|
@ -481,6 +482,7 @@
|
|||
@popover-arrow-outer-color: @popover-bg;
|
||||
// Popover distance with trigger
|
||||
@popover-distance: @popover-arrow-width + 4px;
|
||||
@popover-padding-horizontal: @padding-md;
|
||||
|
||||
// Modal
|
||||
// --
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
</template>
|
||||
<script>
|
||||
import { defineComponent } from 'vue';
|
||||
import demo from '../v2-doc/src/docs/popconfirm/demo/index.vue';
|
||||
import demo from '../v2-doc/src/docs/popover/demo/index.vue';
|
||||
// import Affix from '../components/affix';
|
||||
export default defineComponent({
|
||||
components: {
|
||||
|
|
2
v2-doc
2
v2-doc
|
@ -1 +1 @@
|
|||
Subproject commit dcd8922ce91de1a48c515d3b06b898d27fcb30f4
|
||||
Subproject commit 53e2e630b1d0c666252e9b747690f0e524e5a08b
|
Loading…
Reference in New Issue