feat: table border type #152
This commit is contained in:
@@ -146,3 +146,15 @@
|
|||||||
.ce-contextmenu-vertical-align-bottom {
|
.ce-contextmenu-vertical-align-bottom {
|
||||||
background-image: url(../../../assets/images/vertical-align-bottom.svg);
|
background-image: url(../../../assets/images/vertical-align-bottom.svg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ce-contextmenu-border-all {
|
||||||
|
background-image: url(../../../assets/images/table-border-all.svg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ce-contextmenu-border-empty {
|
||||||
|
background-image: url(../../../assets/images/table-border-empty.svg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ce-contextmenu-border-external {
|
||||||
|
background-image: url(../../../assets/images/table-border-external.svg);
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M2.5 3a.5.5 0 01.5-.5h11a.5.5 0 01.5.5v11a.5.5 0 01-.5.5H3a.5.5 0 01-.5-.5V3z" stroke="#3D4757"/><path fill="#3D4757" d="M3 8h11v1H3z"/><path fill="#3D4757" d="M9 3v11H8V3z"/></svg>
|
||||||
|
After Width: | Height: | Size: 265 B |
@@ -0,0 +1 @@
|
|||||||
|
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M13 3h-1V2h1a1 1 0 011 1v1h-1V3zm-3-1v1H8.5v2h-1V3H6V2h4zM4 2v1H3v1H2V3a1 1 0 011-1h1zM2 6h1v1.5h2v1H3V10H2V6zm0 6h1v1h1v1H3a1 1 0 01-1-1v-1zm4 2v-1h1.5v-2h1v2H10v1H6zm6 0v-1h1v-1h1v1a1 1 0 01-1 1h-1zm2-4h-1V8.5h-2v-1h2V6h1v4zM8.5 7.5v-1h-1v1h-1v1h1v1h1v-1h1v-1h-1z" fill="#AAACB0"/></svg>
|
||||||
|
After Width: | Height: | Size: 413 B |
@@ -0,0 +1 @@
|
|||||||
|
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M2.5 3a.5.5 0 01.5-.5h11a.5.5 0 01.5.5v11a.5.5 0 01-.5.5H3a.5.5 0 01-.5-.5V3z" stroke="#3D4757"/><path fill-rule="evenodd" clip-rule="evenodd" d="M9 5V3H8v2h1zm0 9v-2H8v2h1zM5 8H3v1h2V8zm9 0h-2v1h2V8zM9 7v1h1v1H9v1H8V9H7V8h1V7h1z" fill="#AAACB0"/></svg>
|
||||||
|
After Width: | Height: | Size: 337 B |
@@ -1,4 +1,4 @@
|
|||||||
import { IElement, ImageDisplay, INavigateInfo, VerticalAlign } from '../..'
|
import { IElement, ImageDisplay, INavigateInfo, TableBorder, VerticalAlign } from '../..'
|
||||||
import { EditorMode, PageMode, PaperDirection } from '../../dataset/enum/Editor'
|
import { EditorMode, PageMode, PaperDirection } from '../../dataset/enum/Editor'
|
||||||
import { RowFlex } from '../../dataset/enum/Row'
|
import { RowFlex } from '../../dataset/enum/Row'
|
||||||
import { IDrawImagePayload, IPainterOptions } from '../../interface/Draw'
|
import { IDrawImagePayload, IPainterOptions } from '../../interface/Draw'
|
||||||
@@ -49,6 +49,7 @@ export class Command {
|
|||||||
private static mergeTableCell: CommandAdapt['mergeTableCell']
|
private static mergeTableCell: CommandAdapt['mergeTableCell']
|
||||||
private static cancelMergeTableCell: CommandAdapt['cancelMergeTableCell']
|
private static cancelMergeTableCell: CommandAdapt['cancelMergeTableCell']
|
||||||
private static tableTdVerticalAlign: CommandAdapt['tableTdVerticalAlign']
|
private static tableTdVerticalAlign: CommandAdapt['tableTdVerticalAlign']
|
||||||
|
private static tableBorderType: CommandAdapt['tableBorderType']
|
||||||
private static image: CommandAdapt['image']
|
private static image: CommandAdapt['image']
|
||||||
private static hyperlink: CommandAdapt['hyperlink']
|
private static hyperlink: CommandAdapt['hyperlink']
|
||||||
private static deleteHyperlink: CommandAdapt['deleteHyperlink']
|
private static deleteHyperlink: CommandAdapt['deleteHyperlink']
|
||||||
@@ -124,6 +125,7 @@ export class Command {
|
|||||||
Command.mergeTableCell = adapt.mergeTableCell.bind(adapt)
|
Command.mergeTableCell = adapt.mergeTableCell.bind(adapt)
|
||||||
Command.cancelMergeTableCell = adapt.cancelMergeTableCell.bind(adapt)
|
Command.cancelMergeTableCell = adapt.cancelMergeTableCell.bind(adapt)
|
||||||
Command.tableTdVerticalAlign = adapt.tableTdVerticalAlign.bind(adapt)
|
Command.tableTdVerticalAlign = adapt.tableTdVerticalAlign.bind(adapt)
|
||||||
|
Command.tableBorderType = adapt.tableBorderType.bind(adapt)
|
||||||
Command.image = adapt.image.bind(adapt)
|
Command.image = adapt.image.bind(adapt)
|
||||||
Command.hyperlink = adapt.hyperlink.bind(adapt)
|
Command.hyperlink = adapt.hyperlink.bind(adapt)
|
||||||
Command.deleteHyperlink = adapt.deleteHyperlink.bind(adapt)
|
Command.deleteHyperlink = adapt.deleteHyperlink.bind(adapt)
|
||||||
@@ -323,6 +325,10 @@ export class Command {
|
|||||||
return Command.tableTdVerticalAlign(payload)
|
return Command.tableTdVerticalAlign(payload)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public executeTableBorderType(payload: TableBorder) {
|
||||||
|
return Command.tableBorderType(payload)
|
||||||
|
}
|
||||||
|
|
||||||
public executeHyperlink(payload: IElement) {
|
public executeHyperlink(payload: IElement) {
|
||||||
return Command.hyperlink(payload)
|
return Command.hyperlink(payload)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { EditorContext, EditorMode, PageMode, PaperDirection } from '../../datas
|
|||||||
import { ElementType } from '../../dataset/enum/Element'
|
import { ElementType } from '../../dataset/enum/Element'
|
||||||
import { ElementStyleKey } from '../../dataset/enum/ElementStyle'
|
import { ElementStyleKey } from '../../dataset/enum/ElementStyle'
|
||||||
import { RowFlex } from '../../dataset/enum/Row'
|
import { RowFlex } from '../../dataset/enum/Row'
|
||||||
|
import { TableBorder } from '../../dataset/enum/table/Table'
|
||||||
import { VerticalAlign } from '../../dataset/enum/VerticalAlign'
|
import { VerticalAlign } from '../../dataset/enum/VerticalAlign'
|
||||||
import { IDrawImagePayload, IPainterOptions } from '../../interface/Draw'
|
import { IDrawImagePayload, IPainterOptions } from '../../interface/Draw'
|
||||||
import { IEditorOption, IEditorResult } from '../../interface/Editor'
|
import { IEditorOption, IEditorResult } from '../../interface/Editor'
|
||||||
@@ -1032,9 +1033,9 @@ export class CommandAdapt {
|
|||||||
const element = originalElementList[index!]
|
const element = originalElementList[index!]
|
||||||
const curTd = element?.trList?.[trIndex!]?.tdList?.[tdIndex!]
|
const curTd = element?.trList?.[trIndex!]?.tdList?.[tdIndex!]
|
||||||
if (
|
if (
|
||||||
!curTd
|
!curTd ||
|
||||||
|| curTd.verticalAlign === payload
|
curTd.verticalAlign === payload ||
|
||||||
|| (!curTd.verticalAlign && payload === VerticalAlign.TOP)
|
(!curTd.verticalAlign && payload === VerticalAlign.TOP)
|
||||||
) {
|
) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -1046,6 +1047,27 @@ export class CommandAdapt {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public tableBorderType(payload: TableBorder) {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
|
const positionContext = this.position.getPositionContext()
|
||||||
|
if (!positionContext.isTable) return
|
||||||
|
const { index } = positionContext
|
||||||
|
const originalElementList = this.draw.getOriginalElementList()
|
||||||
|
const element = originalElementList[index!]
|
||||||
|
if (
|
||||||
|
(!element.borderType && payload === TableBorder.ALL) ||
|
||||||
|
element.borderType === payload
|
||||||
|
) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
element.borderType = payload
|
||||||
|
const { endIndex } = this.range.getRange()
|
||||||
|
this.draw.render({
|
||||||
|
curIndex: endIndex
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
public hyperlink(payload: IElement) {
|
public hyperlink(payload: IElement) {
|
||||||
const isReadonly = this.draw.isReadonly()
|
const isReadonly = this.draw.isReadonly()
|
||||||
if (isReadonly) return
|
if (isReadonly) return
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { VerticalAlign } from '../../../dataset/enum/VerticalAlign'
|
import { VerticalAlign } from '../../../dataset/enum/VerticalAlign'
|
||||||
|
import { TableBorder } from '../../../dataset/enum/table/Table'
|
||||||
import { IRegisterContextMenu } from '../../../interface/contextmenu/ContextMenu'
|
import { IRegisterContextMenu } from '../../../interface/contextmenu/ContextMenu'
|
||||||
import { Command } from '../../command/Command'
|
import { Command } from '../../command/Command'
|
||||||
|
|
||||||
@@ -6,6 +7,39 @@ export const tableMenus: IRegisterContextMenu[] = [
|
|||||||
{
|
{
|
||||||
isDivider: true
|
isDivider: true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
i18nPath: 'contextmenu.table.border',
|
||||||
|
icon: 'border-all',
|
||||||
|
when: (payload) => {
|
||||||
|
return !payload.isReadonly && payload.isInTable
|
||||||
|
},
|
||||||
|
childMenus: [
|
||||||
|
{
|
||||||
|
i18nPath: 'contextmenu.table.borderAll',
|
||||||
|
icon: 'border-all',
|
||||||
|
when: () => true,
|
||||||
|
callback: (command: Command) => {
|
||||||
|
command.executeTableBorderType(TableBorder.ALL)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
i18nPath: 'contextmenu.table.borderEmpty',
|
||||||
|
icon: 'border-empty',
|
||||||
|
when: () => true,
|
||||||
|
callback: (command: Command) => {
|
||||||
|
command.executeTableBorderType(TableBorder.EMPTY)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
i18nPath: 'contextmenu.table.borderExternal',
|
||||||
|
icon: 'border-external',
|
||||||
|
when: () => true,
|
||||||
|
callback: (command: Command) => {
|
||||||
|
command.executeTableBorderType(TableBorder.EXTERNAL)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
i18nPath: 'contextmenu.table.verticalAlign',
|
i18nPath: 'contextmenu.table.verticalAlign',
|
||||||
icon: 'vertical-align',
|
icon: 'vertical-align',
|
||||||
|
|||||||
@@ -1,8 +1,17 @@
|
|||||||
import { ElementType, IElement } from '../../../..'
|
import { ElementType, IElement, TableBorder } from '../../../..'
|
||||||
import { IEditorOption } from '../../../../interface/Editor'
|
import { IEditorOption } from '../../../../interface/Editor'
|
||||||
import { RangeManager } from '../../../range/RangeManager'
|
import { RangeManager } from '../../../range/RangeManager'
|
||||||
import { Draw } from '../../Draw'
|
import { Draw } from '../../Draw'
|
||||||
|
|
||||||
|
interface IDrawTableBorderOption {
|
||||||
|
ctx: CanvasRenderingContext2D;
|
||||||
|
startX: number;
|
||||||
|
startY: number;
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
isDrawFullBorder?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export class TableParticle {
|
export class TableParticle {
|
||||||
|
|
||||||
private range: RangeManager
|
private range: RangeManager
|
||||||
@@ -13,14 +22,19 @@ export class TableParticle {
|
|||||||
this.options = draw.getOptions()
|
this.options = draw.getOptions()
|
||||||
}
|
}
|
||||||
|
|
||||||
private _drawBorder(ctx: CanvasRenderingContext2D, startX: number, startY: number, width: number, height: number) {
|
private _drawBorder(payload: IDrawTableBorderOption) {
|
||||||
|
const { ctx, startX, startY, width, height, isDrawFullBorder } = payload
|
||||||
ctx.beginPath()
|
ctx.beginPath()
|
||||||
const x = Math.round(startX)
|
const x = Math.round(startX)
|
||||||
const y = Math.round(startY)
|
const y = Math.round(startY)
|
||||||
ctx.translate(0.5, 0.5)
|
ctx.translate(0.5, 0.5)
|
||||||
|
if (isDrawFullBorder) {
|
||||||
|
ctx.rect(x, y, width, height)
|
||||||
|
} else {
|
||||||
ctx.moveTo(x, y + height)
|
ctx.moveTo(x, y + height)
|
||||||
ctx.lineTo(x, y)
|
ctx.lineTo(x, y)
|
||||||
ctx.lineTo(x + width, y)
|
ctx.lineTo(x + width, y)
|
||||||
|
}
|
||||||
ctx.stroke()
|
ctx.stroke()
|
||||||
ctx.translate(-0.5, -0.5)
|
ctx.translate(-0.5, -0.5)
|
||||||
}
|
}
|
||||||
@@ -159,14 +173,23 @@ export class TableParticle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public render(ctx: CanvasRenderingContext2D, element: IElement, startX: number, startY: number) {
|
public render(ctx: CanvasRenderingContext2D, element: IElement, startX: number, startY: number) {
|
||||||
const { colgroup, trList } = element
|
const { colgroup, trList, borderType } = element
|
||||||
if (!colgroup || !trList) return
|
if (!colgroup || !trList || borderType === TableBorder.EMPTY) return
|
||||||
const { scale } = this.options
|
const { scale } = this.options
|
||||||
const tableWidth = element.width! * scale
|
const tableWidth = element.width! * scale
|
||||||
const tableHeight = element.height! * scale
|
const tableHeight = element.height! * scale
|
||||||
|
const isExternalBorderType = borderType === TableBorder.EXTERNAL
|
||||||
ctx.save()
|
ctx.save()
|
||||||
// 渲染边框
|
// 渲染边框
|
||||||
this._drawBorder(ctx, startX, startY, tableWidth, tableHeight)
|
this._drawBorder({
|
||||||
|
ctx,
|
||||||
|
startX,
|
||||||
|
startY,
|
||||||
|
width: tableWidth,
|
||||||
|
height: tableHeight,
|
||||||
|
isDrawFullBorder: isExternalBorderType
|
||||||
|
})
|
||||||
|
if (!isExternalBorderType) {
|
||||||
// 渲染表格
|
// 渲染表格
|
||||||
for (let t = 0; t < trList.length; t++) {
|
for (let t = 0; t < trList.length; t++) {
|
||||||
const tr = trList[t]
|
const tr = trList[t]
|
||||||
@@ -186,6 +209,7 @@ export class TableParticle {
|
|||||||
ctx.translate(-0.5, -0.5)
|
ctx.translate(-0.5, -0.5)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
ctx.restore()
|
ctx.restore()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,11 @@
|
|||||||
"verticalAlign": "Vertical align",
|
"verticalAlign": "Vertical align",
|
||||||
"verticalAlignTop": "Top",
|
"verticalAlignTop": "Top",
|
||||||
"verticalAlignMiddle": "Middle",
|
"verticalAlignMiddle": "Middle",
|
||||||
"verticalAlignBottom": "Bottom"
|
"verticalAlignBottom": "Bottom",
|
||||||
|
"border": "Table border",
|
||||||
|
"borderAll": "All",
|
||||||
|
"borderEmpty": "Empty",
|
||||||
|
"borderExternal": "External"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"datePicker": {
|
"datePicker": {
|
||||||
|
|||||||
@@ -39,7 +39,11 @@
|
|||||||
"verticalAlign": "垂直对齐",
|
"verticalAlign": "垂直对齐",
|
||||||
"verticalAlignTop": "顶端对齐",
|
"verticalAlignTop": "顶端对齐",
|
||||||
"verticalAlignMiddle": "垂直居中",
|
"verticalAlignMiddle": "垂直居中",
|
||||||
"verticalAlignBottom": "底端对齐"
|
"verticalAlignBottom": "底端对齐",
|
||||||
|
"border": "表格边框",
|
||||||
|
"borderAll": "所有框线",
|
||||||
|
"borderEmpty": "无框线",
|
||||||
|
"borderExternal": "外侧框线"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"datePicker": {
|
"datePicker": {
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ export const EDITOR_ELEMENT_ZIP_ATTR: Array<keyof IElement> = [
|
|||||||
'rowMargin',
|
'rowMargin',
|
||||||
'dashArray',
|
'dashArray',
|
||||||
'trList',
|
'trList',
|
||||||
|
'borderType',
|
||||||
'width',
|
'width',
|
||||||
'height',
|
'height',
|
||||||
'url',
|
'url',
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
export enum TableBorder {
|
||||||
|
ALL = 'all',
|
||||||
|
EMPTY = 'empty',
|
||||||
|
EXTERNAL = 'external'
|
||||||
|
}
|
||||||
+3
-1
@@ -34,6 +34,7 @@ import { defaultCursorOption } from './dataset/constant/Cursor'
|
|||||||
import { IPageNumber } from './interface/PageNumber'
|
import { IPageNumber } from './interface/PageNumber'
|
||||||
import { defaultPageNumberOption } from './dataset/constant/PageNumber'
|
import { defaultPageNumberOption } from './dataset/constant/PageNumber'
|
||||||
import { VerticalAlign } from './dataset/enum/VerticalAlign'
|
import { VerticalAlign } from './dataset/enum/VerticalAlign'
|
||||||
|
import { TableBorder } from './dataset/enum/table/Table'
|
||||||
|
|
||||||
export default class Editor {
|
export default class Editor {
|
||||||
|
|
||||||
@@ -175,7 +176,8 @@ export {
|
|||||||
Command,
|
Command,
|
||||||
KeyMap,
|
KeyMap,
|
||||||
BlockType,
|
BlockType,
|
||||||
PaperDirection
|
PaperDirection,
|
||||||
|
TableBorder
|
||||||
}
|
}
|
||||||
|
|
||||||
// 对外类型
|
// 对外类型
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { ControlComponent, ImageDisplay } from '../dataset/enum/Control'
|
import { ControlComponent, ImageDisplay } from '../dataset/enum/Control'
|
||||||
import { ElementType } from '../dataset/enum/Element'
|
import { ElementType } from '../dataset/enum/Element'
|
||||||
import { RowFlex } from '../dataset/enum/Row'
|
import { RowFlex } from '../dataset/enum/Row'
|
||||||
|
import { TableBorder } from '../dataset/enum/table/Table'
|
||||||
import { IBlock } from './Block'
|
import { IBlock } from './Block'
|
||||||
import { ICheckbox } from './Checkbox'
|
import { ICheckbox } from './Checkbox'
|
||||||
import { IControl } from './Control'
|
import { IControl } from './Control'
|
||||||
@@ -32,6 +33,7 @@ export interface IElementStyle {
|
|||||||
export interface ITableAttr {
|
export interface ITableAttr {
|
||||||
colgroup?: IColgroup[];
|
colgroup?: IColgroup[];
|
||||||
trList?: ITr[];
|
trList?: ITr[];
|
||||||
|
borderType?: TableBorder;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ITableElement {
|
export interface ITableElement {
|
||||||
@@ -40,14 +42,14 @@ export interface ITableElement {
|
|||||||
tableId?: string;
|
tableId?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ITable = ITableAttr & ITableElement
|
||||||
|
|
||||||
export interface IHyperlinkElement {
|
export interface IHyperlinkElement {
|
||||||
valueList?: IElement[];
|
valueList?: IElement[];
|
||||||
url?: string;
|
url?: string;
|
||||||
hyperlinkId?: string;
|
hyperlinkId?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ITable = ITableAttr & ITableElement
|
|
||||||
|
|
||||||
export interface ISuperscriptSubscript {
|
export interface ISuperscriptSubscript {
|
||||||
actualSize?: number;
|
actualSize?: number;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user