add tiptap

This commit is contained in:
Timi
2026-08-21 01:11:23 +08:00
parent 763783b984
commit 68d9946b70
41 changed files with 5845 additions and 35 deletions
@@ -0,0 +1,126 @@
<template>
<t-popconfirm
v-model:visible="visible"
trigger="click"
placement="bottom"
:show-arrow="false"
:popup-props="{ overlayClassName: 'tp-table-pop' }"
@visible-change="onVisibleChange"
>
<template #icon><span></span></template>
<template #content>
<div class="table-picker" @mouseleave="onReset">
<div class="tip" v-text="`${hoverRow} × ${hoverCol}`" />
<div class="grid">
<button
v-for="item in tablePickerItems"
:key="item.key"
class="cell"
:class="{ active: item.active }"
type="button"
@mousemove="onHover(item.row, item.col)"
@click="onSelect(item.row, item.col)"
/>
</div>
</div>
</template>
<t-button v-popup="'插入表格'" variant="outline" :theme="active ? 'primary' : 'default'">
<t-icon name="table" />
</t-button>
</t-popconfirm>
</template>
<script lang="ts" setup>
import { TABLE_PICKER_SIZE } from "./shared";
import type { TiptapEditorInstance } from "./useTiptapEditor";
defineOptions({
name: "TiptapTableButton"
});
const props = defineProps<{
editor?: TiptapEditorInstance;
active: boolean;
}>();
const visible = ref(false);
const hoverRow = ref(1);
const hoverCol = ref(1);
const tablePickerItems = computed(() => {
const items: { key: string; row: number; col: number; active: boolean }[] = [];
for (let row = 1; row < TABLE_PICKER_SIZE + 1; row += 1) {
for (let col = 1; col < TABLE_PICKER_SIZE + 1; col += 1) {
items.push({
key: `${row}-${col}`,
row,
col,
active: row < hoverRow.value + 1 && col < hoverCol.value + 1
});
}
}
return items;
});
function onVisibleChange(nextVisible: boolean) {
if (!nextVisible) {
return;
}
hoverRow.value = 1;
hoverCol.value = 1;
}
function onReset() {
hoverRow.value = 1;
hoverCol.value = 1;
}
function onHover(row: number, col: number) {
hoverRow.value = row;
hoverCol.value = col;
}
function onSelect(row: number, col: number) {
if (!props.editor) {
return;
}
hoverRow.value = row;
hoverCol.value = col;
props.editor.chain().focus().insertTable({ rows: row, cols: col, withHeaderRow: true }).run();
visible.value = false;
}
</script>
<style lang="less" scoped>
.table-picker {
width: 10.5rem;
.tip {
height: 1.5rem;
color: var(--td-text-color-secondary);
font-size: .75rem;
line-height: 1.5rem;
}
.grid {
gap: .125rem;
display: grid;
grid-template-columns: repeat(7, 1fr);
}
.cell {
width: 1.25rem;
height: 1.25rem;
padding: 0;
border: 1px solid var(--td-component-border);
cursor: pointer;
background: var(--td-bg-color-container);
transition: background .15s ease, border-color .15s ease;
&.active {
border-color: var(--td-brand-color);
background: var(--td-brand-color-light);
}
}
}
</style>