update farris btn group
This commit is contained in:
parent
2562ef9e77
commit
ec5fa3a10c
Binary file not shown.
|
@ -1,37 +1,90 @@
|
||||||
import { defineComponent, computed } from 'vue';
|
import { defineComponent, computed, ref, watch } from 'vue';
|
||||||
import type { SetupContext } from 'vue';
|
import type { SetupContext } from 'vue';
|
||||||
import { buttonGroupProps, ButtonGroupProps } from './button-group.props';
|
import { buttonGroupProps, ButtonGroupProps } from './button-group.props';
|
||||||
import { useButtonGroup } from './composition/use-button-group';
|
import { useButtonGroup } from './composition/use-button-group';
|
||||||
|
import { ElForm } from 'element-plus';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'FButtonGroup',
|
name: 'FButtonGroup',
|
||||||
props: buttonGroupProps,
|
props: buttonGroupProps,
|
||||||
emits: ['click', 'changeState', 'change', 'clickMenuOut'],
|
emits: ['click', 'changeState', 'change', 'clickMenuOut'],
|
||||||
setup(props: ButtonGroupProps, context: SetupContext) {
|
setup(props: ButtonGroupProps, context: SetupContext) {
|
||||||
// const { onClickButton } = useButtonGroup(props, context);
|
/* 显示出来的按钮组 */
|
||||||
const fButtonGroupSize = computed(() => ({
|
const flatButtons = props.data && props.data.slice(0, props.count);
|
||||||
'btn-group-lg': props.size === 'large',
|
const dpButtons = props.data && props.data.slice(props.count);
|
||||||
'btn-group-sm': props.size === 'small'
|
const $dpMenu = ref<InstanceType<typeof ElForm>>(null);
|
||||||
}));
|
const $dpBtn = ref<InstanceType<typeof ElForm>>(null);
|
||||||
// 样式:
|
const { showPanel, clickEvent, toggle, getRealPlacement, bindMenuMouseenter, unbindMenuMouseleave, bindMenuMouseleave } =
|
||||||
// 'btn '+
|
useButtonGroup(props, context, $dpMenu, $dpBtn);
|
||||||
// (btn.type?'btn-'+ btn.type:'btn-link')+
|
getRealPlacement(props.placement);
|
||||||
// ' '+
|
|
||||||
// (btn.type && btn.type !== 'link' ? 'f-btn-ml' :'')
|
|
||||||
|
|
||||||
// btn btn-btn.type f-btn-ml
|
return () => (
|
||||||
// btn btn-link
|
<div class="f-btn-group">
|
||||||
|
<div class={((props.size === 'large' ? 'btn-group-lg' : 'btn-group-sm') + ' btn-group f-btn-group-links')}>
|
||||||
|
{
|
||||||
|
flatButtons.map((btn) => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{
|
||||||
|
btn.icon &&
|
||||||
|
<button id="btn.id"
|
||||||
|
class={('btn btn-link btn-icontext' + (btn.disabled ? ' disabled' : ''))}
|
||||||
|
onClick={(event: MouseEvent) => toggle(event, btn)}>
|
||||||
|
<i class={"'f-icon '+ btn.icon?btn.icon:''"}></i>
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
{
|
||||||
|
!btn.icon &&
|
||||||
|
<button id="btn.id"
|
||||||
|
class={('btn ' + (btn.type ? 'btn-' + btn.type : 'btn-link') +
|
||||||
|
' ' + (btn.type && btn.type !== 'link' ? 'f-btn-ml' : '') +
|
||||||
|
(btn.disabled ? ' disabled' : ''))}
|
||||||
|
onClick={(event: MouseEvent) => toggle(event, btn)} >
|
||||||
|
{btn?.text}
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
{
|
||||||
|
!dpButtons.length ? '' :
|
||||||
|
<div class="btn-group f-btn-group-dropdown" onMouseleave={(event: MouseEvent) => unbindMenuMouseleave()}>
|
||||||
|
<button ref={$dpBtn} type="button" class="f-btn-dropdown" onClick={(event: MouseEvent) => clickEvent(event)}>
|
||||||
|
<span class="f-icon f-icon-lookup"></span>
|
||||||
|
</button>
|
||||||
|
<div ref={$dpMenu} class={('dropdown-menu f-btn-group-dropdown-menu' + (showPanel.value ? ' show' : ''))}
|
||||||
|
style="position:fixed;"
|
||||||
|
onMouseenter={(event: MouseEvent) => bindMenuMouseenter()}
|
||||||
|
onMouseleave={(event: MouseEvent) => bindMenuMouseleave()}
|
||||||
|
>
|
||||||
|
{
|
||||||
|
dpButtons.map((dpBtn) => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{
|
||||||
|
<div>
|
||||||
|
{dpBtn.divider && <div class="dropdown-divider"></div>}
|
||||||
|
<li id="dpBtn.id" class={('dropdown-item' + (dpBtn.disabled ? ' disabled' : ''))}
|
||||||
|
onClick={(event: MouseEvent) => toggle(event, dpBtn)}>
|
||||||
|
{
|
||||||
|
dpBtn.icon &&
|
||||||
|
<i class={('f-icon dropdown-item-icon' + dpBtn.icon)}></i>
|
||||||
|
}
|
||||||
|
<span>{dpBtn?.text}</span>
|
||||||
|
</li >
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
// const fButtonType = computed(() => ({
|
})
|
||||||
// 'btn-primary': props.buttonType === 'primary',
|
}
|
||||||
// 'btn-warning': props.buttonType === 'warning',
|
</div >
|
||||||
// 'btn-danger': props.buttonType === 'danger',
|
</div >
|
||||||
// 'btn-success': props.buttonType === 'success',
|
}
|
||||||
// 'btn-link': props.buttonType === 'link',
|
</div >
|
||||||
// 'btn-secondary': props.buttonType === 'secondary',
|
);
|
||||||
// }));
|
|
||||||
const theFlatButtons = useButtonGroup(props, context);
|
|
||||||
|
|
||||||
return () => '';
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,25 +1,36 @@
|
||||||
import { ExtractPropTypes, PropType } from 'vue';
|
import { ExtractPropTypes, PropType } from 'vue';
|
||||||
|
|
||||||
// eslint-disable-next-line max-len
|
type PlacementDirection =
|
||||||
type PlacementDirection = 'top' | 'top-left' | 'top-right' | 'left' | 'left-top' | 'left-bottom' | 'bottom' | 'bottom-left' | 'bottom-right' | 'right' | 'right-top' | 'right-bottom';
|
| 'top'
|
||||||
|
| 'top-left'
|
||||||
|
| 'top-right'
|
||||||
|
| 'left'
|
||||||
|
| 'left-top'
|
||||||
|
| 'left-bottom'
|
||||||
|
| 'bottom'
|
||||||
|
| 'bottom-left'
|
||||||
|
| 'bottom-right'
|
||||||
|
| 'right'
|
||||||
|
| 'right-top'
|
||||||
|
| 'right-bottom';
|
||||||
|
|
||||||
export const buttonGroupProps = {
|
export const buttonGroupProps = {
|
||||||
/**
|
/**
|
||||||
* 组件标识
|
* 组件标识
|
||||||
*/
|
*/
|
||||||
id: String,
|
id: String,
|
||||||
/**
|
/**
|
||||||
* 横向纠正的参照
|
* 横向纠正的参照
|
||||||
*/
|
*/
|
||||||
rectifyReferenceH: { type: HTMLElement, default: 'referenceEl' },
|
rectifyReferenceH: { type: HTMLElement},
|
||||||
/**
|
/**
|
||||||
* 纵向纠正的参照
|
* 纵向纠正的参照
|
||||||
*/
|
*/
|
||||||
rectifyReferenceV: { type: HTMLElement, default: 'referenceEl' },
|
rectifyReferenceV: { type: HTMLElement},
|
||||||
/**
|
/**
|
||||||
* 是否自动纠正位置
|
* 是否自动纠正位置
|
||||||
*/
|
*/
|
||||||
autoRectify: { type: Boolean, default: 'true' },
|
autoRectify: { type: Boolean, default: false },
|
||||||
/**
|
/**
|
||||||
* 计算方向的真正placement
|
* 计算方向的真正placement
|
||||||
*/
|
*/
|
||||||
|
@ -47,7 +58,7 @@ export const buttonGroupProps = {
|
||||||
/**
|
/**
|
||||||
* 按钮展示位置
|
* 按钮展示位置
|
||||||
*/
|
*/
|
||||||
placement: { type: String, default: 'bottom' }, /**
|
placement: { type: String as PropType<PlacementDirection>, default: 'bottom' }, /**
|
||||||
/**
|
/**
|
||||||
* 下拉面板显示
|
* 下拉面板显示
|
||||||
*/
|
*/
|
||||||
|
@ -55,8 +66,7 @@ export const buttonGroupProps = {
|
||||||
/**
|
/**
|
||||||
* 下拉面板显示标志
|
* 下拉面板显示标志
|
||||||
*/
|
*/
|
||||||
dpFlag: { type: Boolean, default: false },
|
dpFlag: { type: Boolean, default: false }
|
||||||
|
|
||||||
};
|
};
|
||||||
export default buttonGroupProps;
|
export default buttonGroupProps;
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,8 @@ export default defineComponent({
|
||||||
setup(props: ButtonProps, context: SetupContext) {
|
setup(props: ButtonProps, context: SetupContext) {
|
||||||
const { onClickButton } = useButton(props, context);
|
const { onClickButton } = useButton(props, context);
|
||||||
return () => (
|
return () => (
|
||||||
<button class={(props.size === 'large' ? 'btn-lg ' : 'btn-sm ') + 'btn ' + (props.buttonType ? 'btn-' + props.buttonType + ' ' : '')}
|
<button class={(props.size === 'large' ? 'btn-lg ' : 'btn-sm ') + 'btn ' + (props.type ? 'btn-' + props.type + ' ' : '')}
|
||||||
disabled={props.disable}
|
disabled={props.disabled}
|
||||||
onClick={(event: MouseEvent) => onClickButton(event)} >
|
onClick={(event: MouseEvent) => onClickButton(event)} >
|
||||||
{context.slots.default && context.slots.default()}
|
{context.slots.default && context.slots.default()}
|
||||||
</button >
|
</button >
|
||||||
|
|
|
@ -11,11 +11,11 @@ export const buttonProps = {
|
||||||
/**
|
/**
|
||||||
* 设置按钮类型
|
* 设置按钮类型
|
||||||
*/
|
*/
|
||||||
buttonType: { type: String as PropType<ButtonType>, default: 'primary' },
|
type: { type: String as PropType<ButtonType>, default: 'primary' },
|
||||||
/**
|
/**
|
||||||
* 是否禁用
|
* 是否禁用
|
||||||
*/
|
*/
|
||||||
disable: { type: Boolean, default: false },
|
disabled: { type: Boolean, default: false },
|
||||||
/**
|
/**
|
||||||
* 按钮尺寸
|
* 按钮尺寸
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,13 +1,9 @@
|
||||||
import { ComputedRef } from 'vue';
|
|
||||||
|
|
||||||
export interface UseButtonGroup {
|
export interface UseButtonGroup {
|
||||||
/**
|
showPanel: any;
|
||||||
* 附加按钮的Class
|
|
||||||
*/
|
|
||||||
// buttonClass: ComputedRef<Record<string, boolean | undefined>>;
|
|
||||||
/**
|
|
||||||
* 点击附加按钮事件响应函数
|
|
||||||
*/
|
|
||||||
clickEvent: ($event: Event) => void;
|
clickEvent: ($event: Event) => void;
|
||||||
|
toggle: ($event: Event, btn: any) => void;
|
||||||
|
getRealPlacement: (pment: any) => void;
|
||||||
|
bindMenuMouseenter: (this: any) => void;
|
||||||
|
unbindMenuMouseleave: (this: any) => void;
|
||||||
|
bindMenuMouseleave: (this: any) => void;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import { ComputedRef } from 'vue';
|
|
||||||
|
|
||||||
export interface UseButton {
|
export interface UseButton {
|
||||||
/**
|
/**
|
||||||
* 附加按钮的Class
|
* 附加按钮的Class
|
||||||
|
|
|
@ -1,70 +1,89 @@
|
||||||
import { UseButtonGroup } from './types-group';
|
import { UseButtonGroup } from './types-group';
|
||||||
import { ButtonGroupProps } from '../button-group.props';
|
import { ButtonGroupProps } from '../button-group.props';
|
||||||
import { computed, SetupContext } from 'vue';
|
import { computed, SetupContext, ref, nextTick } from 'vue';
|
||||||
|
|
||||||
export function useButtonGroup(props: ButtonGroupProps, context: SetupContext): UseButtonGroup {
|
export function useButtonGroup(props: ButtonGroupProps, context: SetupContext, dpMenu: any, dpBtn: any): UseButtonGroup {
|
||||||
// ngAfterViewChecked() {
|
/* menu size */
|
||||||
// if (this.show) {
|
let _menuWidth = 0;
|
||||||
// this.setPosition(this.event)
|
let _menuHeight = 0;
|
||||||
// }
|
const showPanel = ref(props.showPanel);
|
||||||
// }
|
let realPlacement = ref(props.realPlacement);
|
||||||
|
let mouseEnter = false;
|
||||||
|
|
||||||
// function onClickButton($event: Event) {
|
/* 下拉按钮显示到body中 可改变面板方向*/
|
||||||
// $event.stopPropagation();
|
|
||||||
// // this.disabled
|
|
||||||
// if (props.disable) {
|
|
||||||
// context.emit('clickButton', $event);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
function clickEvent($event: Event) {
|
|
||||||
$event.stopPropagation();
|
|
||||||
props.showPanel = !props.showPanel;
|
|
||||||
// body添加面板
|
|
||||||
if (props.showPanel) {
|
|
||||||
this.appendBody();
|
|
||||||
this.event = $event;
|
|
||||||
// 绑定相应的事件
|
|
||||||
this.ngZone.runOutsideAngular(() => {
|
|
||||||
this.bindMenuMouseenter();
|
|
||||||
this.bindiMenuMouseleave();
|
|
||||||
this.mouseNotEnterLeave();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// 面板显示 脏值检测
|
|
||||||
this.changeRef.detectChanges();
|
|
||||||
this.changeRef.markForCheck();
|
|
||||||
context.emit('changeState', props.showPanel);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 按钮触发事件 */
|
|
||||||
function toggle($event: any, btn) {
|
|
||||||
$event.stopPropagation();
|
|
||||||
if (btn.disabled) return;
|
|
||||||
props.showPanel = false;
|
|
||||||
// 关闭下拉按钮面板 脏值检测
|
|
||||||
this.changeRef.detectChanges();
|
|
||||||
this.changeRef.markForCheck();
|
|
||||||
context.emit('change', btn.id);
|
|
||||||
context.emit('click', btn);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 显示出来的按钮组 */
|
|
||||||
function flatButtons() {
|
|
||||||
return props.data && props.data.slice(0, this.count);
|
|
||||||
}
|
|
||||||
|
|
||||||
function dpButtons() {
|
|
||||||
return props.data && props.data.slice(this.count);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 下拉按钮显示到body中 可改变面板方向
|
|
||||||
function appendBody() {
|
function appendBody() {
|
||||||
if (this.dpMenu.nativeElement) {
|
if (dpMenu.value) {
|
||||||
// 添加到body 便于全部显示
|
// 添加到body 便于全部显示
|
||||||
document.body.appendChild(this.dpMenu.nativeElement);
|
document.body.appendChild(dpMenu.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* flag true */
|
||||||
|
function changeFlagToTrue() {
|
||||||
|
showPanel.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* flag false */
|
||||||
|
function changeFlagToFalse() {
|
||||||
|
showPanel.value = false;
|
||||||
|
}
|
||||||
|
/** 鼠标未移入下拉列表后一段时间关闭 */
|
||||||
|
function unbindMenuMouseleave() {
|
||||||
|
if (showPanel.value && !mouseEnter) {
|
||||||
|
setTimeout(() => {
|
||||||
|
if (showPanel.value && !mouseEnter) {
|
||||||
|
changeFlagToFalse();
|
||||||
|
mouseEnter = false;
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* 鼠标离开时 关闭menu */
|
||||||
|
function mouseLeave() {
|
||||||
|
setTimeout(() => {
|
||||||
|
if (showPanel.value) {
|
||||||
|
// close();
|
||||||
|
changeFlagToFalse();
|
||||||
|
mouseEnter = false;
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 绑定下拉面板鼠标进入事件 */
|
||||||
|
function bindMenuMouseenter() {
|
||||||
|
changeFlagToTrue();
|
||||||
|
mouseEnter = true;
|
||||||
|
}
|
||||||
|
/* 绑定下拉面板鼠标离开事件 */
|
||||||
|
function bindMenuMouseleave() {
|
||||||
|
mouseLeave();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确认参照的边界
|
||||||
|
*/
|
||||||
|
function getReferencePosition() {
|
||||||
|
let rRight = document.documentElement.clientWidth;
|
||||||
|
let rBottom = document.documentElement.clientHeight;
|
||||||
|
let rTop = 0;
|
||||||
|
let rLeft = 0;
|
||||||
|
// 横向参照
|
||||||
|
if (props.rectifyReferenceH) {
|
||||||
|
const elemH = document.querySelector('props.rectifyReferenceH');
|
||||||
|
if (elemH) {
|
||||||
|
rRight = elemH.getBoundingClientRect().right;
|
||||||
|
rLeft = elemH.getBoundingClientRect().left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 纵向参照
|
||||||
|
if (props.rectifyReferenceV) {
|
||||||
|
const elemV = document.querySelector('props.rectifyReferenceV');
|
||||||
|
if (elemV) {
|
||||||
|
rBottom = elemV.getBoundingClientRect().bottom;
|
||||||
|
rTop = elemV.getBoundingClientRect().top;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { top: rTop, left: rLeft, right: rRight, bottom: rBottom };
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 当下拉超出边界时 转换方向,
|
* 当下拉超出边界时 转换方向,
|
||||||
|
@ -75,97 +94,97 @@ export function useButtonGroup(props: ButtonGroupProps, context: SetupContext):
|
||||||
if (!props.autoRectify) {
|
if (!props.autoRectify) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const referPosition = this.getReferencePosition();
|
const referPosition = getReferencePosition();
|
||||||
let newPlacement = props.realPlacement;
|
let newPlacement = realPlacement;
|
||||||
if (newPlacement.indexOf('bottom') > -1) {
|
if (newPlacement.indexOf('bottom') > -1) {
|
||||||
if (this._menuHeight > referPosition.bottom - btnSize.bottom) {
|
if (_menuHeight > referPosition.bottom - btnSize.bottom) {
|
||||||
newPlacement = newPlacement.replace('bottom', 'top');
|
newPlacement = newPlacement.replace('bottom', 'top');
|
||||||
}
|
}
|
||||||
} else if (newPlacement.indexOf('top') > -1) {
|
} else if (newPlacement.indexOf('top') > -1) {
|
||||||
if (this._menuHeight > btnSize.top - referPosition.top) {
|
if (_menuHeight > btnSize.top - referPosition.top) {
|
||||||
newPlacement = newPlacement.replace('top', 'bottom');
|
newPlacement = newPlacement.replace('top', 'bottom');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (newPlacement.indexOf('left') > -1) {
|
if (newPlacement.indexOf('left') > -1) {
|
||||||
if (this._menuWidth > btnSize.left - referPosition.left) {
|
if (_menuWidth > btnSize.left - referPosition.left) {
|
||||||
newPlacement = newPlacement.replace('left', 'right');
|
newPlacement = newPlacement.replace('left', 'right');
|
||||||
}
|
}
|
||||||
} else if (newPlacement.indexOf('right') > -1) {
|
} else if (newPlacement.indexOf('right') > -1) {
|
||||||
if (this._menuWidth > referPosition.right - btnSize.right) {
|
if (_menuWidth > referPosition.right - btnSize.right) {
|
||||||
newPlacement = newPlacement.replace('right', 'left');
|
newPlacement = newPlacement.replace('right', 'left');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.rectifyPlacement = newPlacement;
|
realPlacement = newPlacement;
|
||||||
}
|
}
|
||||||
/**
|
/*
|
||||||
* 确认参照的边界
|
* 计算的位置区分忒细化
|
||||||
*/
|
*/
|
||||||
function getReferencePosition() {
|
function changePosition(btnSize: any) {
|
||||||
let rRight = document.documentElement.clientWidth;
|
let rplacement = '';
|
||||||
let rBottom = document.documentElement.clientHeight;
|
if (props.autoRectify) {
|
||||||
let rTop = 0;
|
rplacement = props.rectifyPlacement;
|
||||||
let rLeft = 0;
|
} else {
|
||||||
// 横向参照
|
rplacement = realPlacement;
|
||||||
if (props.rectifyReferenceH) {
|
|
||||||
rRight = props.rectifyReferenceH.getBoundingClientRect().right;
|
|
||||||
rLeft = props.rectifyReferenceH.getBoundingClientRect().left;
|
|
||||||
}
|
}
|
||||||
// 纵向参照
|
let styleTop = 0;
|
||||||
if (props.rectifyReferenceV) {
|
let styleLeft = 0;
|
||||||
rBottom = props.rectifyReferenceV.getBoundingClientRect().bottom;
|
if (rplacement.indexOf('top') > -1) {
|
||||||
rTop = props.rectifyReferenceV.getBoundingClientRect().top;
|
styleTop = btnSize.top - _menuHeight;
|
||||||
|
} else if (rplacement.indexOf('bottom') > -1) {
|
||||||
|
styleTop = btnSize.bottom;
|
||||||
}
|
}
|
||||||
return { top: rTop, left: rLeft, right: rRight, bottom: rBottom };
|
if (rplacement.indexOf('right') > -1) {
|
||||||
|
styleLeft = btnSize.right;
|
||||||
|
} else if (rplacement.indexOf('left') > -1) {
|
||||||
|
styleLeft = btnSize.left - _menuWidth;
|
||||||
|
}
|
||||||
|
// 开头
|
||||||
|
if (rplacement.indexOf('-top') > -1) {
|
||||||
|
styleTop -= btnSize.height;
|
||||||
|
} else if (rplacement.indexOf('-bottom') > -1) {
|
||||||
|
styleTop += btnSize.height;
|
||||||
|
}
|
||||||
|
dpMenu.value.style.top = styleTop + 'px';
|
||||||
|
dpMenu.value.style.left = styleLeft + 'px';
|
||||||
}
|
}
|
||||||
/**
|
/* 动态指定menu在body中的位置 */
|
||||||
* 变化对应的class
|
async function setPosition() {
|
||||||
* @param position
|
await nextTick();
|
||||||
*/
|
// 下拉按钮
|
||||||
function _getClsName(position) {
|
const btnSize = dpBtn.value.getBoundingClientRect();
|
||||||
let className = '';
|
// 下拉面板
|
||||||
switch (position) {
|
const menuRect = dpMenu.value.getBoundingClientRect();
|
||||||
case 'top-right':
|
_menuHeight = menuRect.height;
|
||||||
case 'top':
|
_menuWidth = menuRect.width;
|
||||||
// 朝上,朝上-朝右
|
// 如果要自动纠正方向
|
||||||
className = 'dropup';
|
if (props.autoRectify) {
|
||||||
break;
|
changePlacement(btnSize);
|
||||||
case 'top-left':
|
|
||||||
// 朝上-朝左
|
|
||||||
className = 'dropup-left';
|
|
||||||
break;
|
|
||||||
case 'left-bottom':
|
|
||||||
case 'left':
|
|
||||||
// 横向——朝左——朝下
|
|
||||||
className = 'dropleft';
|
|
||||||
break;
|
|
||||||
case 'left-top':
|
|
||||||
// 横向——朝左——朝上
|
|
||||||
className = 'dropleft-up';
|
|
||||||
break;
|
|
||||||
case 'right-bottom':
|
|
||||||
case 'right':
|
|
||||||
// 横向——朝右——朝下
|
|
||||||
className = 'dropright';
|
|
||||||
break;
|
|
||||||
case 'right-top':
|
|
||||||
// 横向——朝右——朝上
|
|
||||||
className = 'dropright-up';
|
|
||||||
break;
|
|
||||||
case 'bottom-left':
|
|
||||||
// 朝下——朝左
|
|
||||||
className = 'dropdown-left';
|
|
||||||
break;
|
|
||||||
case 'bottom-right':
|
|
||||||
className = 'dropdown';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// 朝下,朝下——朝右
|
|
||||||
className = 'dropdown';
|
|
||||||
}
|
}
|
||||||
return className;
|
changePosition(btnSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRealPlacement(pment) {
|
/** 展示下拉列表 */
|
||||||
|
function clickEvent($event: Event) {
|
||||||
|
$event.stopPropagation();
|
||||||
|
showPanel.value = !showPanel.value;
|
||||||
|
// body添加面板
|
||||||
|
if (showPanel.value) {
|
||||||
|
appendBody();
|
||||||
|
setPosition();
|
||||||
|
}
|
||||||
|
context.emit('changeState', showPanel.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 按钮触发事件 */
|
||||||
|
function toggle($event: any, btn: any) {
|
||||||
|
$event.stopPropagation();
|
||||||
|
if (btn.disabled) return;
|
||||||
|
showPanel.value = false;
|
||||||
|
context.emit('change', btn.id);
|
||||||
|
context.emit('click', btn);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRealPlacement(pment: any) {
|
||||||
let result = 'bottom-right';
|
let result = 'bottom-right';
|
||||||
switch (pment) {
|
switch (pment) {
|
||||||
case 'top':
|
case 'top':
|
||||||
|
@ -183,147 +202,16 @@ export function useButtonGroup(props: ButtonGroupProps, context: SetupContext):
|
||||||
default:
|
default:
|
||||||
result = pment;
|
result = pment;
|
||||||
}
|
}
|
||||||
return result;
|
realPlacement = result;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 计算的位置区分忒细化
|
|
||||||
*/
|
|
||||||
function changePosition(btnSize: any) {
|
|
||||||
let rplacement = '';
|
|
||||||
if (props.autoRectify) {
|
|
||||||
rplacement = this.rectifyPlacement;
|
|
||||||
} else {
|
|
||||||
rplacement = props.realPlacement;
|
|
||||||
}
|
|
||||||
let styleTop = 0;
|
|
||||||
let styleLeft = 0;
|
|
||||||
if (rplacement.indexOf('top') > -1) {
|
|
||||||
styleTop = btnSize.top - this._menuHeight;
|
|
||||||
} else if (rplacement.indexOf('bottom') > -1) {
|
|
||||||
styleTop = btnSize.bottom;
|
|
||||||
}
|
|
||||||
if (rplacement.indexOf('right') > -1) {
|
|
||||||
styleLeft = btnSize.right;
|
|
||||||
} else if (rplacement.indexOf('left') > -1) {
|
|
||||||
styleLeft = btnSize.left - this._menuWidth;
|
|
||||||
}
|
|
||||||
// 开头
|
|
||||||
if (rplacement.indexOf('-top') > -1) {
|
|
||||||
styleTop -= btnSize.height;
|
|
||||||
} else if (rplacement.indexOf('-bottom') > -1) {
|
|
||||||
styleTop += btnSize.height;
|
|
||||||
}
|
|
||||||
this.dpMenu.nativeElement.style.top = styleTop + 'px';
|
|
||||||
this.dpMenu.nativeElement.style.left = styleLeft + 'px';
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 绑定下拉面板鼠标进入事件 */
|
|
||||||
function bindMenuMouseenter() {
|
|
||||||
this.mouseenterEvent = this.changeFlagToTrue.bind(this);
|
|
||||||
this.dpMenu.nativeElement.addEventListener('mouseenter', this.mouseenterEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 绑定下拉面板鼠标离开事件 */
|
|
||||||
function bindiMenuMouseleave() {
|
|
||||||
this.mouseleaveEvent = this.mouseLeave.bind(this);
|
|
||||||
this.dpMenu.nativeElement.addEventListener('mouseleave', this.mouseleaveEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 绑定点击面板区域之外触发的事件 */
|
|
||||||
// bindDocClick() {
|
|
||||||
// this.documentClickEvent = this.clickDoc.bind(this);
|
|
||||||
// document.addEventListener('click', this.documentClickEvent);
|
|
||||||
// }
|
|
||||||
|
|
||||||
/* 解绑事件 */
|
|
||||||
function unbindMenuMouseenter() {
|
|
||||||
if (this.mouseenterEvent) {
|
|
||||||
this.dpMenu.nativeElement.removeEventListener('mouseenter', this.mouseenterEvent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function unbindiMenuMouseleave() {
|
|
||||||
if (this.mouseleaveEvent) {
|
|
||||||
this.dpMenu.nativeElement.removeEventListener('mouseleave', this.mouseleaveEvent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// unbindDocClick() {
|
|
||||||
// if (this.documentClickEvent) {
|
|
||||||
// document.removeEventListener('click', this.documentClickEvent);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
/* flag true */
|
|
||||||
function changeFlagToTrue() {
|
|
||||||
props.dpFlag = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* flag false */
|
|
||||||
function changeFlagToFalse() {
|
|
||||||
props.dpFlag = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 鼠标离开时 关闭menu */
|
|
||||||
function mouseLeave() {
|
|
||||||
if (props.dpFlag) {
|
|
||||||
this.changeFlagToFalse();
|
|
||||||
// this.unbindDocClick();
|
|
||||||
this.unbindiMenuMouseleave();
|
|
||||||
this.unbindMenuMouseenter();
|
|
||||||
this.close();
|
|
||||||
if (this.setTimeObj) {
|
|
||||||
this.ngZone.runOutsideAngular(() => {
|
|
||||||
clearTimeout(this.setTimeObj);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 鼠标没有进入到面板 一段时间后面板自动消失 */
|
|
||||||
function mouseNotEnterLeave() {
|
|
||||||
this.ngZone.runOutsideAngular(() => {
|
|
||||||
this.setTimeObj = setTimeout(() => {
|
|
||||||
if (!props.dpFlag) {
|
|
||||||
this.changeFlagToFalse();
|
|
||||||
// this.unbindDocClick();
|
|
||||||
this.unbindiMenuMouseleave();
|
|
||||||
this.unbindMenuMouseenter();
|
|
||||||
this.close();
|
|
||||||
if (this.setTimeObj) {
|
|
||||||
clearTimeout(this.setTimeObj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 2000);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 关闭下拉面板 */
|
|
||||||
function close() {
|
|
||||||
props.showPanel = false;
|
|
||||||
// 关闭下拉按钮面板 脏值检测
|
|
||||||
if (!this.changeRef.destroyed) {
|
|
||||||
this.changeRef.detectChanges();
|
|
||||||
this.changeRef.markForCheck();
|
|
||||||
}
|
|
||||||
this.dpBtn.nativeElement.blur();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 动态指定menu在body中的位置 */
|
|
||||||
function setPosition(e) {
|
|
||||||
// 下拉按钮
|
|
||||||
const btnSize = this.dpBtn.nativeElement.getBoundingClientRect();
|
|
||||||
// 下拉面板
|
|
||||||
const menuRect = this.dpMenu.nativeElement.getBoundingClientRect();
|
|
||||||
this._menuHeight = menuRect.height;
|
|
||||||
this._menuWidth = menuRect.width;
|
|
||||||
// 如果要自动纠正方向
|
|
||||||
if (props.autoRectify) {
|
|
||||||
this.changePlacement(btnSize);
|
|
||||||
}
|
|
||||||
this.changePosition(btnSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
clickEvent
|
showPanel,
|
||||||
|
clickEvent,
|
||||||
|
toggle,
|
||||||
|
getRealPlacement,
|
||||||
|
bindMenuMouseenter,
|
||||||
|
unbindMenuMouseleave,
|
||||||
|
bindMenuMouseleave
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { UseButton } from './types';
|
import { UseButton } from './types';
|
||||||
import { ButtonProps } from '../button.props';
|
import { ButtonProps } from '../button.props';
|
||||||
import { computed, SetupContext } from 'vue';
|
import { SetupContext } from 'vue';
|
||||||
|
|
||||||
export function useButton(props: ButtonProps, context: SetupContext): UseButton {
|
export function useButton(props: ButtonProps, context: SetupContext): UseButton {
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import Avatar from "./components/avatar.vue";
|
||||||
import Tabs from "./components/tabs.vue";
|
import Tabs from "./components/tabs.vue";
|
||||||
import ButtonEdit from "./components/button-edit.vue";
|
import ButtonEdit from "./components/button-edit.vue";
|
||||||
import FButton from "./components/button.vue";
|
import FButton from "./components/button.vue";
|
||||||
|
import FButtonGroup from "./components/button-group.vue";
|
||||||
import Switch from "./components/switch.vue";
|
import Switch from "./components/switch.vue";
|
||||||
import RadioGroup from "./components/radio-group.vue";
|
import RadioGroup from "./components/radio-group.vue";
|
||||||
import Section from "./components/section.vue";
|
import Section from "./components/section.vue";
|
||||||
|
@ -37,6 +38,7 @@ const canAutoComplete = ref(false);
|
||||||
<ButtonEdit></ButtonEdit>
|
<ButtonEdit></ButtonEdit>
|
||||||
<Avatar></Avatar>
|
<Avatar></Avatar>
|
||||||
<FButton></FButton>
|
<FButton></FButton>
|
||||||
|
<FButtonGroup></FButtonGroup>
|
||||||
<Switch></Switch>
|
<Switch></Switch>
|
||||||
<RadioGroup></RadioGroup>
|
<RadioGroup></RadioGroup>
|
||||||
<Section></Section>
|
<Section></Section>
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue';
|
||||||
|
|
||||||
|
import FButtonGroup from '../../components/button/src/button-group.component';
|
||||||
|
|
||||||
|
const data = ref([
|
||||||
|
{
|
||||||
|
id: 'b1',
|
||||||
|
text: '增加',
|
||||||
|
type: 'primary'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'b2',
|
||||||
|
text: '删除',
|
||||||
|
type: 'warning'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'b3',
|
||||||
|
text: '保存',
|
||||||
|
type: 'success'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'b4',
|
||||||
|
text: '编辑',
|
||||||
|
type: 'danger'
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
const data1 = ref([
|
||||||
|
{
|
||||||
|
id: 'b1',
|
||||||
|
text: '增加',
|
||||||
|
type: 'link'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'b2',
|
||||||
|
text: '删除',
|
||||||
|
type: 'link',
|
||||||
|
disabled: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'b3',
|
||||||
|
text: '保存',
|
||||||
|
type: 'link'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'b4',
|
||||||
|
text: '编辑',
|
||||||
|
type: 'link',
|
||||||
|
disabled: true
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<FButtonGroup :count="data.length" :data="data" :placement="'bottom-left'"></FButtonGroup>
|
||||||
|
<FButtonGroup :count="2" :data="data1" :placement="'bottom-right'"></FButtonGroup>
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -3,24 +3,24 @@ import { ref } from 'vue';
|
||||||
|
|
||||||
import FButton from '../../components/button/src/button.component';
|
import FButton from '../../components/button/src/button.component';
|
||||||
|
|
||||||
const disable = ref(false);
|
const disabled = ref(false);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<input type="checkbox" id="checkbox" v-model="disable" />
|
<input type="checkbox" id="checkbox" v-model="disabled" />
|
||||||
<div>
|
<div>
|
||||||
<label for="checkbox">disable:{{ disable }}</label>
|
<label for="checkbox">disabled:{{ disabled }}</label>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<FButton style="margin: 5px;" :disable="disable"> 主要按钮 </FButton>
|
<FButton style="margin: 5px;" :disabled="disabled"> 主要按钮 </FButton>
|
||||||
<FButton style="margin: 5px;" :button-type="'danger'" :disable="disable"> 危险按钮 </FButton>
|
<FButton style="margin: 5px;" :type="'danger'" :disabled="disabled"> 危险按钮 </FButton>
|
||||||
<FButton style="margin: 5px;" :button-type="'success'" :disable="disable"> 成功按钮 </FButton>
|
<FButton style="margin: 5px;" :type="'success'" :disabled="disabled"> 成功按钮 </FButton>
|
||||||
<FButton style="margin: 5px;" :button-type="'warning'" :disable="disable"> 警告按钮 </FButton>
|
<FButton style="margin: 5px;" :type="'warning'" :disabled="disabled"> 警告按钮 </FButton>
|
||||||
<FButton style="margin: 5px;" :button-type="'secondary'" :disable="disable"> 信息按钮 </FButton>
|
<FButton style="margin: 5px;" :type="'secondary'" :disabled="disabled"> 信息按钮 </FButton>
|
||||||
<FButton style="margin: 5px;" :button-type="'link'" :disable="disable"> 文本按钮 </FButton>
|
<FButton style="margin: 5px;" :type="'link'" :disabled="disabled"> 文本按钮 </FButton>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<FButton style="margin: 5px;" :size="'small'" :disable="disable"> 小尺寸 </FButton>
|
<FButton style="margin: 5px;" :size="'small'" :disabled="disabled"> 小尺寸 </FButton>
|
||||||
<FButton style="margin: 5px;" :size="'large'" :disable="disable"> 大尺寸 </FButton>
|
<FButton style="margin: 5px;" :size="'large'" :disabled="disabled"> 大尺寸 </FButton>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
Loading…
Reference in New Issue