mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2026-07-07 10:08:45 +08:00
feat(table): 抽取 ActionPopconfirm 并优化 sub-actions 展开交互
将 Popconfirm 逻辑抽离为独立组件,ActionButton 内置 tooltip 支持,sub-actions 触发按钮改用箭头图标切换展开状态。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
78a1259665
commit
b183e71f64
@ -37,6 +37,7 @@
|
||||
"url": "https://github.com/Tencent/tmagic-editor.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"@element-plus/icons-vue": "^2.3.2",
|
||||
"lodash-es": "^4.17.21"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@ -1,20 +1,26 @@
|
||||
<template>
|
||||
<TMagicButton
|
||||
v-show="visible"
|
||||
:class="btnClass"
|
||||
link
|
||||
size="small"
|
||||
:type="action.buttonType || 'primary'"
|
||||
:icon="action.icon"
|
||||
:disabled="disabled(action.disabled, row)"
|
||||
@click="onClick"
|
||||
<TMagicTooltip
|
||||
:placement="action.tooltipPlacement || 'top'"
|
||||
:disabled="!Boolean(action.tooltip)"
|
||||
:content="action.tooltip"
|
||||
>
|
||||
<span v-html="formatter(action.text, row)"></span>
|
||||
</TMagicButton>
|
||||
<TMagicButton
|
||||
v-show="visible"
|
||||
:class="btnClass"
|
||||
link
|
||||
size="small"
|
||||
:type="action.buttonType || 'primary'"
|
||||
:icon="action.icon"
|
||||
:disabled="disabled(action.disabled, row)"
|
||||
@click="onClick"
|
||||
>
|
||||
<span v-html="formatter(action.text, row)"></span>
|
||||
</TMagicButton>
|
||||
</TMagicTooltip>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { TMagicButton } from '@tmagic/design';
|
||||
import { TMagicButton, TMagicTooltip } from '@tmagic/design';
|
||||
|
||||
import { disabled, formatActionText as formatter } from './actionHelpers';
|
||||
import { ColumnActionConfig } from './schema';
|
||||
|
||||
44
packages/table/src/ActionPopconfirm.vue
Normal file
44
packages/table/src/ActionPopconfirm.vue
Normal file
@ -0,0 +1,44 @@
|
||||
<template>
|
||||
<TMagicPopconfirm
|
||||
placement="top"
|
||||
:width="action.popconfirmWidth"
|
||||
:title="formatter(action.confirmText, row) || '确定执行此操作?'"
|
||||
@confirm="onConfirm"
|
||||
>
|
||||
<template #reference>
|
||||
<ActionButton :action="action" :row="row" :index="index" :btn-class="btnClass" :visible="visible" />
|
||||
</template>
|
||||
</TMagicPopconfirm>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { TMagicPopconfirm } from '@tmagic/design';
|
||||
|
||||
import ActionButton from './ActionButton.vue';
|
||||
import { formatActionText as formatter } from './actionHelpers';
|
||||
import { ColumnActionConfig } from './schema';
|
||||
|
||||
defineOptions({
|
||||
name: 'MTableActionPopconfirm',
|
||||
});
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
action: ColumnActionConfig;
|
||||
row: any;
|
||||
index: number;
|
||||
btnClass?: string;
|
||||
visible?: boolean;
|
||||
}>(),
|
||||
{
|
||||
btnClass: 'action-btn',
|
||||
visible: true,
|
||||
},
|
||||
);
|
||||
|
||||
const emit = defineEmits<{
|
||||
confirm: [action: ColumnActionConfig, row: any, index: number];
|
||||
}>();
|
||||
|
||||
const onConfirm = () => emit('confirm', props.action, props.row, props.index);
|
||||
</script>
|
||||
@ -1,24 +1,17 @@
|
||||
<template>
|
||||
<template v-for="(action, actionIndex) in config.actions" :key="actionIndex">
|
||||
<TMagicPopconfirm
|
||||
<ActionPopconfirm
|
||||
v-if="action.popconfirm"
|
||||
placement="top"
|
||||
:width="action.popconfirmWidth"
|
||||
:title="formatter(action.confirmText, row) || '确定执行此操作?'"
|
||||
@confirm="actionHandler(action, row, index)"
|
||||
>
|
||||
<template #reference>
|
||||
<ActionButton
|
||||
:action="action"
|
||||
:row="row"
|
||||
:index="index"
|
||||
:visible="display(action.display, row) && !editState[index]"
|
||||
/>
|
||||
</template>
|
||||
</TMagicPopconfirm>
|
||||
:action="action"
|
||||
:row="row"
|
||||
:index="index"
|
||||
:visible="display(action.display, row) && !editState[index]"
|
||||
@confirm="actionHandler"
|
||||
/>
|
||||
|
||||
<TMagicPopover
|
||||
v-else-if="action.type === 'sub-actions'"
|
||||
v-model:visible="popoverVisible"
|
||||
trigger="click"
|
||||
:placement="action.subActionConfig?.placement || 'bottom'"
|
||||
:width="action.subActionConfig?.popoverWidth"
|
||||
@ -26,66 +19,49 @@
|
||||
:destroy-on-close="action.subActionConfig?.popoverDestroyOnClose"
|
||||
>
|
||||
<template #reference>
|
||||
<ActionButton
|
||||
:action="action"
|
||||
:row="row"
|
||||
:index="index"
|
||||
:visible="display(action.display, row) && !editState[index]"
|
||||
/>
|
||||
<TMagicButton
|
||||
v-show="action.subActionConfig?.items?.length && display(action.display, row) && !editState[index]"
|
||||
class="action-btn"
|
||||
link
|
||||
size="small"
|
||||
:type="action.buttonType || 'primary'"
|
||||
:icon="popoverVisible ? ArrowDown : ArrowRight"
|
||||
@click.stop="togglePopover"
|
||||
></TMagicButton>
|
||||
</template>
|
||||
<div class="sub-actions">
|
||||
<template v-for="(subAction, subIndex) in action.subActionConfig?.items" :key="subIndex">
|
||||
<TMagicPopconfirm
|
||||
<ActionPopconfirm
|
||||
v-if="subAction.popconfirm"
|
||||
placement="top"
|
||||
:width="subAction.popconfirmWidth"
|
||||
:title="formatter(subAction.confirmText, row) || '确定执行此操作?'"
|
||||
@confirm="actionHandler(subAction, row, index)"
|
||||
>
|
||||
<template #reference>
|
||||
<ActionButton
|
||||
:action="subAction"
|
||||
:row="row"
|
||||
:index="index"
|
||||
btn-class="sub-action-btn"
|
||||
:visible="display(subAction.display, row)"
|
||||
/>
|
||||
</template>
|
||||
</TMagicPopconfirm>
|
||||
:action="subAction"
|
||||
:row="row"
|
||||
:index="index"
|
||||
btn-class="sub-action-btn"
|
||||
:visible="display(subAction.display, row)"
|
||||
@confirm="actionHandler"
|
||||
/>
|
||||
|
||||
<TMagicTooltip
|
||||
<ActionButton
|
||||
v-else
|
||||
:placement="subAction.tooltipPlacement || 'top'"
|
||||
:disabled="!Boolean(subAction.tooltip)"
|
||||
:content="subAction.tooltip"
|
||||
>
|
||||
<ActionButton
|
||||
:action="subAction"
|
||||
:row="row"
|
||||
:index="index"
|
||||
btn-class="sub-action-btn"
|
||||
:visible="display(subAction.display, row)"
|
||||
@click="actionHandler"
|
||||
/>
|
||||
</TMagicTooltip>
|
||||
:action="subAction"
|
||||
:row="row"
|
||||
:index="index"
|
||||
btn-class="sub-action-btn"
|
||||
:visible="display(subAction.display, row)"
|
||||
@click="actionHandler"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
</TMagicPopover>
|
||||
|
||||
<TMagicTooltip
|
||||
<ActionButton
|
||||
v-else
|
||||
:placement="action.tooltipPlacement || 'top'"
|
||||
:disabled="!Boolean(action.tooltip)"
|
||||
:content="action.tooltip"
|
||||
>
|
||||
<ActionButton
|
||||
:action="action"
|
||||
:row="row"
|
||||
:index="index"
|
||||
:visible="display(action.display, row) && !editState[index]"
|
||||
@click="actionHandler"
|
||||
/>
|
||||
</TMagicTooltip>
|
||||
:action="action"
|
||||
:row="row"
|
||||
:index="index"
|
||||
:visible="display(action.display, row) && !editState[index]"
|
||||
@click="actionHandler"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<TMagicButton
|
||||
@ -109,12 +85,15 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { ArrowDown, ArrowRight } from '@element-plus/icons-vue';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
|
||||
import { TMagicButton, tMagicMessage, TMagicPopconfirm, TMagicPopover, TMagicTooltip } from '@tmagic/design';
|
||||
import { TMagicButton, tMagicMessage, TMagicPopover } from '@tmagic/design';
|
||||
|
||||
import ActionButton from './ActionButton.vue';
|
||||
import { display, formatActionText as formatter } from './actionHelpers';
|
||||
import { display } from './actionHelpers';
|
||||
import ActionPopconfirm from './ActionPopconfirm.vue';
|
||||
import { ColumnActionConfig, ColumnConfig } from './schema';
|
||||
|
||||
defineOptions({
|
||||
@ -138,6 +117,11 @@ const props = withDefaults(
|
||||
},
|
||||
);
|
||||
|
||||
const popoverVisible = ref(false);
|
||||
const togglePopover = () => {
|
||||
popoverVisible.value = !popoverVisible.value;
|
||||
};
|
||||
|
||||
const emit = defineEmits<{
|
||||
'after-action': [{ index: number }];
|
||||
'after-action-cancel': [{ index: number }];
|
||||
@ -192,15 +176,23 @@ defineExpose({
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
<style lang="scss">
|
||||
.sub-actions {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
align-items: flex-start;
|
||||
|
||||
.sub-actions .sub-action-btn {
|
||||
justify-content: flex-start;
|
||||
width: 100%;
|
||||
.sub-action-btn {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.tmagic-design-button + .tmagic-design-button {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.tmagic-design-button {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
3
pnpm-lock.yaml
generated
3
pnpm-lock.yaml
generated
@ -497,6 +497,9 @@ importers:
|
||||
|
||||
packages/table:
|
||||
dependencies:
|
||||
'@element-plus/icons-vue':
|
||||
specifier: ^2.3.2
|
||||
version: 2.3.2(vue@3.5.38(typescript@6.0.3))
|
||||
'@tmagic/design':
|
||||
specifier: workspace:*
|
||||
version: link:../design
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user